=== Trace listing source: msbio1.lst 1 ; PAGE ,132 ; 2 ; TITLE MSBIO1.asm - BIOS 3 ;============================================================================== 4 ;REVISION HISTORY: 5 ;AN000 - New for DOS Version 4.00 - J.K. 6 ;AC000 - Changed for DOS Version 4.00 - J.K. 7 ;AN00x - PTM number for DOS Version 4.00 - J.K. 8 ;============================================================================== 9 %if 0 ; COMMENT * 10 THE LINK STEP IS PERFORMED BY USING THE FOLLOWING "NEW.ARF" FILE: 11 msbio1+ 12 msSTACK+ 13 MsCON+ 14 msAUX+ 15 msLPT+ 16 msCLOCK+ 17 msdISK+ 18 msBIO2+ 19 C:\BIO2\OLDOBJ\disk+ 20 C:\BIO2\OLDOBJ\msinit+ 21 C:\BIO2\OLDOBJ\sysinit1+ 22 C:\BIO2\OLDOBJ\sysinit2+ 23 C:\BIO2\OLDOBJ\sysimes,msbio,/M; 24 25 THE FOLLOWING IS A BATCH FILE THAT CAN BE USED TO CREATE THE IBMBIO.COM 26 WHERE "LOCSCR" IS A FILE THAT JUST HAS THE NUMBER, 70: 27 28 link @NEW.ARF 29 exe2bin ibmbio ibmbio.com [list -] 1 ****************** <1> warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi] 14 <2> [list -] 14 <1> [list -] 57 58 %include "entryseg.nas" 1 <1> === Switch to base=000000h -> "DOSENTRY" 2 <1> section DOSENTRY class=%[DOSENTRY] === Switch to base=000000h -> "DOSENTRY" 3 <1> section DOSENTRY 59 60 %include "ddataseg.nas" 1 <1> === Switch to base=001140h -> "DOSSTART" 2 <1> section DOSSTART align=16 PUBLIC class=DOSSTART 3 <1> ; (no prior section) ; DOSSTART ENDS 4 <1> === Switch to base=001140h -> "START" 5 <1> section START align=1 PUBLIC class=START 6 <1> ; (no prior section) ; START ENDS 7 <1> === Switch to base=001140h -> "CONSTANTS" 8 <1> section CONSTANTS align=2 PUBLIC class=CONST 9 <1> ; (no prior section) ; CONSTANTS ENDS 10 <1> === Switch to base=001140h -> "DATA" 11 <1> section DATA align=2 PUBLIC class=DATA 12 <1> ; (no prior section) ; DATA ENDS 13 <1> === Switch to base=001140h -> "TABLE" 14 <1> section TABLE align=2 PUBLIC class=TABLE 15 <1> ; (no prior section) ; TABLE ENDS 16 <1> === Switch to base=001140h -> "CODE" 17 <1> section CODE align=1 PUBLIC class=CODE 18 <1> ; (no prior section) ; CODE ENDS 19 <1> === Switch to base=001140h -> "DOSDATATABLE" 20 <1> section DOSDATATABLE align=2 PUBLIC class=DOSDATACODE 21 <1> ; (no prior section) ; DOSDATATABLE ENDS 22 <1> === Switch to base=001140h -> "DOSDATACODE" 23 <1> section DOSDATACODE align=1 PUBLIC class=DOSDATACODE 24 <1> ; (no prior section) ; DOSDATACODE ENDS 25 <1> === Switch to base=001140h -> "LAST" 26 <1> section LAST align=16 PUBLIC class=LAST 27 <1> ; (no prior section) ; LAST ENDS 28 <1> 29 <1> group DOSGROUP DOSSTART START CONSTANTS DATA TABLE CODE DOSDATATABLE DOSDATACODE LAST 61 === Switch to base=002530h -> "AFTERDOSDATA" 62 addsection AFTERDOSDATA, align=16 class=AFTERDOSDATA 63 === Switch to base=002530h -> "SYSINITSEG" 64 addsection SYSINITSEG, PUBLIC class=INIT === Switch to base=002530h -> "SYSINITTRAIL" 65 addsection SYSINITTRAIL, PUBLIC class=INIT 66 67 group SYSINITGROUP SYSINITSEG SYSINITTRAIL 68 === Switch to base=008400h -> "AFTERSYSINIT" 69 addsection AFTERSYSINIT, PUBLIC class=AFTERSYSINIT align=16 70 global SYSSIZE 71 SYSSIZE LABEL BYTE 72 73 %include "dcodeseg.nas" 1 <1> 2 <1> %ifndef DCODESEGNAS 3 <1> %assign DCODESEGNAS 1 4 <1> === Switch to base=008400h -> "DOSCODETABLE" 5 <1> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <1> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=008400h -> "DOSCODECODE" 7 <1> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <1> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=008400h -> "DOSBIOCODE" 9 <1> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=008400h -> "BIOCODE" 10 <1> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <1> 12 <1> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <1> 14 <1> %endif 74 %include "msgroup.mac" ;DEFINE CODE SEGMENT 1 <1> EVBOUND equ 1 ;THIS VALUE BEING 0 DOES NO BOUNDARY ALLIGNMENT, VALUE 1 ;3.30 2 <1> ; ALIGNS TO EVEN ;3.30 3 <1> 4 <1> ; NASM original macros 5 <1> 6 <1> %include "dcodeseg.nas" 1 <2> 2 <2> %ifndef DCODESEGNAS 3 <2> %assign DCODESEGNAS 1 4 <2> === Switch to base=008400h -> "DOSCODETABLE" 5 <2> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <2> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=008400h -> "DOSCODECODE" 7 <2> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <2> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=008400h -> "DOSBIOCODE" 9 <2> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=008400h -> "BIOCODE" 10 <2> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <2> 12 <2> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <2> 14 <2> %endif 7 <1> 8 <1> %if EVBOUND ;;IF EVEN (WORD) ALLIGNMENT IS REQUESTED, ;3.30 9 <1> 10 <1> %imacro EVENB 0.nolist 11 <1> EVEN ;;ADJUST TO EVEN BOUNDARY 12 <1> %endmacro 13 <1> 14 <1> %imacro ODD 0.nolist 15 <1> %if (($ - $$) % 2) == 0 16 <1> db ? 17 <1> %endif 18 <1> %endmacro 19 <1> 20 <1> %else ;;SINCE EVEN ALLIGNMENT IS NOT DESIRED, JUST USE BYTE ALLI;3.30 GNMENT 21 <1> 22 <1> %imacro EVENB 0.nolist 23 <1> ;;REQUEST FOR WORD ALLIGNMENT DOES NOTHING ;3.30 24 <1> %endmacro 25 <1> 26 <1> %imacro ODD 0.nolist 27 <1> ;;REQUEST FOR ODD ALLIGNMENT DOES NOTHING ;3.30 28 <1> %endmacro 29 <1> 30 <1> %endif ;3.30 31 <1> 32 <1> %imacro CODE_SEGMENT 0.nolist === Switch to base=008400h -> "BIOCODE" 33 <1> section BIOCODE 34 <1> %endmacro 35 <1> 36 <1> ; end of NASM original macros 37 <1> 38 <1> CODE_SEGMENT ;3.30 39 <1> ASSUME CS:BIOCODE ;3.30 40 <1> ;3.30 75 === Switch to base=008400h -> "DOSCODETABLE" 76 addsection DOSCODETABLE ; actually added in dosseg.nas === Switch to base=008400h -> "DOSCODECODE" 77 addsection DOSCODECODE ; actually added in dosseg.nas 78 === Switch to base=011BF0h -> "AFTERDOSCODE" 79 addsection AFTERDOSCODE, align=16 PUBLIC class=AFTERDOSCODE 80 === Switch to base=008400h -> "BIOCODE" 81 addsection BIOCODE ; actually added before === Switch to base=000000h -> "DOSENTRY" 82 addsection DOSENTRY 83 84 %include "jumpmac.mac" 1 <1> ;;Rev 3.30 Modification 2 <1> ; 3 <1> ; given a label either 2 byte jump to another label _J 4 <1> ; if it is near enough or 3 byte jump to 5 <1> ; 6 <1> 7 <1> ; NASM original macros 8 <1> 9 <1> %if 0 10 <1> %imacro jump 1.nolist 11 <1> ;.xcref 12 <1> 13 <1> %ifndef %1_J ;; is this the first invocation 14 <1> %%a: JMP %1 15 <1> %ELSE 16 <1> %IF (%1_J >= $) || ($-%1_J > 126) 17 <1> %%a: JMP %1 ;; is the jump too far away? 18 <1> %ELSE 19 <1> %%a: JMP %1_J ;; do the short one... 20 <1> %ENDIF 21 <1> %ENDIF 22 <1> %ixdefine %1_j %%a 23 <1> ;.cref 24 <1> %endmacro 25 <1> ;.xcref jump 26 <1> %else 27 <1> %imacro jump 1.nolist 28 <1> ;REDEFINE THE ABOVE MACRO TO ALWAYS TRY A 3 BYTE NEAR JUMP 29 <1> jmp %1 30 <1> %endmacro ;;End of Modification 31 <1> %endif 32 <1> 33 <1> 85 %unimacro PATHSTART 2 86 %unimacro PATHEND 2 87 88 %imacro PATHSTART 2 89 %IF PATHGEN ;3.30 90 PUBLIC %2%1S,%2%1E ;3.30 91 %2%1S LABEL BYTE ;3.30 92 %ENDIF ;3.30 93 %endmacro ;3.30 94 ;3.30 95 %imacro PATHEND 2 96 %IF PATHGEN ;3.30 97 %2%1E LABEL BYTE ;3.30 98 %ENDIF ;3.30 99 %endmacro ;3.30 100 101 %include "pushpop.mac" 1 <1> ; NASM original macros 2 <1> 3 <1> %unimacro stripangles 2.nolist 4 <1> %assign ?stackdepth 0 5 <1> 6 <1> %imacro stripangles 2.nolist 7 <1> %defstr %%param %2 8 <1> %rep 16 9 <1> %substr %%opening %%param 1 10 <1> %ifidn %%opening, '<' 11 <1> %substr %%param %%param 2,-1 12 <1> %endif 13 <1> %endrep 14 <1> %rep 16 15 <1> %strlen %%length %%param 16 <1> %substr %%closing %%param %%length 17 <1> %ifidn %%closing, '>' 18 <1> %substr %%param %%param 1,-2 19 <1> %endif 20 <1> %endrep 21 <1> %deftok %%token %%param 22 <1> %1 %%token 23 <1> %endmacro 24 <1> 25 <1> ;BREAK 26 <1> 27 <1> %imacro SaveReg 0-*.nolist ;; push those registers 28 <1> %rep %0 29 <1> %assign ?stackdepth ?stackdepth + 1 30 <1> stripangles push, %1 31 <1> %rotate 1 32 <1> %endrep 33 <1> %endmacro 34 <1> ;.xcref SaveReg 35 <1> 36 <1> ;BREAK 37 <1> 38 <1> %imacro RestoreReg 0-*.nolist ;; pop those registers 39 <1> %rep %0 40 <1> %assign ?stackdepth ?stackdepth - 1 41 <1> stripangles pop, %1 42 <1> %rotate 1 43 <1> %endrep 44 <1> %endmacro 45 <1> ;.xcref RestoreReg 102 %include "devsym.mac" ;MJB001 1 <1> %warning out: DEVSYM.INC... 1 ****************** <1> warning: out: DEVSYM.INC... [-w+user] 2 <1> ; SCCSID = @(#)DEVSYM.ASM 1.10 85/09/04 3 <1> ; SCCSID = @(#)DEVSYM.ASM 1.10 85/09/04 4 <1> 5 <1> ; THE DEVICE TABLE LIST HAS THE FORM: 6 <1> SYSDEV STRUC 0 00000000 ???????? SDEVNEXT DD ? ;POINTER TO NEXT DEVICE HEADER 0 00000004 ???? SDEVATT DW ? ;ATTRIBUTES OF THE DEVICE 0 00000006 ???? SDEVSTRAT DW ? ;STRATEGY ENTRY POINT 0 00000008 ???? SDEVINT DW ? ;INTERRUPT ENTRY POINT 0 0000000A ???????????????? SDEVNAME DB 8 DUP (?) ;NAME OF DEVICE (ONLY FIRST BYTE USED FOR BLOCK) 12 <1> SYSDEV ENDS 13 <1> 14 <1> ; 15 <1> ; ATTRIBUTE BIT MASKS 16 <1> ; 17 <1> ; CHARACTER DEVICES: 18 <1> ; 19 <1> ; BIT 15 -> MUST BE 1 20 <1> ; 14 -> 1 IF THE DEVICE UNDERSTANDS IOCTL CONTROL STRINGS 21 <1> ; 13 -> 1 IF THE DEVICE SUPPORTS OUTPUT-UNTIL-BUSY 22 <1> ; 12 -> UNUSED 23 <1> ; 11 -> 1 IF THE DEVICE UNDERSTANDS OPEN/CLOSE 24 <1> ; 10 -> MUST BE 0 25 <1> ; 9 -> MUST BE 0 26 <1> ; 8 -> UNUSED 27 <1> ; 7 -> UNUSED 28 <1> ; 6 -> UNUSED 29 <1> ; 5 -> UNUSED 30 <1> ; 4 -> 1 IF DEVICE IS RECIPIENT OF INT 29H 31 <1> ; 3 -> 1 IF DEVICE IS CLOCK DEVICE 32 <1> ; 2 -> 1 IF DEVICE IS NULL DEVICE 33 <1> ; 1 -> 1 IF DEVICE IS CONSOLE OUTPUT 34 <1> ; 0 -> 1 IF DEVICE IS CONSOLE INPUT 35 <1> ; 36 <1> ; BLOCK DEVICES: 37 <1> ; 38 <1> ; BIT 15 -> MUST BE 0 39 <1> ; 14 -> 1 IF THE DEVICE UNDERSTANDS IOCTL CONTROL STRINGS 40 <1> ; 13 -> 1 IF THE DEVICE DETERMINES MEDIA BY EXAMINING THE FAT ID BYTE. 41 <1> ; THIS REQUIRES THE FIRST SECTOR OF THE FAT TO *ALWAYS* RESIDE IN 42 <1> ; THE SAME PLACE. 43 <1> ; 12 -> UNUSED 44 <1> ; 11 -> 1 IF THE DEVICE UNDERSTANDS OPEN/CLOSE/REMOVABLE MEDIA 45 <1> ; 10 -> MUST BE 0 46 <1> ; 9 -> MUST BE 0 47 <1> ; 8 -> UNUSED 48 <1> ; 7 -> UNUSED 49 <1> ; 6 -> IF DEVICE HAS SUPPORT FOR GETMAP/SETMAP OF LOGICAL DRIVES. 50 <1> ; IF THE DEVICE UNDERSTANDS GENERIC IOCTL FUNCTION CALLS. 51 <1> ; 5 -> UNUSED 52 <1> ; 4 -> UNUSED 53 <1> ; 3 -> UNUSED 54 <1> ; 2 -> UNUSED 55 <1> ; 1 -> UNUSED 56 <1> ; 0 -> UNUSED 57 <1> ; 58 <1> 59 <1> DEVTYP EQU 8000H ; BIT 15 - 1 IF CHAR, 0 IF BLOCK 60 <1> CHARDEV EQU 8000H 61 <1> DEVIOCTL EQU 4000H ; BIT 14 - CONTROL MODE BIT 62 <1> ISFATBYDEV EQU 2000H ; BIT 13 - DEVICE USES FAT ID BYTES, 63 <1> ; COMP MEDIA. 64 <1> OUTTILBUSY EQU 2000H ; OUTPUT UNTIL BUSY IS ENABLED 65 <1> ISNET EQU 1000H ; BIT 12 - 1 IF A NET DEVICE, 0 IF 66 <1> ; NOT. CURRENTLY BLOCK ONLY. 67 <1> DEVOPCL EQU 0800H ; BIT 11 - 1 IF THIS DEVICE HAS 68 <1> ; OPEN,CLOSE AND REMOVABLE MEDIA 69 <1> ; ENTRY POINTS, 0 IF NOT 70 <1> 71 <1> EXTENTBIT EQU 0400H ; BIT 10 - CURRENTLY 0 ON ALL DEVS 72 <1> ; THIS BIT IS RESERVED FOR FUTURE USE 73 <1> ; TO EXTEND THE DEVICE HEADER BEYOND 74 <1> ; ITS CURRENT FORM. 75 <1> 76 <1> ; NOTE BIT 9 IS CURRENTLY USED ON IBM SYSTEMS TO INDICATE "DRIVE IS SHARED". 77 <1> ; SEE IOCTL FUNCTION 9. THIS USE IS NOT DOCUMENTED, IT IS USED BY SOME 78 <1> ; OF THE UTILITIES WHICH ARE SUPPOSED TO FAIL ON SHARED DRIVES ON SERVER 79 <1> ; MACHINES (FORMAT,CHKDSK,RECOVER,..). 80 <1> 81 <1> DEV320 EQU 0040H ;BIT 6 - FOR BLOCK DEVICES, THIS 82 <1> ;DEVICE SUPPORTS SET/GET MAP OF 83 <1> ;LOGICAL DRIVES, AND SUPPORTS 84 <1> ;GENERIC IOCTL CALLS. 85 <1> ;FOR CHARACTER DEVICES, THIS 86 <1> ;DEVICE SUPPORTS GENERIC IOCTL. 87 <1> ;THIS IS A DOS 3.2 DEVICE DRIVER. 88 <1> ISSPEC EQU 0010H ;BIT 4 - THIS DEVICE IS SPECIAL 89 <1> ISCLOCK EQU 0008H ;BIT 3 - THIS DEVICE IS THE CLOCK DEVICE. 90 <1> ISNULL EQU 0004H ;BIT 2 - THIS DEVICE IS THE NULL DEVICE. 91 <1> ISCOUT EQU 0002H ;BIT 1 - THIS DEVICE IS THE CONSOLE OUTPUT. 92 <1> ISCIN EQU 0001H ;BIT 0 - THIS DEVICE IS THE CONSOLE INPUT. 93 <1> EXTDRVR EQU 0002H ;BIT 1 - BLOCK DEVICE EXTNDED DRIVER 94 <1> 95 <1> ;STATIC REQUEST HEADER 96 <1> SRHEAD STRUC 0 00000000 ?? REQLEN DB ? ;LENGTH IN BYTES OF REQUEST BLOCK 0 00000001 ?? REQUNIT DB ? ;DEVICE UNIT NUMBER 0 00000002 ?? REQFUNC DB ? ;TYPE OF REQUEST 0 00000003 ???? REQSTAT DW ? ;STATUS WORD 0 00000005 ???????????????? DB 8 DUP(?) ;RESERVED FOR QUEUE LINKS 102 <1> SRHEAD ENDS 103 <1> 104 <1> ;STATUS WORD MASKS 105 <1> STERR EQU 8000H ;BIT 15 - ERROR 106 <1> STBUI EQU 0200H ;BIT 9 - BUISY 107 <1> STDON EQU 0100H ;BIT 8 - DONE 108 <1> STECODE EQU 00FFH ;ERROR CODE 109 <1> ; 2/12/KK 110 <1> ; Interim character identifier 2/12/KK 111 <1> Ddkey EQU 0000010000000000B ; 2/12/KK 112 <1> 113 <1> ;FUNCTION CODES 114 <1> DEVINIT EQU 0 ;INITIALIZATION 115 <1> DINITHL EQU 26 ;SIZE OF INIT HEADER 116 <1> DEVMDCH EQU 1 ;MEDIA CHECK 117 <1> DMEDHL EQU 15 ;SIZE OF MEDIA CHECK HEADER 118 <1> DEVBPB EQU 2 ;GET BPB 119 <1> DEVRDIOCTL EQU 3 ;IOCTL READ 120 <1> DBPBHL EQU 22 ;SIZE OF GET BPB HEADER 121 <1> DEVRD EQU 4 ;READ 122 <1> DRDWRHL EQU 22 ;SIZE OF RD/WR HEADER 123 <1> DEVRDND EQU 5 ;NON DESTRUCTIVE READ NO WAIT (CHARACTER DEVS) 124 <1> DRDNDHL EQU 14 ;SIZE OF NON DESTRUCTIVE READ HEADER 125 <1> DEVIST EQU 6 ;INPUT STATUS 126 <1> DSTATHL EQU 13 ;SIZE OF STATUS HEADER 127 <1> DEVIFL EQU 7 ;INPUT FLUSH 128 <1> DFLSHL EQU 15 ;SIZE OF FLUSH HEADER 129 <1> DEVWRT EQU 8 ;WRITE 130 <1> DEVWRTV EQU 9 ;WRITE WITH VERIFY 131 <1> DEVOST EQU 10 ;OUTPUT STATUS 132 <1> DEVOFL EQU 11 ;OUTPUT FLUSH 133 <1> DEVWRIOCTL EQU 12 ;IOCTL WRITE 134 <1> DEVOPN EQU 13 ;DEVICE OPEN 135 <1> DEVCLS EQU 14 ;DEVICE CLOSE 136 <1> DOPCLHL EQU 13 ;SIZE OF OPEN/CLOSE HEADER 137 <1> DEVRMD EQU 15 ;REMOVABLE MEDIA 138 <1> REMHL EQU 13 ;SIZE OF REMOVABLE MEDIA HEADER 139 <1> GENIOCTL EQU 19 140 <1> ; THE NEXT THREE ARE USED IN DOS 4.0 141 <1> ; 20 142 <1> ; 21 143 <1> ; 22 144 <1> DEVGETOWN EQU 23 ;GET DEVICE OWNER 145 <1> DEVSETOWN EQU 24 ;SET DEVICE OWNER 146 <1> OWNHL EQU 13 ;SIZE OF DEVICE OWNER HEADER 147 <1> 148 <1> DEVOUT EQU 16 ; OUTPUT UNTIL BUSY. 149 <1> DEVOUTL EQU DEVWRT ; LENGTH OF OUTPUT UNTIL BUSY 150 <1> 151 <1> ; GENERIC IOCTL REQUEST STRUCTURE 152 <1> ; SEE THE DOS 4.0 DEVICE DRIVER SPEC FOR FURTHER ELABORATION. 153 <1> ; 154 <1> IOCTL_REQ STRUC 155 00000000 <1> DB (SRHEAD_struc_size) DUP(?) 156 <1> ; GENERIC IOCTL ADDITION. 0 0000000D ?? MAJORFUNCTION DB ? ;FUNCTION CODE 0 0000000E ?? MINORFUNCTION DB ? ;FUNCTION CATEGORY 0 0000000F ???? REG_SI DW ? 0 00000011 ???? REG_DI DW ? 0 00000013 ???????? GENERICIOCTL_PACKET DD ? ; POINTER TO DATA BUFFER 162 <1> IOCTL_REQ ENDS 163 <1> 164 <1> ; DEFINITIONS FOR IOCTL_REQ.MINORFUNCTION 165 <1> GEN_IOCTL_WRT_TRK EQU 40H 166 <1> GEN_IOCTL_RD_TRK EQU 60H 167 <1> GEN_IOCTL_FN_TST EQU 20H ; USED TO DIFF. BET READS AND WRTS 168 <1> 169 <1> ;; 32-bit absolute read/write input list structure 170 <1> 171 <1> ABS_32RW STRUC 0 00000000 ???????? SECTOR_RBA DD ? ; relative block address 0 00000004 ???? ABS_RW_COUNT DW ? ; number of sectors to be transferred 0 00000006 ???????? BUFFER_ADDR DD ? ; data addrress 175 <1> ABS_32RW ENDS 176 <1> 177 <1> ;; media ID info 178 <1> 179 <1> MEDIA_ID_INFO STRUC 0 00000000 ???? MEDIA_level DW ? ; info level 0 00000002 ???????? MEDIA_Serial DD ? ; serial # 182 00000006 <1> MEDIA_Label DB 11 dup (?) ;volume label 0 00000011 ???????????????? MEDIA_System DB 8 dup (?) ;system type 184 <1> MEDIA_ID_INFO ENDS 185 <1> 186 <1> ;; equates for DOS34_FLAG 187 <1> 188 <1> IFS_ABSRW EQU 00001H ;IFS absolute read/write 189 <1> NO_IFS_ABSRW EQU 0FFFEH ;no IFS absolute read/write 190 <1> IFS_DRIVE_RESET EQU 00002H ;IFS drvive reset 191 <1> NO_IFS_DRIVE_RESET EQU 0FFFDH ;no IFS drive reset 192 <1> FROM_DISK_RESET EQU 00004H ;from disk reset 193 <1> NO_FROM_DISK_RESET EQU 0FFFBH ;not from disk reset 194 <1> From_String_Output EQU 00008H ;from con string output 195 <1> NO_From_String_Output EQU 0FFF7H ;not from con string output 196 <1> From_DOS_WRITE EQU 00010H ;from dos_write 197 <1> NO_From_DOS_WRITE EQU 0FFEFH ;not from dos_write 198 <1> Force_I24_Fail EQU 00020H ;form IFS CALL BACK 199 <1> NO_Force_I24_Fail EQU 0FFDFH ;not form IFS CALL BACK 200 <1> Disable_EOF_I24 EQU 00040H ;disable EOF int24 for input status 201 <1> NO_Disable_EOF_I24 EQU 0FFBFH ;disable EOF int24 for input status 202 <1> DBCS_VOLID EQU 00080H ;indicate from volume id 203 <1> DBCS_VOLID2 EQU 00100H ;indicate 8th char is DBCS 204 <1> CTRL_BREAK_FLAG EQU 00200H ;indicate control break is input 205 <1> NO_CTRL_BREAK_FLAG EQU 0FDFFH ;reset control break 206 <1> SEARCH_FASTOPEN EQU 00400H ;set fastopen flag for search 207 <1> X25_special EQU 00800H ;flag for X25 driver 103 %include "msbds.mac" 1 <1> 2 <1> %warning out: MSBDS.INC... 2 ****************** <1> warning: out: MSBDS.INC... [-w+user] 3 <1> ; SCCSID = @(#)IBMBDS.ASM 1.9 85/09/16 4 <1> ;============================================================================== 5 <1> ;REVISION HISTORY: 6 <1> ;AN000 - New for DOS Version 4.00 - J.K. 7 <1> ;AC000 - Changed for DOS Version 4.00 - J.K. 8 <1> ;AN00x - PTM number for DOS Version 4.00 - J.K. 9 <1> ;============================================================================== 10 <1> ;AN001; D113 Disable I/O access to unformatted media 9/03/87 J.K. 11 <1> ;============================================================================== 12 <1> 13 <1> ; VALUES FOR VARIOUS FLAGS IN BDS.FLAGS. 14 <1> 15 <1> FNON_REMOVABLE EQU 01H ;FOR NON-REMOVABLE MEDIA 16 <1> FCHANGELINE EQU 02H ;IF CHANGELINE SUPPORTED ON DRIVE 17 <1> RETURN_FAKE_BPB EQU 04H ; WHEN SET, DON'T DO A BUILD BPB 18 <1> ; JUST RETURN THE FAKE ONE 19 <1> GOOD_TRACKLAYOUT EQU 08H ; THE TRACK LAYOUT HAS NO FUNNY SECTORS 20 <1> ; FCHANGED_BY_FORMAT EQU 08H 21 <1> FI_AM_MULT EQU 10H ;IF MORE THAN ONE LOGICAL FOR THIS PHYSICAL 22 <1> FI_OWN_PHYSICAL EQU 20H ;SIGNIFY LOGICAL OWNER OF THIS PHYSICAL 23 <1> FCHANGED EQU 40H ;INDICATES MEDIA CHANGED 24 <1> SET_DASD_TRUE EQU 80H ; SET DASD BEFORE NEXT FORMAT 25 <1> FCHANGED_BY_FORMAT EQU 100H ;MEDIA CHANGED BY FORMAT 26 <1> UNFORMATTED_MEDIA EQU 200H ;AN001; Fixed disk only 27 <1> F_LBA equ 400h ; LBA supported 28 <1> 29 <1> LBAPACKETSTRUC struc 0 00000000 ???? lpSize dw ? 0 00000002 ???? lpCount dw ? 0 00000004 ???????? lpBuffer dd ? 0 00000008 ???????????????? lpSector dd ?,? 34 <1> LBAPACKETSTRUC ends 35 <1> 36 <1> ; 37 <1> ; VARIOUS FORM FACTORS TO DESCRIBE MEDIA 38 <1> ; 39 <1> FF48TPI EQU 0 40 <1> FF96TPI EQU 1 41 <1> FFSMALL EQU 2 42 <1> FFHARDFILE EQU 5 43 <1> FFOTHER EQU 7 44 <1> 45 <1> BDS_TYPE STRUC 0 00000000 ???????? LINK DD ? ; LINK TO NEXT BDS 0 00000004 ?? DRIVENUM DB ? ; INT 13 DRIVE NUMBER 0 00000005 ?? DRIVELET DB ? ; DOS DRIVE NUMBER 0 00000006 ???? BYTEPERSEC DW ? ; NUMBER OF BYTES/SEC 0 00000008 ?? SECPERCLUS DB ? ; SEC PER ALLOCATION UNIT 0 00000009 ???? RESSEC DW ? ; NUMBER OF RESERVED SECTORS 0 0000000B ?? CFAT DB ? ; NUMBER OF FATS 0 0000000C ???? CDIR DW ? ; NUMBER OF DIRECTORY ENTRIES 0 0000000E ???? DRVLIM DW ? ; NUMBER OF SECTORS ON MEDIUM 0 00000010 ?? MEDIAD DB ? ; MEDIA DESCRIPTOR BYTE 0 00000011 ???? CSECFAT DW ? ; NUMBER OF SECTORS/FAT 0 00000013 ???? SECLIM DW ? ; SECTORS PER TRACK 0 00000015 ???? HDLIM DW ? ; MAX NUMBER OF HEADS 0 00000017 ???? HIDSEC_L DW ? ; NUMBER OF HIDDEN SECTORS 0 00000019 ???? HIDSEC_H dw ? ;0 ;J.K.87 0 0000001B ???? DRVLIM_L dw ? ;0 ;J.K.87 0 0000001D ???? DRVLIM_H dw ? ;0 ;J.K.87 0 0000001F ?? FATSIZ DB ? ; FLAGS... 0 00000020 ???? OPCNT DW ? ; OPEN REF. COUNT 0 00000022 ?? FORMFACTOR DB ? ; FORM FACTOR INDEX 0 00000023 ???? FLAGS DW ? ; VARIOUS FLAGS 0 00000025 ???? CCYLN DW ? ; MAX NUMBER OF CYLINDERS 0 00000027 ???? RBYTEPERSEC DW ? ; RECOMMENDED BPB 0 00000029 ?? RSECPERCLUS DB ? 0 0000002A ???? RRESSEC DW ? 0 0000002C ?? RCFAT DB ? 0 0000002D ???? RCDIR DW ? 0 0000002F ???? RDRVLIM DW ? 0 00000031 ?? RMEDIAD DB ? 0 00000032 ???? RCSECFAT DW ? 0 00000034 ???? RSECLIM DW ? 0 00000036 ???? RHDLIM DW ? 0 00000038 ???? RHIDSEC_L DW ? 0 0000003A ???? RHIDSEC_H DW ? ;0 ;J.K.87 0 0000003C ???? RDRVLIM_L dw ? ;0 ;J.K.87 0 0000003E ???? RDRVLIM_H dw ? ;0 ;J.K.87 0 00000040 ???????????? RESERVE DB 6 DUP (?) ; RESERVED FOR FUTURE 0 00000046 ?? TRACK DB ? ; LAST TRACK ACCESSED ON DRIVE 0 00000047 ???? TIM_LO DW ? ; TIME OF LAST ACCESS. KEEP 0 00000049 ???? TIM_HI DW ? ; THESE CONTIGUOUS. 86 0000004B <1> VOLID DB 12 DUP (?) ; VOLUME ID OF MEDIUM 0 00000057 ???????? VOL_SERIAL dd ? ;0 ;J.K.87 Current volume serial number from Boot record 88 0000005B <1> FILESYS_Id db 9 dup (?) ;(0) ;J.K.87 Current file system id from Boot record 89 <1> BDS_TYPE ENDS 90 <1> 91 <1> BPBSIZE equ TRACK - RBYTEPERSEC ; SIZE IN BYTES OF RECBPB AREA IN THE BDS 92 <1> 93 <1> 94 <1> ;********************************************************************* 95 <1> ; BDS structure for mini disk - J.K. 4/7/86 96 <1> ;********************************************************************* 97 <1> 98 <1> BDSM_type struc 0 00000000 ???? mlink DW ? ;-1 ;Link to next structure 0 00000002 ???? DW ? 0 00000004 ?? mdriveNum DB ? ;80 ;Int 13 Drive Number 0 00000005 ?? mdriveLet DB ? ;3 ;Logical Drive Number 0 00000006 ???? mBytePerSec DW ? ;512 0 00000008 ?? mSecPerClus DB ? ;1 ;Sectors/allocation unit 0 00000009 ???? mRESSEC DW ? ;1 ;Reserved sectors for DOS 0 0000000B ?? mcFAT DB ? ;2 ;No. of allocation tables 0 0000000C ???? mcDIR DW ? ;16 ;Number of directory entries 0 0000000E ???? mDRVLIM DW ? ;0 ;Number of sectors (at 512 bytes each) 0 00000010 ?? mMediad DB ? ;11111000B ;Media descriptor 0 00000011 ???? mcSecFat DW ? ;1 ;Number of FAT sectors 0 00000013 ???? mSECLIM DW ? ;0 ;Sector limit 0 00000015 ???? mHDLIM DW ? ;0 ;Head limit 0 00000017 ???? mHIDSEC_L DW ? ;0 ;Hidden sector count 0 00000019 ???? mHidsec_H dw ? ;0 ;J.K.87 0 0000001B ???? mDrvlim_L dw ? ;0 ;J.K.87 0 0000001D ???? mDrvlim_H dw ? ;0 ;J.K.87 0 0000001F ?? mFatSiz DB ? ;0 ;TRUE => bigfat 0 00000020 ???? mOPCNT DW ? ;0 ;Open Ref. Count 0 00000022 ?? mFormFactor DB ? ;3 ;Form Factor 0 00000023 ???? mFLAGS DW ? ;0020H ;Various Flags 0 00000025 ???? mcCyln dw ? ;40 ;max number of cylinders 122 00000027 <1> mRecBPB db 31 dup (?) ;(0) ;Recommended BPB for drive 0 00000046 ?? mTrack db ? ;-1 0 00000047 ???? IsMini dw ? ;1 ;Overlapping TIM_LOH 0 00000049 ???? Hidden_Trks dw ? ;0 ;Overlapping TIM_HIH 126 0000004B <1> mVOLID DB 11 dup (?) ;"NO NAME " ;Volume ID for this disk 0 00000056 ?? DB ? ;0 ;ASCIZII for "NO NAME " 0 00000057 ???????? mVol_Serial dd ? ;0 ;Current volume serial number from Boot record 0 0000005B ???????????????? mFileSys_Id db 8 dup (?) ;"FAT12 " ;Current file system id from Boot record 0 00000063 ?? db ? ;0 131 <1> 132 <1> BDSM_type ENDS 133 <1> ;****************************************************************************** 134 <1> Max_mini_dsk_num equ 23 ;J.K. 4/7/86 - max # of mini disk ibmbio can support 135 <1> ; 136 <1> 104 105 ; REV 2.1 5/1/83 ARR ADDED TIMER INT HANDLER AND CHANGED ORDER OF AUX 106 ; PRN INIT FOR HAL0 107 ; 108 ; REV 2.15 7/13/83 ARR BECAUSE IBM IS FUNDAMENTALY BRAIN DAMAGED, AND 109 ; BASCOM IS RUDE ABOUT THE 1CH TIMER INTERRUPT, THE TIMER 110 ; HANDLER HAS TO GO BACK OUT!!!!! IBM SEEMS UNWILLING TO 111 ; BELIEVE THE PROBLEM IS WITH THE BASCOM RUNTIME, NOT THE 112 ; DOS. THEY HAVE EVEN BEEN GIVEN A PATCH FOR BASCOM!!!!! 113 ; THE CORRECT CODE IS COMMENTED OUT AND HAS AN ARR 2.15 114 ; ANNOTATION. THIS MEANS THE BIOS WILL GO BACK TO THE 115 ; MULTIPLE ROLL OVER BUG. 116 ; REV 2.20 8/5/83 ARR IBM MAKES HARDWARE CHANGE. NOW WANTS TO USE HALF 117 ; HIGHT DRIVES FOR HAL0, AND BACK FIT FOR PC/PC XT. PROBLEM 118 ; WITH HEAD SETTLE TIME. PREVIOUS DRIVES GOT BY ON A 0 119 ; SETTLE TIME, 1/2 HIGHT DRIVES NEED 15 HEAD SETTLE WHEN 120 ; DOING WRITES (0 OK ON READ) IF THE HEAD IS BEING STEPPED. 121 ; THIS REQUIRES A LAST TRACK VALUE TO BE KEPT SO THAT BIOS 122 ; KNOWS WHEN HEAD IS BEING MOVED. TO HELP OUT STUPID 123 ; PROGRAMS THAT ISSUE INT 13H DIRECTLY, THE HEAD SETTLE WILL 124 ; NORMALLY BE SET TO 15. IT WILL BE CHANGED TO 0 ON READS, 125 ; OR ON WRITES WHICH DO NOT REQUIRE HEAD STEP. 126 ; REV 2.21 8/11/83 MZ IBM WANTS WRITE WITH VERIFY TO USE HEAD SETTLE 0. 127 ; USE SAME TRICK AS ABOVE. 128 ; REV 2.25 6/20/83 MJB001 ADDED SUPPORT FOR 96TPI AND SALMON 129 ; REV 2.30 6/27/83 MJB002 ADDED REAL-TIME CLOCK 130 ; REV 2.40 7/8/83 MJB003 ADDED VOLUME-ID CHECKING AND INT 2F MACRO 131 ; DEFINITIONS PUSH* AND POP* 132 ; REV 2.41 7/12/83 ARR MORE 2.X ENHANCEMENTS. OPEN/CLOSE MEDIA CHANGE 133 ; REV 2.42 11/3/83 ARR MORE 2.X ENHANCEMENTS. DISK OPEN/CLOSE, FORMAT 134 ; CODE AND OTHER MISC HOOKED OUT TO SHRINK BIOS. CODE FOR 135 ; DISK OPEN/CLOSE, FORMAT INCLUDED ONLY WITH 96TPI DISKS. 136 ; REV 2.43 12/6/83 MZ EXAMINE BOOT SECTORS ON HARD DISKS FOR 16-BIT FAT 137 ; CHECK. EXAMINE LARGE FAT BIT IN BPB FOR WALK OF MEDIA FOR 138 ; DOS 139 ; REV 2.44 12/9/83 ARR CHANGE TO ERROR REPORTING ON INT 17H 140 ; REV 2.45 12/22/83 MZ MAKE HEAD SETTLE CHANGE ONLY WHEN DISK PARM IS 0. 141 142 ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 143 ; 144 ; IBM ADDRESSES FOR I/O 145 ; 146 ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 147 148 %include "msdskpr.mac" 1 <1> ; The following structure defines the disk parameter table 2 <1> ; pointed to by Interrupt vector 1EH (location 0:78H) 3 <1> 4 <1> DISK_PARMS STRUC 0 00000000 ?? DISK_SPECIFY_1 DB ? 0 00000001 ?? DISK_SPECIFY_2 DB ? 0 00000002 ?? DISK_MOTOR_WAIT DB ? ; Wait till motor off 0 00000003 ?? DISK_SECTOR_SIZ DB ? ; Bytes/Sector (2 = 512) 0 00000004 ?? DISK_EOT DB ? ; Sectors per track (MAX) 0 00000005 ?? DISK_RW_GAP DB ? ; Read Write Gap 0 00000006 ?? DISK_DTL DB ? 0 00000007 ?? DISK_FORMT_GAP DB ? ; Format Gap Length 0 00000008 ?? DISK_FILL DB ? ; Format Fill Byte 0 00000009 ?? DISK_HEAD_STTL DB ? ; Head Settle Time (MSec) 0 0000000A ?? DISK_MOTOR_STRT DB ? ; Motor start delay 16 <1> DISK_PARMS ENDS 17 <1> 18 <1> ROMStatus equ 1 19 <1> ROMRead equ 2 20 <1> ROMWrite equ 3 21 <1> ROMVerify equ 4 22 <1> ROMFormat equ 5 149 150 LF equ 10 ;LINE FEED 151 CR equ 13 ;CARRIAGE RETURN 152 BACKSP equ 8 ;BACKSPACE 153 BRKADR equ 1BH * 4 ;006C 1BH BREAK VECTOR ADDRESS 154 TIMADR equ 1CH * 4 ;0070 1CH TIMER INTERRUPT 155 DSKADR equ 1EH * 4 ;ADDRESS OF PTR TO DISK PARAMETERS 156 SEC9 equ 522H ;ADDRESS OF DISK PARAMETERS 157 HEADSETTLE equ SEC9+9 ; ARR 2.20 ADDRESS OF HEAD SETTLE TIME 158 NORMSETTLE equ 15 ; ARR 2.20 NORMAL HEAD SETTLE 159 SPEEDSETTLE equ 0 ; ARR 2.20 SPEED UP SETTLE TIME 160 INITSPOT equ 534H ; ARR IBM WANTS 4 ZEROS HERE 161 AKPORT equ 20H 162 EOI equ 20H 163 164 ASSUME CS:BIOCODE,DS:NOTHING,ES:NOTHING 165 166 EXTRN MEDIA$CHK:NEAR 167 EXTRN GET$BPB:NEAR 168 EXTRN DSK$INIT:NEAR 169 EXTRN DSK$READ:NEAR 170 EXTRN DSK$WRIT:NEAR 171 EXTRN DSK$WRITV:NEAR 172 EXTRN DSK$OPEN:NEAR 173 EXTRN DSK$CLOSE:NEAR 174 EXTRN DSK$REM:NEAR 175 EXTRN GENERIC$IOCTL:NEAR 176 EXTRN IOCTL$GETOWN:NEAR 177 EXTRN IOCTL$SETOWN:NEAR 178 EXTRN CON$READ:NEAR 179 EXTRN CON$RDND:NEAR 180 EXTRN CON$FLSH:NEAR 181 EXTRN CON$WRIT:NEAR 182 ; EXTRN CON$GENIOCTL:NEAR ;J.K. 4/29/86 183 EXTRN AUX$READ:NEAR 184 EXTRN AUX$WRIT:NEAR 185 EXTRN AUX$FLSH:NEAR 186 EXTRN AUX$RDND:NEAR 187 EXTRN AUX$WRST:NEAR 188 EXTRN TIM$READ:NEAR 189 EXTRN TIM$WRIT:NEAR 190 EXTRN PRN$WRIT:NEAR 191 EXTRN PRN$STAT:NEAR 192 EXTRN PRN$TILBUSY:NEAR 193 EXTRN PRN$GENIOCTL:NEAR 194 EXTRN WRMSG:NEAR 195 196 197 ;=== Push trace listing source: msbdata.nas 198 %include "msbdata.nas" ; NASM included file 1 <1> 2 <1> %include "nasmorg.mac" 1 <2> 2 <2> %if 0 3 <2> 4 <2> NASM macros to replace JWasm org directive 5 <2> 2024 by E. C. Masloch, Public Domain 6 <2> 7 <2> %endif 8 <2> 9 <2> %imacro org 1-2.nolist db 0 10 <2> times (%1) - ($ - $$) %2 11 <2> %endmacro 3 <1> === Switch to base=000000h -> "DOSENTRY" 4 <1> section DOSENTRY 5 <1> ;============================================================================== 6 <1> ;REVISION HISTORY: 7 <1> ;AN000 - New for DOS Version 3.4 - J.K. 8 <1> ;AC000 - Changed for DOS Version 3.4 - J.K. 9 <1> ;ANxxx - PTR, DCRs 10 <1> ;============================================================================== 11 <1> ;AN001 - d9 Double word MOV instruction for 80386 based machine. 7/1/87 J.K. 12 <1> ;AN002 - d25 Change DASD ERP to that recommended by Storage Systems. 7/29/87 J.K. 13 <1> ;AN003; d304 Boot record structure change for OS2 11/9/87 J.K. 14 <1> ;============================================================================== 15 <1> EXTRN INIT:NEAR 16 <1> 17 <1> PUBLIC START$ 18 <1> START$: 0 00000000 E9[0000] JMP INIT ;START$ PATCH BY INIT TO POINT TO 20 <1> ;HDRIVE BPB 21 <1> ; PUBLIC FORMAT_PATCH 22 <1> ;FORMAT_PATCH: ;ARR 2.42 23 <1> ; JMP FMTSET ;MJB001 DISPATCH FOR CALL FROM FORMAT UTILITY 24 <1> 25 <1> 26 <1> PATHSTART 001,BIO 89 <2> %IF PATHGEN 90 <2> PUBLIC %2%1S,%2%1E 91 <2> %2%1S LABEL BYTE 92 <2> %ENDIF 27 <1> 28 <1> ; DB 20 DUP (0) ;IBM WANTS SOME ZEROED AREA (DELETED) 29 <1> 30 <1> 31 <1> ;HEADER DB "Ver 2.45" 32 <1> ;-------------------------------------------------------------- 33 <1> ; 34 <1> ; COMMAND JUMP TABLES 35 <1> ; 36 <1> ; BEWARE - THESE TABLES OVERLAP SOMEWHAT! -C.P. 37 <1> ; 38 <1> === Switch to base=008400h -> "BIOCODE" 39 <1> usesection BIOCODE 40 <1> 0 00007BB0 ?? ODD 42 <1> DSKTBL LABEL BYTE 0 00007BB1 18 DB (.last - .) / 2 ; THIS IS THE SIZE OF THE TABLE YUK!!!! 0 00007BB2 [0000] .: DW DSK$INIT 0 00007BB4 [0000] DW MEDIA$CHK 0 00007BB6 [0000] DW GET$BPB 0 00007BB8 [7301] DW CMDERR ;RS 0 00007BBA [0000] DW DSK$READ 0 00007BBC [6F01] DW BUS$EXIT 0 00007BBE [8F01] DW EXIT 0 00007BC0 [8F01] DW EXIT 0 00007BC2 [0000] DW DSK$WRIT 0 00007BC4 [0000] DW DSK$WRITV 0 00007BC6 [8F01] DW EXIT ;ARR 2.41 0 00007BC8 [8F01] DW EXIT ;ARR 2.41 0 00007BCA [7301] DW CMDERR ;RS 57 <1> ; PUBLIC TABLE_PATCH 58 <1> ; TABLE_PATCH: equ $ ;ARR 2.42 0 00007BCC [0000] DW DSK$OPEN ;ARR 2.41 0 00007BCE [0000] DW DSK$CLOSE ;ARR 2.41 0 00007BD0 [0000] DW DSK$REM ;ARR 2.41 0 00007BD2 [8F01] DW EXIT 0 00007BD4 [8F01] DW EXIT 0 00007BD6 [8F01] DW EXIT 0 00007BD8 [0000] DW GENERIC$IOCTL ; KGS 3.20 0 00007BDA [8F01] DW EXIT 0 00007BDC [8F01] DW EXIT 0 00007BDE [8F01] DW EXIT 0 00007BE0 [0000] DW IOCTL$GETOWN ; RS 3.20 0 00007BE2 [0000] .last: DW IOCTL$SETOWN ; RE 3.20 71 <1> 0 00007BE4 ?? ODD 73 <1> CONTBL LABEL BYTE 0 00007BE5 0A DB (.last - .) / 2 0 00007BE6 [8F01] .: DW EXIT ;INIT 0 00007BE8 [8F01] DW EXIT 0 00007BEA [8F01] DW EXIT 0 00007BEC [7301] DW CMDERR 0 00007BEE [0000] DW CON$READ 0 00007BF0 [0000] DW CON$RDND 0 00007BF2 [8F01] DW EXIT 0 00007BF4 [0000] DW CON$FLSH 0 00007BF6 [0000] DW CON$WRIT 0 00007BF8 [0000] DW CON$WRIT 0 00007BFA [8F01] .last: DW EXIT ;ARR 2.41 86 <1> 87 <1> ; DW CMDERR ;J.K. 4/29/86 for CON$GENIOCTL support 88 <1> ; DW CMDERR ;J.K. 4/29/86 89 <1> ; DW CMDERR ;J.K. 4/29/86 90 <1> ; DW CMDERR ;J.K. 4/29/86 91 <1> ; DW CMDERR ;J.K. 4/29/86 92 <1> ; DW CMDERR ;J.K. 4/29/86 93 <1> ; DW CMDERR ;J.K. 4/29/86 94 <1> ; DW CMDERR ;J.K. 4/29/86 95 <1> ; DW CON$GENIOCTL ;J.K. 4/29/86 96 <1> 0 00007BFC ?? ODD 98 <1> AUXTBL LABEL BYTE 0 00007BFD 0A DB (.last - .) / 2 0 00007BFE [8F01] .: DW EXIT ;INIT 0 00007C00 [8F01] DW EXIT 0 00007C02 [8F01] DW EXIT 0 00007C04 [7301] DW CMDERR 0 00007C06 [0000] DW AUX$READ 0 00007C08 [0000] DW AUX$RDND 0 00007C0A [8F01] DW EXIT 0 00007C0C [0000] DW AUX$FLSH 0 00007C0E [0000] DW AUX$WRIT 0 00007C10 [0000] DW AUX$WRIT 0 00007C12 [0000] .last: DW AUX$WRST 111 <1> 0 00007C14 ?? ODD 113 <1> TIMTBL LABEL BYTE 0 00007C15 09 DB (.last - .) / 2 0 00007C16 [8F01] .: DW EXIT ;INIT 0 00007C18 [8F01] DW EXIT 0 00007C1A [8F01] DW EXIT 0 00007C1C [7301] DW CMDERR 0 00007C1E [0000] DW TIM$READ 0 00007C20 [6F01] DW BUS$EXIT 0 00007C22 [8F01] DW EXIT 0 00007C24 [8F01] DW EXIT 0 00007C26 [0000] DW TIM$WRIT 0 00007C28 [0000] .last: DW TIM$WRIT 125 <1> 0 00007C2A ?? ODD 127 <1> PRNTBL LABEL BYTE 0 00007C2B 16 DB (.last - .) / 2 0 00007C2C [8F01] .: DW EXIT ;INIT 0 00007C2E [8F01] DW EXIT 0 00007C30 [8F01] DW EXIT 0 00007C32 [7301] DW CMDERR 0 00007C34 [8301] DW EXIT$ZER ;INDICATE ZERO CHARS READ 0 00007C36 [6F01] DW BUS$EXIT 0 00007C38 [8F01] DW EXIT 0 00007C3A [8F01] DW EXIT 0 00007C3C [0000] DW PRN$WRIT 0 00007C3E [0000] DW PRN$WRIT 0 00007C40 [0000] DW PRN$STAT 0 00007C42 [8F01] DW EXIT 0 00007C44 [8F01] DW EXIT ;ARR 2.41 0 00007C46 [8F01] DW EXIT ;ARR 2.41 0 00007C48 [8F01] DW EXIT ;ARR 2.41 0 00007C4A [8F01] DW EXIT ;ARR 2.41 0 00007C4C [0000] DW PRN$TILBUSY 0 00007C4E [8F01] DW EXIT ;RS 3.20 0 00007C50 [8F01] DW EXIT ;RS 3.20 0 00007C52 [0000] DW PRN$GENIOCTL ;RS 3.20 0 00007C54 [8F01] DW EXIT ;RS 3.20 0 00007C56 [8F01] DW EXIT ;RS 3.20 0 00007C58 [8F01] .last: DW EXIT ;RS 3.20 152 <1> 153 <1> === Switch to base=000000h -> "DOSENTRY" 154 <1> usesection DOSENTRY 155 <1> 156 <1> extern conentry, prnentry, auxentry 157 <1> extern com1entry, com2entry, com3entry, com4entry 158 <1> extern lpt1entry, lpt2entry, lpt3entry, clockentry, blockentry 159 <1> 0 00000003 00 EVENB 161 <1> PUBLIC CONHEADER 162 <1> CONHEADER LABEL WORD ;HEADER FOR DEVICE "CON" 0 00000004 [1600][0000] dw AUXDEV2, seg AUXDEV2 0 00000008 1380 DW 10000000_00010011B ;CON IN AND CON OUT + SPECIAL 0 0000000A [E803] DW strategyentry 0 0000000C [ED03] DW conentry 0 0000000E 434F4E2020202020 DB 'CON ' 168 <1> 169 <1> EVENB 170 <1> PUBLIC AUXDEV2 171 <1> AUXDEV2 LABEL WORD ;HEADER FOR DEVICE "AUX" 0 00000016 [2800][0000] dw PRNDEV2, seg PRNDEV2 0 0000001A 0080 DW 10000000_00000000B 0 0000001C [E803] DW strategyentry 0 0000001E [F703] DW auxentry 0 00000020 4155582020202020 DB 'AUX ' 177 <1> 178 <1> EVENB 179 <1> PUBLIC PRNDEV2 180 <1> PRNDEV2 LABEL WORD ;HEADER FOR DEVICE "PRN" 0 00000028 [3A00][0000] dw TIMDEV, seg TIMDEV 0 0000002C 40A0 DW CHARDEV + OUTTILBUSY + DEV320 0 0000002E [E803] DW strategyentry 0 00000030 [F203] DW prnentry 0 00000032 50524E2020202020 DB 'PRN ' 186 <1> 187 <1> EVENB 188 <1> PUBLIC TIMDEV 189 <1> TIMDEV LABEL WORD 0 0000003A [4C00][0000] dw DSKDEV, seg DSKDEV 0 0000003E 0880 DW 10000000_00001000B 0 00000040 [E803] DW strategyentry 0 00000042 [1F04] DW clockentry 0 00000044 434C4F434B242020 DB 'CLOCK$ ' 195 <1> 196 <1> EVENB 197 <1> PUBLIC DSKDEV 198 <1> DSKDEV LABEL WORD 0 0000004C [6000][0000] dw COM1DEV, seg COM1DEV 0 00000050 4208 DW 00001000_01000010B ;J.K.I1. 32 bit sector calculation 0 00000052 [E803] DW strategyentry 0 00000054 [2404] DW blockentry 0 00000056 04 DRVMAX DB 4 204 <1> PUBLIC DRVMAX 205 <1> 206 <1> PUBLIC STEP_DRV 0 00000057 FE STEP_DRV DB -2 ; ARR 2.20 LAST DRIVE ACCESSED 208 <1> 209 <1> PUBLIC PHYS_DRV 0 00000058 00 PHYS_DRV DB 0 ; USED BY SETDRIVE FOR GETTING BDS FOR 211 <1> ; LOGICAL DRIVE, OR PHYSICAL DRIVE. 212 <1> PUBLIC FHAVE96 0 00000059 00 FHAVE96 DB 0 ; FLAG TO INDICATE PRESENCE OF 214 <1> ; 96TPI SUPPORT 215 <1> PUBLIC SINGLE 0 0000005A 00 SINGLE DB 0 ; USED TO DETECT SINGLE DRIVE SYSTEMS 217 <1> 218 <1> PUBLIC FHAVEK09 0 0000005B 00 FHAVEK09 DB 0 ;INDICATES IF THIS IS A K09 OR NOT 220 <1> ; USED BY CONSOLE DRIVER. 221 <1> PUBLIC NEW_ROM 0 0000005C 00 NEW_ROM DB 0 ;SET TO 1 IF WE HAVE A ROM THAT CAN 223 <1> ; HANDLE STRANGE MEDIA LAYOUTS. 224 <1> 225 <1> PUBLIC FSETOWNER 0 0000005D ?? FSETOWNER DB ? ;=1 IF WE ARE SETTING THE OWNER OF A 227 <1> ;DRIVE. (EXAMINED BY CHECKSINGLE). 228 <1> public Secrete_Code 0 0000005E 6B6A Secrete_Code dw 'kj' ;J.K. 11/7/86 Secrete code for DOS 3.30 IBMBIO. 230 <1> 231 <1> EVENB 232 <1> PUBLIC COM1DEV 233 <1> COM1DEV LABEL WORD 0 00000060 [7200][0000] dw LPT1DEV, seg LPT1DEV 0 00000064 0080 DW 10000000_00000000B 0 00000066 [E803] DW strategyentry 0 00000068 [FC03] DW com1entry 0 0000006A 434F4D3120202020 DB 'COM1 ' 239 <1> 240 <1> EVENB 241 <1> PUBLIC LPT1DEV 242 <1> LPT1DEV LABEL WORD 0 00000072 [8400][0000] dw LPT2DEV, seg LPT2DEV 0 00000076 40A0 DW CHARDEV + OUTTILBUSY + DEV320 0 00000078 [E803] DW strategyentry 0 0000007A [1004] DW lpt1entry 0 0000007C 4C50543120202020 DB 'LPT1 ' 248 <1> 249 <1> EVENB 250 <1> PUBLIC LPT2DEV 251 <1> LPT2DEV LABEL WORD 0 00000084 [9600][0000] dw LPT3DEV, seg LPT3DEV 0 00000088 40A0 DW CHARDEV + OUTTILBUSY + DEV320 0 0000008A [E803] DW strategyentry 0 0000008C [1504] DW lpt2entry 0 0000008E 4C50543220202020 DB 'LPT2 ' 257 <1> 258 <1> EVENB 259 <1> PUBLIC LPT3DEV 260 <1> LPT3DEV LABEL WORD 0 00000096 [C400][0000] dw COM2DEV, seg COM2DEV 0 0000009A 40A0 DW CHARDEV + OUTTILBUSY + DEV320 0 0000009C [E803] DW strategyentry 0 0000009E [1A04] DW lpt3entry 0 000000A0 4C50543320202020 DB 'LPT3 ' 266 <1> 267 <1> 0 000000A8 00 org 0B0h 269 <1> EVENB 0 000000B0 FFFFFFFF dd -1 ; prior OLD13 271 <1> 272 <1> org 0B4h ; noted in EDR-DOS sources as being used by some applications 273 <1> PUBLIC ORIG13 274 <1> ORIG13 label DWORD 0 000000B4 32310000 db '21',0,0 ;J.K. 11/8/86 This is my employee serial # !!! 276 <1> 277 <1> EVENB 278 <1> PUBLIC PTRSAV 0 000000B8 00000000 PTRSAV DD 0 280 <1> PUBLIC AUXBUF 0 000000BC 00000000 AUXBUF DB 0,0,0,0 ;SET OF 1 BYTE BUFFERS FOR COM 1,2,3, AND 4 282 <1> 283 <1> EVENB 284 <1> PUBLIC PREVOPER,NUMBER_OF_SEC 0 000000C0 ???? PREVOPER DW ? ; HOLDS INT 13 REQUEST (I.E. REGISTER AX). 0 000000C2 ?? NUMBER_OF_SEC DB ? ; HOLDS NUMBER OF SECTORS TO READ ON AN ECC ERROR 287 <1> 288 <1> 0 000000C3 00 EVENB 290 <1> PUBLIC COM2DEV 291 <1> COM2DEV LABEL WORD 0 000000C4 [D600][0000] dw COM3DEV, seg COM3DEV 0 000000C8 0080 DW 10000000_00000000B 0 000000CA [E803] DW strategyentry 0 000000CC [0104] DW com2entry 0 000000CE 434F4D3220202020 DB 'COM2 ' 297 <1> 298 <1> EVENB 299 <1> PUBLIC COM3DEV 300 <1> COM3DEV LABEL WORD ;EDK 0 000000D6 [E800][0000] dw COM4DEV, seg COM4DEV 0 000000DA 0080 DW 10000000_00000000B 0 000000DC [E803] DW strategyentry 0 000000DE [0604] DW com3entry 0 000000E0 434F4D3320202020 DB 'COM3 ' 306 <1> 307 <1> EVENB 308 <1> PUBLIC COM4DEV 309 <1> COM4DEV LABEL WORD ;EDK 0 000000E8 FFFF[0000] DW -1,DOSENTRY 0 000000EC 0080 DW 10000000_00000000B 0 000000EE [E803] DW strategyentry 0 000000F0 [0B04] DW com4entry 0 000000F2 434F4D3420202020 DB 'COM4 ' 315 <1> 316 <1> 317 <1> %imacro irtentry 1-2.nolist 318 <1> db %1 319 <1> %2 dd 0 320 <1> %endmacro 321 <1> 322 <1> 323 <1> %assign num 256-($-$$) 324 <1> %warning num bytes in front of IRT 324 ****************** <1> warning: 6 bytes in front of IRT [-w+user] 325 <1> 0 000000FA 00 _fill 256, 0, START$ ; fixed address: 70h:100h 327 <1> InterruptRestorationTable: 328 <1> global InterruptRestorationTable 0 00000100 1000000000 irtentry 10h 0 00000105 1300000000 irtentry 13h, OLD13: 331 <1> PUBLIC OLD13 0 0000010A 1500000000 irtentry 15h 0 0000010F 1900000000 irtentry 19h, ORIG19: 334 <1> PUBLIC ORIG19 0 00000114 1B00000000 irtentry 1Bh 336 <1> ; Above interrupts are in the order MS-DOS 6.x saves them 337 <1> ; (FDEMM386?/Jemm expects Int19 within the first five entries) 0 00000119 0000000000 irtentry 00h 0 0000011E FF db -1 340 <1> 0 0000011F 00 EVENB 342 <1> PUBLIC WRTVERIFY 343 <1> WRTVERIFY LABEL WORD 344 <1> PUBLIC RFLAG 345 <1> ROMREAD equ ROMRead ; NASM port equate 0 00000120 02 RFLAG DB ROMREAD ;2 FOR READ, 3 FOR WRITE 0 00000121 00 VERIFY DB 0 ;1 IF VERIFY AFTER WRITE 348 <1> PUBLIC SECCNT 0 00000122 0000 SECCNT DW 0 350 <1> PUBLIC HARDNUM 0 00000124 63 HARDNUM DB 99 ;LOGICAL DRIVE NUMBER OF FIRST HARDFILE 352 <1> PUBLIC MOTORSTARTUP,SETTLECURRENT,SETTLESLOW 0 00000125 ?? MOTORSTARTUP DB ? ; VALUE FROM TABLE 0 00000126 ?? SETTLECURRENT DB ? ; VALUE FROM TABLE 0 00000127 ?? SETTLESLOW DB ? ; SLOW SETTLE VALUE 356 <1> 0 00000128 ?? NEXTSPEED DB ? ; VALUE OF SPEED TO BE USED 358 <1> save_head_sttl equ Save_head_sttl ; NASM port label 359 <1> public save_head_sttl 0 00000129 ?? Save_head_sttl db ? ;used by READ_SECTOR routine 361 <1> 362 <1> PUBLIC EOT 0 0000012A 09 EOT DB 9 364 <1> 0 0000012B 00 EVENB 366 <1> PUBLIC DPT 0 0000012C ???????? DPT DD ? 368 <1> 369 <1> ;KEEP THE NEXT TWO ITEMS CONTIGUOUS - SEE IOCTL_BLOCK FOR REASON 370 <1> PUBLIC CURSEC,CURHD,CURTRK,SPSAV 0 00000130 00 CURSEC DB 0 ;CURRENT SECTOR 0 00000131 00 CURHD DB 0 ;CURRENT HEAD 0 00000132 0000 CURTRK DW 0 ;CURRENT TRACK 0 00000134 0000 SPSAV DW 0 ;SAVE THE STACK POINTER 375 <1> 376 <1> ; THE FOLLOWING ARE USED FOR IOCTL FUNCTION CALLS 377 <1> PUBLIC FORMT_EOT,HDNUM,TRKNUM,GAP_PATCH 0 00000136 08 FORMT_EOT DB 8 ; EOT USED FOR FORMAT 0 00000137 00 HDNUM DB 0 ; HEAD NUMBER 0 00000138 0000 TRKNUM DW 0 ; TRACK BEING MANIPULATED 0 0000013A 50 GAP_PATCH DB 50H ; FORMAT GAP PATCHED INTO DPT 382 <1> 383 <1> ;DISK ERRORS RETURNED FROM THE IBM ROM 384 <1> PUBLIC ERRIN 385 <1> ERRIN LABEL BYTE 0 0000013B CC db 0cch ;AN002; Write Fault error 0 0000013C 80 DB 80H ;NO RESPONSE 0 0000013D 40 DB 40H ;SEEK FAILURE 0 0000013E 10 DB 10H ;BAD CRC 0 0000013F 08 DB 8 ;DMA OVERRUN 0 00000140 06 DB 6 ; MEDIA CHANGE 0 00000141 04 DB 4 ;SECTOR NOT FOUND 0 00000142 03 DB 3 ;WRITE ATTEMPT TO WRITE-PROTECT DISK 394 <1> PUBLIC LSTERR 0 00000143 00 LSTERR DB 0 ;ALL OTHER ERRORS 396 <1> 397 <1> ;RETURNED ERROR CODES CORRESPONDING TO ABOVE 398 <1> PUBLIC ERROUT 399 <1> ERROUT LABEL BYTE 0 00000144 0A db 10 ;AN002; Write Fault error 0 00000145 02 DB 2 ;NO RESPONSE 0 00000146 06 DB 6 ;SEEK FAILURE 0 00000147 04 DB 4 ;BAD CRC 0 00000148 04 DB 4 ;DMA OVERRUN 0 00000149 0F DB 15 ; INVALID MEDIA CHANGE 0 0000014A 08 DB 8 ;SECTOR NOT FOUND 0 0000014B 00 DB 0 ;WRITE ATTEMPT ON WRITE-PROTECT DISK 0 0000014C 0C DB 12 ;GENERAL ERROR 409 <1> PUBLIC NUMERR 410 <1> NUMERR equ ERROUT-ERRIN 411 <1> 412 <1> 413 <1> ;********************************************************************* 414 <1> ; "BDS" CONTAINS INFORMATION FOR EACH DRIVE IN THE SYSTEM. 415 <1> ; VARIOUS VALUES ARE PATCHED WHENEVER ACTIONS ARE PERFORMED. 416 <1> ; SECTORS/ALLOC. UNIT IN BPB INITIALLY SET TO -1 TO SIGNIFY THAT 417 <1> ; THE BPB HAS NOT BEEN FILLED. LINK ALSO SET TO -1 TO SIGNIFY END 418 <1> ; OF LIST. # OF CYLINDERS IN MAXPARMS INITIALIZED TO -1 TO INDICATE 419 <1> ; THAT THE PARAMETERS HAVE NOT BEEN SET. 420 <1> ; 421 <1> 422 <1> BPBTYPE STRUC 0 00000000 ?? SPF DB ? 0 00000001 ?? SPT DB ? 0 00000002 ?? CDIRE DB ? 0 00000003 ???? CSEC DW ? 0 00000005 ?? SPA DB ? 0 00000006 ?? CHEAD DB ? 429 <1> BPBTYPE ENDS 430 <1> PUBLIC SM92 431 <1> SM92: 432 <1> BPBTYPE_size equ BPBTYPE_struc_size ; NASM port equate 433 <1> istruc BPBTYPE 434 <1> at SPF 0 0000014D 03 db 3 436 <1> at SPT 0 0000014E 09 db 9 438 <1> at CDIRE 0 0000014F 70 db 70H 440 <1> at CSEC 0 00000150 A005 dw 2*9*80 442 <1> at SPA 0 00000152 02 db 2 444 <1> at CHEAD 0 00000153 02 db 2 446 <1> iend 447 <1> 448 <1> 0 00000154 00 org 16Ch ; noted in EDR-DOS sources as a fixed offset 450 <1> EVENB 451 <1> ; WARNING!!! THESE ARE ADDRESSED TOGETHER IN GETDX 0 0000016C 00 AUXNUM DB 0 ;WHICH AUX DEVICE WAS REQUESTED 0 0000016D 00 DB 0 454 <1> 455 <1> ; following data apparently must be after AUXNUM / 16Ch. 456 <1> ; don't know why but we get hangs or stack overflow errors 457 <1> ; if we move this to before 16Ch. 458 <1> 459 <1> ; HARD-WIRE THE LINK TO THE NEXT INT2F HANDLER. 460 <1> EVENB 461 <1> PUBLIC NEXT2F_13 462 <1> NEXT2F_13 LABEL WORD 463 <1> extern disk_i2F 0 0000016E [BB03][0000] dw disk_i2F, seg disk_i2F 465 <1> 466 <1> EVENB 467 <1> PUBLIC START_BDS 468 <1> START_BDS LABEL WORD 0 00000172 FFFFFFFF dw -1,-1 ; START OF BDS LINKED LIST. 470 <1> 471 <1> PUBLIC ACCESSCOUNT 0 00000176 00 ACCESSCOUNT DB 0 ; NUMBER OF TIMES MEDIA CHECK CALLED 473 <1> PUBLIC TIM_DRV 0 00000177 FF TIM_DRV DB -1 ; TIME WHEN LAST DISK I/O PERFORMED 475 <1> PUBLIC MEDBYT 0 00000178 ?? MEDBYT DB ? 477 <1> 478 <1> ; end of data that must be after 16Ch. 479 <1> 480 <1> ;------------------------------------------------------------- 481 <1> 482 <1> ; READ IN BOOT SECTOR HERE, READ DONE IN READBOOT. 483 <1> ; ALSO READ SECTOR FOR DMA CHECK FOR HARD DISK. 484 <1> 485 <1> ;J.K. The buffer for a disk sector is going to be at a double word boundary 486 <1> ; for 80386 machine. 487 <1> 0 00000179 00 align 16, db 0 489 <1> DISKSECTOR equ DiskSector ; NASM port label 490 <1> PUBLIC DISKSECTOR 491 00000180 <1> DiskSector DB 11 DUP(?) ; TAKE CARE OF 3 JUMP BYTES PLUS OEM NAME. 492 <1> BPB_IN_SECTOR equ Bpb_In_Sector ; NASM port label 493 <1> PUBLIC BPB_IN_SECTOR 0 0000018B ???? Bpb_In_Sector DW ? 495 <1> SECPERCLUSINSECTOR equ SecPerClusInSector ; NASM port label 496 <1> PUBLIC SECPERCLUSINSECTOR 0 0000018D ?? SecPerClusInSector DB ? 0 0000018E ???? DW ? 499 <1> public NumberOfFats 0 00000190 ?? NumberOfFats DB ? 0 00000191 ???? DW ? 0 00000193 ???? DW ? 503 <1> MEDIABYTE equ MediaByte ; NASM port label 504 <1> PUBLIC MEDIABYTE 0 00000195 ?? MediaByte DB ? 0 00000196 ???? DW ? 0 00000198 ???? DW ? 0 0000019A ???? DW ? 0 0000019C ???? DW ? 0 0000019E ???? DW ? ;AN000; Extended Hidden sector (high) 0 000001A0 ???? DW ? ;AN000; Extended Total sector (low) 0 000001A2 ???? DW ? ;AN000; Extended Total sector (high) 0 000001A4 ?? db ? ;AN003; PHYDRV in boot record. 0 000001A5 ?? db ? ;AN003; CURRENT HEAD in boot record. 515 <1> public Ext_Boot_Sig 0 000001A6 ?? Ext_Boot_Sig DB ? ;AN000; Extended Boot record sig. (=90h) 517 <1> public Boot_Serial_L 0 000001A7 ???? Boot_Serial_L DW ? ;AN000; Boot volume serial number (Low) 519 <1> public Boot_Serial_H 0 000001A9 ???? Boot_Serial_H DW ? ;AN000; Boot volume serial number (High) 521 <1> public Boot_Volume_Label 0 000001AB 202020202020202020 Boot_Volume_Label DB 11 dup (' ') ;AN000; Volume label 0 000001B4 2020 523 <1> public Boot_System_ID 0 000001B6 2020202020202020 Boot_System_ID DB 8 dup (' ') ;AN000; File system Id. 0 000001BE 00 times 512-($-DiskSector) db 0 526 <1> 527 <1> 528 <1> global dosentry_xmsentry 529 <1> %include "codesw.mac" 1 <2> DOSCODE_HMA_SEGMENT equ 0FFFEh 2 <2> ; address DOSCODE at this segment when in HMA 3 <2> DOSCODE_HMA_start_at equ (10000h - DOSCODE_HMA_SEGMENT) * 10h 4 <2> ; offset from DOSCODE offset 0 to address 10_0000h 5 <2> DOSCODE_HMA_OFFSET equ DOSCODE_HMA_start_at + 30h 6 <2> ; 50h = 20h ROM-BIOS, 20h VDISK header, 10h HMCB 530 <1> %include "entry.asm" ; new in lDOS 1 <2> 2 <2> %if 0 3 <2> 4 <2> lDOS DOSENTRY handling 5 <2> by E. C. Masloch, 2018--2025 6 <2> 7 <2> Usage of the works is permitted provided that this 8 <2> instrument is retained with the works, so that any entity 9 <2> that uses the works is notified of this instrument. 10 <2> 11 <2> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY. 12 <2> 13 <2> %endif 14 <2> 15 <2> %if 0 16 <2> 17 <2> (lMS-DOS: Comments not current) 18 <2> 19 <2> The DOSENTRY section is always located at segment 70h. It includes some data 20 <2> structures found in MS-DOS (most notably the Int19 interrupt restoration table 21 <2> at 70h:100h), the device headers for all default devices (except NUL) and all 22 <2> code entries into the DOS code. If the DOS code is not relocateable, DOSENTRY 23 <2> and DOSCODE are merged into one section. 24 <2> 25 <2> Relocated entries which are in DOSENTRY for relocation: 26 <2> Interrupt 00h Division error exception 27 <2> Interrupt 06h Invalid opcode exception 28 <2> Interrupt 13h BIOS disk services 29 <2> Interrupt 19h Reboot 30 <2> Interrupt 1Bh Ctrl-Break notification 31 <2> Interrupt 20h Terminate program 32 <2> Interrupt 21h DOS services 33 <2> Interrupt 25h Absolute disk read 34 <2> Interrupt 26h Absolute disk write 35 <2> Interrupt 27h Terminate and stay resident 36 <2> Interrupt 28h Idle 37 <2> Interrupt 29h Display character 38 <2> Interrupt 2Fh Multiplex, DOS services 39 <2> CALL 5 CP/M compatibility services (subset of interrupt 21h) 40 <2> Device strategy All device functions 41 <2> Case map function Maps language-specific characters >=80h to uppercase 42 <2> Redirector mapper Maps unhandled redirector calls to MS-DOS interface 43 <2> 44 <2> If DOSCODE is not the same section as DOSENTRY (if DOSCODE is relocateable), 45 <2> each of the relocated entries calls relocatedentry with a parameter behind the 46 <2> near call opcode. The near call opcode and the byte sized parameter for each 47 <2> entry need 4 byte. relocatedentry insures that DOSCODE is available (switches 48 <2> the A20 line on if DOSCODE is in the HMA) and jumps to the DOSCODE function 49 <2> relocated_relocatedentry. The latter uses the in-code parameter (behind the 50 <2> function call within DOSENTRY) as a displacement into doscode_entrypoint_list, 51 <2> where we store the target near address in DOSCODE. 52 <2> 53 <2> If the target DOSCODE near address is equal to DEVStrategy, then the entry in 54 <2> doscode_entrypoint_list contains another word (after the DEVStrategy address) 55 <2> which points at a device strategy function dispatch table, stored in DOSCODE. 56 <2> Some of the device strategies also include another byte after the table offset, 57 <2> which gives the device unit to use (only used for PRN/LPTx and AUX/COMx). 58 <2> 59 <2> It is insured that an entry of doscode_entrypoint_list with displacement 60 <2> equal to 0CCh is not used, so that relocated_relocatedentry can reliably 61 <2> detect breakpoints set after the call jumps. Such a breakpoint hides the true 62 <2> displacement value and thus must be detected and circumvented. 63 <2> 64 <2> Entries which are in DOSENTRY but don't execute code in DOSCODE: 65 <2> Interrupt 23h Always terminates application 66 <2> Interrupt 24h Always fails call 67 <2> Interrupt 2Eh Always reports error 68 <2> Device interrupt MS-DOS device compatibility (does nothing) 69 <2> Dummy file sharer Always returns error 0001h (Invalid function) 70 <2> Dummy redirector Always returns error 0001h (Invalid function) 71 <2> Other hooked interrupts Do nothing 72 <2> 73 <2> %endif 74 <2> === Switch to base=000000h -> "DOSENTRY" 75 <2> usesection DOSENTRY 76 <2> 77 <2> %assign _DOSCODEHMA 1 78 <2> %assign _RELOCATEDOSCODE 1 79 <2> 80 <2> %assign _FATFS 0 81 <2> %assign _MAPPER 0 82 <2> %assign _INT28 0 83 <2> %assign _CALL5 1 84 <2> 85 <2> 86 <2> %define ENTRYPOINT_LIST .none,dw "",dw "",db "" 87 <2> 88 <2> %imacro _relocate 1-3.nolist "","" 89 <2> call relocatedentry 90 <2> retf ; help debugging. handler will reflect back 91 <2> ; to the stub here with the modified stack. 92 <2> add_to_entrypoint_list %%label,dw %1,dw %2,db %3,ENTRYPOINT_LIST 93 <2> extern %1 94 <2> 95 <2> db %%label - doscode_entrypoint_list 96 <2> %endmacro 97 <2> %if _RELOCATEDOSCODE 98 <2> %idefine relocate _relocate 99 <2> %endif 100 <2> %idefine devicerelocate _relocate 101 <2> 102 <2> %imacro add_to_entrypoint_list 4-*.nolist 103 <2> %if %0 & 3 104 <2> %fatal Expected a number of arguments that is a multiple of four 105 <2> %endif 106 <2> %push 107 <2> %define %$label %1 108 <2> %define %$two %2 109 <2> %define %$three %3 110 <2> %define %$four %4 111 <2> %assign %$found 0 112 <2> %rotate 4 113 <2> %rep (%0 - 4) / 4 114 <2> %ifn %$found 115 <2> %ifidn %$two, %2 116 <2> %ifidn %$three,%3 117 <2> %ifidn %$four, %4 118 <2> %$label: equ %1 119 <2> %assign %$found 1 120 <2> %endif 121 <2> %endif 122 <2> %endif 123 <2> %endif 124 <2> %rotate 4 125 <2> %endrep 126 <2> %ifn %$found 127 <2> %xdefine ENTRYPOINT_LIST ENTRYPOINT_LIST,%$label,%$two,%$three,%$four 128 <2> %endif 129 <2> %pop 130 <2> %endmacro 131 <2> 132 <2> %imacro write_entrypoint_list 0-*.nolist 133 <2> align 2 134 <2> doscode_entrypoint_list: 135 <2> %if %0 & 3 136 <2> %fatal Expected a number of arguments that is a multiple of four 137 <2> %endif 138 <2> %rep %0 / 4 139 <2> align 2 140 <2> ; %if ($ - doscode_entrypoint_list) == 0CCh 141 <2> ; %warning added word to doscode_entrypoint_list to find bp after call jump 142 <2> ; dw 9090h 143 <2> ; %endif 144 <2> %1: ; label (used as displacement from doscode_entrypoint_list) 145 <2> %2 ; entrypoint (word) 146 <2> %3 ; device function table, if any (word) 147 <2> %4 ; device unit number, if any (byte) 148 <2> %rotate 4 149 <2> %endrep 150 <2> doscode_entrypoint_list.end: 151 <2> %endmacro 152 <2> 153 <2> 154 <2> align 2 155 <2> %if _RELOCATEDOSCODE 156 <2> %if _DOSCODEHMA 0 00000380 90 nop 0 00000381 90 nop ; insure ri00o != 0 159 <2> %endif 0 00000382 E8BF00CB00 i00: relocate relocatedi00 161 <2> ; i06: relocate relocatedi06 0 00000387 E8BA00CB02 msdisk_i13: relocate relocatedmsdisk_i13 0 0000038C E8B500CB04 ms96tpi_i13: relocate relocatedms96tpi_i13 164 <2> ; %ifn _INT19_IN_DOSENTRY 0 00000391 E8B000CB06 i19: relocate relocatedi19 166 <2> ; %endif 0 00000396 E8AB00CB08 i1B: relocate relocatedi1B 0 0000039B 31C0 i20: xor ax, ax 0 0000039D E8A400CB0A i21: relocate relocatedi21 0 000003A2 E89F00CB0C i25: relocate relocatedi25 0 000003A7 E89A00CB0E i26: relocate relocatedi26 0 000003AC E89500CB10 i27: relocate relocatedi27 173 <2> %if _INT28 174 <2> i28: relocate relocatedi28 175 <2> %endif 0 000003B1 E89000CB12 i29: relocate relocatedi29 0 000003B6 E88B00CB14 i2F: relocate relocatedi2F 0 000003BB E88600CB16 disk_i2F: relocate relocateddisk_i2F 0 000003C0 E88100CB18 set_i13_i2F: relocate relocatedset_i13_i2F 0 000003C5 E87C00CB1A i31: relocate relocatedi31 181 <2> %if _CALL5 0 000003CA E87700CB1C call5: relocate relocatedcall5 183 <2> %endif 184 <2> %if _FATFS 185 <2> fatfs: jmp short .jump 186 <2> .next: jmp FIXDOSENTRY:mapper 187 <2> .jump: relocate relocatedfatfs 188 <2> fatfs2: jmp short .jump 189 <2> .next: jmp FIXDOSENTRY:NotHooked 190 <2> .jump: relocate relocatedfatfs2 191 <2> %endif 192 <2> %if _MAPPER 193 <2> mapper: relocate relocatedmapper 194 <2> %endif 0 000003CF E87200CB1E casemap:relocate relocatedcasemap 0 000003D4 E86D00CB20 fastentry: relocate relocatedfastentry 0 000003D9 E86800CB22 ifsentry: relocate relocatedifsentry 0 000003DE E86300CB24 okcallentry: relocate relocatedokcallentry 0 000003E3 E85E00CB26 badcallentry: relocate relocatedbadcallentry 200 <2> %endif 0 000003E8 E85900CB28 strategyentry: relocate relocatedstrategyentry 0 000003ED E85400CB2A conentry: relocate relocatedconentry 0 000003F2 E84F00CB2C prnentry: relocate relocatedprnentry 0 000003F7 E84A00CB2E auxentry: relocate relocatedauxentry 0 000003FC E84500CB30 com1entry: relocate relocatedcom1entry 0 00000401 E84000CB32 com2entry: relocate relocatedcom2entry 0 00000406 E83B00CB34 com3entry: relocate relocatedcom3entry 0 0000040B E83600CB36 com4entry: relocate relocatedcom4entry 0 00000410 E83100CB38 lpt1entry: relocate relocatedlpt1entry 0 00000415 E82C00CB3A lpt2entry: relocate relocatedlpt2entry 0 0000041A E82700CB3C lpt3entry: relocate relocatedlpt3entry 0 0000041F E82200CB3E clockentry: relocate relocatedclockentry 0 00000424 E81D00CB40 blockentry: relocate relocatedblockentry 0 00000429 E81800CB42 time_to_ticks_entry: relocate relocatedtime_to_ticks_entry 215 <2> 216 <2> 217 <2> i23: 0 0000042E F9 stc 219 <2> entry_retf: 0 0000042F CB retf 221 <2> 222 <2> i24: 0 00000430 B003 mov al, 03h 224 <2> entry_iret: 0 00000432 CF iret 226 <2> 227 <2> a20off_entry: 0 00000433 B406 mov ah, 06h ; Local Disable A20 (04h would be Global) 0 00000435 2EFF1E[5C05] call far [ cs:dosentry_xmsentry ] 230 <2> ; ignore errors 0 0000043A B404 mov ah, 04h ; Global Disable A20 0 0000043C 2EFF1E[5C05] call far [ cs:dosentry_xmsentry ] 233 <2> ; ignore errors 0 00000441 5B pop bx ; get bx and ax from stack 0 00000442 58 pop ax 0 00000443 CF iret ; pop ip, cs, fl 237 <2> 238 <2> 239 <2> global i20, i21, i25, i26, i27, i2F, call5, i23, i24, entry_iret 240 <2> global fastentry, ifsentry, okcallentry, badcallentry, i00, casemap, i31 241 <2> global a20off_entry, i19, msdisk_i13, ms96tpi_i13, disk_i2F, set_i13_i2F 242 <2> global i29, entry_iret, i1B 243 <2> global conentry, prnentry, auxentry 244 <2> global com1entry, com2entry, com3entry, com4entry 245 <2> global lpt1entry, lpt2entry, lpt3entry, clockentry, blockentry 246 <2> global time_to_ticks_entry 247 <2> 248 <2> %if 0 249 <2> %imacro irtentry 1.nolist 250 <2> db %1 251 <2> dd 0 252 <2> %endmacro 253 <2> 254 <2> 255 <2> %assign num 256-($-$$) 256 <2> %warning num bytes in front of IRT 257 <2> 258 <2> _fill 256, 0, dosentry_start 259 <2> InterruptRestorationTable: 260 <2> irtentry 10h 261 <2> irtentry 13h 262 <2> irtentry 15h 263 <2> irtentry 19h 264 <2> irtentry 1Bh 265 <2> ; Above interrupts are in the order MS-DOS 6.x saves them 266 <2> ; (FDEMM386?/Jemm expects Int19 within the first five entries) 267 <2> 268 <2> irtentry 00h 269 <2> irtentry 01h 270 <2> irtentry 03h 271 <2> irtentry 04h 272 <2> irtentry 06h 273 <2> irtentry 08h 274 <2> irtentry 16h 275 <2> irtentry 1Ch 276 <2> irtentry 1Eh 277 <2> irtentry 21h 278 <2> irtentry 23h 279 <2> irtentry 24h 280 <2> irtentry 29h 281 <2> irtentry 2Fh 282 <2> irtentry 33h 283 <2> db -1 284 <2> %endif 285 <2> 286 <2> 287 <2> extern dosdata_to_doscode_segment 288 <2> 289 <2> ; INP: byte [cs:ip + 1] = displacement in doscode_entrypoint_list 290 <2> ; word [DOSCODE:(displaced)] 291 <2> ; = relocated entry address 292 <2> ; word [DOSCODE:(displaced + 2)] 293 <2> ; = optional pointer to device function table 294 <2> ; byte [DOSCODE:(displaced + 4)] 295 <2> ; = optional device unit 296 <2> ; OUT: Jumps to DOSCODE:(relocated entry address) 297 <2> ; If the relocated entry address is DEVStrategy, 298 <2> ; ss:sp-> device unit or garbage (word), 299 <2> ; pointer to device function table (word) 300 <2> ; CHG: - (not even flags!) 301 <2> ; STT: - 302 <2> relocatedentry: 0 00000444 0E push cs 0 00000445 EA[4A04][0000] jmp DOSENTRY:.fixsegment ; insure cs = 70h 305 <2> .fixsegment: 306 <2> 0 0000044A 50 push ax 308 <2> %if _RELOCATEDOSCODE 0 0000044B 1E push ds 310 <2> 311 <2> %if 0 312 <2> mov ds, word [cs:dosentry_to_dosdata_segment] ; => DOSDATA 313 <2> %else 0 0000044C B80000 mov ax, 0 ; ! preserve fl 0 0000044F 8ED8 mov ds, ax 0 00000451 8E1EC600 mov ds, word [31h * 4 + 2] ; => DOSDATA 317 <2> %endif 0 00000455 A1[0000] mov ax, word [dosdata_to_doscode_segment] ; => DOSCODE 319 <2> %if _DOSCODEHMA 0 00000458 9C pushf 0 00000459 83F8FE cmp ax, DOSCODE_HMA_SEGMENT 0 0000045C 7237 jb .not_in_hma 323 <2> 324 <2> ; DOSCODE is in HMA: check A20 and try to enable if disabled 325 <2> 326 <2> ; INP: ax => DOSCODE 327 <2> ; CHG: fl, ds 328 <2> 0 0000045E 50 push ax 0 0000045F 56 push si 331 <2> ; INP: ax => DOSCODE 332 <2> ; OUT: A20 enabled 333 <2> ; CHG: si, fl, ds 0 00000460 E84900 call dosentry_check_a20 0 00000463 752E jne .doscodeavailable ; not equal, A20 line is switched on --> 336 <2> 0 00000465 B405 mov ah, 05h ; Local Enable A20 (03h would be Global ?) 0 00000467 53 push bx 0 00000468 2EFF1E[5C05] call far [ cs:dosentry_xmsentry ] 340 <2> ; request global enable A20 0 0000046D 5B pop bx ; may return an error code in bl 0 0000046E 48 dec ax ; 0001h if successful 0 0000046F B8[0605] mov ax, dosentry_msg.a20_error_xms 0 00000472 7508 jnz .error ; was not 0001h --> 345 <2> 0 00000474 E83500 call dosentry_check_a20 ; check again 0 00000477 751A jne .doscodeavailable ; not equal, A20 line is now switched on --> 348 <2> 0 00000479 B8[1705] mov ax, dosentry_msg.a20_error_actual 350 <2> .error: 0 0000047C BE[F104] mov si, dosentry_msg.a20_error_common 0 0000047F E85500 call dosentry_disp_msg_cs 0 00000482 96 xchg ax, si 0 00000483 E85100 call dosentry_disp_msg_cs 0 00000486 BE[4705] mov si, dosentry_msg.a20_error_after 0 00000489 E84B00 call dosentry_disp_msg_cs 357 <2> .loop: 0 0000048C CC int3 0 0000048D 31C0 xor ax, ax 0 0000048F CD16 int 16h 0 00000491 EBF9 jmp .loop 362 <2> 363 <2> 364 <2> .doscodeavailable: 0 00000493 5E pop si 0 00000494 58 pop ax 367 <2> 368 <2> .not_in_hma: 0 00000495 9D popf 370 <2> %endif 371 <2> ; ax => DOSCODE segment 372 <2> 373 <2> ; have ss:sp -> (bp), ds, ax, cs, ip, original 374 <2> ; want ss:sp -> tip, tcs, cip, ccs, ax, cs, ip, original 375 <2> lframe 0 376 <2> ; above this original stack 377 <2> lpar word, in_tip ; transfer stub ip 378 <2> lpar word, in_tcs ; transfer stub cs 379 <2> lpar word, in_ax ; original ax, passed to relocated_ 380 <2> lpar word, in_ds_out_ccs ; original ds, gets DOSCODE cs 0 00000496 5589E5 lenter 382 <2> lequ ?frame_bp, in_bp_out_cip ; original bp, gets DOSCODE ip 0 00000499 FF7606 push word [bp + ?in_tcs] 0 0000049C FF7608 push word [bp + ?in_tip] 385 <2> lvar dword, out_tcsip ; transfer cs:ip (help debugging) 0 0000049F 874602 xchg ax, word [bp + ?in_ds_out_ccs] 387 <2> ; => DOSCODE 0 000004A2 8ED8 mov ds, ax ; restore ds 0 000004A4 B8[E500] mov ax, relocated_relocatedentry 0 000004A7 874600 xchg ax, word [bp + ?in_bp_out_cip] 391 <2> ; ax = original bp, ?out_cip -> entrypoint 0 000004AA 95 xchg ax, bp ; restore bp, clobber ax 393 <2> lleave ctx 394 <2> 395 <2> ; INP: ss:(sp + 6) -> arbitrary stack of entrypoint 396 <2> ; word [ss:sp + 4] = entrypoint's ip, 397 <2> ; word [ss:sp + 2] = entrypoint's cs, 398 <2> ; word [ss:sp + 0] = original ax value 0 000004AB CB retf ; control flow goes back to transfer stub 400 <2> ; which has a retf to go to DOSCODE 401 <2> %else 402 <2> ; This stub is used by devicerelocate! 403 <2> jmp relocated_relocatedentry 404 <2> %endif 405 <2> 406 <2> ; %if _INT19_IN_DOSENTRY 407 <2> ; %if _RELOCATEDOSCODE 408 <2> ; i19: 409 <2> ; %endif 410 <2> ; %include "int19.asm" 411 <2> ; %endif 412 <2> 413 <2> %if _RELOCATEDOSCODE && _DOSCODEHMA 414 <2> ; CHG: ds, si, ax 415 <2> ; OUT: NZ if A20 line is switched on 416 <2> ; ZR if A20 line is switched off 417 <2> ; may return with IF=0 418 <2> ; UP 419 <2> dosentry_check_a20: 0 000004AC FC cld 0 000004AD 06 push es 0 000004AE 57 push di 0 000004AF 51 push cx 0 000004B0 31F6 xor si, si 0 000004B2 8EDE mov ds, si ; ds = 0000h 0 000004B4 4E dec si 0 000004B5 8EC6 mov es, si ; es = FFFFh 0 000004B7 46 inc si ; ds:si = 0000h:0000h = 00000h 0 000004B8 BF1000 mov di, 0010h ; es:di = FFFFh:0010h = 100000h 430 <2> ; (same address if bit 20 off) 0 000004BB 89F9 mov cx, di ; 32 byte (16 = 10h word) 0 000004BD F3A7 repe cmpsw ; compare, A20 line switched on if differing 0 000004BF 7512 jne .ret ; differing --> 434 <2> 0 000004C1 FA cli ; try not to run interrupt handlers during this 0 000004C2 BF1000 mov di, 10h ; -> FFFFh:0010h = 10_0000h 437 <2> ; (in the HMA, part of the VDISK header) 0 000004C5 8D75F0 lea si, [di - 10h] ; -> 0000h:0000h = 00_0000h 439 <2> ; (in the LMA, offset word of int 00h handler) 0 000004C8 26FF35 push word [es:di] ; save value 0 000004CB 26FF0D dec word [es:di] ; change value (in HMA, or wrapped around LMA) 0 000004CE A7 cmpsw ; compare values, NZ if A20 is switched on 0 000004CF 268F45FE pop word [es:di - 2] ; restore value 444 <2> ; This can still report a false negative (A20 detected off 445 <2> ; when actually it is on), but we don't care about that. 446 <2> .ret: 0 000004D3 59 pop cx 0 000004D4 5F pop di 0 000004D5 07 pop es 0 000004D6 C3 retn 451 <2> 452 <2> 453 <2> dosentry_disp_msg_cs: 0 000004D7 50 push ax 455 <2> @@: 0 000004D8 2EAC cs lodsb 0 000004DA 84C0 test al, al 0 000004DC 7411 jz @F 0 000004DE E80200 call dosentry_disp_al 0 000004E1 EBF5 jmp short @B 461 <2> 462 <2> 463 <2> dosentry_disp_al: 0 000004E3 50 push ax 0 000004E4 53 push bx 0 000004E5 55 push bp 0 000004E6 B40E mov ah, 0Eh 0 000004E8 BB0700 mov bx, 7 0 000004EB CD10 int 10h 0 000004ED 5D pop bp 0 000004EE 5B pop bx 472 <2> @@: 0 000004EF 58 pop ax 0 000004F0 C3 retn 475 <2> 476 <2> 477 <2> dosentry_msg: 0 000004F1 444F53454E54525920 .a20_error_common: asciz "DOSENTRY A20 error: " 0 000004FA 413230206572726F72 0 00000503 3A2000 0 00000506 584D532063616C6C20 .a20_error_xms: asciz "XMS call failed." 0 0000050F 6661696C65642E00 0 00000517 584D532063616C6C20 .a20_error_actual: asciz "XMS call reported success but A20 is still off." 0 00000520 7265706F7274656420 0 00000529 737563636573732062 0 00000532 757420413230206973 0 0000053B 207374696C6C206F66 0 00000544 662E00 0 00000547 0D0A53797374656D20 .a20_error_after: asciz 13,10,"System halted. " 0 00000550 68616C7465642E2000 482 <2> 0 00000559 90 align 4 0 0000055C [2F04][0000] dosentry_xmsentry: dw entry_retf, DOSENTRY ; in DOSENTRY 485 <2> %endif 531 <1> 532 <1> === Switch to base=000000h -> "DOSENTRY" 533 <1> usesection DOSENTRY 534 <1> 535 <1> 536 <1> ;;Rev 3.30 Modification ------------------------------------------------ 537 <1> ; variables for real time clock setting 538 <1> public HaveCMOSClock 0 00000560 00 HaveCMOSClock db 0 ;set by MSINIT. 540 <1> public base_century 0 00000561 13 base_century db 19 542 <1> public base_year 0 00000562 50 base_year db 80 544 <1> public month_tab 0 00000563 1F1C1F1E1F1E1F1F1E month_tab db 31,28,31,30,31,30,31,31,30,31,30,31 0 0000056C 1F1E1F 546 <1> 0 0000056F 00 align 2, db 0 548 <1> ; The following are indirect intra-segment call addresses. The 549 <1> ;procedures are defined in MSINIT for relocation. MSINIT will set these 550 <1> ;address when the relocation is done. 551 <1> public BinToBCD 0 00000570 0000 BinToBCD dw 0 ;should point to Bin_To_BCD proc in MSINIT 0 00000572 [0000] dw DOSENTRY 554 <1> public DaycntToDay 0 00000574 0000 DaycntToDay dw 0 ;should point to Daycnt_to_day in MSINIT 0 00000576 [0000] dw DOSENTRY 557 <1> 558 <1> ;******************************************************************** 559 <1> ; Indirect call address of TIME_TO_TICKS procedure. 560 <1> ;This will be used by the relocatable portable suspend/resume code. 561 <1> 562 <1> extern time_to_ticks_entry 563 <1> 564 <1> public TimeToTicks 0 00000578 [2904] TimeToTicks dw time_to_ticks_entry 0 0000057A [0000] dw DOSENTRY 567 <1> 568 <1> ;;End of Modification ------------------------------------------------ 569 <1> 570 <1> 0 0000057C 00 Set_ID_Flag db 0 ;AN000; If 1, GETBP routine will set the 572 <1> ;Vol_Serial and FileSys_ID in BDS table 573 <1> ;from the media Boot record, if it is > DOS 4.00 574 <1> ;formatted one. Then Set_ID_flag will be set to 2 575 <1> ;to signal that volume_label is set from the extended 576 <1> ;boot record and do not set it from the root 577 <1> ;directory as done in SET_VOLUME_ID routine. 578 <1> ;For the old version, Vol_Serial 579 <1> ;will be set to -1, and FileSys_ID will be set 580 <1> ;to "FAT12 " if it is a floppy. 581 <1> 0 0000057D 00 evenb 583 <1> public lbapacket 584 <1> lbapacket: 585 <1> LBAPACKETSTRUC_size equ LBAPACKETSTRUC_struc_size ; NASM port equate 586 <1> istruc LBAPACKETSTRUC 587 <1> at lpSize 0 0000057E 1000 dw 16 0 00000580 00 iend 590 <1> 591 <1> public Temp_H 0 0000058E 0000 Temp_H dw 0 ;AN000; Temporary for 32 bit calculation. 593 <1> 594 <1> public Start_Sec_H 0 00000590 0000 Start_Sec_H dw 0 ;AN000; Starting sector number high word. 596 <1> ;Used as an input to DISKIO subroutine. 0 00000592 0000 Saved_Word dw 0 ;AN000; Tempory saving place for a word. 598 <1> 599 <1> ;--------------------------------------- 600 <1> ;J.K. 6/29/87 For Multi-track 601 <1> public MulTrk_Flag 0 00000594 0000 MulTrk_Flag dw 0 ;AN001; 603 <1> ;J.K. 6/29/87 End of Multi-track definition. 604 <1> ;--------------------------------------------------------------------- 605 <1> public EC35_Flag 0 00000596 00 EC35_Flag db 0 ; flags for electrically compatible 3.5 inch disk drives (mrw 4/88) 607 <1> ;--------------------------------------------------------------------- 0 00000597 00 evenb 0 00000598 0000 VRetry_Cnt dw 0 ;AN003; 0 0000059A 0000 Soft_ECC_Cnt dw 0 ;AN003; 611 <1> 612 <1> ;--------------------------------------------------------------------- 0 0000059C 00 MultiTrk_Format_Flag db 0 ;AN007;Testing. If 1, then Multi track format request 614 <1> ;--------------------------------------------------------------------- 615 <1> ; 616 <1> ; IF ID IS F9, HAVE A 96TPI DISK ELSE 617 <1> ; IF BIT 2 IS 0 THEN MEDIA IS NOT REMOVABLE AND COULD NOT HAVE CHANGED 618 <1> ; OTHERWISE IF WITHIN 2 SECS OF LAST DISK OPERATION MEDIA COULD NOT 619 <1> ; HAVE CHANGED, OTHERWISE DONT KNOW IF MEDIA HAS CHANGED 620 <1> ; 621 <1> 622 <1> === Switch to base=000000h -> "DOSENTRY" 623 <1> section DOSENTRY 624 <1> 0 0000059D 00 align 2, db 0 0 0000059E ???? Prev_DX DW ? 627 <1> 628 <1> 629 <1> global Set_ID_Flag, Saved_Word 630 <1> global VRetry_Cnt, Soft_ECC_Cnt, MultiTrk_Format_Flag 631 <1> global Prev_DX, dosentry_temp_ds 632 <1> global transfer_orig13 633 <1> global transfer_next2F_13 634 <1> 635 <1> === Switch to base=000000h -> "DOSENTRY" 636 <1> section DOSENTRY 637 <1> 638 <1> PATHSTART 005,DISK 89 <2> %IF PATHGEN 90 <2> PUBLIC %2%1S,%2%1E 91 <2> %2%1S LABEL BYTE 92 <2> %ENDIF 639 <1> EVENB 640 <1> Model_Byte equ MODEL_BYTE ; NASM port label 641 <1> public Model_Byte 0 000005A0 FF MODEL_BYTE DB 0FFH ; MODEL BYTE. SET UP AT INIT TIME. 643 <1> ; FF - PC1 644 <1> ; FE - XT (64/256K PLANAR) 645 <1> ; FD - PC-JR 646 <1> ; FC - PC/AT 647 <1> public Secondary_Model_Byte 0 000005A1 00 Secondary_Model_Byte db 0 649 <1> 650 <1> PUBLIC INT19SEM 0 000005A2 00 INT19SEM DB 0 ; INDICATE THAT ALL INT 19 652 <1> ; INITIALIZATION IS COMPLETE 653 <1> 654 <1> 655 <1> %macro int19old 1-* 656 <1> %rep %0 657 <1> public Int19OLD%1 658 <1> Int19OLD%1 dd -1 ;Orignal hardware int. vectors for INT 19h. 659 <1> %rotate 1 660 <1> %endrep 661 <1> %endmacro 662 <1> 0 000005A3 00 align 2, db 0 664 <1> int19old 02,08,09,0A,0B,0C,0D,0E,70,72,73,74,76,77 656 <2> %rep %0 657 <2> public Int19OLD%1 658 <2> Int19OLD%1 dd -1 659 <2> %rotate 1 660 <2> %endrep 657 <3> public Int19OLD%1 0 000005A4 FFFFFFFF Int19OLD%1 dd -1 659 <3> %rotate 1 657 <3> public Int19OLD%1 0 000005A8 FFFFFFFF Int19OLD%1 dd -1 659 <3> %rotate 1 657 <3> public Int19OLD%1 0 000005AC FFFFFFFF Int19OLD%1 dd -1 659 <3> %rotate 1 657 <3> public Int19OLD%1 0 000005B0 FFFFFFFF Int19OLD%1 dd -1 659 <3> %rotate 1 657 <3> public Int19OLD%1 0 000005B4 FFFFFFFF Int19OLD%1 dd -1 659 <3> %rotate 1 657 <3> public Int19OLD%1 0 000005B8 FFFFFFFF Int19OLD%1 dd -1 659 <3> %rotate 1 657 <3> public Int19OLD%1 0 000005BC FFFFFFFF Int19OLD%1 dd -1 659 <3> %rotate 1 657 <3> public Int19OLD%1 0 000005C0 FFFFFFFF Int19OLD%1 dd -1 659 <3> %rotate 1 657 <3> public Int19OLD%1 0 000005C4 FFFFFFFF Int19OLD%1 dd -1 659 <3> %rotate 1 657 <3> public Int19OLD%1 0 000005C8 FFFFFFFF Int19OLD%1 dd -1 659 <3> %rotate 1 657 <3> public Int19OLD%1 0 000005CC FFFFFFFF Int19OLD%1 dd -1 659 <3> %rotate 1 657 <3> public Int19OLD%1 0 000005D0 FFFFFFFF Int19OLD%1 dd -1 659 <3> %rotate 1 657 <3> public Int19OLD%1 0 000005D4 FFFFFFFF Int19OLD%1 dd -1 659 <3> %rotate 1 657 <3> public Int19OLD%1 0 000005D8 FFFFFFFF Int19OLD%1 dd -1 659 <3> %rotate 1 665 <1> 666 <1> 667 <1> PATHEND 005,DISK 96 <2> %IF PATHGEN 97 <2> %2%1E LABEL BYTE 98 <2> %ENDIF 668 <1> ; = = = = = = = = = = = = = = = = = = = = 669 <1> 670 <1> global SNGMSG 671 <1> global DRVLET 672 <1> 673 <1> ; INCLUDE BIOMES.INC 674 <1> ;=== Push trace listing source: msbio.cl2 675 <1> %include "msbio.cl2" ; NASM included file 1 <2> ; msbio.cl2 2 <2> 3 <2> 4 <2> ;_______________________ 5 <2> 0 000005DC 0D0A496E7365727420 SNGMSG DB 13,10,"Insert diskette for drive " 0 000005E5 6469736B6574746520 0 000005EE 666F72206472697665 0 000005F7 20 7 <2> 8 <2> ;_______________________ 9 <2> 0 000005F8 413A20616E64207072 DRVLET DB "A: and press any key when ready",13,10,10,0 0 00000601 65737320616E79206B 0 0000060A 6579207768656E2072 0 00000613 656164790D0A0A00 676 <1> ;=== Pop trace listing source 677 <1> 678 <1> 679 <1> ;----------------------------------------------- 680 <1> ; 681 <1> ; C O N - CONSOLE DEVICE DRIVER 682 <1> ; 683 <1> org 61Bh ; noted in EDR-DOS sources as a fixed offset 684 <1> 685 <1> PUBLIC ALTAH 0 0000061B 00 ALTAH DB 0 ;SPECIAL KEY HANDLING 687 <1> 688 <1> public KEYRD_Func 0 0000061C 00 KEYRD_Func DB 0 ;AN000; Default is conventional keyboard read 690 <1> public KEYSTS_Func 0 0000061D 01 KEYSTS_Func DB 1 ;AN000; Defualt if conventional keyboard status check. 692 <1> 693 <1> %if KEYRD_Func + 1 != KEYSTS_Func 694 <1> %error msinit.nas assumes KEYSTS_Func directly after KEYRD_Func 695 <1> %endif 696 <1> 697 <1> ; PUBLIC SAV_SC_INFO ;J.K. 4/29/86 FOR CON$GENIOCTL 698 <1> ; PUBLIC SAV_SC_MODE 699 <1> ; PUBLIC SAV_SC_COLORS 700 <1> ; PUBLIC SAV_SC_WIDTH 701 <1> ; PUBLIC SAV_SC_LENGTH 702 <1> ;SAV_SC_INFO LABEL BYTE 703 <1> ;SAV_SC_MODE DB 0 704 <1> ;SAV_SC_COLORS DW 0 705 <1> ;SAV_SC_WIDTH DW 0 706 <1> ;SAV_SC_LENGTH DW 0 ;J.K. 4/29/86 FOR CON$GENIOCTL 707 <1> 708 <1> ;------------------------------------------------------------- 709 <1> ; 710 <1> ; P R N - PRINTER DEVICE 711 <1> ; 712 <1> PUBLIC PRINTDEV 0 0000061E 00 PRINTDEV DB 0 ; INDEX INTO ABOVE ARRAY 714 <1> 715 <1> ; THE FOLLOWING VARIABLE CAN BE MODIFIED VIA IOCTL SUB-FUNCTION 16. IN THIS 716 <1> ; WAY, THE WAIT CAN BE SET TO SUIT THE SPEED OF THE PARTICULAR PRINTER BEING 717 <1> ; USED. ONE FOR EACH PRINTER DEVICE. 718 <1> 0 0000061F 00 EVENB 720 <1> PUBLIC WAIT_COUNT 0 00000620 5000500050005000 WAIT_COUNT DW 4 DUP (50H) ; ARRAY OF RETRY COUNTS FOR PRINTER 722 <1> 723 <1> EVENB 724 <1> PUBLIC DAYCNT 0 00000628 0000 DAYCNT DW 0 726 <1> 0 0000062A 0000 dosentry_temp_ds: dw 0 728 <1> 729 <1> transfer_orig13: 0 0000062C 2EFF2E[B400] jmp far [cs:ORIG13] ; cs reference in DOSENTRY 731 <1> 732 <1> transfer_next2F_13: 0 00000631 2EFF2E[6E01] jmp far [cs:NEXT2F_13] ; cs reference in DOSENTRY 734 <1> 735 <1> 736 <1> EVENB 737 <1> global dskdrvs_indirect 738 <1> dskdrvs_indirect: 0 00000636 00000000 dd 0 740 <1> 741 <1> EVENB 0 0000063A 90 nop 743 <1> global jmp_int_2f_next 744 <1> jmp_int_2f_next: 0 0000063B EA db 0EAh ; jmp far 746 <1> PUBLIC INT_2F_NEXT 0 0000063C ???????? INT_2F_NEXT DD ? 748 <1> 749 <1> 750 <1> global run_int21_shell 751 <1> run_int21_shell: 0 00000640 CD21 int 21h 0 00000642 E8FFFDCB44 relocate relocatedshellreturned 754 <1> 755 <1> 756 <1> %IF itest ;Testing Mode for IBMBIO. 757 <1> PUBLIC NUMBUF 758 <1> NUMBUF DB 5 DUP (?) 759 <1> PUBLIC DIGITS 760 <1> DIGITS DB "0123456789ABCDEF" 761 <1> PUBLIC FTESTBITS 762 <1> ;FTESTBITS DW FTESTDISK+FTESTINIT 763 <1> fTestDISK equ FTESTDISK ; NASM port equate 764 <1> FTESTBITS DW fTestDISK 765 <1> ;ftestbits dw ftestclock 766 <1> %ENDIF 767 <1> 768 <1> 769 <1> %include "code.asm" 1 <2> 2 <2> %if 0 3 <2> 4 <2> lDOS DOSCODE entrypoint handling 5 <2> by E. C. Masloch, 2018--2025 6 <2> 7 <2> Usage of the works is permitted provided that this 8 <2> instrument is retained with the works, so that any entity 9 <2> that uses the works is notified of this instrument. 10 <2> 11 <2> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY. 12 <2> 13 <2> %endif 14 <2> === Switch to base=008400h -> "DOSCODETABLE" 15 <2> usesection DOSCODETABLE 16 <2> global doscode_start 17 <2> doscode_start: ; must be start of segment 18 <2> 0 00000000 26 times DOSCODE_HMA_OFFSET db 38 ; prefix that is unused, 20 <2> ; and not relocated 21 <2> 22 <2> ; (lMS-DOS: Comment not applicable) 23 <2> ; The following table and function is used by devicerelocate 24 <2> ; even if DOSCODE is merged into DOSENTRY (!_RELOCATEDOSCODE). 25 <2> 0 00000050 [0000][0000][0000] write_entrypoint_list ENTRYPOINT_LIST 0 00000056 [0000][0000][0000] 0 0000005C [0000][0000][0000] 0 00000062 [A501][0000][0000] 0 00000068 [0000][0000][0000] 0 0000006E [0000][0000][0000] 0 00000074 [0000][0000][B800] 0 0000007A [C600][E900][CC00] 0 00000080 [CC00][D200][D800] 0 00000086 [DE00][EF00][F600] 0 0000008C [FD00][1001][1601] 0 00000092 [0000][7B01] 27 <2> 28 <2> 29 <2> %if _RELOCATEDOSCODE && _DOSCODEHMA 0 00000096 90 _fill 0C0h + DOSCODE_HMA_start_at, 90h, doscode_start 31 <2> hma_call5: 0 000000E0 EA[CA03][0000] jmp DOSENTRY:call5 33 <2> %endif 34 <2> 35 <2> 36 <2> ; INP: byte [cs:ip] = displacement in doscode_entrypoint_list 37 <2> ; word [DOSCODE:(displaced)] 38 <2> ; = relocated entry address 39 <2> ; word [DOSCODE:(displaced + 2)] 40 <2> ; = optional pointer to device function table 41 <2> ; byte [DOSCODE:(displaced + 4)] 42 <2> ; = optional device unit 43 <2> ; ss:(sp + 6) -> arbitrary stack of entrypoint 44 <2> ; word [ss:sp + 4] = entrypoint's ip, 45 <2> ; word [ss:sp + 2] = entrypoint's cs, 46 <2> ; word [ss:sp + 0] = original ax value, 47 <2> relocated_relocatedentry: 0 000000E5 9C pushf 49 <2> lframe 0 50 <2> lpar word, entrypoint_ip 51 <2> lpar word, entrypoint_cs 52 <2> lpar word, orig_ax 53 <2> lpar word, orig_fl 0 000000E6 5589E5 lenter 0 000000E9 1E push ds 0 000000EA 56 push si 57 <2> 0 000000EB B400 mov ah, 0 0 000000ED 8E5E06 mov ds, word [bp + ?entrypoint_cs] 0 000000F0 8B7608 mov si, word [bp + ?entrypoint_ip] 61 <2> %if 0 62 <2> cld 63 <2> inc si 64 <2> lodsb 65 <2> cmp al, 0CCh ; overwritten by debugger ? 66 <2> jne @F ; no --> 67 <2> int3 ; break to make it remove the breakpoint 68 <2> dec si 69 <2> lodsb ; reload the byte 70 <2> cmp al, 0CCh 71 <2> jne @F 72 <2> %else 0 000000F3 8A4401 mov al, [si + 1] 0 000000F6 EB1A jmp @F 75 <2> %endif 76 <2> 77 <2> .error: 0 000000F8 FC cld 0 000000F9 BE[9301] mov si, doscode_msg.error_common 0 000000FC E83B00 call doscode_disp_msg_cs 0 000000FF BE[A301] mov si, doscode_msg.error_table 82 <2> ..@halt: 0 00000102 E83500 call doscode_disp_msg_cs 0 00000105 BE[1F02] mov si, doscode_msg.error_after 0 00000108 E82F00 call doscode_disp_msg_cs 86 <2> .loop: 0 0000010B CC int3 0 0000010C 31C0 xor ax, ax 0 0000010E CD16 int 16h 0 00000110 EBF9 jmp .loop 91 <2> 92 <2> @@: 0 00000112 0E push cs 0 00000113 1F pop ds 95 <2> 0 00000114 05[5000] add ax, doscode_entrypoint_list 0 00000117 3D[9600] cmp ax, doscode_entrypoint_list.end 0 0000011A 73DC jae .error 0 0000011C 96 xchg ax, si 100 <2> 0 0000011D AD lodsw ; get relocated entry address 102 <2> %if 0 103 <2> cmp ax, DEVStrategy ; set ZF iff DEVStrategy 104 <2> %else 0 0000011E 85C0 test ax, ax 106 <2> %endif 107 <2> 0 00000120 874604 xchg word [bp + ?orig_ax], ax ; store address in ?orig_ax, ax = orig ax 109 <2> 0 00000123 50 push ax 0 00000124 AD lodsw 0 00000125 894608 mov word [bp + ?entrypoint_ip], ax 113 <2> 0 00000128 B400 mov ah, 0 0 0000012A AC lodsb 0 0000012B 894606 mov word [bp + ?entrypoint_cs], ax 0 0000012E 58 pop ax 118 <2> 0 0000012F 5E pop si 0 00000130 1F pop ds 0 00000131 5D lleave 0 00000132 7404 je .is_dev_strat ; dispatch based on ZF 0 00000134 9D popf ; (fl = ?orig_fl = fl) 0 00000135 C20400 retn 4 ; (ip = ?orig_ax = address) 125 <2> 126 <2> .is_dev_strat: 0 00000138 9D popf 0 00000139 C3 retn 129 <2> 130 <2> 131 <2> doscode_disp_msg_cs: 0 0000013A 50 push ax 133 <2> @@: 0 0000013B 2EAC cs lodsb 0 0000013D 84C0 test al, al 0 0000013F 7411 jz @F 0 00000141 E80200 call doscode_disp_al 0 00000144 EBF5 jmp short @B 139 <2> 140 <2> 141 <2> doscode_disp_al: 0 00000146 50 push ax 0 00000147 53 push bx 0 00000148 55 push bp 0 00000149 B40E mov ah, 0Eh 0 0000014B BB0700 mov bx, 7 0 0000014E CD10 int 10h 0 00000150 5D pop bp 0 00000151 5B pop bx 150 <2> @@: 0 00000152 58 pop ax 0 00000153 C3 retn 153 <2> 154 <2> 155 <2> doscode_disp_dxax_hex: ; dx:ax 0 00000154 92 xchg ax, dx 0 00000155 E80100 call doscode_disp_ax_hex 0 00000158 92 xchg ax, dx 159 <2> doscode_disp_ax_hex: ; ax 0 00000159 86C4 xchg al, ah 0 0000015B E80200 call doscode_disp_al_hex 162 <2> ; display former ah 0 0000015E 86C4 xchg al, ah ; and fall trough for al 164 <2> doscode_disp_al_hex: ; al 0 00000160 51 push cx 0 00000161 B104 mov cl, 4 0 00000163 D2C8 ror al, cl 0 00000165 E80300 call doscode_disp_al_lownibble_hex 169 <2> ; display former high-nibble 0 00000168 D2C0 rol al, cl 0 0000016A 59 pop cx 172 <2> ; and fall trough for low-nibble 173 <2> doscode_disp_al_lownibble_hex: 0 0000016B 50 push ax ; save ax for call return 0 0000016C 240F and al, 00001111b 176 <2> ; high nibble must be zero 0 0000016E 0430 add al, '0' ; if number is 0-9, now it's the correct character 0 00000170 3C39 cmp al, '9' 0 00000172 7602 jna .decimalnum ; if we get decimal number with this, ok --> 0 00000174 0407 add al, 7 ; otherwise, add 7 and we are inside our alphabet 181 <2> .decimalnum: 0 00000176 E8CDFF call doscode_disp_al 0 00000179 58 pop ax 0 0000017A C3 retn 185 <2> 186 <2> 187 <2> relocated shellreturned 0 0000017B FB sti 0 0000017C FC cld 0 0000017D 730E jnc .returned 0 0000017F BE[CE01] mov si, doscode_msg.error_shell_failed.1 0 00000182 E8B5FF call doscode_disp_msg_cs 0 00000185 E8D1FF call doscode_disp_ax_hex 0 00000188 BE[FC01] mov si, doscode_msg.error_shell_failed.2 0 0000018B EB03 jmp @F 196 <2> .returned: 0 0000018D BE[FF01] mov si, doscode_msg.error_shell_returned 198 <2> @@: 0 00000190 E96FFF jmp ..@halt 200 <2> 201 <2> 202 <2> doscode_msg: 0 00000193 444F53434F44452065 .error_common: asciz "DOSCODE error: " 0 0000019C 72726F723A2000 0 000001A3 496E76616C69642064 .error_table: asciz "Invalid doscode_entrypoint_list reference." 0 000001AC 6F73636F64655F656E 0 000001B5 747279706F696E745F 0 000001BE 6C6973742072656665 0 000001C7 72656E63652E00 0 000001CE 496E697469616C2073 .error_shell_failed.1: asciz "Initial shell process execution failed! Code=" 0 000001D7 68656C6C2070726F63 0 000001E0 657373206578656375 0 000001E9 74696F6E206661696C 0 000001F2 65642120436F64653D 0 000001FB 00 0 000001FC 682E00 .error_shell_failed.2: asciz "h." 0 000001FF 496E697469616C2073 .error_shell_returned: asciz "Initial shell process returned!" 0 00000208 68656C6C2070726F63 0 00000211 657373207265747572 0 0000021A 6E65642100 0 0000021F 0D0A53797374656D20 .error_after: asciz 13,10,"System halted. " 0 00000228 68616C7465642E2000 770 <1> 771 <1> PATHEND 001,BIO 96 <2> %IF PATHGEN 97 <2> %2%1E LABEL BYTE 98 <2> %ENDIF 772 <1> 773 <1> 199 ;=== Pop trace listing source 200 201 === Switch to base=008400h -> "BIOCODE" 202 usesection BIOCODE 203 204 %IF itest 205 PUBLIC MSGNUM 206 MSGNUM: 207 PUSHF 208 TEST [cs:FTESTBITS],AX 209 JZ MRET 210 PUSH SI 211 PUSH BX 212 PUSH CX 213 PUSH ES 214 PUSH DI 215 MOV DI,OFFSET NUMBUF 216 PUSH CS 217 POP ES 218 MOV CX,4 219 NUMLOOP: 220 PUSH CX 221 MOV CL,4 222 ROL BX,CL 223 POP CX 224 PUSH BX 225 AND BX,0FH 226 MOV AL,[cs:DIGITS + BX] 227 STOSB 228 POP BX 229 LOOP NUMLOOP 230 POP DI 231 POP ES 232 POP CX 233 POP BX 234 MOV SI,OFFSET NUMBUF 235 CALL MSGOUT 236 POP SI 237 POPF 238 RET 239 240 PUBLIC MSGOUT 241 MSGOUT: 242 PUSHF 243 TEST [cs:FTESTBITS],AX 244 JZ MRET 245 PUSH DS 246 PUSH AX 247 PUSH BX 248 PUSH CS 249 POP DS 250 CALL WRMSG 251 POP BX 252 POP AX 253 POP DS 254 MRET: 255 POPF 256 RET 257 258 PUBLIC DUMPBYTES ;J.K. 4/9/86 259 ;Dumpbytes will dump the bytes in memory in hex. Space will be put in between 260 ;the bytes and CR, LF will be put at the end. - J.K. 261 ;Input: DS:SI -> buffer to dump in Hex. 262 ; CX -> # of bytes (Length of the buffer) 263 ; 264 DUMPBYTES proc near 265 pushf 266 push ax 267 dumploops: 268 lodsb 269 mov ah, al 270 shr ah, 1 271 shr ah, 1 272 shr ah, 1 273 shr ah, 1 274 call hex_to_ascii 275 push ax 276 mov al, ah 277 call outchar 278 pop ax 279 call outchar 280 mov al, ' ' 281 call outchar 282 loop dumploops 283 284 mov al, 0dh 285 call outchar 286 mov al, 0ah 287 call outchar 288 289 pop ax 290 popf 291 ret 292 DUMPBYTES endp 293 294 PUBLIC Hex_to_ascii 295 Hex_to_ascii proc near ;J.K. - 4/9/86 296 and ax, 0f0fh 297 add ah, 30h 298 cmp ah, 3ah 299 jb hta_$1 300 add ah, 7 301 hta_$1: 302 add al, 30h 303 cmp al, 3ah 304 jb hta_$2 305 add al, 7 306 hta_$2: 307 ret 308 Hex_to_ascii endp 309 310 PUBLIC outchar 311 Outchar proc near 312 PUSH AX 313 PUSH SI 314 PUSH DI 315 PUSH BP 316 PUSH BX 317 ;SB33002******************************************************* 318 MOV AH, 0Eh ;SET COMMAND TO WRITE A CHAR ;SB;3.30* 319 MOV BX, 7 ;SET FOREGROUND COLOR ;SB;3.30* 320 INT 10h ;CALL ROM-BIOS ;SB;3.30* 321 ;SB33002******************************************************* 322 POP BX 323 POP BP 324 POP DI 325 POP SI 326 POP AX 327 RET 328 Outchar endp 329 330 %ENDIF 331 %include "msmacro.mac" 1 <1> === Switch to base=008400h -> "BIOCODE" 2 <1> section BIOCODE 3 <1> ; 4 <1> ; This file contains three macros used in debugging the system. If the 5 <1> ; variable "itest" (in msbio.asm) is nonzero code is included in the 6 <1> ; modules to print debugging messages. The level of debugging is controlled 7 <1> ; by the value of the variable fTestBits in msbio.asm. Specific bits in 8 <1> ; the variable determine which messages to print. The equ's below tell 9 <1> ; which bits control which funcitons. For example the fifth bit 10 <1> ; cooresponds to disk activity (see fTestDisk equ below). 11 <1> ; 12 <1> ; The macros in the file are: 13 <1> ; 14 <1> ; message Prints an ascii string on the screen. 15 <1> ; Example usage: 16 <1> ; 17 <1> ; message fTestDisk, <"Start Disk Write", CR, LF> 18 <1> ; message fTestINIT, <"Begin BDS initialization"> 19 <1> ; 20 <1> ; 21 <1> ; MNUM Print the value in a register or memory location on 22 <1> ; the screen. Value is displayed in hex. 23 <1> ; Usage: 24 <1> ; MNUM bitpattern, valueLocation 25 <1> ; 26 <1> ; valueLocation is typically a regester: 27 <1> ; 28 <1> ; mnum fTestCom, AX 29 <1> ; mnum fTestDisk, DX 30 <1> ; 31 <1> ; ValueLocation can also be a memory location: 32 <1> ; 33 <1> ; mnum fTestINIT, Final_Dos_Location 34 <1> ; 35 <1> ; If no valueLocation is given the macro defaults to 36 <1> ; the BX register. 37 <1> ; 38 <1> ; ZWAIT Stops the program until any key is pressed. 39 <1> ; 40 <1> ; 41 <1> ; The three macros preserve all register values. If "test" is zero 42 <1> ; defined during assembly then the marco produce no code. 43 <1> ; 44 <1> 45 <1> %IF itest ;3.30 46 <1> EXTRN MSGOUT:NEAR,MSGNUM:NEAR ;3.30 47 <1> EXTRN NUMBUF:BYTE,DIGITS:BYTE,FTESTBITS:WORD ;3.30 48 <1> EXTRN DUMPBYTES:NEAR,OUTCHAR:NEAR,HEX_TO_ASCII:NEAR ;3.30 49 <1> 50 <1> 51 <1> fTestALL equ 1111111111111111b ; watch everything 52 <1> fTestHARD equ 0000000000000001b ; watch hard disk initialization 53 <1> fTest96 equ 0000000000000010b ; watch 96 tpi activity 54 <1> FTEST13 EQU 0000000000000100B ; WATCH INT 13 ACTIVITY ;3.30 55 <1> FTESTCOM EQU 0000000000001000B ; WATCH PACKET ACTIVITY ;3.30 56 <1> FTESTINIT EQU 0000000000010000B ; WATCH INITIALIZATION MESSAGES ;3.30 57 <1> FTESTDISK EQU 0000000000100000B ; WATCH DISK DEVICE DRIVER CALLS ;3.30 58 <1> FTESTCON EQU 0000000001000000B ; WATCH SYSTEM WAIT ACTIVITY IN CO;3.30 NSOLE 59 <1> FtestClock equ 0000000010000000b ; wathc clock device 5/2/86 ;3.30 60 <1> 61 <1> ; NASM original macros 62 <1> 63 <1> ; 64 <1> ; message macro -- see above for description 65 <1> ; 66 <1> 67 <1> %unimacro stripangles 2+.nolist 68 <1> 69 <1> %imacro stripangles 2+.nolist 70 <1> %defstr %%param %2 71 <1> %rep 16 72 <1> %substr %%opening %%param 1 73 <1> %ifidn %%opening, '<' 74 <1> %substr %%param %%param 2,-1 75 <1> %endif 76 <1> %endrep 77 <1> %rep 16 78 <1> %strlen %%length %%param 79 <1> %substr %%closing %%param %%length 80 <1> %ifidn %%closing, '>' 81 <1> %substr %%param %%param 1,-2 82 <1> %endif 83 <1> %endrep 84 <1> %deftok %%token %%param 85 <1> %1 %%token 86 <1> %endmacro 87 <1> 88 <1> %imacro MESSAGE 2+ 89 <1> jmp short %%b 90 <1> %%a: 91 <1> stripangles db, %2 92 <1> db 0 93 <1> %%b: push SI 94 <1> push AX 95 <1> mov AX, %1 96 <1> mov SI, OFFSET %%a 97 <1> call MSGOUT 98 <1> pop AX 99 <1> pop SI 100 <1> %endmacro 101 <1> 102 <1> 103 <1> ; 104 <1> ; mnum macro -- see above for description 105 <1> ; 106 <1> 107 <1> %imacro MNum 1-2 108 <1> push AX 109 <1> %ifempty %2 110 <1> mov AX,%1 111 <1> call MSGNUM 112 <1> %else 113 <1> push BX 114 <1> mov BX,%2 115 <1> mov AX,%1 116 <1> call MSGNUM 117 <1> pop BX 118 <1> %endif 119 <1> pop AX 120 <1> %endmacro 121 <1> 122 <1> 123 <1> ; 124 <1> ; zwait macro -- see above for description 125 <1> ; 126 <1> 127 <1> %imacro ZWAIT 0 128 <1> Message fTestALL,<"? "> 129 <1> CALL ZWAITrtn 130 <1> %endmacro 131 <1> 132 <1> ZWAITrtn: 133 <1> pushf ; save the flags 134 <1> push AX ; preserve AX 135 <1> xor AH, AH ; set command to get character ;3.30* 136 <1> int 16h ; call rom keyboard routine ;3.30* 137 <1> pop AX ; restore AX 138 <1> popf ; restore the flags 139 <1> ret 140 <1> 141 <1> ;Dump_byte dumps the memory contents in hex. ;3.30 142 <1> ;DUMPOFFLABEL should be a label or a variable defined in DUMPSEG. ;3.30 143 <1> %imacro DUMP_BYTE 3 144 <1> push es ;3.30 145 <1> PUSH DS ;3.30 146 <1> PUSH SI ;3.30 147 <1> PUSH CX ;3.30 148 <1> ;3.30 149 <1> MOV CX, %1 ;3.30 150 <1> MOV DS, CX ;3.30 151 <1> MOV SI, OFFSET %2 ;3.30 152 <1> MOV CX, %3 ;3.30 153 <1> call dumpbytes ;3.30 154 <1> ;3.30 155 <1> POP CX ;3.30 156 <1> POP SI ;3.30 157 <1> POP DS ;3.30 158 <1> pop es ;3.30 159 <1> %endmacro ;3.30 160 <1> ;3.30 161 <1> ;Dump_Byte_Reg dumps the memory contents in hex. - 4/9/86 ;3.30 162 <1> ;DUMPOFFREG should be a register contains the offset value in DUMPSEG. ;3.30 163 <1> %imacro DUMP_BYTE_REG 3 164 <1> DUMP_BYTE_REG MACRO DUMPSEG, DUMPOFFREG, BYTELENGTH ;3.30 165 <1> push es ;3.30 166 <1> PUSH DS ;3.30 167 <1> PUSH SI ;3.30 168 <1> PUSH CX ;3.30 169 <1> ;3.30 170 <1> MOV CX, %1 ;3.30 171 <1> MOV DS, CX ;3.30 172 <1> MOV SI, %2 ;3.30 173 <1> MOV CX, %3 ;3.30 174 <1> call dumpbytes ;3.30 175 <1> ;3.30 176 <1> POP CX ;3.30 177 <1> POP SI ;3.30 178 <1> POP DS ;3.30 179 <1> pop es ;3.30 180 <1> %endmacro ;3.30 181 <1> 182 <1> %else 183 <1> ; if test is not defined then make macro into null statements 184 <1> %imacro Message 0-1+.nolist 185 <1> %endmacro 186 <1> 187 <1> %imacro MNUM 0-1+.nolist 188 <1> %endmacro 189 <1> 190 <1> %imacro ZWAIT 0-1+.nolist 191 <1> %endmacro 192 <1> 193 <1> %imacro DUMP_BYTE 0-1+.nolist 194 <1> %endmacro 195 <1> 196 <1> %imacro DUMP_BYTE_REG 0-1+.nolist 197 <1> %endmacro 198 <1> 199 <1> %endif 200 <1> 201 <1> %unimacro PATHSTART 2 202 <1> %unimacro PATHEND 2 203 <1> 204 <1> %imacro PATHSTART 2 205 <1> %IF PATHGEN ;3.30 206 <1> PUBLIC %2%1S,%2%1E ;3.30 207 <1> %2%1S LABEL BYTE ;3.30 208 <1> %ENDIF ;3.30 209 <1> %endmacro ;3.30 210 <1> ;3.30 211 <1> %imacro PATHEND 2 212 <1> %IF PATHGEN ;3.30 213 <1> %2%1E LABEL BYTE ;3.30 214 <1> %ENDIF ;3.30 215 <1> %endmacro ;3.30 332 333 ;--------------------------------------------------- 334 ; 335 ; DEVICE ENTRY POINT 336 ; 337 CMDLEN equ 0 ;LENGTH OF THIS COMMAND 338 UNIT equ 1 ;SUB UNIT SPECIFIER 339 CMD equ 2 ;COMMAND CODE 340 STATUS equ 3 ;STATUS 341 MEDIA equ 13 ;MEDIA DESCRIPTOR 342 TRANS equ 14 ;TRANSFER ADDRESS 343 COUNT equ 18 ;COUNT OF BLOCKS OR CHARACTERS 344 _START equ 20 ;FIRST BLOCK TO TRANSFER 345 EXTRA equ 22 ;USUALLY A POINTER TO VOL ID FOR ERROR 15 346 START_L equ 26 ;AN000; Extended start sector (Low) 347 START_H equ 28 ;AN000; Extended start sector (High) 348 349 === Switch to base=008400h -> "BIOCODE" 350 section BIOCODE 351 352 dosbiocode_get_ds_dosentry: 353 biocode_get_ds_dosentry: 0 00007C5A 2E8E1E[B000] mov ds, word [cs:.segment] 0 00007C5F C3 retn 356 357 align 2, db 0 0 00007C60 [0000] .segment: dw DOSENTRY 359 360 dosbiocode_get_es_dosentry: 361 biocode_get_es_dosentry: 0 00007C62 2E8E06[B000] mov es, word [cs:biocode_get_ds_dosentry.segment] 0 00007C67 C3 retn 364 365 global biocode_get_es_dosentry, biocode_get_ds_dosentry 366 global dosbiocode_get_es_dosentry, dosbiocode_get_ds_dosentry 367 368 === Switch to base=008400h -> "BIOCODE" 369 section BIOCODE 370 371 372 relocated strategyentry 373 PUBLIC STRATEGY 374 STRATEGY PROC FAR 0 00007C68 1E push ds 0 00007C69 E8EEFF call biocode_get_ds_dosentry 0 00007C6C 891E[B800] MOV WORD PTR [PTRSAV],BX 0 00007C70 8C06[BA00] MOV WORD PTR [PTRSAV+2],ES 0 00007C74 1F pop ds 0 00007C75 CB RET 381 STRATEGY ENDP 382 383 relocated conentry 384 PUBLIC CON$IN 385 CON$IN PROC FAR 0 00007C76 56 PUSH SI 0 00007C77 BE[3500] MOV SI,OFFSET CONTBL 0 00007C7A EB4E JMP SHORT ENTRY 389 CON$IN ENDP 390 391 relocated auxentry 392 relocated com1entry 393 PUBLIC AUX0$IN 394 AUX0$IN PROC FAR 0 00007C7C 56 PUSH SI 0 00007C7D 50 PUSH AX 0 00007C7E 30C0 XOR AL,AL 0 00007C80 EB12 JMP SHORT AUXENT 399 AUX0$IN ENDP 400 401 relocated com2entry 402 PUBLIC AUX1$IN 403 AUX1$IN PROC FAR 0 00007C82 56 PUSH SI 0 00007C83 50 PUSH AX 0 00007C84 B001 MOV AL,1 0 00007C86 EB0C JMP short AUXENT ;J.K. 4/15/86 408 AUX1$IN ENDP 409 410 ;SB33102**************************************************************** 411 ;SB Add code to handle two more COM Ports 412 ;boban 413 414 relocated com3entry 415 PUBLIC AUX2$IN 416 AUX2$IN proc far 0 00007C88 56 push si 0 00007C89 50 push ax 0 00007C8A B002 mov al,2 0 00007C8C EB06 jmp short AUXENT 421 AUX2$IN endp 422 423 relocated com4entry 424 PUBLIC AUX3$IN 425 AUX3$IN proc far 0 00007C8E 56 push si 0 00007C8F 50 push ax 0 00007C90 B003 mov al,3 0 00007C92 EB00 jmp short AUXENT 430 431 ;SB33102**************************************************************** 432 433 AUXENT: 0 00007C94 BE[4D00] MOV SI,OFFSET AUXTBL 0 00007C97 EB32 JMP SHORT ENTRY1 436 AUX3$IN ENDP 437 438 relocated prnentry 439 PRN0$IN PROC FAR 440 PUBLIC PRN0$IN 441 0 00007C99 56 PUSH SI 0 00007C9A 50 PUSH AX 0 00007C9B 31C0 XOR AX,AX 0 00007C9D EB13 JMP SHORT PRNENT 446 PRN0$IN ENDP 447 448 relocated lpt1entry 449 PUBLIC PRN1$IN 450 PRN1$IN PROC FAR 0 00007C9F 56 PUSH SI 0 00007CA0 50 PUSH AX 0 00007CA1 B80001 mov ax, 100h 0 00007CA4 EB0C JMP SHORT PRNENT 455 PRN1$IN ENDP 456 457 relocated lpt2entry 458 PUBLIC PRN2$IN 459 PRN2$IN PROC FAR 0 00007CA6 56 PUSH SI 0 00007CA7 50 PUSH AX 0 00007CA8 B80102 mov ax, 201h 0 00007CAB EB05 JMP SHORT PRNENT 464 PRN2$IN ENDP 465 466 relocated lpt3entry 467 PUBLIC PRN3$IN 468 PRN3$IN PROC FAR 0 00007CAD 56 PUSH SI 0 00007CAE 50 PUSH AX 0 00007CAF B80203 mov ax, 302h 472 PRNENT: 0 00007CB2 BE[7B00] MOV SI,OFFSET PRNTBL 0 00007CB5 1E push ds 0 00007CB6 E8A1FF call biocode_get_ds_dosentry 0 00007CB9 8826[1E06] MOV [PRINTDEV],AH ;SAVE INDEX INTO ARRAY OF RETRY COUNTS 0 00007CBD 1F pop ds 0 00007CBE EB0B JMP SHORT ENTRY1 479 PRN3$IN ENDP 480 481 relocated clockentry 482 PUBLIC TIM$IN 483 TIM$IN PROC FAR 0 00007CC0 56 PUSH SI 0 00007CC1 BE[6500] MOV SI,OFFSET TIMTBL 0 00007CC4 EB04 JMP SHORT ENTRY 487 TIM$IN ENDP 488 489 relocated blockentry 490 PUBLIC DSK$IN 491 DSK$IN PROC FAR 0 00007CC6 56 PUSH SI 0 00007CC7 BE[0100] MOV SI,OFFSET DSKTBL 494 495 ENTRY: 0 00007CCA 50 PUSH AX 497 ENTRY1: 0 00007CCB 51 PUSH CX 0 00007CCC 52 PUSH DX 0 00007CCD 57 PUSH DI 0 00007CCE 55 PUSH BP 0 00007CCF 1E PUSH DS 0 00007CD0 06 PUSH ES 0 00007CD1 53 PUSH BX 505 0 00007CD2 E88DFF call biocode_get_es_dosentry 0 00007CD5 26A2[6C01] MOV [es:AUXNUM],AL ;SAVE CHOICE OF AUX/PRN DEVICE 508 0 00007CD9 26C51E[B800] lds bx, [es:PTRSAV] ;GET POINTER TO I/O PACKET 510 ASSUME DS:NOTHING 511 0 00007CDE 8A4701 MOV AL,BYTE PTR [BX + UNIT] ;AL = UNIT CODE 0 00007CE1 8A670D MOV AH,BYTE PTR [BX + MEDIA] ;AH = MEDIA DESCRIP 0 00007CE4 8B4F12 MOV CX,WORD PTR [BX + COUNT] ;CX = COUNT 0 00007CE7 8B5714 MOV DX,WORD PTR [BX + _START] ;DX = START SECTOR 516 517 ;SB34MSB100********************************************************************* 518 ;SB 519 ;SB The disk device driver can now handle 32 bit start sector number. 520 ;SB So we should check to see if a 32 bit sector number has been specified 521 ;SB and if so get it. Whether a 32 bit sector has been specified or not 522 ;SB the disk driver expects a 32 bit sector number with the high word 523 ;SB in DOSENTRY:Start_Sec_H and the low word in dx. 524 ;SB 525 ;SB Algorithm: 526 ;SB 1. Check to see if the request is for the disk driver by 527 ;SB checking to see if SI points to DSKTBL. 528 ;SB 529 ;SB 2. If request not for the disk nothing special needs to be done. 530 ;SB 531 ;SB 3. If request for the disk then check to see if a 32 bit 532 ;SB sector number has been specified by seeing whether the 533 ;SB the conventional sector number specified is -1. If so 534 ;SB we need to pick the 32 bit sector number from the new 535 ;SB fields in the request packet. See the request header 536 ;SB struc for the fields you need. If the conventional 537 ;SB sector field is not -1 then a 16 bit sector number 538 ;SB has been specified and we just need to initalise the 539 ;SB high word in DOSENTRY:Start_Sec_H to 0 540 ;SB 541 ;SB NOTE: START_L and START_H are the offsets withing the IO_REQUEST packet 542 ;SB which contain the low and hi words of the 32 bit start sector if 543 ;SB it has been used. 544 ;SB 545 ;SB NOTE:Remember not to destroy the registers which have been set up before 546 0 00007CEA 81FE[0100] CMP SI,OFFSET DSKTBL 0 00007CEE 7516 JNZ DSK_REQ_CONT ; Not Disk Req 0 00007CF0 268326[9005]00 and word [es:START_SEC_H], 0; prepare for zx 16-bit sector number 0 00007CF6 83FAFF CMP DX,-1 0 00007CF9 750B JNZ DSK_REQ_16 ; is a 16-bit sector number --> 0 00007CFB 8B571C MOV DX,[BX + START_H] ; 32 bits DSK REQ 553 START_SEC_H equ Start_Sec_H ; NASM port label 0 00007CFE 268916[9005] MOV [es:START_SEC_H],DX ; es:Start_sec_H = Packet.Start_H 0 00007D03 8B571A MOV DX,[BX + START_L] ; DX = Packet.Start_L 556 DSK_REQ_16: 557 DSK_REQ_CONT: 558 559 ;SB34MSB100********************************************************************* 560 0 00007D06 97 XCHG DI,AX 0 00007D07 8A4702 MOV AL,BYTE PTR [BX + CMD] 0 00007D0A 2E3A04 CMP AL,[CS:SI] ;ARR 2.41 0 00007D0D 7714 JA CMDERR 565 0 00007D0F 98 CBW ; NOTE THAT AL <= 15 MEANS OK 0 00007D10 D1E0 SHL AX,1 568 0 00007D12 01C6 ADD SI,AX 0 00007D14 97 XCHG AX,DI 571 0 00007D15 06 push es 0 00007D16 C47F0E LES DI,[BX + TRANS] 0 00007D19 1F pop ds 575 ASSUME DS:DOSENTRY 576 0 00007D1A FC CLD 0 00007D1B 2EFF6401 JMP WORD PTR [cs:SI+1] ;GO DO COMMAND 579 DSK$IN ENDP 580 ; PAGE 581 ;===================================================== 582 ;= 583 ;= SUBROUTINES SHARED BY MULTIPLE DEVICES 584 ;= 585 ;===================================================== 586 ;---------------------------------------------------------- 587 ; 588 ; EXIT - ALL ROUTINES RETURN THROUGH THIS PATH 589 ; 590 PUBLIC BUS$EXIT 591 BUS$EXIT PROC FAR 592 ASSUME DS:NOTHING 0 00007D1F B403 MOV AH,00000011B 0 00007D21 EB1E JMP SHORT ERR1 595 596 PUBLIC CMDERR 597 CMDERR: 0 00007D23 B003 MOV AL,3 ;UNKNOWN COMMAND ERROR 599 600 PUBLIC ERR$CNT 601 ERR$CNT: 0 00007D25 E832FF call biocode_get_ds_dosentry 0 00007D28 C51E[B800] lds bx, [PTRSAV] 604 ASSUME DS:NOTHING 0 00007D2C 294F12 SUB WORD PTR [BX + COUNT],CX ;# OF SUCCESSFUL I/O'S 606 607 PUBLIC ERR$EXIT 608 ERR$EXIT: 0 00007D2F B481 MOV AH,10000001B ;MARK ERROR RETURN 0 00007D31 EB0E JMP SHORT ERR1 611 BUS$EXIT ENDP 612 613 EXITP PROC FAR 614 ASSUME DS:BIOCODE ; WE ARE NOT SURE THIS IS CORRECT 3/18/86 615 EXIT$ZER: 0 00007D33 E824FF call biocode_get_ds_dosentry 0 00007D36 C51E[B800] lds bx, [PTRSAV] 618 ASSUME DS:NOTHING 0 00007D3A 31C0 XOR AX,AX 0 00007D3C 894712 MOV WORD PTR [BX + COUNT],AX ;INDICATE NO CHARS READ 621 622 PUBLIC EXIT 623 EXIT: 624 ASSUME DS:NOTHING 0 00007D3F B401 MOV AH,00000001B 626 ERR1: 627 ASSUME DS:NOTHING 0 00007D41 E816FF call biocode_get_ds_dosentry 0 00007D44 C51E[B800] lds bx, [PTRSAV] 0 00007D48 894703 MOV WORD PTR [BX + STATUS],AX ;MARK OPERATION COMPLETE 631 0 00007D4B 5B POP BX 0 00007D4C 07 POP ES 0 00007D4D 1F POP DS 0 00007D4E 5D POP BP 0 00007D4F 5F POP DI 0 00007D50 5A POP DX 0 00007D51 59 POP CX 0 00007D52 58 POP AX 0 00007D53 5E POP SI 641 global biocode_retf 642 biocode_retf: 0 00007D54 CB RET ;RESTORE REGS AND RETURN 644 EXITP ENDP 645 646 ;------------------------------------------------------------- 647 ; 648 ; CHROUT - WRITE OUT CHAR IN AL USING CURRENT ATTRIBUTE 649 ; 650 ; CALLED VIA INT 29H 651 ; 652 PUBLIC CHROUT 653 CHROUT equ 29H 654 655 relocated i29 656 PUBLIC OUTCHR 657 OUTCHR PROC FAR 0 00007D55 50 PUSH AX 0 00007D56 56 PUSH SI 0 00007D57 57 PUSH DI 0 00007D58 55 PUSH BP 662 ;SB33002a******************************************************* 0 00007D59 53 push bx ; ;SB ;3.30 0 00007D5A B40E mov AH, 0Eh ; set command to write a character;SB;3.30 0 00007D5C BB0700 mov BX, 7 ; set foreground color ;SB ;3.30 0 00007D5F CD10 int 10h ; call rom-bios ;SB ;3.30 0 00007D61 5B pop bx ; ;SB ;3.30 668 ;SB33002a******************************************************* 0 00007D62 5D POP BP 0 00007D63 5F POP DI 0 00007D64 5E POP SI 0 00007D65 58 POP AX 0 00007D66 CF IRET 674 OUTCHR ENDP 675 ;---------------------------------------------- 676 ; 677 ; SET DX TO AUXNUM 678 ; 679 PUBLIC GETDX 680 GETDX PROC NEAR 0 00007D67 1E push ds 0 00007D68 E8EFFE call biocode_get_ds_dosentry 0 00007D6B 8B16[6C01] MOV DX,WORD PTR [AUXNUM] 0 00007D6F 1F pop ds 0 00007D70 C3 RET 686 GETDX ENDP 687 ; PAGE 688 ;************************************************** ARR 2.15 689 690 ;----------------------------------------------- 691 ; 692 ; TIMER INTERRUPT HANDLER 693 ; 694 ;TIMER_LOW DW 0 695 ;TIMER_HIGH DW 0 696 ; 697 ;TIMER: 698 ; STI 699 ; PUSH AX 700 ; PUSH CX 701 ; PUSH DX 702 ; PUSH DS 703 ; PUSH CS 704 ; POP DS 705 ; XOR AX,AX 706 ; INT 1AH ; GET ROM TIME AND ZAP ROLL OVER 707 ; MOV [TIMER_HIGH],CX 708 ; MOV [TIMER_LOW],DX 709 ; OR AL,AL 710 ; JZ T5 711 ; INC WORD PTR [DAYCNT] ; ONE DAY GONE BY 712 ;T5: 713 ; POP DS 714 ; POP DX 715 ; POP CX 716 ; POP AX 717 ; IRET 718 ;************************************************** ARR 2.15 719 ; (no prior section) ; CODE ENDS 720 END === Trace listing source: mscon.lst 1 ; PAGE ,132 ; 2 ; TITLE MSCON - BIOS 3 %warning out: ...MSCON.ASM 3 ****************** warning: out: ...MSCON.ASM [-w+user] 4 ;============================================================================== 5 ;REVISION HISTORY: 6 ;AN000 - New for DOS Version 4.00 - J.K. 7 ;AC000 - Changed for DOS Version 4.00 - J.K. 8 ;AN00x - PTM number for DOS Version 4.00 - J.K. 9 ;============================================================================== 10 11 itest equ 0 12 %include "msgroup.mac" ;DEFINE CODE SEGMENT 1 <1> EVBOUND equ 1 ;THIS VALUE BEING 0 DOES NO BOUNDARY ALLIGNMENT, VALUE 1 ;3.30 2 <1> ; ALIGNS TO EVEN ;3.30 3 <1> 4 <1> ; NASM original macros 5 <1> 6 <1> %include "dcodeseg.nas" 1 <2> 2 <2> %ifndef DCODESEGNAS 3 <2> %assign DCODESEGNAS 1 4 <2> === Switch to base=008400h -> "DOSCODETABLE" 5 <2> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <2> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=008400h -> "DOSCODECODE" 7 <2> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <2> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=008400h -> "DOSBIOCODE" 9 <2> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=008400h -> "BIOCODE" 10 <2> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <2> 12 <2> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <2> 14 <2> %endif 7 <1> 8 <1> %if EVBOUND ;;IF EVEN (WORD) ALLIGNMENT IS REQUESTED, ;3.30 9 <1> 10 <1> %imacro EVENB 0.nolist 11 <1> EVEN ;;ADJUST TO EVEN BOUNDARY 12 <1> %endmacro 13 <1> 14 <1> %imacro ODD 0.nolist 15 <1> %if (($ - $$) % 2) == 0 16 <1> db ? 17 <1> %endif 18 <1> %endmacro 19 <1> 20 <1> %else ;;SINCE EVEN ALLIGNMENT IS NOT DESIRED, JUST USE BYTE ALLI;3.30 GNMENT 21 <1> 22 <1> %imacro EVENB 0.nolist 23 <1> ;;REQUEST FOR WORD ALLIGNMENT DOES NOTHING ;3.30 24 <1> %endmacro 25 <1> 26 <1> %imacro ODD 0.nolist 27 <1> ;;REQUEST FOR ODD ALLIGNMENT DOES NOTHING ;3.30 28 <1> %endmacro 29 <1> 30 <1> %endif ;3.30 31 <1> 32 <1> %imacro CODE_SEGMENT 0.nolist === Switch to base=008400h -> "BIOCODE" 33 <1> section BIOCODE 34 <1> %endmacro 35 <1> 36 <1> ; end of NASM original macros 37 <1> 38 <1> CODE_SEGMENT ;3.30 39 <1> ASSUME CS:BIOCODE ;3.30 40 <1> ;3.30 13 %include "msextrn.mac" 1 <1> === Switch to base=008400h -> "BIOCODE" 2 <1> section BIOCODE 3 <1> ; SCCSID = @(#)IBMEXTRN.ASM 1.11 85/11/18 4 <1> ;This is for IBMINIT module. 5 <1> ;======================================================= 6 <1> ;REVISION HISTORY: 7 <1> ;AN000; - NEW Version 4.00. J.K. 8 <1> ;AC000; - Modified Line 4.00. J.K. 9 <1> ;ANxxx; - PTMyyy 10 <1> ;============================================================================== 11 <1> ;AN001; D486 SHARE installation for large media 2/23/88 J.K. 12 <1> ;============================================================================== 13 <1> 14 <1> extern biocode_get_ds_dosentry, biocode_get_es_dosentry 15 <1> extern dosbiocode_get_ds_dosentry, dosbiocode_get_es_dosentry 16 <1> EXTRN ORIG13:DWORD,ORIG19:DWORD 17 <1> EXTRN COM2DEV:WORD,COM1DEV:WORD 18 <1> EXTRN COM4DEV:WORD,COM3DEV:WORD 19 <1> EXTRN LPT3DEV:WORD,LPT2DEV:WORD,LPT1DEV:WORD 20 <1> EXTRN HARDDRV:BYTE,HARDNUM:BYTE,DRVMAX:BYTE,HDSKTAB:WORD 21 <1> EXTRN DSKDRVS:WORD,HNUM:BYTE,EOT:BYTE,FHAVE96:BYTE 22 <1> EXTRN REAL13:DWORD,DAYCNT:WORD,CONHEADER:WORD 23 <1> EXTRN TWOHARD:BYTE,INT_2F_NEXT:DWORD 24 <1> EXTRN BDSH:WORD,BDSX:WORD,START_BDS:WORD 25 <1> EXTRN FHAVEK09:BYTE, NEW_ROM:BYTE 26 <1> EXTRN SINGLE:BYTE 27 <1> EXTRN BDSMs:BYTE ;for Mini Disk -J.K. 4/7/86 28 <1> EXTRN HaveCMOSClock:byte ;set by IBMINIT. Used by IBMCLOCK.ASM 29 <1> EXTRN BinToBCD:word ;set by IBMINIT. Used by IBMCLOCK.ASM 30 <1> EXTRN DaycntToDay:word ;set by IBMINIT. Used by IBMCLOCK.ASM 31 <1> EXTRN OLD13:DWORD 32 <1> extrn Temp_H:word ;J.K. For 32 bit calculation. IBMDISK 33 <1> extrn Start_Sec_H:word ;J.K. IBMDISK. 34 <1> extrn KEYRD_Func:byte ;J.K. For IBMCON. Defined in IBMBDATA. 35 <1> extrn KEYSTS_Func:byte ;J.K. For IBMCON. Defined in IBMBDATA. 36 <1> extrn DiskSector:byte ;J.K. IBMBDATA 37 <1> extrn Bpb_In_Sector:word ;J.K. IBMBDATA 38 <1> extrn SecPerClusInSector:Byte ;J.K. IBMBDATA 39 <1> extrn NumberOfFats:byte ;J.K. IBMBDATA 40 <1> extrn MediaByte:byte ;J.K. IBMBDATA 41 <1> extrn Ext_Boot_Sig:Byte ;J.K. IBMBDATA 42 <1> extrn Boot_Serial_L:Word ;J.K. IBMBDATA 43 <1> extrn Boot_Serial_H:Word ;J.K. IBMBDATA 44 <1> extrn Boot_Volume_Label:Byte ;J.K. IBMBDATA 45 <1> extrn Boot_System_ID:Byte ;J.K. IBMBDATA 46 <1> extrn Fat_12_ID:Byte ;J.K. IBMDISK 47 <1> extrn Fat_16_ID:Byte ;J.K. IBMDISK 48 <1> extrn lbapacket:byte 49 <1> extrn Vol_No_Name:Byte ;J.K. IBMDISK 50 <1> extrn MOTORSTARTUP:Byte ;J.K. IBMBDATA 51 <1> extrn DoubleWordMov:Byte ;J.K. IBMDISK 52 <1> extrn Model_Byte:Byte ;J.K. IBMBIO2 53 <1> extrn Secondary_Model_Byte:Byte ;J.K. IBMBIO2 54 <1> 55 <1> %IF itest 56 <1> EXTRN NUMBUF:BYTE,DIGITS:BYTE,FTESTBITS:WORD 57 <1> %ENDIF 58 <1> 59 <1> EXTRN START$:NEAR,ERROUT:NEAR,BLOCK13:FAR,INT19:FAR 60 <1> EXTRN INTRET:NEAR,HDRIVE:NEAR,DRIVEX:NEAR,INT13:FAR,CBREAK:NEAR,OUTCHR:NEAR 61 <1> EXTRN DISKRD:NEAR,MEDIA_PATCH:NEAR,GETBP1_PATCH:NEAR 62 <1> EXTRN SET_PATCH:NEAR,DISKIO_PATCH:NEAR,DSKERR:NEAR,INIT_PATCH:NEAR 63 <1> extern DSKERR_PATCH 64 <1> EXTRN TABLE_PATCH:NEAR,EXIT:NEAR,CHANGED_PATCH:NEAR 65 <1> EXTRN ERRIN:NEAR,GETBP:NEAR,SWPDSK:NEAR 66 <1> EXTRN OUTCHR:NEAR,WRMSG:NEAR,TIME_TO_TICKS:NEAR 67 <1> EXTRN INT2F_DISK:NEAR,INSTALL_BDS:NEAR,SETDRIVE:NEAR 68 <1> extrn Mov_Media_IDs:Near ;J.K. 69 <1> extrn Clear_IDs:Near ;J.K. 70 <1> %IF itest 71 <1> EXTRN MSGNUM:NEAR,MSGOUT:NEAR,dumpbytes:near,hex_to_ascii:near 72 <1> EXTRN outchar:near 73 <1> %ENDIF 74 <1> extrn lbatochs:near, chstotuple:near 75 <1> extrn lba_packet_setup:near 76 <1> === Switch to base=002530h -> "SYSINITSEG" 77 <1> section SYSINITSEG PUBLIC class=INIT 78 <1> ASSUME CS:SYSINITSEG 79 <1> EXTRN CURRENT_DOS_LOCATION:WORD 80 <1> EXTRN FINAL_DOS_LOCATION:WORD 81 <1> extrn dos_size:word 82 <1> EXTRN DEVICE_LIST:DWORD 83 <1> EXTRN MEMORY_SIZE:WORD 84 <1> EXTRN DEFAULT_DRIVE:BYTE 85 <1> EXTRN BUFFERS:WORD 86 <1> EXTRN SYSINIT:FAR 87 <1> extrn Big_Media_Flag:Byte ;AN001; 88 <1> ; (no prior section) ; SYSINITSEG ENDS === Switch to base=008400h -> "BIOCODE" 89 <1> section BIOCODE 90 <1> 91 <1> ASSUME CS:BIOCODE 92 <1> 93 <1> ; END OF DISK MODULES FOR CONFIGURATION 94 <1> 95 <1> EXTRN END96TPI:BYTE 96 <1> EXTRN ENDTWOHARD:BYTE 97 <1> EXTRN ENDONEHARD:BYTE 98 <1> EXTRN ENDSWAP:BYTE 99 <1> EXTRN ENDFLOPPY:BYTE 100 <1> 101 <1> ; IBM FIXED UP AT ROM 102 <1> 103 <1> EXTRN IBM_DISK_IO:FAR 14 %include "jumpmac.mac" 1 <1> ;;Rev 3.30 Modification 2 <1> ; 3 <1> ; given a label either 2 byte jump to another label _J 4 <1> ; if it is near enough or 3 byte jump to 5 <1> ; 6 <1> 7 <1> ; NASM original macros 8 <1> 9 <1> %if 0 10 <1> %imacro jump 1.nolist 11 <1> ;.xcref 12 <1> 13 <1> %ifndef %1_J ;; is this the first invocation 14 <1> %%a: JMP %1 15 <1> %ELSE 16 <1> %IF (%1_J >= $) || ($-%1_J > 126) 17 <1> %%a: JMP %1 ;; is the jump too far away? 18 <1> %ELSE 19 <1> %%a: JMP %1_J ;; do the short one... 20 <1> %ENDIF 21 <1> %ENDIF 22 <1> %ixdefine %1_j %%a 23 <1> ;.cref 24 <1> %endmacro 25 <1> ;.xcref jump 26 <1> %else 27 <1> %imacro jump 1.nolist 28 <1> ;REDEFINE THE ABOVE MACRO TO ALWAYS TRY A 3 BYTE NEAR JUMP 29 <1> jmp %1 30 <1> %endmacro ;;End of Modification 31 <1> %endif 32 <1> 33 <1> 15 %include "msequ.mac" 1 <1> %warning out: MSEQU.INC... 1 ****************** <1> warning: out: MSEQU.INC... [-w+user] 2 <1> ;============================================================================== 3 <1> 4 <1> FTOOBIG EQU 80H 5 <1> FBIG EQU 40H 6 <1> ROMSTATUS EQU 1 7 <1> ROMREAD EQU 2 8 <1> ROMWRITE EQU 3 9 <1> ROMVERIFY EQU 4 10 <1> ROMFORMAT EQU 5 11 <1> VID_SIZE EQU 12 12 <1> 13 <1> %include "msbds.mac" ; VARIOUS EQUATES FOR BDS 1 <2> 2 <2> %warning out: MSBDS.INC... 2 ****************** <2> warning: out: MSBDS.INC... [-w+user] 3 <2> ; SCCSID = @(#)IBMBDS.ASM 1.9 85/09/16 4 <2> ;============================================================================== 5 <2> ;REVISION HISTORY: 6 <2> ;AN000 - New for DOS Version 4.00 - J.K. 7 <2> ;AC000 - Changed for DOS Version 4.00 - J.K. 8 <2> ;AN00x - PTM number for DOS Version 4.00 - J.K. 9 <2> ;============================================================================== 10 <2> ;AN001; D113 Disable I/O access to unformatted media 9/03/87 J.K. 11 <2> ;============================================================================== 12 <2> 13 <2> ; VALUES FOR VARIOUS FLAGS IN BDS.FLAGS. 14 <2> 15 <2> FNON_REMOVABLE EQU 01H ;FOR NON-REMOVABLE MEDIA 16 <2> FCHANGELINE EQU 02H ;IF CHANGELINE SUPPORTED ON DRIVE 17 <2> RETURN_FAKE_BPB EQU 04H ; WHEN SET, DON'T DO A BUILD BPB 18 <2> ; JUST RETURN THE FAKE ONE 19 <2> GOOD_TRACKLAYOUT EQU 08H ; THE TRACK LAYOUT HAS NO FUNNY SECTORS 20 <2> ; FCHANGED_BY_FORMAT EQU 08H 21 <2> FI_AM_MULT EQU 10H ;IF MORE THAN ONE LOGICAL FOR THIS PHYSICAL 22 <2> FI_OWN_PHYSICAL EQU 20H ;SIGNIFY LOGICAL OWNER OF THIS PHYSICAL 23 <2> FCHANGED EQU 40H ;INDICATES MEDIA CHANGED 24 <2> SET_DASD_TRUE EQU 80H ; SET DASD BEFORE NEXT FORMAT 25 <2> FCHANGED_BY_FORMAT EQU 100H ;MEDIA CHANGED BY FORMAT 26 <2> UNFORMATTED_MEDIA EQU 200H ;AN001; Fixed disk only 27 <2> F_LBA equ 400h ; LBA supported 28 <2> 29 <2> LBAPACKETSTRUC struc 0 00007D72 ???? lpSize dw ? 0 00007D74 ???? lpCount dw ? 0 00007D76 ???????? lpBuffer dd ? 0 00007D7A ???????????????? lpSector dd ?,? 34 <2> LBAPACKETSTRUC ends 35 <2> 36 <2> ; 37 <2> ; VARIOUS FORM FACTORS TO DESCRIBE MEDIA 38 <2> ; 39 <2> FF48TPI EQU 0 40 <2> FF96TPI EQU 1 41 <2> FFSMALL EQU 2 42 <2> FFHARDFILE EQU 5 43 <2> FFOTHER EQU 7 44 <2> 45 <2> BDS_TYPE STRUC 0 00007D72 ???????? LINK DD ? ; LINK TO NEXT BDS 0 00007D76 ?? DRIVENUM DB ? ; INT 13 DRIVE NUMBER 0 00007D77 ?? DRIVELET DB ? ; DOS DRIVE NUMBER 0 00007D78 ???? BYTEPERSEC DW ? ; NUMBER OF BYTES/SEC 0 00007D7A ?? SECPERCLUS DB ? ; SEC PER ALLOCATION UNIT 0 00007D7B ???? RESSEC DW ? ; NUMBER OF RESERVED SECTORS 0 00007D7D ?? CFAT DB ? ; NUMBER OF FATS 0 00007D7E ???? CDIR DW ? ; NUMBER OF DIRECTORY ENTRIES 0 00007D80 ???? DRVLIM DW ? ; NUMBER OF SECTORS ON MEDIUM 0 00007D82 ?? MEDIAD DB ? ; MEDIA DESCRIPTOR BYTE 0 00007D83 ???? CSECFAT DW ? ; NUMBER OF SECTORS/FAT 0 00007D85 ???? SECLIM DW ? ; SECTORS PER TRACK 0 00007D87 ???? HDLIM DW ? ; MAX NUMBER OF HEADS 0 00007D89 ???? HIDSEC_L DW ? ; NUMBER OF HIDDEN SECTORS 0 00007D8B ???? HIDSEC_H dw ? ;0 ;J.K.87 0 00007D8D ???? DRVLIM_L dw ? ;0 ;J.K.87 0 00007D8F ???? DRVLIM_H dw ? ;0 ;J.K.87 0 00007D91 ?? FATSIZ DB ? ; FLAGS... 0 00007D92 ???? OPCNT DW ? ; OPEN REF. COUNT 0 00007D94 ?? FORMFACTOR DB ? ; FORM FACTOR INDEX 0 00007D95 ???? FLAGS DW ? ; VARIOUS FLAGS 0 00007D97 ???? CCYLN DW ? ; MAX NUMBER OF CYLINDERS 0 00007D99 ???? RBYTEPERSEC DW ? ; RECOMMENDED BPB 0 00007D9B ?? RSECPERCLUS DB ? 0 00007D9C ???? RRESSEC DW ? 0 00007D9E ?? RCFAT DB ? 0 00007D9F ???? RCDIR DW ? 0 00007DA1 ???? RDRVLIM DW ? 0 00007DA3 ?? RMEDIAD DB ? 0 00007DA4 ???? RCSECFAT DW ? 0 00007DA6 ???? RSECLIM DW ? 0 00007DA8 ???? RHDLIM DW ? 0 00007DAA ???? RHIDSEC_L DW ? 0 00007DAC ???? RHIDSEC_H DW ? ;0 ;J.K.87 0 00007DAE ???? RDRVLIM_L dw ? ;0 ;J.K.87 0 00007DB0 ???? RDRVLIM_H dw ? ;0 ;J.K.87 0 00007DB2 ???????????? RESERVE DB 6 DUP (?) ; RESERVED FOR FUTURE 0 00007DB8 ?? TRACK DB ? ; LAST TRACK ACCESSED ON DRIVE 0 00007DB9 ???? TIM_LO DW ? ; TIME OF LAST ACCESS. KEEP 0 00007DBB ???? TIM_HI DW ? ; THESE CONTIGUOUS. 86 0000004B <2> VOLID DB 12 DUP (?) ; VOLUME ID OF MEDIUM 0 00007DC9 ???????? VOL_SERIAL dd ? ;0 ;J.K.87 Current volume serial number from Boot record 88 0000005B <2> FILESYS_Id db 9 dup (?) ;(0) ;J.K.87 Current file system id from Boot record 89 <2> BDS_TYPE ENDS 90 <2> 91 <2> BPBSIZE equ TRACK - RBYTEPERSEC ; SIZE IN BYTES OF RECBPB AREA IN THE BDS 92 <2> 93 <2> 94 <2> ;********************************************************************* 95 <2> ; BDS structure for mini disk - J.K. 4/7/86 96 <2> ;********************************************************************* 97 <2> 98 <2> BDSM_type struc 0 00007D72 ???? mlink DW ? ;-1 ;Link to next structure 0 00007D74 ???? DW ? 0 00007D76 ?? mdriveNum DB ? ;80 ;Int 13 Drive Number 0 00007D77 ?? mdriveLet DB ? ;3 ;Logical Drive Number 0 00007D78 ???? mBytePerSec DW ? ;512 0 00007D7A ?? mSecPerClus DB ? ;1 ;Sectors/allocation unit 0 00007D7B ???? mRESSEC DW ? ;1 ;Reserved sectors for DOS 0 00007D7D ?? mcFAT DB ? ;2 ;No. of allocation tables 0 00007D7E ???? mcDIR DW ? ;16 ;Number of directory entries 0 00007D80 ???? mDRVLIM DW ? ;0 ;Number of sectors (at 512 bytes each) 0 00007D82 ?? mMediad DB ? ;11111000B ;Media descriptor 0 00007D83 ???? mcSecFat DW ? ;1 ;Number of FAT sectors 0 00007D85 ???? mSECLIM DW ? ;0 ;Sector limit 0 00007D87 ???? mHDLIM DW ? ;0 ;Head limit 0 00007D89 ???? mHIDSEC_L DW ? ;0 ;Hidden sector count 0 00007D8B ???? mHidsec_H dw ? ;0 ;J.K.87 0 00007D8D ???? mDrvlim_L dw ? ;0 ;J.K.87 0 00007D8F ???? mDrvlim_H dw ? ;0 ;J.K.87 0 00007D91 ?? mFatSiz DB ? ;0 ;TRUE => bigfat 0 00007D92 ???? mOPCNT DW ? ;0 ;Open Ref. Count 0 00007D94 ?? mFormFactor DB ? ;3 ;Form Factor 0 00007D95 ???? mFLAGS DW ? ;0020H ;Various Flags 0 00007D97 ???? mcCyln dw ? ;40 ;max number of cylinders 122 00000027 <2> mRecBPB db 31 dup (?) ;(0) ;Recommended BPB for drive 0 00007DB8 ?? mTrack db ? ;-1 0 00007DB9 ???? IsMini dw ? ;1 ;Overlapping TIM_LOH 0 00007DBB ???? Hidden_Trks dw ? ;0 ;Overlapping TIM_HIH 126 0000004B <2> mVOLID DB 11 dup (?) ;"NO NAME " ;Volume ID for this disk 0 00007DC8 ?? DB ? ;0 ;ASCIZII for "NO NAME " 0 00007DC9 ???????? mVol_Serial dd ? ;0 ;Current volume serial number from Boot record 0 00007DCD ???????????????? mFileSys_Id db 8 dup (?) ;"FAT12 " ;Current file system id from Boot record 0 00007DD5 ?? db ? ;0 131 <2> 132 <2> BDSM_type ENDS 133 <2> ;****************************************************************************** 134 <2> Max_mini_dsk_num equ 23 ;J.K. 4/7/86 - max # of mini disk ibmbio can support 135 <2> ; 136 <2> 14 <1> 15 <1> ;AN000; Extended BPB structure. 16 <1> BPB_TYPE STRUC 0 00007D72 ???? SECSIZE DW ? 0 00007D74 ?? SECALL DB ? 0 00007D75 ???? RESNUM DW ? 0 00007D77 ?? FATNUM DB ? 0 00007D78 ???? DIRNUM DW ? 0 00007D7A ???? SECNUM DW ? 0 00007D7C ?? FATID DB ? 0 00007D7D ???? FATSIZE DW ? 0 00007D7F ???? SLIM DW ? 0 00007D81 ???? HLIM DW ? 0 00007D83 ???? HIDDEN_L DW ? 0 00007D85 ???? HIDDEN_H dw ? ;0 ;J.K. 0 00007D87 ???? SECNUM_L dw ? ;0 ;J.K. 0 00007D89 ???? SECNUM_H dw ? ;0 ;J.K. 31 <1> BPB_TYPE ENDS 32 <1> 33 <1> ;;;;;;;;;;; 34 <1> BOOT_SERIAL_SIZE equ 4 ;J.K. 35 <1> BOOT_VOLUME_LABEL_SIZE equ 11 ;J.K. 36 <1> BOOT_SYSTEM_ID_SIZE equ 8 ;J.K. 37 <1> EXT_BOOT_SIGNATURE equ 41 ;J.K. 38 <1> RSINIT equ 0A3H ;RS232 INITIALIZATION 39 <1> ;9600 BAUD:NO PARITY:1 STOP:8 BIT WORD 40 <1> LF equ 10 ;LINE FEED 41 <1> CR equ 13 ;CARRIAGE RETURN 42 <1> BACKSP equ 8 ;BACKSPACE 43 <1> BRKADR equ 1BH * 4 ;006C 1BH BREAK VECTOR ADDRESS 44 <1> TIMADR equ 1CH * 4 ;0070 1CH TIMER INTERRUPT 45 <1> DSKADR equ 1EH * 4 ;ADDRESS OF PTR TO DISK PARAMETERS 46 <1> SEC9 equ 522H ;ADDRESS OF DISK PARAMETERS 47 <1> HEADSETTLE equ SEC9+9 ; ARR 2.20 ADDRESS OF HEAD SETTLE TIME 48 <1> NORMSETTLE equ 15 ; ARR 2.20 NORMAL HEAD SETTLE 49 <1> SPEEDSETTLE equ 0 ; ARR 2.20 SPEED UP SETTLE TIME 50 <1> INITSPOT equ 534H ; ARR IBM WANTS 4 ZEROS HERE 51 <1> AKPORT equ 20H 52 <1> EOI equ 20H 53 <1> CMDLEN equ 0 ;LENGTH OF THIS COMMAND 54 <1> UNIT equ 1 ;SUB UNIT SPECIFIER 55 <1> CMD equ 2 ;COMMAND CODE 56 <1> STATUS equ 3 ;STATUS 57 <1> MEDIA equ 13 ;MEDIA DESCRIPTOR 58 <1> TRANS equ 14 ;TRANSFER ADDRESS 59 <1> COUNT equ 18 ;COUNT OF BLOCKS OR CHARACTERS 60 <1> START equ 20 ;FIRST BLOCK TO TRANSFER 61 <1> EXTRA equ 22 ;USUALLY A POINTER TO VOL ID FOR ERROR 15 62 <1> CHROUT equ 29H 63 <1> MAXERR equ 5 64 <1> LSTDRV equ 504H 65 <1> 66 <1> NOTBUSYSTATUS equ 10000000B ; NOT BUSY 67 <1> ACKSTATUS equ 01000000B ; ACKNOWLEDGE (FOR WHAT?) 68 <1> NOPAPERSTATUS equ 00100000B ; NO MORE PAPER 69 <1> SELECTEDSTATUS equ 00010000B ; THE PRINTER SAID IT WAS SELECTED 70 <1> IOERRSTATUS equ 00001000B ; SOME KINDA ERROR 71 <1> RESERVED equ 00000110B ; NOPS 72 <1> TIMEOUTSTATUS equ 00000001B ; TIME OUT. 73 <1> ERROR_UNKNOWN_MEDIA equ 7 ; FOR USE IN BUILD BPB CALL 74 <1> 75 <1> PATHGEN equ 1 16 %include "msmacro.mac" 1 <1> === Switch to base=008400h -> "BIOCODE" 2 <1> section BIOCODE 3 <1> ; 4 <1> ; This file contains three macros used in debugging the system. If the 5 <1> ; variable "itest" (in msbio.asm) is nonzero code is included in the 6 <1> ; modules to print debugging messages. The level of debugging is controlled 7 <1> ; by the value of the variable fTestBits in msbio.asm. Specific bits in 8 <1> ; the variable determine which messages to print. The equ's below tell 9 <1> ; which bits control which funcitons. For example the fifth bit 10 <1> ; cooresponds to disk activity (see fTestDisk equ below). 11 <1> ; 12 <1> ; The macros in the file are: 13 <1> ; 14 <1> ; message Prints an ascii string on the screen. 15 <1> ; Example usage: 16 <1> ; 17 <1> ; message fTestDisk, <"Start Disk Write", CR, LF> 18 <1> ; message fTestINIT, <"Begin BDS initialization"> 19 <1> ; 20 <1> ; 21 <1> ; MNUM Print the value in a register or memory location on 22 <1> ; the screen. Value is displayed in hex. 23 <1> ; Usage: 24 <1> ; MNUM bitpattern, valueLocation 25 <1> ; 26 <1> ; valueLocation is typically a regester: 27 <1> ; 28 <1> ; mnum fTestCom, AX 29 <1> ; mnum fTestDisk, DX 30 <1> ; 31 <1> ; ValueLocation can also be a memory location: 32 <1> ; 33 <1> ; mnum fTestINIT, Final_Dos_Location 34 <1> ; 35 <1> ; If no valueLocation is given the macro defaults to 36 <1> ; the BX register. 37 <1> ; 38 <1> ; ZWAIT Stops the program until any key is pressed. 39 <1> ; 40 <1> ; 41 <1> ; The three macros preserve all register values. If "test" is zero 42 <1> ; defined during assembly then the marco produce no code. 43 <1> ; 44 <1> 45 <1> %IF itest ;3.30 46 <1> EXTRN MSGOUT:NEAR,MSGNUM:NEAR ;3.30 47 <1> EXTRN NUMBUF:BYTE,DIGITS:BYTE,FTESTBITS:WORD ;3.30 48 <1> EXTRN DUMPBYTES:NEAR,OUTCHAR:NEAR,HEX_TO_ASCII:NEAR ;3.30 49 <1> 50 <1> 51 <1> fTestALL equ 1111111111111111b ; watch everything 52 <1> fTestHARD equ 0000000000000001b ; watch hard disk initialization 53 <1> fTest96 equ 0000000000000010b ; watch 96 tpi activity 54 <1> FTEST13 EQU 0000000000000100B ; WATCH INT 13 ACTIVITY ;3.30 55 <1> FTESTCOM EQU 0000000000001000B ; WATCH PACKET ACTIVITY ;3.30 56 <1> FTESTINIT EQU 0000000000010000B ; WATCH INITIALIZATION MESSAGES ;3.30 57 <1> FTESTDISK EQU 0000000000100000B ; WATCH DISK DEVICE DRIVER CALLS ;3.30 58 <1> FTESTCON EQU 0000000001000000B ; WATCH SYSTEM WAIT ACTIVITY IN CO;3.30 NSOLE 59 <1> FtestClock equ 0000000010000000b ; wathc clock device 5/2/86 ;3.30 60 <1> 61 <1> ; NASM original macros 62 <1> 63 <1> ; 64 <1> ; message macro -- see above for description 65 <1> ; 66 <1> 67 <1> %unimacro stripangles 2+.nolist 68 <1> 69 <1> %imacro stripangles 2+.nolist 70 <1> %defstr %%param %2 71 <1> %rep 16 72 <1> %substr %%opening %%param 1 73 <1> %ifidn %%opening, '<' 74 <1> %substr %%param %%param 2,-1 75 <1> %endif 76 <1> %endrep 77 <1> %rep 16 78 <1> %strlen %%length %%param 79 <1> %substr %%closing %%param %%length 80 <1> %ifidn %%closing, '>' 81 <1> %substr %%param %%param 1,-2 82 <1> %endif 83 <1> %endrep 84 <1> %deftok %%token %%param 85 <1> %1 %%token 86 <1> %endmacro 87 <1> 88 <1> %imacro MESSAGE 2+ 89 <1> jmp short %%b 90 <1> %%a: 91 <1> stripangles db, %2 92 <1> db 0 93 <1> %%b: push SI 94 <1> push AX 95 <1> mov AX, %1 96 <1> mov SI, OFFSET %%a 97 <1> call MSGOUT 98 <1> pop AX 99 <1> pop SI 100 <1> %endmacro 101 <1> 102 <1> 103 <1> ; 104 <1> ; mnum macro -- see above for description 105 <1> ; 106 <1> 107 <1> %imacro MNum 1-2 108 <1> push AX 109 <1> %ifempty %2 110 <1> mov AX,%1 111 <1> call MSGNUM 112 <1> %else 113 <1> push BX 114 <1> mov BX,%2 115 <1> mov AX,%1 116 <1> call MSGNUM 117 <1> pop BX 118 <1> %endif 119 <1> pop AX 120 <1> %endmacro 121 <1> 122 <1> 123 <1> ; 124 <1> ; zwait macro -- see above for description 125 <1> ; 126 <1> 127 <1> %imacro ZWAIT 0 128 <1> Message fTestALL,<"? "> 129 <1> CALL ZWAITrtn 130 <1> %endmacro 131 <1> 132 <1> ZWAITrtn: 133 <1> pushf ; save the flags 134 <1> push AX ; preserve AX 135 <1> xor AH, AH ; set command to get character ;3.30* 136 <1> int 16h ; call rom keyboard routine ;3.30* 137 <1> pop AX ; restore AX 138 <1> popf ; restore the flags 139 <1> ret 140 <1> 141 <1> ;Dump_byte dumps the memory contents in hex. ;3.30 142 <1> ;DUMPOFFLABEL should be a label or a variable defined in DUMPSEG. ;3.30 143 <1> %imacro DUMP_BYTE 3 144 <1> push es ;3.30 145 <1> PUSH DS ;3.30 146 <1> PUSH SI ;3.30 147 <1> PUSH CX ;3.30 148 <1> ;3.30 149 <1> MOV CX, %1 ;3.30 150 <1> MOV DS, CX ;3.30 151 <1> MOV SI, OFFSET %2 ;3.30 152 <1> MOV CX, %3 ;3.30 153 <1> call dumpbytes ;3.30 154 <1> ;3.30 155 <1> POP CX ;3.30 156 <1> POP SI ;3.30 157 <1> POP DS ;3.30 158 <1> pop es ;3.30 159 <1> %endmacro ;3.30 160 <1> ;3.30 161 <1> ;Dump_Byte_Reg dumps the memory contents in hex. - 4/9/86 ;3.30 162 <1> ;DUMPOFFREG should be a register contains the offset value in DUMPSEG. ;3.30 163 <1> %imacro DUMP_BYTE_REG 3 164 <1> DUMP_BYTE_REG MACRO DUMPSEG, DUMPOFFREG, BYTELENGTH ;3.30 165 <1> push es ;3.30 166 <1> PUSH DS ;3.30 167 <1> PUSH SI ;3.30 168 <1> PUSH CX ;3.30 169 <1> ;3.30 170 <1> MOV CX, %1 ;3.30 171 <1> MOV DS, CX ;3.30 172 <1> MOV SI, %2 ;3.30 173 <1> MOV CX, %3 ;3.30 174 <1> call dumpbytes ;3.30 175 <1> ;3.30 176 <1> POP CX ;3.30 177 <1> POP SI ;3.30 178 <1> POP DS ;3.30 179 <1> pop es ;3.30 180 <1> %endmacro ;3.30 181 <1> 182 <1> %else 183 <1> ; if test is not defined then make macro into null statements 184 <1> %imacro Message 0-1+.nolist 185 <1> %endmacro 186 <1> 187 <1> %imacro MNUM 0-1+.nolist 188 <1> %endmacro 189 <1> 190 <1> %imacro ZWAIT 0-1+.nolist 191 <1> %endmacro 192 <1> 193 <1> %imacro DUMP_BYTE 0-1+.nolist 194 <1> %endmacro 195 <1> 196 <1> %imacro DUMP_BYTE_REG 0-1+.nolist 197 <1> %endmacro 198 <1> 199 <1> %endif 200 <1> 201 <1> %unimacro PATHSTART 2 202 <1> %unimacro PATHEND 2 203 <1> 204 <1> %imacro PATHSTART 2 205 <1> %IF PATHGEN ;3.30 206 <1> PUBLIC %2%1S,%2%1E ;3.30 207 <1> %2%1S LABEL BYTE ;3.30 208 <1> %ENDIF ;3.30 209 <1> %endmacro ;3.30 210 <1> ;3.30 211 <1> %imacro PATHEND 2 212 <1> %IF PATHGEN ;3.30 213 <1> %2%1E LABEL BYTE ;3.30 214 <1> %ENDIF ;3.30 215 <1> %endmacro ;3.30 17 18 ;*** DOS 3.3 will not support more than 25 rows 19 ; INCLUDE DEVSYM.INC ;J.K. 4/29/86 for CON$GENIOCTL support 20 ; INCLUDE IOCTL.INC ;J.K. 4/29/86 for CON$GENIOCTL support 21 22 EXTRN EXIT:NEAR ;MSBIO1 23 EXTRN BUS$EXIT:NEAR ;MSBIO1 24 25 ; EXTRN CMDERR:NEAR ;MSBIO1 J.K. 4/29/86 26 27 ;DATA 28 EXTRN PTRSAV:DWORD ;MSBIO1 29 EXTRN FHAVEK09:BYTE ;MSDISK 30 EXTRN ALTAH:BYTE ;MSBDATA 31 EXTRN KEYRD_Func:Byte ;MSBDATA 32 EXTRN KEYSTS_Func:Byte ;MSBDATA 33 34 ; EXTRN SAV_SC_INFO:BYTE ;MSBDATA J.K. 4/29/86 35 ; EXTRN SAV_SC_MODE:BYTE ;MSBDATA J.K. 4/29/86 36 ;------------------------------------------------------ 37 ; 38 ; CONSOLE READ ROUTINE 39 ; 40 ASSUME DS:BIOCODE ; THIS WAS SET BY THE CON DD ENTRY POINT 41 PUBLIC CON$READ 42 CON$READ PROC NEAR 0 00007D72 E306 JCXZ CON$EXIT 44 CON$LOOP: 0 00007D74 E80600 CALL CHRIN ;GET CHAR IN AL 0 00007D77 AA STOSB ;STORE CHAR AT ES:DI 0 00007D78 E2FA LOOP CON$LOOP 48 CON$EXIT: 0 00007D7A E9[0000] JUMP EXIT 50 CON$READ ENDP 51 ;--------------------------------------------------------- 52 ; 53 ; INPUT SINGLE CHAR INTO AL 54 ; 55 ;J.K.5/12/87 We are going to issue extended keyboard function, if supported. 56 ;The returning value of the extended key stroke of the extended key board 57 ;function uses 0E0h in AL instead of 00 as in the conventional key board 58 ;function. This creates a conflict when the user entered real Greek Alpha 59 ;charater (= 0E0h) to distinguish the extended key stroke and the Greek Alpha. 60 ;This case will be handled in the following manner; 61 ; AH = 16h 62 ; INT 16h 63 ; If AL == 0, then extended code (in AH) 64 ; else If AL == 0E0h, then 65 ; IF AH <> 0, then extended code (in AH) 66 ; else Greek_Alpha character. 67 ;Also, for compatibility reason, if an extended code is detected, then we 68 ;are going to change the value in AL from 0E0h to 00h. 69 70 71 CHRIN PROC NEAR 72 ;AN000; 73 ; XOR AX,AX 0 00007D7D 8A26[0000] mov ah,[KEYRD_Func] ;AN000; Set by MSINIT. 0 or 10h 0 00007D81 30C0 xor al,al ;AN000; 0 00007D83 8606[0000] XCHG AL,[ALTAH] ;GET CHARACTER & ZERO ALTAH 77 0 00007D87 08C0 OR AL,AL 0 00007D89 752B JNZ KEYRET 80 ;SB34CON000************************************************************** 81 ;SB Keyboard I/O interrupt 82 ;SB AH already contains the keyboard read function number 83 ;SB 1 LOC 84 0 00007D8B CD16 int 16h 86 ;SB34CON000************************************************************** 87 ALT10: 0 00007D8D 09C0 OR AX,AX ;CHECK FOR NON-KEY AFTER BREAK 0 00007D8F 74EC JZ CHRIN 0 00007D91 3D0072 CMP AX,7200H ;CHECK FOR CTRL-PRTSC 0 00007D94 7505 JNZ ALT_Ext_Chk ;AN000; 0 00007D96 B010 MOV AL,16 93 KeyRet equ KEYRET ; NASM port label 0 00007D98 EB1C jmp KeyRet ;AN000; 0 00007D9A 90 nop ; identicalise 96 ALT_Ext_Chk: 97 ;SB34CON001************************************************************** 98 ;SB IF operation was extended function (i.e. KEYRD_Func != 0) THEN 99 ;SB IF character read was 0E0h THEN 100 ;SB IF extended byte was zero (i.e. AH == 0) THEN 101 ;SB goto keyret 102 ;SB ELSE 103 ;SB set AL to zero 104 ;SB goto ALT_SAVE 105 ;SB ENDIF 106 ;SB ENDIF 107 ;SB ENDIF 108 ;SB 9 LOCS 109 0 00007D9B 803E[0000]00 cmp BYTE [KEYRD_Func],0 0 00007DA0 740C jz NOT_EXT 0 00007DA2 3CE0 cmp al,0E0h 0 00007DA4 7508 jnz NOT_EXT 0 00007DA6 08E4 or ah,ah 0 00007DA8 740C jz KEYRET 0 00007DAA 30C0 xor al,al 0 00007DAC EB04 jmp short ALT_SAVE 118 NOT_EXT: 119 120 ;SB34CON001************************************************************** 0 00007DAE 08C0 OR AL,AL ;SPECIAL CASE? 0 00007DB0 7504 JNZ KEYRET 123 ALT_SAVE: 0 00007DB2 8826[0000] MOV [ALTAH],AH ;STORE SPECIAL KEY 125 KEYRET: 0 00007DB6 C3 RET 127 CHRIN ENDP 128 129 ;-------------------------------------------------------------- 130 ; 131 ; KEYBOARD NON DESTRUCTIVE READ, NO WAIT 132 ; 133 ; PC-CONVERTIBLE-TYPE MACHINE: IF BIT 10 IS SET BY THE DOS IN THE STATUS WORD 134 ; OF THE REQUEST PACKET, AND THERE IS NO CHARACTER IN THE INPUT BUFFER, THE 135 ; DRIVER ISSUES A SYSTEM WAIT REQUEST TO THE ROM. ON RETURN FROM THE ROM, IT 136 ; RETURNS A 'CHAR-NOT-FOUND' TO THE DOS. 137 ; 138 CONBUSJ: 139 ASSUME DS:NOTHING 0 00007DB7 EB62 JMP CONBUS 0 00007DB9 90 nop ; identicalise 142 143 ASSUME DS:BIOCODE ; THIS WAS SET BY THE CON DD ENTRY POINT 144 PUBLIC CON$RDND 145 CON$RDND: 0 00007DBA A0[0000] MOV AL,[ALTAH] 0 00007DBD 08C0 OR AL,AL 0 00007DBF 7403 JZ RD1 0 00007DC1 EB4E JMP RDEXIT 0 00007DC3 90 nop ; identicalise 151 152 RD1: 153 ;SB34CON002************************************************************** 154 ;SB Keyboard I/O interrupt 155 ;SB Get keystroke status (KEYSTS_Func) 156 ;SB 2 LOCS 157 0 00007DC4 8A26[0000] mov ah,[KEYSTS_Func] 0 00007DC8 CD16 int 16h 160 ;SB34CON002************************************************************** 0 00007DCA 7403 JZ NOCHR 0 00007DCC EB1B JMP GOTCHR 0 00007DCE 90 nop ; identicalise 164 NOCHR: 0 00007DCF 803E[0000]00 CMP byte [FHAVEK09],0 0 00007DD4 74E1 JZ CONBUSJ 0 00007DD6 C51E[0000] LDS BX,[PTRSAV] 168 ASSUME DS:NOTHING 0 00007DDA F747030004 TEST word [BX + STATUS],0400H ; SYSTEM WAIT ENABLED? 0 00007DDF 74D6 JZ CONBUSJ 171 172 ;******************************** 173 ; NEED TO WAIT FOR IBM RESPONSE TO REQUEST FOR CODE ON HOW TO USE THE SYSTEM 174 ; WAIT CALL. 175 ;******************************** 176 MESSAGE FTESTCON,<"SYSTEM WAIT STAGE",CR,LF> 0 00007DE1 B80041 MOV AX,4100H ; WAIT ON AN EXTERNAL EVENT 178 ; MOV BX,0300H ; NO TIMEOUT 179 ; MOV DX,60H ; LOOK AT I/O PORT 60H 0 00007DE4 CD15 INT 15H ; CALL ROM FOR SYSTEM WAIT 181 MESSAGE FTESTCON,<"OUT OF WAIT. AX IS "> 182 MNUM FTESTCON,AX 183 MESSAGE FTESTCON, 0 00007DE6 EB33 JMP CONBUS 0 00007DE8 90 nop ; identicalise 186 187 ASSUME DS:BIOCODE 188 GOTCHR: 0 00007DE9 09C0 OR AX,AX 0 00007DEB 7508 JNZ NOTBRK ;CHECK FOR NULL AFTER BREAK 191 ;SB34CON004************************************************************** 192 ;SB Keyboard I/O interrupt 193 ;SB Keyboard read function (KEYRD_Func) 194 ;SB 2 LOCS 195 0 00007DED 8A26[0000] mov ah,[KEYRD_Func] 0 00007DF1 CD16 int 16h 198 ;SB34CON004************************************************************** 0 00007DF3 EBC5 JUMP CON$RDND ;AND GET A REAL STATUS 200 NOTBRK: 0 00007DF5 3D0072 CMP AX,7200H ;CHECK FOR CTRL-PRTSC 0 00007DF8 7505 JNZ RD_Ext_Chk ;AN000; 0 00007DFA B010 MOV AL,16 0 00007DFC EB13 jmp RDEXIT ;AN000; 0 00007DFE 90 nop ; identicalise 206 RD_Ext_Chk: ;AN000; 0 00007DFF 803E[0000]00 cmp byte [KEYRD_Func], 0 ;AN000; Extended Keyboard function? 0 00007E04 740B jz RDEXIT ;AN000; No. Normal exit. 0 00007E06 3CE0 cmp al,0E0h ;AN000; Extended key value or Greek Alpha? 0 00007E08 7507 jne RDEXIT ;AN000; 0 00007E0A 80FC00 cmp ah, 0 ;AN000; Scan code exist? 0 00007E0D 7402 jz RDEXIT ;AN000; Yes. Greek Alpha char. 0 00007E0F B000 mov al, 0 ;AN000; No. Extended key stroke. Change it for compatibility 214 PUBLIC RDEXIT 215 RDEXIT: 0 00007E11 C51E[0000] LDS BX,[PTRSAV] 217 ASSUME DS:NOTHING 0 00007E15 88470D MOV [BX + MEDIA],AL 219 EXVEC: 0 00007E18 E9[0000] JUMP EXIT 221 222 CONBUS: 223 ASSUME DS:NOTHING 0 00007E1B E9[0000] JUMP BUS$EXIT 225 ;-------------------------------------------------------------- 226 ; 227 ; KEYBOARD FLUSH ROUTINE 228 ; 229 ASSUME DS:BIOCODE ; THIS WAS SET BY THE CON DD ENTRY POINT 230 PUBLIC CON$FLSH 231 CON$FLSH: 0 00007E1E E80300 CALL FLUSH 0 00007E21 E9[0000] JUMP EXIT 234 235 PUBLIC FLUSH 236 FLUSH: 0 00007E24 C606[0000]00 MOV byte [ALTAH],0 ;CLEAR OUT HOLDING BUFFER 238 239 FLLOOP: 240 ;SB33012**************************************************************** 241 ;SB ; Is there a char there? 0 00007E29 B401 mov AH, 1 ;SB ; command code for check status 0 00007E2B CD16 int 16h ;SB ; call rom-bios keyboard routine 244 ;SB33012**************************************************************** 0 00007E2D 7406 JZ FLDONE 246 ;SB33013**************************************************************** 0 00007E2F 30E4 xor AH, AH ;SB ; if zf is nof set, get character 0 00007E31 CD16 int 16h ;SB ; call rom-bios to get character 249 ;SB33013**************************************************************** 0 00007E33 EBF4 JMP FLLOOP 251 FLDONE: 252 0 00007E35 C3 RET 254 ;---------------------------------------------------------- 255 ; 256 ; CONSOLE WRITE ROUTINE 257 ; 258 ASSUME DS:BIOCODE ; THIS WAS SET BY THE CON DD ENTRY POINT 259 PUBLIC CON$WRIT 260 CON$WRIT: 0 00007E36 E3E0 JCXZ EXVEC 262 CON$LP: 0 00007E38 268A05 MOV AL,[ES:DI] ;GET CHAR 0 00007E3B 47 INC DI 0 00007E3C CD29 INT CHROUT ;OUTPUT CHAR 0 00007E3E E2F8 LOOP CON$LP ;REPEAT UNTIL ALL THROUGH 0 00007E40 E9[0000] JUMP EXIT 268 ;----------------------------------------------- 269 ; 270 ; BREAK KEY HANDLING 271 ; 272 relocated i1B 273 CBREAK: 274 PUBLIC CBREAK 0 00007E43 1E push ds 0 00007E44 E8[0000] call biocode_get_ds_dosentry 0 00007E47 C606[0000]03 MOV byte [ALTAH],3 ;INDICATE BREAK KEY SET 0 00007E4C 1F pop ds 0 00007E4D CF IRET 280 281 ;------------------------------------------------------------------------------ 282 ;J.K. 4/29/86 - CONSOLE GENERIC IOCTL SUPPORT FOR DOS 3.3. 283 ;CON$GENIOCTL supports Get mode information, Set mode information functions. 284 ;It will only save the value from "Set mode information" and will return 285 ;the value through "Get mode information". It is supposed to be set by 286 ;the MODE.COM and other application program can retrieve information 287 ;through "Get mode information" call. 288 ;Initially, there is no valuable informaton until set by MODE command, so 289 ;any attemp to "Get mode information" at that points will fail. (unknown 290 ;command with carry set.) 291 ;At entry: CS = DS = code 292 ; [CS:PTRSAV] has seg, address of the Request Header saved in 293 ; in Strategy routine. 294 ; 295 ; PUBLIC CON$GENIOCTL 296 ; ASSUME DS:CODE 297 ;CON$GENIOCTL: 298 ; les di, [CS:PTRSAV] ;get the request header 299 ; cmp [es:di].MajorFunction, IOC_SC 300 ; je Major_SC_OK 301 ;SC_CMDERR: 302 ; stc 303 ; jmp cmderr ;carry is set, exit to cmderr 304 ;Major_SC_OK: 305 ; mov al, [es:di].MinorFunction ;save minor function 306 ; les di, [es:di].GenericIOCTL_Packet ;pointer of SC_MODE_INFO structure 307 ; mov cx, [es:di].SC_INFO_LENGTH ;save length 308 ; inc di 309 ; inc di ;ES:DI -> SC_MODE in Info. Packet 310 ; cmp cx, SC_INFO_PACKET_LENGTH ;currently 9. 311 ; jne SC_CMDERR ;cannot accept the different packet 312 ; cmp al, GET_SC_MODE ;minor function = 60h ? 313 ; jne SC_SET_MODE_FUNC ;no, check if it is "Set mode function" 314 ; cmp SAV_SC_MODE, 0 ;information set before? 315 ; je SC_CMDERR ;no, cannot get the info. 316 ;;SC_GET_MODE_FUNC: ;es:di -> SC_MODE in info. packet 317 ; ;cx - length 318 ; mov si, offset SAV_SC_INFO 319 ; rep movsb ;ds:si -> sav_sc_info, es:di -> sc_mode 320 ; jmp exit 321 ; 322 ;SC_SET_MODE_FUNC: ;es:di -> SC_MODE 323 ; cmp al, SET_SC_MODE ;minor function = 40h ? 324 ; jne SC_CMDERR 325 ; mov si, offset SAV_SC_INFO 326 ; xchg di, si 327 ; push es 328 ; push ds 329 ; pop es 330 ; pop ds 331 ; rep movsb ;ds:si -> sc_mode, es:di -> sav_sc_info 332 ; jmp exit 333 ; 334 ;J.K. 4/29/86 - End of CONSOLE GENERIC IOCTL SUPPORT FOR DOS 3.3. 335 336 ; (no prior section) ; CODE ENDS 337 END === Trace listing source: msaux.lst 1 ; TITLE MSAUX - DOS 3.3 2 ;---------------------------------------------------------------- 3 ; : 4 ; A U X - AUXILARY DEVICE DRIVER : 5 ; : 6 ; : 7 ; This file contains the Auxilary Device Driver. The : 8 ; auxilary driver handles calls to and from the RS-232 port. : 9 ; Three devices uses this code: AUX, COM1, and COM2. AUX and : 10 ; COM1 talk to the zero RS-232 card and COM2 talks to the : 11 ; 'one' RS-232 card. The beginning of the interrupt entry : 12 ; point for these devices sets the variable AUXNUM in the : 13 ; msbio.asm module. If the value is 0 the routines in this : 14 ; file will talk to the the 'zero' card. If the value in : 15 ; AUXNUM is 1 the routines will talk to the 'one' card. : 16 ; The procedure GETDX is called to put the value 0 or 1 in : 17 ; the DX register depending on the value in AUXBUF. : 18 ; : 19 ; The routines in this files are: : 20 ; : 21 ; routine function : 22 ; ------- -------- : 23 ; AUX$READ Read characters from the : 24 ; specified device. : 25 ; AUX$RDND Non-desrucrtive read with : 26 ; no waiting. : 27 ; AUX$FLSH Flush specified device input : 28 ; buffer. : 29 ; AUX$WRIT Write characters to the : 30 ; specified device. : 31 ; AUX$WRST Get status of specified : 32 ; device : 33 ; : 34 ; These routines are not called directly. Call are made via : 35 ; the strategy and interrupt entry point (see Device Header). : 36 ; : 37 ; Data structure: : 38 ; The Aux Device has a two byte buffer called AUXBUF. The : 39 ; first byte is for the zero card, the second byte is for the : 40 ; one card. A zero value in the byte indicates the buffer is : 41 ; empty. The routines use GETBX to get the address of the : 42 ; buffer. : 43 ; : 44 ;---------------------------------------------------------------- 45 46 ;;Ver 3.30 modification --------------------------- 47 itest equ 0 48 %include "msgroup.mac" ;DEFINE CODE SEGMENT 1 <1> EVBOUND equ 1 ;THIS VALUE BEING 0 DOES NO BOUNDARY ALLIGNMENT, VALUE 1 ;3.30 2 <1> ; ALIGNS TO EVEN ;3.30 3 <1> 4 <1> ; NASM original macros 5 <1> 6 <1> %include "dcodeseg.nas" 1 <2> 2 <2> %ifndef DCODESEGNAS 3 <2> %assign DCODESEGNAS 1 4 <2> === Switch to base=008400h -> "DOSCODETABLE" 5 <2> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <2> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=008400h -> "DOSCODECODE" 7 <2> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <2> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=008400h -> "DOSBIOCODE" 9 <2> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=008400h -> "BIOCODE" 10 <2> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <2> 12 <2> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <2> 14 <2> %endif 7 <1> 8 <1> %if EVBOUND ;;IF EVEN (WORD) ALLIGNMENT IS REQUESTED, ;3.30 9 <1> 10 <1> %imacro EVENB 0.nolist 11 <1> EVEN ;;ADJUST TO EVEN BOUNDARY 12 <1> %endmacro 13 <1> 14 <1> %imacro ODD 0.nolist 15 <1> %if (($ - $$) % 2) == 0 16 <1> db ? 17 <1> %endif 18 <1> %endmacro 19 <1> 20 <1> %else ;;SINCE EVEN ALLIGNMENT IS NOT DESIRED, JUST USE BYTE ALLI;3.30 GNMENT 21 <1> 22 <1> %imacro EVENB 0.nolist 23 <1> ;;REQUEST FOR WORD ALLIGNMENT DOES NOTHING ;3.30 24 <1> %endmacro 25 <1> 26 <1> %imacro ODD 0.nolist 27 <1> ;;REQUEST FOR ODD ALLIGNMENT DOES NOTHING ;3.30 28 <1> %endmacro 29 <1> 30 <1> %endif ;3.30 31 <1> 32 <1> %imacro CODE_SEGMENT 0.nolist === Switch to base=008400h -> "BIOCODE" 33 <1> section BIOCODE 34 <1> %endmacro 35 <1> 36 <1> ; end of NASM original macros 37 <1> 38 <1> CODE_SEGMENT ;3.30 39 <1> ASSUME CS:BIOCODE ;3.30 40 <1> ;3.30 49 %include "jumpmac.mac" 1 <1> ;;Rev 3.30 Modification 2 <1> ; 3 <1> ; given a label either 2 byte jump to another label _J 4 <1> ; if it is near enough or 3 byte jump to 5 <1> ; 6 <1> 7 <1> ; NASM original macros 8 <1> 9 <1> %if 0 10 <1> %imacro jump 1.nolist 11 <1> ;.xcref 12 <1> 13 <1> %ifndef %1_J ;; is this the first invocation 14 <1> %%a: JMP %1 15 <1> %ELSE 16 <1> %IF (%1_J >= $) || ($-%1_J > 126) 17 <1> %%a: JMP %1 ;; is the jump too far away? 18 <1> %ELSE 19 <1> %%a: JMP %1_J ;; do the short one... 20 <1> %ENDIF 21 <1> %ENDIF 22 <1> %ixdefine %1_j %%a 23 <1> ;.cref 24 <1> %endmacro 25 <1> ;.xcref jump 26 <1> %else 27 <1> %imacro jump 1.nolist 28 <1> ;REDEFINE THE ABOVE MACRO TO ALWAYS TRY A 3 BYTE NEAR JUMP 29 <1> jmp %1 30 <1> %endmacro ;;End of Modification 31 <1> %endif 32 <1> 33 <1> 50 %include "msmacro.mac" 1 <1> === Switch to base=008400h -> "BIOCODE" 2 <1> section BIOCODE 3 <1> ; 4 <1> ; This file contains three macros used in debugging the system. If the 5 <1> ; variable "itest" (in msbio.asm) is nonzero code is included in the 6 <1> ; modules to print debugging messages. The level of debugging is controlled 7 <1> ; by the value of the variable fTestBits in msbio.asm. Specific bits in 8 <1> ; the variable determine which messages to print. The equ's below tell 9 <1> ; which bits control which funcitons. For example the fifth bit 10 <1> ; cooresponds to disk activity (see fTestDisk equ below). 11 <1> ; 12 <1> ; The macros in the file are: 13 <1> ; 14 <1> ; message Prints an ascii string on the screen. 15 <1> ; Example usage: 16 <1> ; 17 <1> ; message fTestDisk, <"Start Disk Write", CR, LF> 18 <1> ; message fTestINIT, <"Begin BDS initialization"> 19 <1> ; 20 <1> ; 21 <1> ; MNUM Print the value in a register or memory location on 22 <1> ; the screen. Value is displayed in hex. 23 <1> ; Usage: 24 <1> ; MNUM bitpattern, valueLocation 25 <1> ; 26 <1> ; valueLocation is typically a regester: 27 <1> ; 28 <1> ; mnum fTestCom, AX 29 <1> ; mnum fTestDisk, DX 30 <1> ; 31 <1> ; ValueLocation can also be a memory location: 32 <1> ; 33 <1> ; mnum fTestINIT, Final_Dos_Location 34 <1> ; 35 <1> ; If no valueLocation is given the macro defaults to 36 <1> ; the BX register. 37 <1> ; 38 <1> ; ZWAIT Stops the program until any key is pressed. 39 <1> ; 40 <1> ; 41 <1> ; The three macros preserve all register values. If "test" is zero 42 <1> ; defined during assembly then the marco produce no code. 43 <1> ; 44 <1> 45 <1> %IF itest ;3.30 46 <1> EXTRN MSGOUT:NEAR,MSGNUM:NEAR ;3.30 47 <1> EXTRN NUMBUF:BYTE,DIGITS:BYTE,FTESTBITS:WORD ;3.30 48 <1> EXTRN DUMPBYTES:NEAR,OUTCHAR:NEAR,HEX_TO_ASCII:NEAR ;3.30 49 <1> 50 <1> 51 <1> fTestALL equ 1111111111111111b ; watch everything 52 <1> fTestHARD equ 0000000000000001b ; watch hard disk initialization 53 <1> fTest96 equ 0000000000000010b ; watch 96 tpi activity 54 <1> FTEST13 EQU 0000000000000100B ; WATCH INT 13 ACTIVITY ;3.30 55 <1> FTESTCOM EQU 0000000000001000B ; WATCH PACKET ACTIVITY ;3.30 56 <1> FTESTINIT EQU 0000000000010000B ; WATCH INITIALIZATION MESSAGES ;3.30 57 <1> FTESTDISK EQU 0000000000100000B ; WATCH DISK DEVICE DRIVER CALLS ;3.30 58 <1> FTESTCON EQU 0000000001000000B ; WATCH SYSTEM WAIT ACTIVITY IN CO;3.30 NSOLE 59 <1> FtestClock equ 0000000010000000b ; wathc clock device 5/2/86 ;3.30 60 <1> 61 <1> ; NASM original macros 62 <1> 63 <1> ; 64 <1> ; message macro -- see above for description 65 <1> ; 66 <1> 67 <1> %unimacro stripangles 2+.nolist 68 <1> 69 <1> %imacro stripangles 2+.nolist 70 <1> %defstr %%param %2 71 <1> %rep 16 72 <1> %substr %%opening %%param 1 73 <1> %ifidn %%opening, '<' 74 <1> %substr %%param %%param 2,-1 75 <1> %endif 76 <1> %endrep 77 <1> %rep 16 78 <1> %strlen %%length %%param 79 <1> %substr %%closing %%param %%length 80 <1> %ifidn %%closing, '>' 81 <1> %substr %%param %%param 1,-2 82 <1> %endif 83 <1> %endrep 84 <1> %deftok %%token %%param 85 <1> %1 %%token 86 <1> %endmacro 87 <1> 88 <1> %imacro MESSAGE 2+ 89 <1> jmp short %%b 90 <1> %%a: 91 <1> stripangles db, %2 92 <1> db 0 93 <1> %%b: push SI 94 <1> push AX 95 <1> mov AX, %1 96 <1> mov SI, OFFSET %%a 97 <1> call MSGOUT 98 <1> pop AX 99 <1> pop SI 100 <1> %endmacro 101 <1> 102 <1> 103 <1> ; 104 <1> ; mnum macro -- see above for description 105 <1> ; 106 <1> 107 <1> %imacro MNum 1-2 108 <1> push AX 109 <1> %ifempty %2 110 <1> mov AX,%1 111 <1> call MSGNUM 112 <1> %else 113 <1> push BX 114 <1> mov BX,%2 115 <1> mov AX,%1 116 <1> call MSGNUM 117 <1> pop BX 118 <1> %endif 119 <1> pop AX 120 <1> %endmacro 121 <1> 122 <1> 123 <1> ; 124 <1> ; zwait macro -- see above for description 125 <1> ; 126 <1> 127 <1> %imacro ZWAIT 0 128 <1> Message fTestALL,<"? "> 129 <1> CALL ZWAITrtn 130 <1> %endmacro 131 <1> 132 <1> ZWAITrtn: 133 <1> pushf ; save the flags 134 <1> push AX ; preserve AX 135 <1> xor AH, AH ; set command to get character ;3.30* 136 <1> int 16h ; call rom keyboard routine ;3.30* 137 <1> pop AX ; restore AX 138 <1> popf ; restore the flags 139 <1> ret 140 <1> 141 <1> ;Dump_byte dumps the memory contents in hex. ;3.30 142 <1> ;DUMPOFFLABEL should be a label or a variable defined in DUMPSEG. ;3.30 143 <1> %imacro DUMP_BYTE 3 144 <1> push es ;3.30 145 <1> PUSH DS ;3.30 146 <1> PUSH SI ;3.30 147 <1> PUSH CX ;3.30 148 <1> ;3.30 149 <1> MOV CX, %1 ;3.30 150 <1> MOV DS, CX ;3.30 151 <1> MOV SI, OFFSET %2 ;3.30 152 <1> MOV CX, %3 ;3.30 153 <1> call dumpbytes ;3.30 154 <1> ;3.30 155 <1> POP CX ;3.30 156 <1> POP SI ;3.30 157 <1> POP DS ;3.30 158 <1> pop es ;3.30 159 <1> %endmacro ;3.30 160 <1> ;3.30 161 <1> ;Dump_Byte_Reg dumps the memory contents in hex. - 4/9/86 ;3.30 162 <1> ;DUMPOFFREG should be a register contains the offset value in DUMPSEG. ;3.30 163 <1> %imacro DUMP_BYTE_REG 3 164 <1> DUMP_BYTE_REG MACRO DUMPSEG, DUMPOFFREG, BYTELENGTH ;3.30 165 <1> push es ;3.30 166 <1> PUSH DS ;3.30 167 <1> PUSH SI ;3.30 168 <1> PUSH CX ;3.30 169 <1> ;3.30 170 <1> MOV CX, %1 ;3.30 171 <1> MOV DS, CX ;3.30 172 <1> MOV SI, %2 ;3.30 173 <1> MOV CX, %3 ;3.30 174 <1> call dumpbytes ;3.30 175 <1> ;3.30 176 <1> POP CX ;3.30 177 <1> POP SI ;3.30 178 <1> POP DS ;3.30 179 <1> pop es ;3.30 180 <1> %endmacro ;3.30 181 <1> 182 <1> %else 183 <1> ; if test is not defined then make macro into null statements 184 <1> %imacro Message 0-1+.nolist 185 <1> %endmacro 186 <1> 187 <1> %imacro MNUM 0-1+.nolist 188 <1> %endmacro 189 <1> 190 <1> %imacro ZWAIT 0-1+.nolist 191 <1> %endmacro 192 <1> 193 <1> %imacro DUMP_BYTE 0-1+.nolist 194 <1> %endmacro 195 <1> 196 <1> %imacro DUMP_BYTE_REG 0-1+.nolist 197 <1> %endmacro 198 <1> 199 <1> %endif 200 <1> 201 <1> %unimacro PATHSTART 2 202 <1> %unimacro PATHEND 2 203 <1> 204 <1> %imacro PATHSTART 2 205 <1> %IF PATHGEN ;3.30 206 <1> PUBLIC %2%1S,%2%1E ;3.30 207 <1> %2%1S LABEL BYTE ;3.30 208 <1> %ENDIF ;3.30 209 <1> %endmacro ;3.30 210 <1> ;3.30 211 <1> %imacro PATHEND 2 212 <1> %IF PATHGEN ;3.30 213 <1> %2%1E LABEL BYTE ;3.30 214 <1> %ENDIF ;3.30 215 <1> %endmacro ;3.30 51 52 EXTRN ERR$CNT:NEAR ;MSBIO1 53 EXTRN GETDX:NEAR ;MSBIO1 54 EXTRN RDEXIT:NEAR ;MSCON 55 EXTRN EXIT:NEAR ;MSBIO1 56 EXTRN BUS$EXIT:NEAR ;MSBIO1 57 ;DATA 58 EXTRN AUXBUF:BYTE ;MSDATA 59 60 ; VALUES IN AH, REQUESTING FUNCTION OF INT 14H IN ROM BIOS 61 AUXFUNC_SEND EQU 1 ;TRANSMIT 62 AUXFUNC_RECEIVE EQU 2 ;READ 63 AUXFUNC_STATUS EQU 3 ;REQUEST STATUS 64 65 ; ERROR FLAGS, REPORTED BY INT 14H 66 67 ; THESE FLAGS REPORTED IN AH: 68 FLAG_DATA_READY EQU 01H ;DATA READY 69 FLAG_OVERRUN EQU 02H ;OVERRUN ERROR 70 FLAG_PARITY EQU 04H ;PARITY ERROR 71 FLAG_FRAME EQU 08H ;FRAMING ERROR 72 FLAG_BREAK EQU 10H ;BREAK DETECT 73 FLAG_TRANHOL_EMP EQU 20H ;TRANSMIT HOLDING REGISTER EMPTY 74 FLAG_TRANSHF_EMP EQU 40H ;TRANSMIT SHIFT REGISTER EMPTY 75 FLAG_TIMEOUT EQU 80H ;TIMEOUT 76 77 ; THESE FLAGS REPORTED IN AL: 78 FLAG_DELTA_CTS EQU 01H ;DELTA CLEAR TO SEND 79 FLAG_DELTA_DSR EQU 02H ;DELTA DATA SET READY 80 FLAG_TRAIL_RING EQU 04H ;TRAILING EDGE RING INDICATOR 81 FLAG_DELTA_SIG EQU 08H ;DELTA RECEIVE LINE SIGNAL DETECT 82 FLAG_CTS EQU 10H ;CLEAR TO SEND 83 FLAG_DSR EQU 20H ;DATA SET READY 84 FLAG_RING EQU 40H ;RING INDICATOR 85 FLAG_REC_SIG EQU 80H ;RECEIVE LINE SIGNAL DETECT 86 ;;End of modification ------------------ 87 88 89 ;---------------------------------------------------------------- 90 ; : 91 ; Read zero or more characters from Auxilary Device : 92 ; : 93 ; input:[es:di] points to area to receive aux data : 94 ; cx has number of bytes to be read : 95 ; "auxnum" first byte has number of aux device (rel 0): 96 ; : 97 ;---------------------------------------------------------------- 98 PUBLIC AUX$READ 99 AUX$READ PROC NEAR 100 ASSUME DS:BIOCODE ; SET BY AUX DEVICE DRIVER ENTRY ROUTINE 0 00007E4E E311 jcxz EXVEC2 ; if no characters, get out 0 00007E50 E88700 call GETBX ; put address of AUXBUF in BX 0 00007E53 31C0 xor AX,AX ; clear AX register 0 00007E55 8607 xchg AL,[BX] ; Get character , if any, from 105 ; buffer and clear buffer 0 00007E57 08C0 or AL,AL ; if AL is nonzero there was a 107 ; character in the buffer 0 00007E59 7503 jnz AUX2 ; if so skip AUXIN call 109 AUX1: ; 0 00007E5B E80600 call AUXIN ; get character from port 111 AUX2: ; 0 00007E5E AA stosb ; store character 0 00007E5F E2FA loop AUX1 ; if more character, go around again 114 EXVEC2: ; 0 00007E61 E9[0000] Jump EXIT ; all done, successful exit 116 AUX$READ ENDP 117 118 ; 119 ; AUXIN: make a call on ROM BIOS to read character from 120 ; the auxilary device, then do some error checking. 121 ; If an error occurs then AUXIN jumps to ERR$CNT and 122 ; does NOT return to where it was called from. 123 ; 124 125 AUXIN PROC NEAR 126 0 00007E64 B402 mov ah,AUXFUNC_RECEIVE 0 00007E66 E84800 call AUXOP 129 ;check for Frame, Parity, or Overrun errors 130 ;WARNING: these error bits are unpredictable 131 ; if timeout (bit 7) is set 0 00007E69 F6C40E test ah,FLAG_FRAME | FLAG_PARITY | FLAG_OVERRUN 0 00007E6C 740A jz AROK ;No error if all bits are clear 134 135 ;Error getting character 0 00007E6E 83C402 add sp,+2 ;Remove rtn address (near call) 0 00007E71 30C0 xor al,al 0 00007E73 0CB0 or al,FLAG_REC_SIG | FLAG_DSR | FLAG_CTS 139 0 00007E75 E9[0000] JUMP ERR$CNT 141 AROK: 0 00007E78 C3 RET ;CHAR JUST READ IS IN AL, STATUS IS IN AH 143 AUXIN ENDP 144 145 ;---------------------------------------------------------------- 146 ; : 147 ; Aux non-destructive read with no waiting : 148 ; : 149 ; input: [es:di] points to area to receive aux data : 150 ; : 151 ;---------------------------------------------------------------- 152 ; 153 PUBLIC AUX$RDND 154 AUX$RDND PROC NEAR 155 ASSUME DS:BIOCODE ; SET BY AUX DEVICE DRIVER ENTRY ROUTINE 0 00007E79 E85E00 call GETBX ; have BX point to AUXBUF 0 00007E7C 8A07 mov AL,[BX] ; copy contents of buffer to AL 0 00007E7E 08C0 or AL,AL ; if AL is non-zero (char in buffer) 0 00007E80 7514 jnz AUXRDX ; then return character 0 00007E82 E82600 call AUXSTAT ; if not, get status of AUX device 0 00007E85 F6C401 TEST AH,FLAG_DATA_READY ;TEST DATA READY 0 00007E88 740F jz AUXBUS ; then device is busy (not ready) 163 0 00007E8A A820 TEST AL,FLAG_DSR ;TEST DATA SET READY 0 00007E8C 740B jz AUXBUS ; then device is busy (not ready) 0 00007E8E E8D3FF call AUXIN ; else aux is ready, get character 0 00007E91 E84600 call GETBX ; have bx point to AUXBUF 0 00007E94 8807 mov [BX],AL ; save character in buffer 169 AUXRDX: ; 0 00007E96 E9[0000] Jump RDEXIT ; return character 171 172 AUXBUS: ; 0 00007E99 E9[0000] Jump BUS$EXIT ; jump to device busy exit 174 AUX$RDND ENDP 175 176 ;---------------------------------------------------------------- 177 ; : 178 ; Aux Output Status : 179 ; : 180 ;---------------------------------------------------------------- 181 PUBLIC AUX$WRST 182 AUX$WRST PROC NEAR 183 ASSUME DS:BIOCODE ; SET BY AUX DEVICE DRIVER ENTRY ROUTINE 0 00007E9C E80C00 call AUXSTAT ; get status of AUX in AX 185 ; now test to see if device is busy 186 ; if this bit is not set, 187 ;;Ver 3.30 modification ----------------------- 0 00007E9F A820 TEST AL,FLAG_DSR ;TEST DATA SET READY 0 00007EA1 74F6 jz AUXBUS ; then device is busy (not ready) 0 00007EA3 F6C420 TEST AH,FLAG_TRANHOL_EMP ;TEST TRANSMIT HOLD REG EMPTY 191 ;;End of modification ------------------------- 0 00007EA6 74F1 jz AUXBUS ; then device is busy (not ready) 193 Exit equ EXIT ; NASM port label 0 00007EA8 E9[0000] Jump Exit 195 196 AUX$WRST ENDP 197 198 ; 199 ; AUXSTAT makes a call on the ROM-BIOS to determine the status 200 ; of the auxilary device 201 ; Outputs: 202 ; AX is filled with status of port. 203 ; DX is changes to specify which card - either 0, 1 (, 2, 3) ;ba 204 ; NO other registers are modified 205 ; 206 207 AUXSTAT proc near 0 00007EAB B403 mov ah,AUXFUNC_STATUS 0 00007EAD E80100 call AUXOP 0 00007EB0 C3 ret 211 AUXSTAT endp 212 213 AUXOP PROC NEAR 214 ;AH=FUNCTION CODE 215 ;0=INIT, 1=SEND, 2=RECEIVE, 3=STATUS 0 00007EB1 E8[0000] call GETDX ; have DX point to proper card 0 00007EB4 CD14 int 14h ; call rom-bios for status 0 00007EB6 C3 ret 219 AUXOP ENDP 220 221 ;---------------------------------------------------------------- 222 ; : 223 ; Flush AUX Input buffer - set contents of AUXBUF to zero : 224 ; : 225 ;---------------------------------------------------------------- 226 PUBLIC AUX$FLSH 227 AUX$FLSH PROC NEAR 228 ASSUME DS:BIOCODE ; SET BY AUX DEVICE DRIVER ENTRY ROUTINE 0 00007EB7 E82000 call GETBX ; get BX to point to AUXBUF 0 00007EBA C60700 mov BYTE PTR [BX],0 ; zero out buffer 0 00007EBD E9[0000] Jump Exit ; all done, successful return 232 AUX$FLSH ENDP 233 234 235 236 ;---------------------------------------------------------------- 237 ; : 238 ; Write to Auxilary Device : 239 ; : 240 ;---------------------------------------------------------------- 241 PUBLIC AUX$WRIT 242 AUX$WRIT PROC NEAR 243 ASSUME DS:BIOCODE ; SET BY AUX DEVICE DRIVER ENTRY ROUTINE 0 00007EC0 E39F jcxz EXVEC2 ; if CX is zero, no characters 245 ; to be written, jump to exit 246 AUX$LOOP: 0 00007EC2 268A05 mov AL,[ES:DI] ; get character to be written 0 00007EC5 47 inc DI ; move DI pointer to next character 249 ;;Ver 3.30 modification --------------------------- 0 00007EC6 B401 MOV AH,AUXFUNC_SEND ;VALUE=1, INDICATES A WRITE 0 00007EC8 E8E6FF CALL AUXOP ;SEND CHARACTER OVER AUX PORT 252 0 00007ECB F6C480 TEST AH,FLAG_TIMEOUT ;CHECK FOR ERROR 254 ;;End of modification --------------------------- 0 00007ECE 7405 jz AWOK ; then no error 0 00007ED0 B00A mov AL,10 ; else indicate write fault 0 00007ED2 E9[0000] Jump ERR$CNT ; call error routines 258 259 ; if CX is non-zero, still more 260 AWOK: 0 00007ED5 E2EB loop AUX$LOOP ; more characrter to print 0 00007ED7 E9[0000] Jump Exit ; all done, successful return 263 AUX$WRIT ENDP 264 265 266 ; 267 ; GETBX puts the address of AUXBUF (the Auxilary Device buffer) 268 ; in BX. After calling GETBX, a routine can get to AUXBUF 269 ; with [BX]. 270 ; 271 ; NOTE: The getdx routine is in msbio1 and looks like: 272 ; mov dx,word ptr [cs:auxnum] 273 ; 274 GETBX PROC NEAR 0 00007EDA E8[0000] call GETDX 0 00007EDD 89D3 mov BX,DX 0 00007EDF 81C3[0000] add BX,OFFSET AUXBUF 0 00007EE3 C3 ret 279 GETBX ENDP 280 281 ; (no prior section) ; CODE ENDS 282 END === Trace listing source: mslpt.lst 1 ; PAGE ,132 ; 2 ; TITLE MSLPT - BIOS 3 %warning out: ...MSLPT.ASM 3 ****************** warning: out: ...MSLPT.ASM [-w+user] 4 5 ;============================================================================== 6 ;REVISION HISTORY: 7 ;AN000 - New for DOS Version 4.00 - J.K. 8 ;AC000 - Changed for DOS Version 4.00 - J.K. 9 ;AN00x - PTM number for DOS Version 4.00 - J.K. 10 ;============================================================================== 11 ;AN001 - P156 KBMLPT device driver's retry logic. 8/18/87 J.K. 12 ;============================================================================== 13 itest equ 0 14 %include "msgroup.mac" ;DEFINE CODE SEGMENT 1 <1> EVBOUND equ 1 ;THIS VALUE BEING 0 DOES NO BOUNDARY ALLIGNMENT, VALUE 1 ;3.30 2 <1> ; ALIGNS TO EVEN ;3.30 3 <1> 4 <1> ; NASM original macros 5 <1> 6 <1> %include "dcodeseg.nas" 1 <2> 2 <2> %ifndef DCODESEGNAS 3 <2> %assign DCODESEGNAS 1 4 <2> === Switch to base=008400h -> "DOSCODETABLE" 5 <2> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <2> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=008400h -> "DOSCODECODE" 7 <2> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <2> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=008400h -> "DOSBIOCODE" 9 <2> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=008400h -> "BIOCODE" 10 <2> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <2> 12 <2> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <2> 14 <2> %endif 7 <1> 8 <1> %if EVBOUND ;;IF EVEN (WORD) ALLIGNMENT IS REQUESTED, ;3.30 9 <1> 10 <1> %imacro EVENB 0.nolist 11 <1> EVEN ;;ADJUST TO EVEN BOUNDARY 12 <1> %endmacro 13 <1> 14 <1> %imacro ODD 0.nolist 15 <1> %if (($ - $$) % 2) == 0 16 <1> db ? 17 <1> %endif 18 <1> %endmacro 19 <1> 20 <1> %else ;;SINCE EVEN ALLIGNMENT IS NOT DESIRED, JUST USE BYTE ALLI;3.30 GNMENT 21 <1> 22 <1> %imacro EVENB 0.nolist 23 <1> ;;REQUEST FOR WORD ALLIGNMENT DOES NOTHING ;3.30 24 <1> %endmacro 25 <1> 26 <1> %imacro ODD 0.nolist 27 <1> ;;REQUEST FOR ODD ALLIGNMENT DOES NOTHING ;3.30 28 <1> %endmacro 29 <1> 30 <1> %endif ;3.30 31 <1> 32 <1> %imacro CODE_SEGMENT 0.nolist === Switch to base=008400h -> "BIOCODE" 33 <1> section BIOCODE 34 <1> %endmacro 35 <1> 36 <1> ; end of NASM original macros 37 <1> 38 <1> CODE_SEGMENT ;3.30 39 <1> ASSUME CS:BIOCODE ;3.30 40 <1> ;3.30 15 %include "msextrn.mac" 1 <1> === Switch to base=008400h -> "BIOCODE" 2 <1> section BIOCODE 3 <1> ; SCCSID = @(#)IBMEXTRN.ASM 1.11 85/11/18 4 <1> ;This is for IBMINIT module. 5 <1> ;======================================================= 6 <1> ;REVISION HISTORY: 7 <1> ;AN000; - NEW Version 4.00. J.K. 8 <1> ;AC000; - Modified Line 4.00. J.K. 9 <1> ;ANxxx; - PTMyyy 10 <1> ;============================================================================== 11 <1> ;AN001; D486 SHARE installation for large media 2/23/88 J.K. 12 <1> ;============================================================================== 13 <1> 14 <1> extern biocode_get_ds_dosentry, biocode_get_es_dosentry 15 <1> extern dosbiocode_get_ds_dosentry, dosbiocode_get_es_dosentry 16 <1> EXTRN ORIG13:DWORD,ORIG19:DWORD 17 <1> EXTRN COM2DEV:WORD,COM1DEV:WORD 18 <1> EXTRN COM4DEV:WORD,COM3DEV:WORD 19 <1> EXTRN LPT3DEV:WORD,LPT2DEV:WORD,LPT1DEV:WORD 20 <1> EXTRN HARDDRV:BYTE,HARDNUM:BYTE,DRVMAX:BYTE,HDSKTAB:WORD 21 <1> EXTRN DSKDRVS:WORD,HNUM:BYTE,EOT:BYTE,FHAVE96:BYTE 22 <1> EXTRN REAL13:DWORD,DAYCNT:WORD,CONHEADER:WORD 23 <1> EXTRN TWOHARD:BYTE,INT_2F_NEXT:DWORD 24 <1> EXTRN BDSH:WORD,BDSX:WORD,START_BDS:WORD 25 <1> EXTRN FHAVEK09:BYTE, NEW_ROM:BYTE 26 <1> EXTRN SINGLE:BYTE 27 <1> EXTRN BDSMs:BYTE ;for Mini Disk -J.K. 4/7/86 28 <1> EXTRN HaveCMOSClock:byte ;set by IBMINIT. Used by IBMCLOCK.ASM 29 <1> EXTRN BinToBCD:word ;set by IBMINIT. Used by IBMCLOCK.ASM 30 <1> EXTRN DaycntToDay:word ;set by IBMINIT. Used by IBMCLOCK.ASM 31 <1> EXTRN OLD13:DWORD 32 <1> extrn Temp_H:word ;J.K. For 32 bit calculation. IBMDISK 33 <1> extrn Start_Sec_H:word ;J.K. IBMDISK. 34 <1> extrn KEYRD_Func:byte ;J.K. For IBMCON. Defined in IBMBDATA. 35 <1> extrn KEYSTS_Func:byte ;J.K. For IBMCON. Defined in IBMBDATA. 36 <1> extrn DiskSector:byte ;J.K. IBMBDATA 37 <1> extrn Bpb_In_Sector:word ;J.K. IBMBDATA 38 <1> extrn SecPerClusInSector:Byte ;J.K. IBMBDATA 39 <1> extrn NumberOfFats:byte ;J.K. IBMBDATA 40 <1> extrn MediaByte:byte ;J.K. IBMBDATA 41 <1> extrn Ext_Boot_Sig:Byte ;J.K. IBMBDATA 42 <1> extrn Boot_Serial_L:Word ;J.K. IBMBDATA 43 <1> extrn Boot_Serial_H:Word ;J.K. IBMBDATA 44 <1> extrn Boot_Volume_Label:Byte ;J.K. IBMBDATA 45 <1> extrn Boot_System_ID:Byte ;J.K. IBMBDATA 46 <1> extrn Fat_12_ID:Byte ;J.K. IBMDISK 47 <1> extrn Fat_16_ID:Byte ;J.K. IBMDISK 48 <1> extrn lbapacket:byte 49 <1> extrn Vol_No_Name:Byte ;J.K. IBMDISK 50 <1> extrn MOTORSTARTUP:Byte ;J.K. IBMBDATA 51 <1> extrn DoubleWordMov:Byte ;J.K. IBMDISK 52 <1> extrn Model_Byte:Byte ;J.K. IBMBIO2 53 <1> extrn Secondary_Model_Byte:Byte ;J.K. IBMBIO2 54 <1> 55 <1> %IF itest 56 <1> EXTRN NUMBUF:BYTE,DIGITS:BYTE,FTESTBITS:WORD 57 <1> %ENDIF 58 <1> 59 <1> EXTRN START$:NEAR,ERROUT:NEAR,BLOCK13:FAR,INT19:FAR 60 <1> EXTRN INTRET:NEAR,HDRIVE:NEAR,DRIVEX:NEAR,INT13:FAR,CBREAK:NEAR,OUTCHR:NEAR 61 <1> EXTRN DISKRD:NEAR,MEDIA_PATCH:NEAR,GETBP1_PATCH:NEAR 62 <1> EXTRN SET_PATCH:NEAR,DISKIO_PATCH:NEAR,DSKERR:NEAR,INIT_PATCH:NEAR 63 <1> extern DSKERR_PATCH 64 <1> EXTRN TABLE_PATCH:NEAR,EXIT:NEAR,CHANGED_PATCH:NEAR 65 <1> EXTRN ERRIN:NEAR,GETBP:NEAR,SWPDSK:NEAR 66 <1> EXTRN OUTCHR:NEAR,WRMSG:NEAR,TIME_TO_TICKS:NEAR 67 <1> EXTRN INT2F_DISK:NEAR,INSTALL_BDS:NEAR,SETDRIVE:NEAR 68 <1> extrn Mov_Media_IDs:Near ;J.K. 69 <1> extrn Clear_IDs:Near ;J.K. 70 <1> %IF itest 71 <1> EXTRN MSGNUM:NEAR,MSGOUT:NEAR,dumpbytes:near,hex_to_ascii:near 72 <1> EXTRN outchar:near 73 <1> %ENDIF 74 <1> extrn lbatochs:near, chstotuple:near 75 <1> extrn lba_packet_setup:near 76 <1> === Switch to base=002530h -> "SYSINITSEG" 77 <1> section SYSINITSEG PUBLIC class=INIT 78 <1> ASSUME CS:SYSINITSEG 79 <1> EXTRN CURRENT_DOS_LOCATION:WORD 80 <1> EXTRN FINAL_DOS_LOCATION:WORD 81 <1> extrn dos_size:word 82 <1> EXTRN DEVICE_LIST:DWORD 83 <1> EXTRN MEMORY_SIZE:WORD 84 <1> EXTRN DEFAULT_DRIVE:BYTE 85 <1> EXTRN BUFFERS:WORD 86 <1> EXTRN SYSINIT:FAR 87 <1> extrn Big_Media_Flag:Byte ;AN001; 88 <1> ; (no prior section) ; SYSINITSEG ENDS === Switch to base=008400h -> "BIOCODE" 89 <1> section BIOCODE 90 <1> 91 <1> ASSUME CS:BIOCODE 92 <1> 93 <1> ; END OF DISK MODULES FOR CONFIGURATION 94 <1> 95 <1> EXTRN END96TPI:BYTE 96 <1> EXTRN ENDTWOHARD:BYTE 97 <1> EXTRN ENDONEHARD:BYTE 98 <1> EXTRN ENDSWAP:BYTE 99 <1> EXTRN ENDFLOPPY:BYTE 100 <1> 101 <1> ; IBM FIXED UP AT ROM 102 <1> 103 <1> EXTRN IBM_DISK_IO:FAR 16 %include "msequ.mac" 1 <1> %warning out: MSEQU.INC... 1 ****************** <1> warning: out: MSEQU.INC... [-w+user] 2 <1> ;============================================================================== 3 <1> 4 <1> FTOOBIG EQU 80H 5 <1> FBIG EQU 40H 6 <1> ROMSTATUS EQU 1 7 <1> ROMREAD EQU 2 8 <1> ROMWRITE EQU 3 9 <1> ROMVERIFY EQU 4 10 <1> ROMFORMAT EQU 5 11 <1> VID_SIZE EQU 12 12 <1> 13 <1> %include "msbds.mac" ; VARIOUS EQUATES FOR BDS 1 <2> 2 <2> %warning out: MSBDS.INC... 2 ****************** <2> warning: out: MSBDS.INC... [-w+user] 3 <2> ; SCCSID = @(#)IBMBDS.ASM 1.9 85/09/16 4 <2> ;============================================================================== 5 <2> ;REVISION HISTORY: 6 <2> ;AN000 - New for DOS Version 4.00 - J.K. 7 <2> ;AC000 - Changed for DOS Version 4.00 - J.K. 8 <2> ;AN00x - PTM number for DOS Version 4.00 - J.K. 9 <2> ;============================================================================== 10 <2> ;AN001; D113 Disable I/O access to unformatted media 9/03/87 J.K. 11 <2> ;============================================================================== 12 <2> 13 <2> ; VALUES FOR VARIOUS FLAGS IN BDS.FLAGS. 14 <2> 15 <2> FNON_REMOVABLE EQU 01H ;FOR NON-REMOVABLE MEDIA 16 <2> FCHANGELINE EQU 02H ;IF CHANGELINE SUPPORTED ON DRIVE 17 <2> RETURN_FAKE_BPB EQU 04H ; WHEN SET, DON'T DO A BUILD BPB 18 <2> ; JUST RETURN THE FAKE ONE 19 <2> GOOD_TRACKLAYOUT EQU 08H ; THE TRACK LAYOUT HAS NO FUNNY SECTORS 20 <2> ; FCHANGED_BY_FORMAT EQU 08H 21 <2> FI_AM_MULT EQU 10H ;IF MORE THAN ONE LOGICAL FOR THIS PHYSICAL 22 <2> FI_OWN_PHYSICAL EQU 20H ;SIGNIFY LOGICAL OWNER OF THIS PHYSICAL 23 <2> FCHANGED EQU 40H ;INDICATES MEDIA CHANGED 24 <2> SET_DASD_TRUE EQU 80H ; SET DASD BEFORE NEXT FORMAT 25 <2> FCHANGED_BY_FORMAT EQU 100H ;MEDIA CHANGED BY FORMAT 26 <2> UNFORMATTED_MEDIA EQU 200H ;AN001; Fixed disk only 27 <2> F_LBA equ 400h ; LBA supported 28 <2> 29 <2> LBAPACKETSTRUC struc 0 00007EE4 ???? lpSize dw ? 0 00007EE6 ???? lpCount dw ? 0 00007EE8 ???????? lpBuffer dd ? 0 00007EEC ???????????????? lpSector dd ?,? 34 <2> LBAPACKETSTRUC ends 35 <2> 36 <2> ; 37 <2> ; VARIOUS FORM FACTORS TO DESCRIBE MEDIA 38 <2> ; 39 <2> FF48TPI EQU 0 40 <2> FF96TPI EQU 1 41 <2> FFSMALL EQU 2 42 <2> FFHARDFILE EQU 5 43 <2> FFOTHER EQU 7 44 <2> 45 <2> BDS_TYPE STRUC 0 00007EE4 ???????? LINK DD ? ; LINK TO NEXT BDS 0 00007EE8 ?? DRIVENUM DB ? ; INT 13 DRIVE NUMBER 0 00007EE9 ?? DRIVELET DB ? ; DOS DRIVE NUMBER 0 00007EEA ???? BYTEPERSEC DW ? ; NUMBER OF BYTES/SEC 0 00007EEC ?? SECPERCLUS DB ? ; SEC PER ALLOCATION UNIT 0 00007EED ???? RESSEC DW ? ; NUMBER OF RESERVED SECTORS 0 00007EEF ?? CFAT DB ? ; NUMBER OF FATS 0 00007EF0 ???? CDIR DW ? ; NUMBER OF DIRECTORY ENTRIES 0 00007EF2 ???? DRVLIM DW ? ; NUMBER OF SECTORS ON MEDIUM 0 00007EF4 ?? MEDIAD DB ? ; MEDIA DESCRIPTOR BYTE 0 00007EF5 ???? CSECFAT DW ? ; NUMBER OF SECTORS/FAT 0 00007EF7 ???? SECLIM DW ? ; SECTORS PER TRACK 0 00007EF9 ???? HDLIM DW ? ; MAX NUMBER OF HEADS 0 00007EFB ???? HIDSEC_L DW ? ; NUMBER OF HIDDEN SECTORS 0 00007EFD ???? HIDSEC_H dw ? ;0 ;J.K.87 0 00007EFF ???? DRVLIM_L dw ? ;0 ;J.K.87 0 00007F01 ???? DRVLIM_H dw ? ;0 ;J.K.87 0 00007F03 ?? FATSIZ DB ? ; FLAGS... 0 00007F04 ???? OPCNT DW ? ; OPEN REF. COUNT 0 00007F06 ?? FORMFACTOR DB ? ; FORM FACTOR INDEX 0 00007F07 ???? FLAGS DW ? ; VARIOUS FLAGS 0 00007F09 ???? CCYLN DW ? ; MAX NUMBER OF CYLINDERS 0 00007F0B ???? RBYTEPERSEC DW ? ; RECOMMENDED BPB 0 00007F0D ?? RSECPERCLUS DB ? 0 00007F0E ???? RRESSEC DW ? 0 00007F10 ?? RCFAT DB ? 0 00007F11 ???? RCDIR DW ? 0 00007F13 ???? RDRVLIM DW ? 0 00007F15 ?? RMEDIAD DB ? 0 00007F16 ???? RCSECFAT DW ? 0 00007F18 ???? RSECLIM DW ? 0 00007F1A ???? RHDLIM DW ? 0 00007F1C ???? RHIDSEC_L DW ? 0 00007F1E ???? RHIDSEC_H DW ? ;0 ;J.K.87 0 00007F20 ???? RDRVLIM_L dw ? ;0 ;J.K.87 0 00007F22 ???? RDRVLIM_H dw ? ;0 ;J.K.87 0 00007F24 ???????????? RESERVE DB 6 DUP (?) ; RESERVED FOR FUTURE 0 00007F2A ?? TRACK DB ? ; LAST TRACK ACCESSED ON DRIVE 0 00007F2B ???? TIM_LO DW ? ; TIME OF LAST ACCESS. KEEP 0 00007F2D ???? TIM_HI DW ? ; THESE CONTIGUOUS. 86 0000004B <2> VOLID DB 12 DUP (?) ; VOLUME ID OF MEDIUM 0 00007F3B ???????? VOL_SERIAL dd ? ;0 ;J.K.87 Current volume serial number from Boot record 88 0000005B <2> FILESYS_Id db 9 dup (?) ;(0) ;J.K.87 Current file system id from Boot record 89 <2> BDS_TYPE ENDS 90 <2> 91 <2> BPBSIZE equ TRACK - RBYTEPERSEC ; SIZE IN BYTES OF RECBPB AREA IN THE BDS 92 <2> 93 <2> 94 <2> ;********************************************************************* 95 <2> ; BDS structure for mini disk - J.K. 4/7/86 96 <2> ;********************************************************************* 97 <2> 98 <2> BDSM_type struc 0 00007EE4 ???? mlink DW ? ;-1 ;Link to next structure 0 00007EE6 ???? DW ? 0 00007EE8 ?? mdriveNum DB ? ;80 ;Int 13 Drive Number 0 00007EE9 ?? mdriveLet DB ? ;3 ;Logical Drive Number 0 00007EEA ???? mBytePerSec DW ? ;512 0 00007EEC ?? mSecPerClus DB ? ;1 ;Sectors/allocation unit 0 00007EED ???? mRESSEC DW ? ;1 ;Reserved sectors for DOS 0 00007EEF ?? mcFAT DB ? ;2 ;No. of allocation tables 0 00007EF0 ???? mcDIR DW ? ;16 ;Number of directory entries 0 00007EF2 ???? mDRVLIM DW ? ;0 ;Number of sectors (at 512 bytes each) 0 00007EF4 ?? mMediad DB ? ;11111000B ;Media descriptor 0 00007EF5 ???? mcSecFat DW ? ;1 ;Number of FAT sectors 0 00007EF7 ???? mSECLIM DW ? ;0 ;Sector limit 0 00007EF9 ???? mHDLIM DW ? ;0 ;Head limit 0 00007EFB ???? mHIDSEC_L DW ? ;0 ;Hidden sector count 0 00007EFD ???? mHidsec_H dw ? ;0 ;J.K.87 0 00007EFF ???? mDrvlim_L dw ? ;0 ;J.K.87 0 00007F01 ???? mDrvlim_H dw ? ;0 ;J.K.87 0 00007F03 ?? mFatSiz DB ? ;0 ;TRUE => bigfat 0 00007F04 ???? mOPCNT DW ? ;0 ;Open Ref. Count 0 00007F06 ?? mFormFactor DB ? ;3 ;Form Factor 0 00007F07 ???? mFLAGS DW ? ;0020H ;Various Flags 0 00007F09 ???? mcCyln dw ? ;40 ;max number of cylinders 122 00000027 <2> mRecBPB db 31 dup (?) ;(0) ;Recommended BPB for drive 0 00007F2A ?? mTrack db ? ;-1 0 00007F2B ???? IsMini dw ? ;1 ;Overlapping TIM_LOH 0 00007F2D ???? Hidden_Trks dw ? ;0 ;Overlapping TIM_HIH 126 0000004B <2> mVOLID DB 11 dup (?) ;"NO NAME " ;Volume ID for this disk 0 00007F3A ?? DB ? ;0 ;ASCIZII for "NO NAME " 0 00007F3B ???????? mVol_Serial dd ? ;0 ;Current volume serial number from Boot record 0 00007F3F ???????????????? mFileSys_Id db 8 dup (?) ;"FAT12 " ;Current file system id from Boot record 0 00007F47 ?? db ? ;0 131 <2> 132 <2> BDSM_type ENDS 133 <2> ;****************************************************************************** 134 <2> Max_mini_dsk_num equ 23 ;J.K. 4/7/86 - max # of mini disk ibmbio can support 135 <2> ; 136 <2> 14 <1> 15 <1> ;AN000; Extended BPB structure. 16 <1> BPB_TYPE STRUC 0 00007EE4 ???? SECSIZE DW ? 0 00007EE6 ?? SECALL DB ? 0 00007EE7 ???? RESNUM DW ? 0 00007EE9 ?? FATNUM DB ? 0 00007EEA ???? DIRNUM DW ? 0 00007EEC ???? SECNUM DW ? 0 00007EEE ?? FATID DB ? 0 00007EEF ???? FATSIZE DW ? 0 00007EF1 ???? SLIM DW ? 0 00007EF3 ???? HLIM DW ? 0 00007EF5 ???? HIDDEN_L DW ? 0 00007EF7 ???? HIDDEN_H dw ? ;0 ;J.K. 0 00007EF9 ???? SECNUM_L dw ? ;0 ;J.K. 0 00007EFB ???? SECNUM_H dw ? ;0 ;J.K. 31 <1> BPB_TYPE ENDS 32 <1> 33 <1> ;;;;;;;;;;; 34 <1> BOOT_SERIAL_SIZE equ 4 ;J.K. 35 <1> BOOT_VOLUME_LABEL_SIZE equ 11 ;J.K. 36 <1> BOOT_SYSTEM_ID_SIZE equ 8 ;J.K. 37 <1> EXT_BOOT_SIGNATURE equ 41 ;J.K. 38 <1> RSINIT equ 0A3H ;RS232 INITIALIZATION 39 <1> ;9600 BAUD:NO PARITY:1 STOP:8 BIT WORD 40 <1> LF equ 10 ;LINE FEED 41 <1> CR equ 13 ;CARRIAGE RETURN 42 <1> BACKSP equ 8 ;BACKSPACE 43 <1> BRKADR equ 1BH * 4 ;006C 1BH BREAK VECTOR ADDRESS 44 <1> TIMADR equ 1CH * 4 ;0070 1CH TIMER INTERRUPT 45 <1> DSKADR equ 1EH * 4 ;ADDRESS OF PTR TO DISK PARAMETERS 46 <1> SEC9 equ 522H ;ADDRESS OF DISK PARAMETERS 47 <1> HEADSETTLE equ SEC9+9 ; ARR 2.20 ADDRESS OF HEAD SETTLE TIME 48 <1> NORMSETTLE equ 15 ; ARR 2.20 NORMAL HEAD SETTLE 49 <1> SPEEDSETTLE equ 0 ; ARR 2.20 SPEED UP SETTLE TIME 50 <1> INITSPOT equ 534H ; ARR IBM WANTS 4 ZEROS HERE 51 <1> AKPORT equ 20H 52 <1> EOI equ 20H 53 <1> CMDLEN equ 0 ;LENGTH OF THIS COMMAND 54 <1> UNIT equ 1 ;SUB UNIT SPECIFIER 55 <1> CMD equ 2 ;COMMAND CODE 56 <1> STATUS equ 3 ;STATUS 57 <1> MEDIA equ 13 ;MEDIA DESCRIPTOR 58 <1> TRANS equ 14 ;TRANSFER ADDRESS 59 <1> COUNT equ 18 ;COUNT OF BLOCKS OR CHARACTERS 60 <1> START equ 20 ;FIRST BLOCK TO TRANSFER 61 <1> EXTRA equ 22 ;USUALLY A POINTER TO VOL ID FOR ERROR 15 62 <1> CHROUT equ 29H 63 <1> MAXERR equ 5 64 <1> LSTDRV equ 504H 65 <1> 66 <1> NOTBUSYSTATUS equ 10000000B ; NOT BUSY 67 <1> ACKSTATUS equ 01000000B ; ACKNOWLEDGE (FOR WHAT?) 68 <1> NOPAPERSTATUS equ 00100000B ; NO MORE PAPER 69 <1> SELECTEDSTATUS equ 00010000B ; THE PRINTER SAID IT WAS SELECTED 70 <1> IOERRSTATUS equ 00001000B ; SOME KINDA ERROR 71 <1> RESERVED equ 00000110B ; NOPS 72 <1> TIMEOUTSTATUS equ 00000001B ; TIME OUT. 73 <1> ERROR_UNKNOWN_MEDIA equ 7 ; FOR USE IN BUILD BPB CALL 74 <1> 75 <1> PATHGEN equ 1 17 %include "msmacro.mac" 1 <1> === Switch to base=008400h -> "BIOCODE" 2 <1> section BIOCODE 3 <1> ; 4 <1> ; This file contains three macros used in debugging the system. If the 5 <1> ; variable "itest" (in msbio.asm) is nonzero code is included in the 6 <1> ; modules to print debugging messages. The level of debugging is controlled 7 <1> ; by the value of the variable fTestBits in msbio.asm. Specific bits in 8 <1> ; the variable determine which messages to print. The equ's below tell 9 <1> ; which bits control which funcitons. For example the fifth bit 10 <1> ; cooresponds to disk activity (see fTestDisk equ below). 11 <1> ; 12 <1> ; The macros in the file are: 13 <1> ; 14 <1> ; message Prints an ascii string on the screen. 15 <1> ; Example usage: 16 <1> ; 17 <1> ; message fTestDisk, <"Start Disk Write", CR, LF> 18 <1> ; message fTestINIT, <"Begin BDS initialization"> 19 <1> ; 20 <1> ; 21 <1> ; MNUM Print the value in a register or memory location on 22 <1> ; the screen. Value is displayed in hex. 23 <1> ; Usage: 24 <1> ; MNUM bitpattern, valueLocation 25 <1> ; 26 <1> ; valueLocation is typically a regester: 27 <1> ; 28 <1> ; mnum fTestCom, AX 29 <1> ; mnum fTestDisk, DX 30 <1> ; 31 <1> ; ValueLocation can also be a memory location: 32 <1> ; 33 <1> ; mnum fTestINIT, Final_Dos_Location 34 <1> ; 35 <1> ; If no valueLocation is given the macro defaults to 36 <1> ; the BX register. 37 <1> ; 38 <1> ; ZWAIT Stops the program until any key is pressed. 39 <1> ; 40 <1> ; 41 <1> ; The three macros preserve all register values. If "test" is zero 42 <1> ; defined during assembly then the marco produce no code. 43 <1> ; 44 <1> 45 <1> %IF itest ;3.30 46 <1> EXTRN MSGOUT:NEAR,MSGNUM:NEAR ;3.30 47 <1> EXTRN NUMBUF:BYTE,DIGITS:BYTE,FTESTBITS:WORD ;3.30 48 <1> EXTRN DUMPBYTES:NEAR,OUTCHAR:NEAR,HEX_TO_ASCII:NEAR ;3.30 49 <1> 50 <1> 51 <1> fTestALL equ 1111111111111111b ; watch everything 52 <1> fTestHARD equ 0000000000000001b ; watch hard disk initialization 53 <1> fTest96 equ 0000000000000010b ; watch 96 tpi activity 54 <1> FTEST13 EQU 0000000000000100B ; WATCH INT 13 ACTIVITY ;3.30 55 <1> FTESTCOM EQU 0000000000001000B ; WATCH PACKET ACTIVITY ;3.30 56 <1> FTESTINIT EQU 0000000000010000B ; WATCH INITIALIZATION MESSAGES ;3.30 57 <1> FTESTDISK EQU 0000000000100000B ; WATCH DISK DEVICE DRIVER CALLS ;3.30 58 <1> FTESTCON EQU 0000000001000000B ; WATCH SYSTEM WAIT ACTIVITY IN CO;3.30 NSOLE 59 <1> FtestClock equ 0000000010000000b ; wathc clock device 5/2/86 ;3.30 60 <1> 61 <1> ; NASM original macros 62 <1> 63 <1> ; 64 <1> ; message macro -- see above for description 65 <1> ; 66 <1> 67 <1> %unimacro stripangles 2+.nolist 68 <1> 69 <1> %imacro stripangles 2+.nolist 70 <1> %defstr %%param %2 71 <1> %rep 16 72 <1> %substr %%opening %%param 1 73 <1> %ifidn %%opening, '<' 74 <1> %substr %%param %%param 2,-1 75 <1> %endif 76 <1> %endrep 77 <1> %rep 16 78 <1> %strlen %%length %%param 79 <1> %substr %%closing %%param %%length 80 <1> %ifidn %%closing, '>' 81 <1> %substr %%param %%param 1,-2 82 <1> %endif 83 <1> %endrep 84 <1> %deftok %%token %%param 85 <1> %1 %%token 86 <1> %endmacro 87 <1> 88 <1> %imacro MESSAGE 2+ 89 <1> jmp short %%b 90 <1> %%a: 91 <1> stripangles db, %2 92 <1> db 0 93 <1> %%b: push SI 94 <1> push AX 95 <1> mov AX, %1 96 <1> mov SI, OFFSET %%a 97 <1> call MSGOUT 98 <1> pop AX 99 <1> pop SI 100 <1> %endmacro 101 <1> 102 <1> 103 <1> ; 104 <1> ; mnum macro -- see above for description 105 <1> ; 106 <1> 107 <1> %imacro MNum 1-2 108 <1> push AX 109 <1> %ifempty %2 110 <1> mov AX,%1 111 <1> call MSGNUM 112 <1> %else 113 <1> push BX 114 <1> mov BX,%2 115 <1> mov AX,%1 116 <1> call MSGNUM 117 <1> pop BX 118 <1> %endif 119 <1> pop AX 120 <1> %endmacro 121 <1> 122 <1> 123 <1> ; 124 <1> ; zwait macro -- see above for description 125 <1> ; 126 <1> 127 <1> %imacro ZWAIT 0 128 <1> Message fTestALL,<"? "> 129 <1> CALL ZWAITrtn 130 <1> %endmacro 131 <1> 132 <1> ZWAITrtn: 133 <1> pushf ; save the flags 134 <1> push AX ; preserve AX 135 <1> xor AH, AH ; set command to get character ;3.30* 136 <1> int 16h ; call rom keyboard routine ;3.30* 137 <1> pop AX ; restore AX 138 <1> popf ; restore the flags 139 <1> ret 140 <1> 141 <1> ;Dump_byte dumps the memory contents in hex. ;3.30 142 <1> ;DUMPOFFLABEL should be a label or a variable defined in DUMPSEG. ;3.30 143 <1> %imacro DUMP_BYTE 3 144 <1> push es ;3.30 145 <1> PUSH DS ;3.30 146 <1> PUSH SI ;3.30 147 <1> PUSH CX ;3.30 148 <1> ;3.30 149 <1> MOV CX, %1 ;3.30 150 <1> MOV DS, CX ;3.30 151 <1> MOV SI, OFFSET %2 ;3.30 152 <1> MOV CX, %3 ;3.30 153 <1> call dumpbytes ;3.30 154 <1> ;3.30 155 <1> POP CX ;3.30 156 <1> POP SI ;3.30 157 <1> POP DS ;3.30 158 <1> pop es ;3.30 159 <1> %endmacro ;3.30 160 <1> ;3.30 161 <1> ;Dump_Byte_Reg dumps the memory contents in hex. - 4/9/86 ;3.30 162 <1> ;DUMPOFFREG should be a register contains the offset value in DUMPSEG. ;3.30 163 <1> %imacro DUMP_BYTE_REG 3 164 <1> DUMP_BYTE_REG MACRO DUMPSEG, DUMPOFFREG, BYTELENGTH ;3.30 165 <1> push es ;3.30 166 <1> PUSH DS ;3.30 167 <1> PUSH SI ;3.30 168 <1> PUSH CX ;3.30 169 <1> ;3.30 170 <1> MOV CX, %1 ;3.30 171 <1> MOV DS, CX ;3.30 172 <1> MOV SI, %2 ;3.30 173 <1> MOV CX, %3 ;3.30 174 <1> call dumpbytes ;3.30 175 <1> ;3.30 176 <1> POP CX ;3.30 177 <1> POP SI ;3.30 178 <1> POP DS ;3.30 179 <1> pop es ;3.30 180 <1> %endmacro ;3.30 181 <1> 182 <1> %else 183 <1> ; if test is not defined then make macro into null statements 184 <1> %imacro Message 0-1+.nolist 185 <1> %endmacro 186 <1> 187 <1> %imacro MNUM 0-1+.nolist 188 <1> %endmacro 189 <1> 190 <1> %imacro ZWAIT 0-1+.nolist 191 <1> %endmacro 192 <1> 193 <1> %imacro DUMP_BYTE 0-1+.nolist 194 <1> %endmacro 195 <1> 196 <1> %imacro DUMP_BYTE_REG 0-1+.nolist 197 <1> %endmacro 198 <1> 199 <1> %endif 200 <1> 201 <1> %unimacro PATHSTART 2 202 <1> %unimacro PATHEND 2 203 <1> 204 <1> %imacro PATHSTART 2 205 <1> %IF PATHGEN ;3.30 206 <1> PUBLIC %2%1S,%2%1E ;3.30 207 <1> %2%1S LABEL BYTE ;3.30 208 <1> %ENDIF ;3.30 209 <1> %endmacro ;3.30 210 <1> ;3.30 211 <1> %imacro PATHEND 2 212 <1> %IF PATHGEN ;3.30 213 <1> %2%1E LABEL BYTE ;3.30 214 <1> %ENDIF ;3.30 215 <1> %endmacro ;3.30 18 %include "devsym.mac" 1 <1> %warning out: DEVSYM.INC... 1 ****************** <1> warning: out: DEVSYM.INC... [-w+user] 2 <1> ; SCCSID = @(#)DEVSYM.ASM 1.10 85/09/04 3 <1> ; SCCSID = @(#)DEVSYM.ASM 1.10 85/09/04 4 <1> 5 <1> ; THE DEVICE TABLE LIST HAS THE FORM: 6 <1> SYSDEV STRUC 0 00007EE4 ???????? SDEVNEXT DD ? ;POINTER TO NEXT DEVICE HEADER 0 00007EE8 ???? SDEVATT DW ? ;ATTRIBUTES OF THE DEVICE 0 00007EEA ???? SDEVSTRAT DW ? ;STRATEGY ENTRY POINT 0 00007EEC ???? SDEVINT DW ? ;INTERRUPT ENTRY POINT 0 00007EEE ???????????????? SDEVNAME DB 8 DUP (?) ;NAME OF DEVICE (ONLY FIRST BYTE USED FOR BLOCK) 12 <1> SYSDEV ENDS 13 <1> 14 <1> ; 15 <1> ; ATTRIBUTE BIT MASKS 16 <1> ; 17 <1> ; CHARACTER DEVICES: 18 <1> ; 19 <1> ; BIT 15 -> MUST BE 1 20 <1> ; 14 -> 1 IF THE DEVICE UNDERSTANDS IOCTL CONTROL STRINGS 21 <1> ; 13 -> 1 IF THE DEVICE SUPPORTS OUTPUT-UNTIL-BUSY 22 <1> ; 12 -> UNUSED 23 <1> ; 11 -> 1 IF THE DEVICE UNDERSTANDS OPEN/CLOSE 24 <1> ; 10 -> MUST BE 0 25 <1> ; 9 -> MUST BE 0 26 <1> ; 8 -> UNUSED 27 <1> ; 7 -> UNUSED 28 <1> ; 6 -> UNUSED 29 <1> ; 5 -> UNUSED 30 <1> ; 4 -> 1 IF DEVICE IS RECIPIENT OF INT 29H 31 <1> ; 3 -> 1 IF DEVICE IS CLOCK DEVICE 32 <1> ; 2 -> 1 IF DEVICE IS NULL DEVICE 33 <1> ; 1 -> 1 IF DEVICE IS CONSOLE OUTPUT 34 <1> ; 0 -> 1 IF DEVICE IS CONSOLE INPUT 35 <1> ; 36 <1> ; BLOCK DEVICES: 37 <1> ; 38 <1> ; BIT 15 -> MUST BE 0 39 <1> ; 14 -> 1 IF THE DEVICE UNDERSTANDS IOCTL CONTROL STRINGS 40 <1> ; 13 -> 1 IF THE DEVICE DETERMINES MEDIA BY EXAMINING THE FAT ID BYTE. 41 <1> ; THIS REQUIRES THE FIRST SECTOR OF THE FAT TO *ALWAYS* RESIDE IN 42 <1> ; THE SAME PLACE. 43 <1> ; 12 -> UNUSED 44 <1> ; 11 -> 1 IF THE DEVICE UNDERSTANDS OPEN/CLOSE/REMOVABLE MEDIA 45 <1> ; 10 -> MUST BE 0 46 <1> ; 9 -> MUST BE 0 47 <1> ; 8 -> UNUSED 48 <1> ; 7 -> UNUSED 49 <1> ; 6 -> IF DEVICE HAS SUPPORT FOR GETMAP/SETMAP OF LOGICAL DRIVES. 50 <1> ; IF THE DEVICE UNDERSTANDS GENERIC IOCTL FUNCTION CALLS. 51 <1> ; 5 -> UNUSED 52 <1> ; 4 -> UNUSED 53 <1> ; 3 -> UNUSED 54 <1> ; 2 -> UNUSED 55 <1> ; 1 -> UNUSED 56 <1> ; 0 -> UNUSED 57 <1> ; 58 <1> 59 <1> DEVTYP EQU 8000H ; BIT 15 - 1 IF CHAR, 0 IF BLOCK 60 <1> CHARDEV EQU 8000H 61 <1> DEVIOCTL EQU 4000H ; BIT 14 - CONTROL MODE BIT 62 <1> ISFATBYDEV EQU 2000H ; BIT 13 - DEVICE USES FAT ID BYTES, 63 <1> ; COMP MEDIA. 64 <1> OUTTILBUSY EQU 2000H ; OUTPUT UNTIL BUSY IS ENABLED 65 <1> ISNET EQU 1000H ; BIT 12 - 1 IF A NET DEVICE, 0 IF 66 <1> ; NOT. CURRENTLY BLOCK ONLY. 67 <1> DEVOPCL EQU 0800H ; BIT 11 - 1 IF THIS DEVICE HAS 68 <1> ; OPEN,CLOSE AND REMOVABLE MEDIA 69 <1> ; ENTRY POINTS, 0 IF NOT 70 <1> 71 <1> EXTENTBIT EQU 0400H ; BIT 10 - CURRENTLY 0 ON ALL DEVS 72 <1> ; THIS BIT IS RESERVED FOR FUTURE USE 73 <1> ; TO EXTEND THE DEVICE HEADER BEYOND 74 <1> ; ITS CURRENT FORM. 75 <1> 76 <1> ; NOTE BIT 9 IS CURRENTLY USED ON IBM SYSTEMS TO INDICATE "DRIVE IS SHARED". 77 <1> ; SEE IOCTL FUNCTION 9. THIS USE IS NOT DOCUMENTED, IT IS USED BY SOME 78 <1> ; OF THE UTILITIES WHICH ARE SUPPOSED TO FAIL ON SHARED DRIVES ON SERVER 79 <1> ; MACHINES (FORMAT,CHKDSK,RECOVER,..). 80 <1> 81 <1> DEV320 EQU 0040H ;BIT 6 - FOR BLOCK DEVICES, THIS 82 <1> ;DEVICE SUPPORTS SET/GET MAP OF 83 <1> ;LOGICAL DRIVES, AND SUPPORTS 84 <1> ;GENERIC IOCTL CALLS. 85 <1> ;FOR CHARACTER DEVICES, THIS 86 <1> ;DEVICE SUPPORTS GENERIC IOCTL. 87 <1> ;THIS IS A DOS 3.2 DEVICE DRIVER. 88 <1> ISSPEC EQU 0010H ;BIT 4 - THIS DEVICE IS SPECIAL 89 <1> ISCLOCK EQU 0008H ;BIT 3 - THIS DEVICE IS THE CLOCK DEVICE. 90 <1> ISNULL EQU 0004H ;BIT 2 - THIS DEVICE IS THE NULL DEVICE. 91 <1> ISCOUT EQU 0002H ;BIT 1 - THIS DEVICE IS THE CONSOLE OUTPUT. 92 <1> ISCIN EQU 0001H ;BIT 0 - THIS DEVICE IS THE CONSOLE INPUT. 93 <1> EXTDRVR EQU 0002H ;BIT 1 - BLOCK DEVICE EXTNDED DRIVER 94 <1> 95 <1> ;STATIC REQUEST HEADER 96 <1> SRHEAD STRUC 0 00007EE4 ?? REQLEN DB ? ;LENGTH IN BYTES OF REQUEST BLOCK 0 00007EE5 ?? REQUNIT DB ? ;DEVICE UNIT NUMBER 0 00007EE6 ?? REQFUNC DB ? ;TYPE OF REQUEST 0 00007EE7 ???? REQSTAT DW ? ;STATUS WORD 0 00007EE9 ???????????????? DB 8 DUP(?) ;RESERVED FOR QUEUE LINKS 102 <1> SRHEAD ENDS 103 <1> 104 <1> ;STATUS WORD MASKS 105 <1> STERR EQU 8000H ;BIT 15 - ERROR 106 <1> STBUI EQU 0200H ;BIT 9 - BUISY 107 <1> STDON EQU 0100H ;BIT 8 - DONE 108 <1> STECODE EQU 00FFH ;ERROR CODE 109 <1> ; 2/12/KK 110 <1> ; Interim character identifier 2/12/KK 111 <1> Ddkey EQU 0000010000000000B ; 2/12/KK 112 <1> 113 <1> ;FUNCTION CODES 114 <1> DEVINIT EQU 0 ;INITIALIZATION 115 <1> DINITHL EQU 26 ;SIZE OF INIT HEADER 116 <1> DEVMDCH EQU 1 ;MEDIA CHECK 117 <1> DMEDHL EQU 15 ;SIZE OF MEDIA CHECK HEADER 118 <1> DEVBPB EQU 2 ;GET BPB 119 <1> DEVRDIOCTL EQU 3 ;IOCTL READ 120 <1> DBPBHL EQU 22 ;SIZE OF GET BPB HEADER 121 <1> DEVRD EQU 4 ;READ 122 <1> DRDWRHL EQU 22 ;SIZE OF RD/WR HEADER 123 <1> DEVRDND EQU 5 ;NON DESTRUCTIVE READ NO WAIT (CHARACTER DEVS) 124 <1> DRDNDHL EQU 14 ;SIZE OF NON DESTRUCTIVE READ HEADER 125 <1> DEVIST EQU 6 ;INPUT STATUS 126 <1> DSTATHL EQU 13 ;SIZE OF STATUS HEADER 127 <1> DEVIFL EQU 7 ;INPUT FLUSH 128 <1> DFLSHL EQU 15 ;SIZE OF FLUSH HEADER 129 <1> DEVWRT EQU 8 ;WRITE 130 <1> DEVWRTV EQU 9 ;WRITE WITH VERIFY 131 <1> DEVOST EQU 10 ;OUTPUT STATUS 132 <1> DEVOFL EQU 11 ;OUTPUT FLUSH 133 <1> DEVWRIOCTL EQU 12 ;IOCTL WRITE 134 <1> DEVOPN EQU 13 ;DEVICE OPEN 135 <1> DEVCLS EQU 14 ;DEVICE CLOSE 136 <1> DOPCLHL EQU 13 ;SIZE OF OPEN/CLOSE HEADER 137 <1> DEVRMD EQU 15 ;REMOVABLE MEDIA 138 <1> REMHL EQU 13 ;SIZE OF REMOVABLE MEDIA HEADER 139 <1> GENIOCTL EQU 19 140 <1> ; THE NEXT THREE ARE USED IN DOS 4.0 141 <1> ; 20 142 <1> ; 21 143 <1> ; 22 144 <1> DEVGETOWN EQU 23 ;GET DEVICE OWNER 145 <1> DEVSETOWN EQU 24 ;SET DEVICE OWNER 146 <1> OWNHL EQU 13 ;SIZE OF DEVICE OWNER HEADER 147 <1> 148 <1> DEVOUT EQU 16 ; OUTPUT UNTIL BUSY. 149 <1> DEVOUTL EQU DEVWRT ; LENGTH OF OUTPUT UNTIL BUSY 150 <1> 151 <1> ; GENERIC IOCTL REQUEST STRUCTURE 152 <1> ; SEE THE DOS 4.0 DEVICE DRIVER SPEC FOR FURTHER ELABORATION. 153 <1> ; 154 <1> IOCTL_REQ STRUC 155 00000000 <1> DB (SRHEAD_struc_size) DUP(?) 156 <1> ; GENERIC IOCTL ADDITION. 0 00007EF1 ?? MAJORFUNCTION DB ? ;FUNCTION CODE 0 00007EF2 ?? MINORFUNCTION DB ? ;FUNCTION CATEGORY 0 00007EF3 ???? REG_SI DW ? 0 00007EF5 ???? REG_DI DW ? 0 00007EF7 ???????? GENERICIOCTL_PACKET DD ? ; POINTER TO DATA BUFFER 162 <1> IOCTL_REQ ENDS 163 <1> 164 <1> ; DEFINITIONS FOR IOCTL_REQ.MINORFUNCTION 165 <1> GEN_IOCTL_WRT_TRK EQU 40H 166 <1> GEN_IOCTL_RD_TRK EQU 60H 167 <1> GEN_IOCTL_FN_TST EQU 20H ; USED TO DIFF. BET READS AND WRTS 168 <1> 169 <1> ;; 32-bit absolute read/write input list structure 170 <1> 171 <1> ABS_32RW STRUC 0 00007EE4 ???????? SECTOR_RBA DD ? ; relative block address 0 00007EE8 ???? ABS_RW_COUNT DW ? ; number of sectors to be transferred 0 00007EEA ???????? BUFFER_ADDR DD ? ; data addrress 175 <1> ABS_32RW ENDS 176 <1> 177 <1> ;; media ID info 178 <1> 179 <1> MEDIA_ID_INFO STRUC 0 00007EE4 ???? MEDIA_level DW ? ; info level 0 00007EE6 ???????? MEDIA_Serial DD ? ; serial # 182 00000006 <1> MEDIA_Label DB 11 dup (?) ;volume label 0 00007EF5 ???????????????? MEDIA_System DB 8 dup (?) ;system type 184 <1> MEDIA_ID_INFO ENDS 185 <1> 186 <1> ;; equates for DOS34_FLAG 187 <1> 188 <1> IFS_ABSRW EQU 00001H ;IFS absolute read/write 189 <1> NO_IFS_ABSRW EQU 0FFFEH ;no IFS absolute read/write 190 <1> IFS_DRIVE_RESET EQU 00002H ;IFS drvive reset 191 <1> NO_IFS_DRIVE_RESET EQU 0FFFDH ;no IFS drive reset 192 <1> FROM_DISK_RESET EQU 00004H ;from disk reset 193 <1> NO_FROM_DISK_RESET EQU 0FFFBH ;not from disk reset 194 <1> From_String_Output EQU 00008H ;from con string output 195 <1> NO_From_String_Output EQU 0FFF7H ;not from con string output 196 <1> From_DOS_WRITE EQU 00010H ;from dos_write 197 <1> NO_From_DOS_WRITE EQU 0FFEFH ;not from dos_write 198 <1> Force_I24_Fail EQU 00020H ;form IFS CALL BACK 199 <1> NO_Force_I24_Fail EQU 0FFDFH ;not form IFS CALL BACK 200 <1> Disable_EOF_I24 EQU 00040H ;disable EOF int24 for input status 201 <1> NO_Disable_EOF_I24 EQU 0FFBFH ;disable EOF int24 for input status 202 <1> DBCS_VOLID EQU 00080H ;indicate from volume id 203 <1> DBCS_VOLID2 EQU 00100H ;indicate 8th char is DBCS 204 <1> CTRL_BREAK_FLAG EQU 00200H ;indicate control break is input 205 <1> NO_CTRL_BREAK_FLAG EQU 0FDFFH ;reset control break 206 <1> SEARCH_FASTOPEN EQU 00400H ;set fastopen flag for search 207 <1> X25_special EQU 00800H ;flag for X25 driver 19 %include "ioctl.mac" 1 <1> 2 <1> %warning out: IOCTL.INC... 2 ****************** <1> warning: out: IOCTL.INC... [-w+user] 3 <1> ; THESE ARE ALL THE IMPORTANT STRUCTURES AND EQUATES FOR IOCTL 4 <1> ;============================================================================== 5 <1> ;REVISION HISTORY: 6 <1> ;AN000 - New for DOS Version 4.00 - J.K. 7 <1> ;AC000 - Changed for DOS Version 4.00 - J.K. 8 <1> ;AN00x - PTM number for DOS Version 4.00 - J.K. 9 <1> ;============================================================================== 10 <1> ;AN001; D241 Provide support of Multi-track Format/Verify 9/23/87 J.K. 11 <1> ;AN002; P1535 Unformatted hard file problem 10/15/87 J.K. 12 <1> ;AN003; D490 IOCTL subfunction 63h,43h,64h,44h conflicts with OS2 2/26/88 J.K. 13 <1> ;============================================================================== 14 <1> 15 <1> ;*** J.K. 16 <1> ;General Guide - 17 <1> ;Category Code: 18 <1> ; 0... .... DOS Defined 19 <1> ; 1... .... User defined 20 <1> ; .xxx xxxx Code 21 <1> 22 <1> ;Function Code: 23 <1> ; 0... .... Return error if unsupported 24 <1> ; 1... .... Ignore if unsupported 25 <1> ; .0.. .... Intercepted by DOS 26 <1> ; .1.. .... Passed to driver 27 <1> ; ..0. .... Sends data/commands to device 28 <1> ; ..1. .... Quries data/info from device 29 <1> ; ...x .... Subfunction 30 <1> ; 31 <1> ; Note that "Sends/queries" data bit is intended only to regularize the 32 <1> ; function set. It plays no critical role; some functions may contain both 33 <1> ; command and query elements. The convention is that such commands are 34 <1> ; defined as "sends data". 35 <1> 36 <1> ;*****************************;* 37 <1> ; BLOCK DRIVERS ;* 38 <1> ;*****************************;* 39 <1> 40 <1> ; IOCTL SUB-FUNCTIONS 41 <1> IOCTL_GET_DEVICE_INFO EQU 0 42 <1> IOCTL_SET_DEVICE_INFO EQU 1 43 <1> IOCTL_READ_HANDLE EQU 2 44 <1> IOCTL_WRITE_HANDLE EQU 3 45 <1> IOCTL_READ_DRIVE EQU 4 46 <1> IOCTL_WRITE_DRIVE EQU 5 47 <1> IOCTL_GET_INPUT_STATUS EQU 6 48 <1> IOCTL_GET_OUTPUT_STATUS EQU 7 49 <1> IOCTL_CHANGEABLE? EQU 8 50 <1> IOCTL_DeviceLocOrRem? EQU 9 51 <1> IOCTL_HandleLocOrRem? EQU 0Ah ;10 52 <1> IOCTL_SHARING_RETRY EQU 0Bh ;11 53 <1> GENERIC_IOCTL_HANDLE EQU 0Ch ;12 54 <1> GENERIC_IOCTL EQU 0Dh ;13 55 <1> 56 <1> ; GENERIC IOCTL CATEGORY CODES 57 <1> IOC_OTHER EQU 0 ; Other device control J.K. 4/29/86 58 <1> IOC_SE EQU 1 ; SERIAL DEVICE CONTROL 59 <1> IOC_TC EQU 2 ; TERMINAL CONTROL 60 <1> IOC_SC EQU 3 ; SCREEN CONTROL 61 <1> IOC_KC EQU 4 ; KEYBOARD CONTROL 62 <1> IOC_PC EQU 5 ; PRINTER CONTROL 63 <1> IOC_DC EQU 8 ; DISK CONTROL (SAME AS RAWIO) 64 <1> 65 <1> ; GENERIC IOCTL SUB-FUNCTIONS 66 <1> RAWIO EQU 8 67 <1> 68 <1> ; RAWIO SUB-FUNCTIONS 69 <1> GET_DEVICE_PARAMETERS EQU 60H 70 <1> SET_DEVICE_PARAMETERS EQU 40H 71 <1> READ_TRACK EQU 61H 72 <1> WRITE_TRACK EQU 41H 73 <1> VERIFY_TRACK EQU 62H 74 <1> FORMAT_TRACK EQU 42H 75 <1> GET_MEDIA_ID EQU 66h ;AN000;AN003;changed from 63h 76 <1> SET_MEDIA_ID EQU 46h ;AN000;AN003;changed from 43h 77 <1> GET_ACCESS_FLAG EQU 67h ;AN002;AN003;Unpublished function.Changed from 64h 78 <1> SET_ACCESS_FLAG EQU 47h ;AN002;AN003;Unpublished function.Changed from 44h 79 <1> 80 <1> ; SPECIAL FUNCTION FOR GET DEVICE PARAMETERS 81 <1> BUILD_DEVICE_BPB EQU 000000001B 82 <1> 83 <1> ; SPECIAL FUNCTIONS FOR SET DEVICE PARAMETERS 84 <1> INSTALL_FAKE_BPB EQU 000000001B 85 <1> ONLY_SET_TRACKLAYOUT EQU 000000010B 86 <1> TRACKLAYOUT_IS_GOOD EQU 000000100B 87 <1> 88 <1> ; SPECIAL FUNCTION FOR FORMAT TRACK 89 <1> STATUS_FOR_FORMAT EQU 000000001B 90 <1> DO_FAST_FORMAT equ 000000010B ;AN001; 91 <1> ; CODES RETURNED FROM FORMAT STATUS CALL 92 <1> FORMAT_NO_ROM_SUPPORT EQU 000000001B 93 <1> FORMAT_COMB_NOT_SUPPORTED EQU 000000010B 94 <1> 95 <1> ; DEVICETYPE VALUES 96 <1> MAX_SECTORS_IN_TRACK EQU 63 ; MAXIMUM SECTORS ON A DISK.(Was 40 in DOS 3.2) 97 <1> DEV_5INCH EQU 0 98 <1> DEV_5INCH96TPI EQU 1 99 <1> DEV_3INCH720KB EQU 2 100 <1> DEV_8INCHSS EQU 3 101 <1> DEV_8INCHDS EQU 4 102 <1> DEV_HARDDISK EQU 5 103 <1> DEV_OTHER EQU 7 104 <1> 105 <1> MAX_DEV_TYPE EQU 7 ; MAXIMUM DEVICE TYPE THAT WE 106 <1> ; CURRENTLY SUPPORT. 107 <1> 108 <1> %include "bpb.mac" 1 <2> %warning out: BPB.INC... 1 ****************** <2> warning: out: BPB.INC... [-w+user] 2 <2> ; SCCSID = @(#)BPB.ASM 1.1 85/04/29 3 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 4 <2> ; C A V E A T P R O G R A M M E R ; 5 <2> ; ; 6 <2> 7 <2> ; BIOS PARAMETER BLOCK DEFINITION 8 <2> ; THIS STRUCTURE IS USED TO BUILD A FULL DPB 9 <2> 10 <2> BPBLOCK STRUC 0 00007EE4 ???? BPSECSZ DW ? ; SIZE IN BYTES OF PHYSICAL SECTOR 0 00007EE6 ?? BPCLUS DB ? ; SECTORS/ALLOC UNIT 0 00007EE7 ???? BPRES DW ? ; NUMBER OF RESERVED SECTORS 0 00007EE9 ?? BPFTCNT DB ? ; NUMBER OF FATS 0 00007EEA ???? BPDRCNT DW ? ; NUMBER OF DIRECTORY ENTRIES 0 00007EEC ???? BPSCCNT DW ? ; TOTAL NUMBER OF SECTORS 0 00007EEE ?? BPMEDIA DB ? ; MEDIA DESCRIPTOR BYTE 0 00007EEF ???? BPFTSEC DW ? ; NUMBER OF SECTORS TAKEN UP BY ONE FAT 19 <2> BPBLOCK ENDS 20 <2> 21 <2> A_BPB STRUC 0 00007EE4 ???? BPB_BYTESPERSECTOR DW ? 0 00007EE6 ?? BPB_SECTORSPERCLUSTER DB ? 0 00007EE7 ???? BPB_RESERVEDSECTORS DW ? 0 00007EE9 ?? BPB_NUMBEROFFATS DB ? 0 00007EEA ???? BPB_ROOTENTRIES DW ? 0 00007EEC ???? BPB_TOTALSECTORS DW ? 0 00007EEE ?? BPB_MEDIADESCRIPTOR DB ? 0 00007EEF ???? BPB_SECTORSPERFAT DW ? 0 00007EF1 ???? BPB_SECTORSPERTRACK DW ? 0 00007EF3 ???? BPB_HEADS DW ? 0 00007EF5 ???? BPB_HIDDENSECTORS DW ? 0 00007EF7 ???? DW ? 0 00007EF9 ???? BPB_BIGTOTALSECTORS DW ? 0 00007EFB ???? DW ? 0 00007EFD ???????????? DB 6 DUP(?) 37 <2> A_BPB ENDS 38 <2> ; ; 39 <2> ; C A V E A T P R O G R A M M E R ; 40 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 41 <2> 109 <1> 110 <1> A_SECTORTABLE STRUC 0 00007EE4 ???? ST_SECTORNUMBER DW ? 0 00007EE6 ???? ST_SECTORSIZE DW ? 113 <1> A_SECTORTABLE ENDS 114 <1> 115 <1> A_DEVICEPARAMETERS STRUC 0 00007EE4 ?? DP_SPECIALFUNCTIONS DB ? 0 00007EE5 ?? DP_DEVICETYPE DB ? 0 00007EE6 ???? DP_DEVICEATTRIBUTES DW ? 0 00007EE8 ???? DP_CYLINDERS DW ? 0 00007EEA ?? DP_MEDIATYPE DB ? 121 00000007 <1> DP_BPB DB A_BPB_struc_size DUP (?) 0 00007F0A ???? DP_TRACKTABLEENTRIES DW ? 123 00000028 <1> DP_SECTORTABLE DB MAX_SECTORS_IN_TRACK * A_SECTORTABLE_struc_size DUP (?) 124 <1> A_DEVICEPARAMETERS ENDS 125 <1> 126 <1> A_TRACKREADWRITEPACKET STRUC 0 00007EE4 ?? TRWP_SPECIALFUNCTIONS DB ? 0 00007EE5 ???? TRWP_HEAD DW ? 0 00007EE7 ???? TRWP_CYLINDER DW ? 0 00007EE9 ???? TRWP_FIRSTSECTOR DW ? 0 00007EEB ???? TRWP_SECTORSTOREADWRITE DW ? 0 00007EED ???????? TRWP_TRANSFERADDRESS DD ? 133 <1> A_TRACKREADWRITEPACKET ENDS 134 <1> 135 <1> ;AN001; - FP_TRACKCOUNT is only meaningful when FP_SPECIALFUNCTIONS bit 1 = 1. 136 <1> A_FORMATPACKET STRUC 0 00007EE4 ?? FP_SPECIALFUNCTIONS DB ? 0 00007EE5 ???? FP_HEAD DW ? 0 00007EE7 ???? FP_CYLINDER DW ? 0 00007EE9 ???? FP_TRACKCOUNT DW ? ;1 141 <1> A_FORMATPACKET ENDS 142 <1> 143 <1> A_VERIFYPACKET STRUC 0 00007EE4 ?? VP_SPECIALFUNCTIONS DB ? 0 00007EE5 ???? VP_HEAD DW ? 0 00007EE7 ???? VP_CYLINDER DW ? 147 <1> A_VERIFYPACKET ENDS 148 <1> 149 <1> A_MEDIA_ID_INFO STRUC 0 00007EE4 ???? MI_LEVEL DW ? ;0 ;J.K. 87 Info. level 0 00007EE6 ???????? MI_SERIAL DD ? ;J.K. 87 Serial # 152 00000006 <1> MI_LABEL DB 11 DUP (?) ;(' ') ;J.K. 87 volume label 0 00007EF5 ???????????????? MI_SYSTEM DB 8 DUP (?) ;(' ') ;J.K. 87 File system type 154 <1> A_MEDIA_ID_INFO ENDS 155 <1> 156 <1> A_DISKACCESS_CONTROL STRUC ;AN002; Unpublished function. Only for Hard file. 0 00007EE4 ?? DAC_SPECIALFUNCTIONS DB ? ;0 ;AN002; Always 0 0 00007EE5 ?? DAC_ACCESS_FLAG DB ? ;0 ;AN002; Non Zero - allow disk I/O to unformatted hard file 159 <1> A_DISKACCESS_CONTROL ENDS ;AN002; 0 - Disallow disk I/O to unformatted hard file 160 <1> 161 <1> ;********************************;* 162 <1> ; CHARACTER DEVICES (PRINTERS) ;* 163 <1> ;********************************;* 164 <1> 165 <1> ;RAWIO SUB-FUNCTIONS 166 <1> GET_RETRY_COUNT EQU 65H 167 <1> SET_RETRY_COUNT EQU 45H 168 <1> 169 <1> A_RETRYCOUNT STRUC 0 00007EE4 ???? RC_COUNT DW ? 171 <1> A_RETRYCOUNT ENDS 172 <1> 173 <1> ;********************************;* ;J.K. 4/29/86 174 <1> ; CHARACTER DEVICES (SCREEN) ;* 175 <1> ;********************************;* ;J.K. 4/29/86 176 <1> ; 177 <1> ;SC_MODE_INFO struc 178 <1> ;SC_INFO_LENGTH DW 9 179 <1> ;SC_MODE DB 0 180 <1> ;SC_COLORS DW 0 181 <1> ;SC_WIDTH DW 0 182 <1> ;SC_LENGTH DW 0 183 <1> ;SC_MODE_INFO ends 184 <1> ; 185 <1> ;SC_INFO_PACKET_LENGTH EQU 9 ;LENGTH OF THE INFO PACKET. 186 <1> 187 <1> ;SUBFUNCTIONS FOR CON$GENIOCTL 188 <1> ;GET_SC_MODE EQU 60h 189 <1> ;SET_SC_MODE EQU 40h 190 <1> ;The following subfunctions are reserved for installable CODE PAGE switch 191 <1> ;console devices. - J.K. 4/29/86 192 <1> ;Get_active_codepage equ 6Ah 193 <1> ;Invoke_active_codepage equ 4Ah 194 <1> ;Start_designate_codepage equ 4Ch 195 <1> ;End_designate_codepage equ 4Dh 196 <1> ;Get_list_of_designated_codepage equ 6Bh 197 <1> ;J.K. 4/29/86 *** End of Con$genioctl equates & structures 20 21 EXTRN BUS$EXIT:NEAR ;MSBIO1 22 EXTRN ERR$CNT:NEAR ;MSBIO1 23 EXTRN CMDERR:NEAR ;MSBIO1 24 EXTRN GETDX:NEAR ;MSBIO1 25 EXTRN EXIT:NEAR ;MSBIO1 26 EXTRN ERR$EXIT:NEAR ;MSBIO1 27 ;DATA 28 EXTRN PTRSAV:DWORD ;MSBIO1 29 EXTRN TIMDEV:WORD ;MSCLOCK 30 EXTRN LPT2DEV:WORD ;MSBIO2 31 EXTRN WAIT_COUNT:WORD ;MSDATA 32 EXTRN PRINTDEV:BYTE ;MSDATA 33 ; IBM ROM STATUS BITS (I DON'T TRUST THEM, NEITHER SHOULD YOU) 34 35 NOTBUSYSTATUS equ 10000000B ; NOT BUSY 36 ACKSTATUS equ 01000000B ; ACKNOWLEDGE (FOR WHAT?) 37 NOPAPERSTATUS equ 00100000B ; NO MORE PAPER 38 SELECTEDSTATUS equ 00010000B ; THE PRINTER SAID IT WAS SELECTED 39 IOERRSTATUS equ 00001000B ; SOME KINDA ERROR 40 RESERVED equ 00000110B ; NOPS 41 TIMEOUTSTATUS equ 00000001B ; TIME OUT. 42 43 44 ; WARNING!!! THE IBM ROM DOES NOT RETURN JUST ONE BIT. IT RETURNS A 45 ; WHOLE SLEW OF BITS, ONLY ONE OF WHICH IS CORRECT. 46 47 ;---------------------------------------------------------- 48 ;J.K. AN001; PRN$WRIT will retry only if error code is TIMEOUT. 49 50 ; WRITE TO PRINTER DEVICE 51 52 ; CX HAS COUNT OF BYTES 53 ; ES:DI POINT TO DESTINATION 54 ; AUXNUM HAS PRINTER NUMBER 55 56 PUBLIC PRN$WRIT 57 PRN$WRIT PROC NEAR 58 ASSUME DS:BIOCODE ; SET BY PRINTER DEVICE DRIVER ENTRY 59 0 00007EE4 E31A jcxz Prn$Done ;No char to output 61 Prn$Loop: 0 00007EE6 BB0200 mov bx, 2 ;Initialize retry count 63 Prn$Out: 64 ;SB34LPT000**************************************************************** 65 ;SB Print the character at [ES:DI] 66 ;SB Call the function PrnOP to do this 67 ;SB The character to be printed goes in AL and the function code 68 ;SB for 'Output character' goes in AH 69 ;SB Check for error in printing. 70 ;SB If there is no error go to print the next character. 71 ;SB If there is an error indicated see if it is due to TIMEOUT. If the 72 ;SB error is not TIMEOUT then we can do nothing about it. Just go to 73 ;SB print the next character. If it is due to timeout we can execute 74 ;SB the code to retry the print which follows this piece of code 75 ;SB LOCS: 6 76 0 00007EE9 268A05 mov al,[es:di] ; assume AX disposible since enter 0 00007EEC 30E4 xor ah,ah ; via int 21h 79 PrnOp equ PRNOP ; NASM port label 0 00007EEE E82400 call PrnOp ; print to printer 0 00007EF1 740A jz Prn$Con ; no error - continue 0 00007EF3 F6C401 test ah,TIMEOUTSTATUS 0 00007EF6 7405 jz Prn$Con ; NOT time out - continue 84 85 ;SB34LPT000**************************************************************** 0 00007EF8 4B dec bx ;Retry until count is exhausted. 0 00007EF9 75EE jnz Prn$Out ;Retry it. 0 00007EFB EB06 jmp short Pmessg ;Return with error. 89 ; 90 ; next character 91 ; 92 Prn$Con: 0 00007EFD 47 inc di ;point to next char and continue 0 00007EFE E2E6 loop Prn$Loop 95 Prn$Done: 96 Exit equ EXIT ; NASM port label 0 00007F00 E9[0000] jmp Exit 98 Pmessg: 99 Err$Cnt equ ERR$CNT ; NASM port label 0 00007F03 E9[0000] jmp Err$Cnt 101 PRN$WRIT endp 102 103 ; JCXZ EXVEC3 ; NO CHARS TO OUTPUT.. 104 ;PRN$LOOP: 105 ; MOV BX,2 ; INITIALIZE RETRY FLAG 106 ;PRN$OUT: 107 ; MOV AL,[ES:DI] ; GET CHAR INTO AL 108 ; INC DI ; POINT TO NEXT CHAR 109 ; XOR AH,AH ; AH=0 => OUTPUT CHAR IN DL 110 ; CALL PRNOP ; TO INDICATE PRINT CHAR IN AL 111 ; JNZ PRRETRY 112 ; LOOP PRN$LOOP 113 ;EXVEC3: 114 ; JMP EXIT 115 ;PRRETRY: 116 ; DEC DI ; UNDO THE INC ABOVE... 117 ; DEC BX 118 ; JNZ PRN$OUT 119 ;PMESSG: 120 ; JMP ERR$CNT ;RETURN WITH THE ERROR 121 ;PRN$WRIT ENDP 122 123 ;-------------------------------------------------------- 124 125 ; PRINTER STATUS ROUTINE 126 127 PUBLIC PRN$STAT 128 PRN$STAT PROC NEAR 129 ASSUME DS:BIOCODE ; SET BY PRINTER DEVICE DRIVER ENTRY 130 0 00007F06 E80A00 CALL PRNSTAT ;DEVICE IN DX 132 PMESSG equ Pmessg ; NASM port label 0 00007F09 75F8 JNZ PMESSG ; OTHER ERRORS WERE FOUND 134 ;J.K. The next three lines are commented out, since it is a dead code. 135 ; MOV AL,9 ; AGAIN, ASSUME OUT OF PAPER... 136 ; TEST AH,NOPAPERSTATUS 137 ; JNZ PMESSG 0 00007F0B F6C480 TEST AH,NOTBUSYSTATUS 0 00007F0E 75F0 jnz Prn$Done ;No error. Exit 0 00007F10 E9[0000] JMP BUS$EXIT 141 PRN$STAT ENDP 142 143 ; TAKE THE APPROPRIATE PRINTER AND DO THE OPERATION. TRIAGE THE STATUS 144 ; RETURNED IN AH INTO SOME MEANINGFUL ERROR. 145 146 PRNSTAT PROC NEAR 147 ;SB33037********************************************************************** 0 00007F13 B402 mov AH, 2 ; set command for get status ;SB ;3.30* 149 PRNOP: ;SB ;3.30* 0 00007F15 E8[0000] call GETDX ; determine which printer ;SB ;3.30* 0 00007F18 CD17 int 17h ; call ROM-BIOS printer routine ;SB;3.30* 152 153 ;SB33037********************************************************************** 154 155 ; EXAMINE THE STATUS BITS TO SEE IF AN ERROR OCCURRED. UNFORTUNATELY, SEVERAL 156 ; OF THE BITS ARE SET SO WE HAVE TO PICK AND CHOOSE. WE MUST BE EXTREMELY 157 ; CAREFUL ABOUT BREAKING BASIC. 158 0 00007F1A F6C408 TEST AH,IOERRSTATUS ; I/O ERROR? 0 00007F1D 740A JZ CHECKNOTREADY ; NO, TRY NOT READY 161 162 ; AT THIS POINT, WE KNOW WE HAVE AN ERROR. THE CONVERSE IS NOT TRUE. 163 0 00007F1F B009 MOV AL,9 ; FIRST, ASSUME OUT OF PAPER 0 00007F21 F6C420 TEST AH,NOPAPERSTATUS ; OUT OF PAPER SET? 0 00007F24 7502 JNZ RET1 ; YES, ERROR IS SET 0 00007F26 FEC0 INC AL ; INDICATE I/O ERROR 168 RET1: 169 170 ; WE HAVE TRIAGED NOW FOR OUT OF PAPER AND IO ERR (IGNORING TIME-OUT) 171 0 00007F28 C3 RET ; RETURN WITH ERROR 173 174 ; THE BITS SAID NO ERROR. UNFORTUNATELY, THERE MAY BE OTHER THINGS AT WORK 175 ; HERE. 176 177 CHECKNOTREADY: 0 00007F29 B002 MOV AL,2 ; ASSUME NOT-READY 0 00007F2B F6C401 TEST AH,TIMEOUTSTATUS ; IS TIME-OUT SET? 180 ; IF NZ THEN ERROR, ELSE OK??? 181 PRNOP2: 0 00007F2E C3 RET 183 PRNSTAT ENDP 184 185 ; OUTPUT UNTIL BUSY. THIS ENTRY POINT IS USED EXCLUSIVELY BY THE PRINT 186 ; SPOOLERS. UNDER NO CURCUMSTANCES SHOULD THE DEVICE DRIVER BLOCK WAITING FOR 187 ; THE DEVICE TO BECOME READY. 188 189 ; INPUTS: CX HAS COUNT OF BYTES TO OUTPUT. 190 ; ES:DI POINTS TO SOURCE BUFFER 191 ; OUTPUTS: SET THE NUMBER OF BYTES TRANSFERRED APPROPRIATELY 192 PUBLIC PRN$TILBUSY 193 PRN$TILBUSY PROC NEAR 194 ASSUME DS:BIOCODE ; SET BY PRINTER DEVICE DRIVER ENTRY 195 0 00007F2F 1E PUSH DS 0 00007F30 06 PUSH ES 0 00007F31 1F POP DS ; NOW ES AND DS BOTH POINT TO SOURCE BUFFER 199 ASSUME DS:NOTHING 200 0 00007F32 89FE MOV SI,DI ; EVERYTHING IS SET FOR LODSB 202 PRN$TILBLOOP: 0 00007F34 51 PUSH CX 0 00007F35 53 PUSH BX 0 00007F36 31DB XOR BX,BX 0 00007F38 1E push ds 0 00007F39 E8[0000] call biocode_get_ds_dosentry 0 00007F3C 8A1E[0000] MOV BL,[PRINTDEV] 0 00007F40 D1E3 SHL BX,1 0 00007F42 8B8F[0000] MOV CX,[WAIT_COUNT + BX] ; WAIT COUNT TIMES TO COME READY 0 00007F46 1F pop ds 0 00007F47 5B POP BX 213 PRN$GETSTAT: 0 00007F48 E8C8FF CALL PRNSTAT ; GET STATUS 0 00007F4B 7520 JNZ PRN$BPERR ; ERROR 0 00007F4D F6C480 TEST AH,10000000B ; READY YET? 0 00007F50 E1F6 LOOPZ PRN$GETSTAT ; NO, GO FOR MORE 0 00007F52 59 POP CX ; GET ORIGINAL COUNT 0 00007F53 7419 JZ PRN$BERR ; STILL NOT READY => DONE 0 00007F55 AC LODSB 0 00007F56 30E4 XOR AH,AH 0 00007F58 E8BAFF CALL PRNOP 0 00007F5B 7511 JNZ PRN$BERR ; ERROR 0 00007F5D E2D5 LOOP PRN$TILBLOOP ; GO FOR MORE 225 PRN$B: 0 00007F5F 1F POP DS 0 00007F60 E8[0000] call biocode_get_ds_dosentry 0 00007F63 C51E[0000] lds bx, [PTRSAV] 229 ASSUME DS:NOTHING 0 00007F67 294F12 SUB WORD PTR [BX + COUNT],CX ;# OF SUCCESSFUL I/O'S 0 00007F6A E9[0000] JMP EXIT 232 PRN$TILBUSY ENDP 233 234 PRN$BPERR PROC NEAR 235 ASSUME DS:BIOCODE 0 00007F6D 59 POP CX 237 PRN$BERR: 0 00007F6E 1F POP DS 0 00007F6F E8[0000] call biocode_get_ds_dosentry 0 00007F72 C51E[0000] lds bx, [PTRSAV] 241 ASSUME DS:NOTHING 242 0 00007F76 294F12 SUB WORD PTR [BX + COUNT],CX ;# OF SUCCESSFUL I/O'S 0 00007F79 E9[0000] JMP ERR$EXIT 245 PRN$BPERR ENDP 246 ; 247 ; MANIPULATES THE VALUE IN WAIT_COUNT DEPENDING ON THE VALUE PASSED IN THE 248 ; GENERIC IOCTL PACKET. 249 ; IT EITHER SETS OR RETURNS THE CURRENT VALUE FOR THE RETRY COUNT FOR THE 250 ; DEVICE. 251 ; 252 PUBLIC PRN$GENIOCTL 253 PRN$GENIOCTL PROC NEAR 254 ASSUME DS:BIOCODE ; SET BY PRINTER DEVICE DRIVER ENTRY 255 0 00007F7C C43E[0000] LES DI,[PTRSAV] 0 00007F80 26807D0D05 CMP byte [ES:DI + MAJORFUNCTION],IOC_PC 0 00007F85 7403 JE PRNFUNC_OK 259 PRNFUNCERR: 0 00007F87 E9[0000] JMP CMDERR 261 262 PRNFUNC_OK: 0 00007F8A 268A450E MOV AL,[ES:DI + MINORFUNCTION] 0 00007F8E 26C47D13 LES DI,[ES:DI + GENERICIOCTL_PACKET] 0 00007F92 31DB XOR BX,BX 0 00007F94 8A1E[0000] MOV BL,[PRINTDEV] ; GET INDEX INTO RETRY COUNTS 0 00007F98 D1E3 SHL BX,1 0 00007F9A 8B8F[0000] MOV CX,[WAIT_COUNT + BX] ; PULL OUT RETRY COUNT FOR DEVICE 0 00007F9E 3C65 CMP AL,GET_RETRY_COUNT 0 00007FA0 7407 JZ PRNGETCOUNT 0 00007FA2 3C45 CMP AL,SET_RETRY_COUNT 0 00007FA4 75E1 JNZ PRNFUNCERR 0 00007FA6 268B0D MOV CX,[ES:DI + RC_COUNT] 274 PRNGETCOUNT: 0 00007FA9 898F[0000] MOV [WAIT_COUNT + BX],CX ; PLACE "NEW" RETRY COUNT 0 00007FAD 26890D MOV [ES:DI + RC_COUNT],CX ; RETURN CURRENT RETRY COUNT 0 00007FB0 E9[0000] JMP EXIT 278 PRN$GENIOCTL ENDP 279 ; (no prior section) ; CODE ENDS 280 END === Trace listing source: msclock.lst 1 ; TITLE MSCLOCK - DOS 3.3 2 ;---------------------------------------------------------------- 3 ; : 4 ; CLOCK DEVICE DRIVER : 5 ; : 6 ; : 7 ; This file contains the Clock Device Driver. : 8 ; : 9 ; The routines in this files are: : 10 ; : 11 ; routine function : 12 ; ------- -------- : 13 ; TIM$WRIT Set the current time : 14 ; TIM$READ Read the current time : 15 ; Time_To_Ticks Convert time to corresponding : 16 ; number of clock ticks : 17 ; : 18 ; The clock ticks at the rate of: : 19 ; : 20 ; 1193180/65536 ticks/second (about 18.2 ticks per second): 21 ; See each routine for information on the use. : 22 ; : 23 ;---------------------------------------------------------------- 24 25 26 itest equ 0 27 %include "entryseg.nas" 1 <1> === Switch to base=000000h -> "DOSENTRY" 2 <1> section DOSENTRY class=%[DOSENTRY] === Switch to base=000000h -> "DOSENTRY" 3 <1> section DOSENTRY 28 %include "msgroup.mac" ;DEFINE CODE SEGMENT 1 <1> EVBOUND equ 1 ;THIS VALUE BEING 0 DOES NO BOUNDARY ALLIGNMENT, VALUE 1 ;3.30 2 <1> ; ALIGNS TO EVEN ;3.30 3 <1> 4 <1> ; NASM original macros 5 <1> 6 <1> %include "dcodeseg.nas" 1 <2> 2 <2> %ifndef DCODESEGNAS 3 <2> %assign DCODESEGNAS 1 4 <2> === Switch to base=008400h -> "DOSCODETABLE" 5 <2> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <2> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=008400h -> "DOSCODECODE" 7 <2> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <2> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=008400h -> "DOSBIOCODE" 9 <2> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=008400h -> "BIOCODE" 10 <2> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <2> 12 <2> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <2> 14 <2> %endif 7 <1> 8 <1> %if EVBOUND ;;IF EVEN (WORD) ALLIGNMENT IS REQUESTED, ;3.30 9 <1> 10 <1> %imacro EVENB 0.nolist 11 <1> EVEN ;;ADJUST TO EVEN BOUNDARY 12 <1> %endmacro 13 <1> 14 <1> %imacro ODD 0.nolist 15 <1> %if (($ - $$) % 2) == 0 16 <1> db ? 17 <1> %endif 18 <1> %endmacro 19 <1> 20 <1> %else ;;SINCE EVEN ALLIGNMENT IS NOT DESIRED, JUST USE BYTE ALLI;3.30 GNMENT 21 <1> 22 <1> %imacro EVENB 0.nolist 23 <1> ;;REQUEST FOR WORD ALLIGNMENT DOES NOTHING ;3.30 24 <1> %endmacro 25 <1> 26 <1> %imacro ODD 0.nolist 27 <1> ;;REQUEST FOR ODD ALLIGNMENT DOES NOTHING ;3.30 28 <1> %endmacro 29 <1> 30 <1> %endif ;3.30 31 <1> 32 <1> %imacro CODE_SEGMENT 0.nolist === Switch to base=008400h -> "BIOCODE" 33 <1> section BIOCODE 34 <1> %endmacro 35 <1> 36 <1> ; end of NASM original macros 37 <1> 38 <1> CODE_SEGMENT ;3.30 39 <1> ASSUME CS:BIOCODE ;3.30 40 <1> ;3.30 29 %include "msmacro.mac" 1 <1> === Switch to base=008400h -> "BIOCODE" 2 <1> section BIOCODE 3 <1> ; 4 <1> ; This file contains three macros used in debugging the system. If the 5 <1> ; variable "itest" (in msbio.asm) is nonzero code is included in the 6 <1> ; modules to print debugging messages. The level of debugging is controlled 7 <1> ; by the value of the variable fTestBits in msbio.asm. Specific bits in 8 <1> ; the variable determine which messages to print. The equ's below tell 9 <1> ; which bits control which funcitons. For example the fifth bit 10 <1> ; cooresponds to disk activity (see fTestDisk equ below). 11 <1> ; 12 <1> ; The macros in the file are: 13 <1> ; 14 <1> ; message Prints an ascii string on the screen. 15 <1> ; Example usage: 16 <1> ; 17 <1> ; message fTestDisk, <"Start Disk Write", CR, LF> 18 <1> ; message fTestINIT, <"Begin BDS initialization"> 19 <1> ; 20 <1> ; 21 <1> ; MNUM Print the value in a register or memory location on 22 <1> ; the screen. Value is displayed in hex. 23 <1> ; Usage: 24 <1> ; MNUM bitpattern, valueLocation 25 <1> ; 26 <1> ; valueLocation is typically a regester: 27 <1> ; 28 <1> ; mnum fTestCom, AX 29 <1> ; mnum fTestDisk, DX 30 <1> ; 31 <1> ; ValueLocation can also be a memory location: 32 <1> ; 33 <1> ; mnum fTestINIT, Final_Dos_Location 34 <1> ; 35 <1> ; If no valueLocation is given the macro defaults to 36 <1> ; the BX register. 37 <1> ; 38 <1> ; ZWAIT Stops the program until any key is pressed. 39 <1> ; 40 <1> ; 41 <1> ; The three macros preserve all register values. If "test" is zero 42 <1> ; defined during assembly then the marco produce no code. 43 <1> ; 44 <1> 45 <1> %IF itest ;3.30 46 <1> EXTRN MSGOUT:NEAR,MSGNUM:NEAR ;3.30 47 <1> EXTRN NUMBUF:BYTE,DIGITS:BYTE,FTESTBITS:WORD ;3.30 48 <1> EXTRN DUMPBYTES:NEAR,OUTCHAR:NEAR,HEX_TO_ASCII:NEAR ;3.30 49 <1> 50 <1> 51 <1> fTestALL equ 1111111111111111b ; watch everything 52 <1> fTestHARD equ 0000000000000001b ; watch hard disk initialization 53 <1> fTest96 equ 0000000000000010b ; watch 96 tpi activity 54 <1> FTEST13 EQU 0000000000000100B ; WATCH INT 13 ACTIVITY ;3.30 55 <1> FTESTCOM EQU 0000000000001000B ; WATCH PACKET ACTIVITY ;3.30 56 <1> FTESTINIT EQU 0000000000010000B ; WATCH INITIALIZATION MESSAGES ;3.30 57 <1> FTESTDISK EQU 0000000000100000B ; WATCH DISK DEVICE DRIVER CALLS ;3.30 58 <1> FTESTCON EQU 0000000001000000B ; WATCH SYSTEM WAIT ACTIVITY IN CO;3.30 NSOLE 59 <1> FtestClock equ 0000000010000000b ; wathc clock device 5/2/86 ;3.30 60 <1> 61 <1> ; NASM original macros 62 <1> 63 <1> ; 64 <1> ; message macro -- see above for description 65 <1> ; 66 <1> 67 <1> %unimacro stripangles 2+.nolist 68 <1> 69 <1> %imacro stripangles 2+.nolist 70 <1> %defstr %%param %2 71 <1> %rep 16 72 <1> %substr %%opening %%param 1 73 <1> %ifidn %%opening, '<' 74 <1> %substr %%param %%param 2,-1 75 <1> %endif 76 <1> %endrep 77 <1> %rep 16 78 <1> %strlen %%length %%param 79 <1> %substr %%closing %%param %%length 80 <1> %ifidn %%closing, '>' 81 <1> %substr %%param %%param 1,-2 82 <1> %endif 83 <1> %endrep 84 <1> %deftok %%token %%param 85 <1> %1 %%token 86 <1> %endmacro 87 <1> 88 <1> %imacro MESSAGE 2+ 89 <1> jmp short %%b 90 <1> %%a: 91 <1> stripangles db, %2 92 <1> db 0 93 <1> %%b: push SI 94 <1> push AX 95 <1> mov AX, %1 96 <1> mov SI, OFFSET %%a 97 <1> call MSGOUT 98 <1> pop AX 99 <1> pop SI 100 <1> %endmacro 101 <1> 102 <1> 103 <1> ; 104 <1> ; mnum macro -- see above for description 105 <1> ; 106 <1> 107 <1> %imacro MNum 1-2 108 <1> push AX 109 <1> %ifempty %2 110 <1> mov AX,%1 111 <1> call MSGNUM 112 <1> %else 113 <1> push BX 114 <1> mov BX,%2 115 <1> mov AX,%1 116 <1> call MSGNUM 117 <1> pop BX 118 <1> %endif 119 <1> pop AX 120 <1> %endmacro 121 <1> 122 <1> 123 <1> ; 124 <1> ; zwait macro -- see above for description 125 <1> ; 126 <1> 127 <1> %imacro ZWAIT 0 128 <1> Message fTestALL,<"? "> 129 <1> CALL ZWAITrtn 130 <1> %endmacro 131 <1> 132 <1> ZWAITrtn: 133 <1> pushf ; save the flags 134 <1> push AX ; preserve AX 135 <1> xor AH, AH ; set command to get character ;3.30* 136 <1> int 16h ; call rom keyboard routine ;3.30* 137 <1> pop AX ; restore AX 138 <1> popf ; restore the flags 139 <1> ret 140 <1> 141 <1> ;Dump_byte dumps the memory contents in hex. ;3.30 142 <1> ;DUMPOFFLABEL should be a label or a variable defined in DUMPSEG. ;3.30 143 <1> %imacro DUMP_BYTE 3 144 <1> push es ;3.30 145 <1> PUSH DS ;3.30 146 <1> PUSH SI ;3.30 147 <1> PUSH CX ;3.30 148 <1> ;3.30 149 <1> MOV CX, %1 ;3.30 150 <1> MOV DS, CX ;3.30 151 <1> MOV SI, OFFSET %2 ;3.30 152 <1> MOV CX, %3 ;3.30 153 <1> call dumpbytes ;3.30 154 <1> ;3.30 155 <1> POP CX ;3.30 156 <1> POP SI ;3.30 157 <1> POP DS ;3.30 158 <1> pop es ;3.30 159 <1> %endmacro ;3.30 160 <1> ;3.30 161 <1> ;Dump_Byte_Reg dumps the memory contents in hex. - 4/9/86 ;3.30 162 <1> ;DUMPOFFREG should be a register contains the offset value in DUMPSEG. ;3.30 163 <1> %imacro DUMP_BYTE_REG 3 164 <1> DUMP_BYTE_REG MACRO DUMPSEG, DUMPOFFREG, BYTELENGTH ;3.30 165 <1> push es ;3.30 166 <1> PUSH DS ;3.30 167 <1> PUSH SI ;3.30 168 <1> PUSH CX ;3.30 169 <1> ;3.30 170 <1> MOV CX, %1 ;3.30 171 <1> MOV DS, CX ;3.30 172 <1> MOV SI, %2 ;3.30 173 <1> MOV CX, %3 ;3.30 174 <1> call dumpbytes ;3.30 175 <1> ;3.30 176 <1> POP CX ;3.30 177 <1> POP SI ;3.30 178 <1> POP DS ;3.30 179 <1> pop es ;3.30 180 <1> %endmacro ;3.30 181 <1> 182 <1> %else 183 <1> ; if test is not defined then make macro into null statements 184 <1> %imacro Message 0-1+.nolist 185 <1> %endmacro 186 <1> 187 <1> %imacro MNUM 0-1+.nolist 188 <1> %endmacro 189 <1> 190 <1> %imacro ZWAIT 0-1+.nolist 191 <1> %endmacro 192 <1> 193 <1> %imacro DUMP_BYTE 0-1+.nolist 194 <1> %endmacro 195 <1> 196 <1> %imacro DUMP_BYTE_REG 0-1+.nolist 197 <1> %endmacro 198 <1> 199 <1> %endif 200 <1> 201 <1> %unimacro PATHSTART 2 202 <1> %unimacro PATHEND 2 203 <1> 204 <1> %imacro PATHSTART 2 205 <1> %IF PATHGEN ;3.30 206 <1> PUBLIC %2%1S,%2%1E ;3.30 207 <1> %2%1S LABEL BYTE ;3.30 208 <1> %ENDIF ;3.30 209 <1> %endmacro ;3.30 210 <1> ;3.30 211 <1> %imacro PATHEND 2 212 <1> %IF PATHGEN ;3.30 213 <1> %2%1E LABEL BYTE ;3.30 214 <1> %ENDIF ;3.30 215 <1> %endmacro ;3.30 30 === Switch to base=000000h -> "DOSENTRY" 31 section DOSENTRY 32 33 EXTRN EXIT:NEAR 34 ; 35 ; DAYCNT is the number of days since 1-1-80. 36 ; Each time the clock is read it is necessary to check if another day has 37 ; passed. The ROM only returns the day rollover once so if it is missed 38 ; the time will be off by a day. 39 ; 40 EXTRN DAYCNT:WORD ;MSDATA 41 42 extern HaveCMOSClock 43 extern base_century 44 extern base_year 45 extern month_tab 46 extern BinToBCD 47 extern DaycntToDay 48 extern TimeToTicks 49 Time_To_Ticks equ TIME_TO_TICKS ; NASM port label 50 extern time_to_ticks_entry 51 52 === Switch to base=008400h -> "BIOCODE" 53 section BIOCODE 54 55 ;-------------------------------------------------------------------- 56 ; 57 ; Settime sets the current time 58 ; 59 ; On entry [ES:DI] has the current time: 60 ; 61 ; number of days since 1-1-80 (WORD) 62 ; minutes (0-59) (BYTE) 63 ; hours (0-23) (BYTE) 64 ; hundredths of seconds (0-99) (BYTE) 65 ; seconds (0-59) (BYTE) 66 ; 67 ; Each number has been checked for the correct range. 68 ; 69 PUBLIC TIM$WRIT 70 TIM$WRIT PROC NEAR 71 ASSUME DS:BIOCODE 0 00007FB4 268B05 mov AX,WORD PTR [ES:DI] 0 00007FB7 50 push AX ;DAYCNT. We need to set this at the very 74 ; end to avoid tick windows. 75 ;;Rev 3.30 Modification 0 00007FB8 803E[0000]00 cmp byte [HaveCMOSClock], 0 0 00007FBD 7426 je No_CMOS_1 0 00007FBF 268A4503 mov al,[es:di+3] ;get binary hours 0 00007FC3 FF1E[0000] call far [BinToBCD] ;convert to BCD 0 00007FC7 88C5 mov ch,al ;CH = BCD hours 0 00007FC9 268A4502 mov al,[es:di+2] ;get binary minutes 0 00007FCD FF1E[0000] call far [BinToBCD] ;convert to BCD 0 00007FD1 88C1 mov cl,al ;CL = BCD minutes 0 00007FD3 268A4505 mov al,[es:di+5] ;get binary seconds 0 00007FD7 FF1E[0000] call far [BinToBCD] ;convert to BCD 0 00007FDB 88C6 mov dh,al ;DH = BCD seconds 0 00007FDD B200 mov dl,0 ;DL = 0 (ST) or 1 (DST) 0 00007FDF FA cli ;turn off timer 0 00007FE0 B403 mov ah,03h ;set RTC time 0 00007FE2 CD1A int 1Ah ;call rom bios clock routine 0 00007FE4 FB sti 92 93 ;;End of Modification 94 No_CMOS_1: 0 00007FE5 268B4D02 mov CX,WORD PTR [ES:DI+2] 0 00007FE9 268B5504 mov DX,WORD PTR [ES:DI+4] 97 ;;Rev 3.30 Modification 98 time_to_ticks equ TIME_TO_TICKS ; NASM port label 0 00007FED 9A[0000][0000] call DOSENTRY:time_to_ticks_entry ; convert time to ticks 100 ;CX:DX now has time in ticks 0 00007FF2 FA cli ; Turn off timer 0 00007FF3 B401 mov AH, 1 ; command is set time in clock 0 00007FF5 CD1A int 1Ah ; call rom-bios clock routines 0 00007FF7 8F06[0000] pop word [DAYCNT] 0 00007FFB FB sti 106 ;CMOS clock ------------------------------------- 0 00007FFC 803E[0000]00 cmp byte [HaveCMOSClock], 0 0 00008001 740A je No_CMOS_2 0 00008003 FF1E[0000] call far [DaycntToDay] ; convert to BCD format 0 00008007 FA cli ; Turn off timer 0 00008008 B405 mov AH,05h ; set RTC date 0 0000800A CD1A int 1Ah ; call rom-bios clock routines 0 0000800C FB sti 114 ;------------------------------------------------ 115 116 No_CMOS_2: 0 0000800D E9[0000] jmp EXIT 118 TIM$WRIT ENDP 119 ;;End of Modification 120 121 122 ; 123 ; convert time to ticks 124 ; input : time in CX and DX 125 ; ticks returned in CX:DX 126 ; 127 relocated time_to_ticks_entry 128 TIME_TO_TICKS PROC FAR 129 130 ; first convert from Hour,min,sec,hund. to 131 ; total number of 100th of seconds 0 00008010 B03C mov AL,60 0 00008012 F6E5 mul CH ;Hours to minutes 0 00008014 B500 mov CH,0 0 00008016 01C8 add AX,CX ;Total minutes 0 00008018 B97017 mov CX,6000 ;60*100 0 0000801B 89D3 mov BX,DX ;Get out of the way of the multiply 0 0000801D F7E1 mul CX ;Convert to 1/100 sec 0 0000801F 89C1 mov CX,AX 0 00008021 B064 mov AL,100 0 00008023 F6E7 mul BH ;Convert seconds to 1/100 sec 0 00008025 01C1 add CX,AX ;Combine seconds with hours and min. 0 00008027 83D200 adc DX,0 ;Ripple carry 0 0000802A B700 mov BH,0 0 0000802C 01D9 add CX,BX ;Combine 1/100 sec 0 0000802E 83D200 adc DX,0 147 148 ;;Rev 3.30 Modification 149 ;DX:CX IS TIME IN 1/100 SEC 0 00008031 92 XCHG AX,DX 0 00008032 91 XCHG AX,CX ;NOW TIME IS IN CX:AX 0 00008033 BB0BE9 MOV BX,59659 0 00008036 F7E3 MUL BX ;MULTIPLY LOW HALF 0 00008038 87D1 XCHG DX,CX 0 0000803A 92 XCHG AX,DX ;CX->AX, AX->DX, DX->CX 0 0000803B F7E3 MUL BX ;MULTIPLY HIGH HALF 0 0000803D 01C8 ADD AX,CX ;COMBINE OVERLAPPING PRODUCTS 0 0000803F 83D200 ADC DX,0 0 00008042 92 XCHG AX,DX ;AX:DX=TIME*59659 0 00008043 BB0500 MOV BX,5 0 00008046 F6F3 DIV BL ;DIVIDE HIGH HALF BY 5 0 00008048 88C1 MOV CL,AL 0 0000804A B500 MOV CH,0 0 0000804C 88E0 MOV AL,AH ;REMAINDER OF DIVIDE-BY-5 0 0000804E 98 CBW 0 0000804F 92 XCHG AX,DX ;USE IT TO EXTEND LOW HALF 0 00008050 F7F3 DIV BX ;DIVDE LOW HALF BY 5 0 00008052 89C2 MOV DX,AX 169 ; CX:DX is now number of ticks in time 0 00008054 CB ret 171 TIME_TO_TICKS ENDP 172 ;;End of Modification 173 174 175 ; 176 ; Gettime reads date and time 177 ; and returns the following information: 178 ; 179 ; [ES:DI] =count of days since 1-1-80 180 ; [ES:DI+2]=hours 181 ; [ES:DI+3]=minutes 182 ; [ES:DI+4]=seconds 183 ; [ES:DI+5]=hundredths of seconds 184 ; 185 PUBLIC TIM$READ 186 TIM$READ PROC NEAR 187 ; read the clock 0 00008055 30E4 xor AH, AH ; set command to read clock 0 00008057 CD1A int 1Ah ; call rom-bios to get time 190 0 00008059 08C0 or al,al ; check for a new day 0 0000805B 7404 jz noroll1 ; if al=0 then don't reset day count 0 0000805D FF06[0000] INC word [DAYCNT] ; CATCH ROLLOVE 194 noroll1: 0 00008061 8B36[0000] MOV SI,[DAYCNT] 196 197 ; 198 ; we now need to convert the time in tick to the time in 100th of 199 ; seconds. The relation between tick and seconds is: 200 ; 201 ; 65536 seconds 202 ; ---------------- 203 ; 1,193,180 tick 204 ; 205 ; To get to 100th of second we need to multiply by 100. The equation is: 206 ; 207 ; Ticks from clock * 65536 * 100 208 ; --------------------------------- = time in 100th of seconds 209 ; 1,193,180 210 ; 211 ; Fortunately this fromula simplifies to: 212 ; 213 ; Ticks from clock * 5 * 65,536 214 ; --------------------------------- = time in 100th of seconds 215 ; 59,659 216 ; 217 ; The calculation is done by first multipling tick by 5. Next we divide by 218 ; 59,659. In this division we multiply by 65,536 by shifting the dividend 219 ; my 16 bits to the left. 220 ; 221 ; start with ticks in CX:DX 222 ; multiply by 5 0 00008065 89C8 MOV AX,CX 0 00008067 89D3 MOV BX,DX 0 00008069 D1E2 SHL DX,1 0 0000806B D1D1 RCL CX,1 ;TIMES 2 0 0000806D D1E2 SHL DX,1 0 0000806F D1D1 RCL CX,1 ;TIMES 4 0 00008071 01DA ADD DX,BX 0 00008073 11C8 ADC AX,CX ;TIMES 5 0 00008075 92 XCHG AX,DX 232 233 234 ; now have ticks * 5 in DX:AX 235 ; we now need to multiply by 65,536 and divide by 59659 d. 236 0 00008076 B90BE9 mov CX,59659 ; get divisor 0 00008079 F7F1 div CX 239 ; DX now has remainder 240 ; AX has high word of final quotient 0 0000807B 89C3 mov BX,AX ; put high work if safe place 0 0000807D 31C0 xor AX,AX ; this is the multiply by 65536 0 0000807F F7F1 div CX ; BX:AX now has time in 100th of seconds 244 245 ; 246 ;Rounding based on the remainder may be added here 247 ;The result in BX:AX is time in 1/100 second. 0 00008081 89DA mov DX,BX 0 00008083 B9C800 mov CX,200 ;Extract 1/100's 250 ;Division by 200 is necessary to ensure no overflow--max result 251 ;is number of seconds in a day/2 = 43200. 0 00008086 F7F1 div CX 0 00008088 80FA64 cmp DL,100 ;Remainder over 100? 0 0000808B 7203 jb NOADJ 0 0000808D 80EA64 sub DL,100 ;Keep 1/100's less than 100 256 NOADJ: 0 00008090 F5 cmc ;If we subtracted 100, carry is now set 0 00008091 88D3 mov BL,DL ;Save 1/100's 259 ;To compensate for dividing by 200 instead of 100, we now multiply 260 ;by two, shifting a one in if the remainder had exceeded 100. 0 00008093 D1D0 rcl AX,1 0 00008095 B200 mov DL,0 0 00008097 D1D2 rcl DX,1 0 00008099 B93C00 mov CX,60 ;Divide out seconds 0 0000809C F7F1 div CX 0 0000809E 88D7 mov BH,DL ;Save the seconds 0 000080A0 F6F1 div CL ;Break into hours and minutes 0 000080A2 86C4 xchg AL,AH 269 270 ;Time is now in AX:BX (hours, minutes, seconds, 1/100 sec) 271 0 000080A4 50 push AX 0 000080A5 89F0 MOV AX,SI ; DAYCNT 0 000080A7 AB stosw 0 000080A8 58 pop AX 0 000080A9 AB stosw 0 000080AA 89D8 mov AX,BX 0 000080AC AB stosw 0 000080AD E9[0000] jmp EXIT 280 281 TIM$READ ENDP 282 ; (no prior section) ; CODE ENDS 283 END 284 285 === Trace listing source: msdisk.lst 1 ; PAGE ,132 ; 2 ; TITLE MSDISK - BIOS 3 %warning out: ...MSDISK.ASM 3 ****************** warning: out: ...MSDISK.ASM [-w+user] 4 5 ;============================================================================== 6 ;REVISION HISTORY: 7 ;AN000 - New for DOS Version 4.00 - J.K. 8 ;AC000 - Changed for DOS Version 4.00 - J.K. 9 ;AN00x - PTM number for DOS Version 4.00 - J.K. 10 ;============================================================================== 11 ;AN001; d24 Multi Track enable/disable command in CONFIG.SYS 6/27/87 J.K. 12 ;AN002; d9 Double word MOV instruction 7/1/87 J.K. 13 ;AN003: d25 Change DASD ERP to that recommended by Storage systems 7/28/87 J.K. 14 ;AN004; D113 Disable I/O access to unformatted media 9/03/87 J.K. 15 ;AN005; P985 Allow I/O access to unformatted media 9/14/87 J.K. 16 ;AN006; P1535 Disallow I/O access to unformatted media. 10/15/87 J.K. 17 ; (Give the user to control this - Generic IOCTL subfunction 64h/44h 18 ;AN007; p2828 Do not retry for multi-track format request 12/08/87 J.K. 19 ;AC008; p3197 Should reset change line after BPB set in BDS table 01/21/88 J.K. 20 ;AN009; p3349 Should retry at hard file timeout error 02/03/88 J.K. 21 ;AN010; p4696 ECC error handler should cover PC ATs for CMC disks 05/04/88 J.K. 22 ;AN011; p5034 Possible virgin hard file problem with direct INT 13 06/03/88 J.K. 23 ;AN012; P5049 Attempt to write at DISK BASE table in ROM BIOS 06/06/88 J.K. 24 ;AN013; P5055 Diskcopy fails (Regression of P5049) 06/09/88 J.K. 25 ;============================================================================== 26 27 ;for testing, set itest to 1. So as MSBIO1.ASM. 28 itest equ 0 29 EXTRN NUMERR:ABS ;MSDATA 30 31 %include "msgroup.mac" ;DEFINE CODE SEGMENT 1 <1> EVBOUND equ 1 ;THIS VALUE BEING 0 DOES NO BOUNDARY ALLIGNMENT, VALUE 1 ;3.30 2 <1> ; ALIGNS TO EVEN ;3.30 3 <1> 4 <1> ; NASM original macros 5 <1> 6 <1> %include "dcodeseg.nas" 1 <2> 2 <2> %ifndef DCODESEGNAS 3 <2> %assign DCODESEGNAS 1 4 <2> === Switch to base=008400h -> "DOSCODETABLE" 5 <2> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <2> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=008400h -> "DOSCODECODE" 7 <2> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <2> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=008400h -> "DOSBIOCODE" 9 <2> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=008400h -> "BIOCODE" 10 <2> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <2> 12 <2> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <2> 14 <2> %endif 7 <1> 8 <1> %if EVBOUND ;;IF EVEN (WORD) ALLIGNMENT IS REQUESTED, ;3.30 9 <1> 10 <1> %imacro EVENB 0.nolist 11 <1> EVEN ;;ADJUST TO EVEN BOUNDARY 12 <1> %endmacro 13 <1> 14 <1> %imacro ODD 0.nolist 15 <1> %if (($ - $$) % 2) == 0 16 <1> db ? 17 <1> %endif 18 <1> %endmacro 19 <1> 20 <1> %else ;;SINCE EVEN ALLIGNMENT IS NOT DESIRED, JUST USE BYTE ALLI;3.30 GNMENT 21 <1> 22 <1> %imacro EVENB 0.nolist 23 <1> ;;REQUEST FOR WORD ALLIGNMENT DOES NOTHING ;3.30 24 <1> %endmacro 25 <1> 26 <1> %imacro ODD 0.nolist 27 <1> ;;REQUEST FOR ODD ALLIGNMENT DOES NOTHING ;3.30 28 <1> %endmacro 29 <1> 30 <1> %endif ;3.30 31 <1> 32 <1> %imacro CODE_SEGMENT 0.nolist === Switch to base=008400h -> "BIOCODE" 33 <1> section BIOCODE 34 <1> %endmacro 35 <1> 36 <1> ; end of NASM original macros 37 <1> 38 <1> CODE_SEGMENT ;3.30 39 <1> ASSUME CS:BIOCODE ;3.30 40 <1> ;3.30 32 %include "msequ.mac" 1 <1> %warning out: MSEQU.INC... 1 ****************** <1> warning: out: MSEQU.INC... [-w+user] 2 <1> ;============================================================================== 3 <1> 4 <1> FTOOBIG EQU 80H 5 <1> FBIG EQU 40H 6 <1> ROMSTATUS EQU 1 7 <1> ROMREAD EQU 2 8 <1> ROMWRITE EQU 3 9 <1> ROMVERIFY EQU 4 10 <1> ROMFORMAT EQU 5 11 <1> VID_SIZE EQU 12 12 <1> 13 <1> %include "msbds.mac" ; VARIOUS EQUATES FOR BDS 1 <2> 2 <2> %warning out: MSBDS.INC... 2 ****************** <2> warning: out: MSBDS.INC... [-w+user] 3 <2> ; SCCSID = @(#)IBMBDS.ASM 1.9 85/09/16 4 <2> ;============================================================================== 5 <2> ;REVISION HISTORY: 6 <2> ;AN000 - New for DOS Version 4.00 - J.K. 7 <2> ;AC000 - Changed for DOS Version 4.00 - J.K. 8 <2> ;AN00x - PTM number for DOS Version 4.00 - J.K. 9 <2> ;============================================================================== 10 <2> ;AN001; D113 Disable I/O access to unformatted media 9/03/87 J.K. 11 <2> ;============================================================================== 12 <2> 13 <2> ; VALUES FOR VARIOUS FLAGS IN BDS.FLAGS. 14 <2> 15 <2> FNON_REMOVABLE EQU 01H ;FOR NON-REMOVABLE MEDIA 16 <2> FCHANGELINE EQU 02H ;IF CHANGELINE SUPPORTED ON DRIVE 17 <2> RETURN_FAKE_BPB EQU 04H ; WHEN SET, DON'T DO A BUILD BPB 18 <2> ; JUST RETURN THE FAKE ONE 19 <2> GOOD_TRACKLAYOUT EQU 08H ; THE TRACK LAYOUT HAS NO FUNNY SECTORS 20 <2> ; FCHANGED_BY_FORMAT EQU 08H 21 <2> FI_AM_MULT EQU 10H ;IF MORE THAN ONE LOGICAL FOR THIS PHYSICAL 22 <2> FI_OWN_PHYSICAL EQU 20H ;SIGNIFY LOGICAL OWNER OF THIS PHYSICAL 23 <2> FCHANGED EQU 40H ;INDICATES MEDIA CHANGED 24 <2> SET_DASD_TRUE EQU 80H ; SET DASD BEFORE NEXT FORMAT 25 <2> FCHANGED_BY_FORMAT EQU 100H ;MEDIA CHANGED BY FORMAT 26 <2> UNFORMATTED_MEDIA EQU 200H ;AN001; Fixed disk only 27 <2> F_LBA equ 400h ; LBA supported 28 <2> 29 <2> LBAPACKETSTRUC struc 0 000080B0 ???? lpSize dw ? 0 000080B2 ???? lpCount dw ? 0 000080B4 ???????? lpBuffer dd ? 0 000080B8 ???????????????? lpSector dd ?,? 34 <2> LBAPACKETSTRUC ends 35 <2> 36 <2> ; 37 <2> ; VARIOUS FORM FACTORS TO DESCRIBE MEDIA 38 <2> ; 39 <2> FF48TPI EQU 0 40 <2> FF96TPI EQU 1 41 <2> FFSMALL EQU 2 42 <2> FFHARDFILE EQU 5 43 <2> FFOTHER EQU 7 44 <2> 45 <2> BDS_TYPE STRUC 0 000080B0 ???????? LINK DD ? ; LINK TO NEXT BDS 0 000080B4 ?? DRIVENUM DB ? ; INT 13 DRIVE NUMBER 0 000080B5 ?? DRIVELET DB ? ; DOS DRIVE NUMBER 0 000080B6 ???? BYTEPERSEC DW ? ; NUMBER OF BYTES/SEC 0 000080B8 ?? SECPERCLUS DB ? ; SEC PER ALLOCATION UNIT 0 000080B9 ???? RESSEC DW ? ; NUMBER OF RESERVED SECTORS 0 000080BB ?? CFAT DB ? ; NUMBER OF FATS 0 000080BC ???? CDIR DW ? ; NUMBER OF DIRECTORY ENTRIES 0 000080BE ???? DRVLIM DW ? ; NUMBER OF SECTORS ON MEDIUM 0 000080C0 ?? MEDIAD DB ? ; MEDIA DESCRIPTOR BYTE 0 000080C1 ???? CSECFAT DW ? ; NUMBER OF SECTORS/FAT 0 000080C3 ???? SECLIM DW ? ; SECTORS PER TRACK 0 000080C5 ???? HDLIM DW ? ; MAX NUMBER OF HEADS 0 000080C7 ???? HIDSEC_L DW ? ; NUMBER OF HIDDEN SECTORS 0 000080C9 ???? HIDSEC_H dw ? ;0 ;J.K.87 0 000080CB ???? DRVLIM_L dw ? ;0 ;J.K.87 0 000080CD ???? DRVLIM_H dw ? ;0 ;J.K.87 0 000080CF ?? FATSIZ DB ? ; FLAGS... 0 000080D0 ???? OPCNT DW ? ; OPEN REF. COUNT 0 000080D2 ?? FORMFACTOR DB ? ; FORM FACTOR INDEX 0 000080D3 ???? FLAGS DW ? ; VARIOUS FLAGS 0 000080D5 ???? CCYLN DW ? ; MAX NUMBER OF CYLINDERS 0 000080D7 ???? RBYTEPERSEC DW ? ; RECOMMENDED BPB 0 000080D9 ?? RSECPERCLUS DB ? 0 000080DA ???? RRESSEC DW ? 0 000080DC ?? RCFAT DB ? 0 000080DD ???? RCDIR DW ? 0 000080DF ???? RDRVLIM DW ? 0 000080E1 ?? RMEDIAD DB ? 0 000080E2 ???? RCSECFAT DW ? 0 000080E4 ???? RSECLIM DW ? 0 000080E6 ???? RHDLIM DW ? 0 000080E8 ???? RHIDSEC_L DW ? 0 000080EA ???? RHIDSEC_H DW ? ;0 ;J.K.87 0 000080EC ???? RDRVLIM_L dw ? ;0 ;J.K.87 0 000080EE ???? RDRVLIM_H dw ? ;0 ;J.K.87 0 000080F0 ???????????? RESERVE DB 6 DUP (?) ; RESERVED FOR FUTURE 0 000080F6 ?? TRACK DB ? ; LAST TRACK ACCESSED ON DRIVE 0 000080F7 ???? TIM_LO DW ? ; TIME OF LAST ACCESS. KEEP 0 000080F9 ???? TIM_HI DW ? ; THESE CONTIGUOUS. 86 0000004B <2> VOLID DB 12 DUP (?) ; VOLUME ID OF MEDIUM 0 00008107 ???????? VOL_SERIAL dd ? ;0 ;J.K.87 Current volume serial number from Boot record 88 0000005B <2> FILESYS_Id db 9 dup (?) ;(0) ;J.K.87 Current file system id from Boot record 89 <2> BDS_TYPE ENDS 90 <2> 91 <2> BPBSIZE equ TRACK - RBYTEPERSEC ; SIZE IN BYTES OF RECBPB AREA IN THE BDS 92 <2> 93 <2> 94 <2> ;********************************************************************* 95 <2> ; BDS structure for mini disk - J.K. 4/7/86 96 <2> ;********************************************************************* 97 <2> 98 <2> BDSM_type struc 0 000080B0 ???? mlink DW ? ;-1 ;Link to next structure 0 000080B2 ???? DW ? 0 000080B4 ?? mdriveNum DB ? ;80 ;Int 13 Drive Number 0 000080B5 ?? mdriveLet DB ? ;3 ;Logical Drive Number 0 000080B6 ???? mBytePerSec DW ? ;512 0 000080B8 ?? mSecPerClus DB ? ;1 ;Sectors/allocation unit 0 000080B9 ???? mRESSEC DW ? ;1 ;Reserved sectors for DOS 0 000080BB ?? mcFAT DB ? ;2 ;No. of allocation tables 0 000080BC ???? mcDIR DW ? ;16 ;Number of directory entries 0 000080BE ???? mDRVLIM DW ? ;0 ;Number of sectors (at 512 bytes each) 0 000080C0 ?? mMediad DB ? ;11111000B ;Media descriptor 0 000080C1 ???? mcSecFat DW ? ;1 ;Number of FAT sectors 0 000080C3 ???? mSECLIM DW ? ;0 ;Sector limit 0 000080C5 ???? mHDLIM DW ? ;0 ;Head limit 0 000080C7 ???? mHIDSEC_L DW ? ;0 ;Hidden sector count 0 000080C9 ???? mHidsec_H dw ? ;0 ;J.K.87 0 000080CB ???? mDrvlim_L dw ? ;0 ;J.K.87 0 000080CD ???? mDrvlim_H dw ? ;0 ;J.K.87 0 000080CF ?? mFatSiz DB ? ;0 ;TRUE => bigfat 0 000080D0 ???? mOPCNT DW ? ;0 ;Open Ref. Count 0 000080D2 ?? mFormFactor DB ? ;3 ;Form Factor 0 000080D3 ???? mFLAGS DW ? ;0020H ;Various Flags 0 000080D5 ???? mcCyln dw ? ;40 ;max number of cylinders 122 00000027 <2> mRecBPB db 31 dup (?) ;(0) ;Recommended BPB for drive 0 000080F6 ?? mTrack db ? ;-1 0 000080F7 ???? IsMini dw ? ;1 ;Overlapping TIM_LOH 0 000080F9 ???? Hidden_Trks dw ? ;0 ;Overlapping TIM_HIH 126 0000004B <2> mVOLID DB 11 dup (?) ;"NO NAME " ;Volume ID for this disk 0 00008106 ?? DB ? ;0 ;ASCIZII for "NO NAME " 0 00008107 ???????? mVol_Serial dd ? ;0 ;Current volume serial number from Boot record 0 0000810B ???????????????? mFileSys_Id db 8 dup (?) ;"FAT12 " ;Current file system id from Boot record 0 00008113 ?? db ? ;0 131 <2> 132 <2> BDSM_type ENDS 133 <2> ;****************************************************************************** 134 <2> Max_mini_dsk_num equ 23 ;J.K. 4/7/86 - max # of mini disk ibmbio can support 135 <2> ; 136 <2> 14 <1> 15 <1> ;AN000; Extended BPB structure. 16 <1> BPB_TYPE STRUC 0 000080B0 ???? SECSIZE DW ? 0 000080B2 ?? SECALL DB ? 0 000080B3 ???? RESNUM DW ? 0 000080B5 ?? FATNUM DB ? 0 000080B6 ???? DIRNUM DW ? 0 000080B8 ???? SECNUM DW ? 0 000080BA ?? FATID DB ? 0 000080BB ???? FATSIZE DW ? 0 000080BD ???? SLIM DW ? 0 000080BF ???? HLIM DW ? 0 000080C1 ???? HIDDEN_L DW ? 0 000080C3 ???? HIDDEN_H dw ? ;0 ;J.K. 0 000080C5 ???? SECNUM_L dw ? ;0 ;J.K. 0 000080C7 ???? SECNUM_H dw ? ;0 ;J.K. 31 <1> BPB_TYPE ENDS 32 <1> 33 <1> ;;;;;;;;;;; 34 <1> BOOT_SERIAL_SIZE equ 4 ;J.K. 35 <1> BOOT_VOLUME_LABEL_SIZE equ 11 ;J.K. 36 <1> BOOT_SYSTEM_ID_SIZE equ 8 ;J.K. 37 <1> EXT_BOOT_SIGNATURE equ 41 ;J.K. 38 <1> RSINIT equ 0A3H ;RS232 INITIALIZATION 39 <1> ;9600 BAUD:NO PARITY:1 STOP:8 BIT WORD 40 <1> LF equ 10 ;LINE FEED 41 <1> CR equ 13 ;CARRIAGE RETURN 42 <1> BACKSP equ 8 ;BACKSPACE 43 <1> BRKADR equ 1BH * 4 ;006C 1BH BREAK VECTOR ADDRESS 44 <1> TIMADR equ 1CH * 4 ;0070 1CH TIMER INTERRUPT 45 <1> DSKADR equ 1EH * 4 ;ADDRESS OF PTR TO DISK PARAMETERS 46 <1> SEC9 equ 522H ;ADDRESS OF DISK PARAMETERS 47 <1> HEADSETTLE equ SEC9+9 ; ARR 2.20 ADDRESS OF HEAD SETTLE TIME 48 <1> NORMSETTLE equ 15 ; ARR 2.20 NORMAL HEAD SETTLE 49 <1> SPEEDSETTLE equ 0 ; ARR 2.20 SPEED UP SETTLE TIME 50 <1> INITSPOT equ 534H ; ARR IBM WANTS 4 ZEROS HERE 51 <1> AKPORT equ 20H 52 <1> EOI equ 20H 53 <1> CMDLEN equ 0 ;LENGTH OF THIS COMMAND 54 <1> UNIT equ 1 ;SUB UNIT SPECIFIER 55 <1> CMD equ 2 ;COMMAND CODE 56 <1> STATUS equ 3 ;STATUS 57 <1> MEDIA equ 13 ;MEDIA DESCRIPTOR 58 <1> TRANS equ 14 ;TRANSFER ADDRESS 59 <1> COUNT equ 18 ;COUNT OF BLOCKS OR CHARACTERS 60 <1> START equ 20 ;FIRST BLOCK TO TRANSFER 61 <1> EXTRA equ 22 ;USUALLY A POINTER TO VOL ID FOR ERROR 15 62 <1> CHROUT equ 29H 63 <1> MAXERR equ 5 64 <1> LSTDRV equ 504H 65 <1> 66 <1> NOTBUSYSTATUS equ 10000000B ; NOT BUSY 67 <1> ACKSTATUS equ 01000000B ; ACKNOWLEDGE (FOR WHAT?) 68 <1> NOPAPERSTATUS equ 00100000B ; NO MORE PAPER 69 <1> SELECTEDSTATUS equ 00010000B ; THE PRINTER SAID IT WAS SELECTED 70 <1> IOERRSTATUS equ 00001000B ; SOME KINDA ERROR 71 <1> RESERVED equ 00000110B ; NOPS 72 <1> TIMEOUTSTATUS equ 00000001B ; TIME OUT. 73 <1> ERROR_UNKNOWN_MEDIA equ 7 ; FOR USE IN BUILD BPB CALL 74 <1> 75 <1> PATHGEN equ 1 33 %include "pushpop.mac" 1 <1> ; NASM original macros 2 <1> 3 <1> %unimacro stripangles 2.nolist 4 <1> %assign ?stackdepth 0 5 <1> 6 <1> %imacro stripangles 2.nolist 7 <1> %defstr %%param %2 8 <1> %rep 16 9 <1> %substr %%opening %%param 1 10 <1> %ifidn %%opening, '<' 11 <1> %substr %%param %%param 2,-1 12 <1> %endif 13 <1> %endrep 14 <1> %rep 16 15 <1> %strlen %%length %%param 16 <1> %substr %%closing %%param %%length 17 <1> %ifidn %%closing, '>' 18 <1> %substr %%param %%param 1,-2 19 <1> %endif 20 <1> %endrep 21 <1> %deftok %%token %%param 22 <1> %1 %%token 23 <1> %endmacro 24 <1> 25 <1> ;BREAK 26 <1> 27 <1> %imacro SaveReg 0-*.nolist ;; push those registers 28 <1> %rep %0 29 <1> %assign ?stackdepth ?stackdepth + 1 30 <1> stripangles push, %1 31 <1> %rotate 1 32 <1> %endrep 33 <1> %endmacro 34 <1> ;.xcref SaveReg 35 <1> 36 <1> ;BREAK 37 <1> 38 <1> %imacro RestoreReg 0-*.nolist ;; pop those registers 39 <1> %rep %0 40 <1> %assign ?stackdepth ?stackdepth - 1 41 <1> stripangles pop, %1 42 <1> %rotate 1 43 <1> %endrep 44 <1> %endmacro 45 <1> ;.xcref RestoreReg 34 %include "msmacro.mac" 1 <1> === Switch to base=008400h -> "BIOCODE" 2 <1> section BIOCODE 3 <1> ; 4 <1> ; This file contains three macros used in debugging the system. If the 5 <1> ; variable "itest" (in msbio.asm) is nonzero code is included in the 6 <1> ; modules to print debugging messages. The level of debugging is controlled 7 <1> ; by the value of the variable fTestBits in msbio.asm. Specific bits in 8 <1> ; the variable determine which messages to print. The equ's below tell 9 <1> ; which bits control which funcitons. For example the fifth bit 10 <1> ; cooresponds to disk activity (see fTestDisk equ below). 11 <1> ; 12 <1> ; The macros in the file are: 13 <1> ; 14 <1> ; message Prints an ascii string on the screen. 15 <1> ; Example usage: 16 <1> ; 17 <1> ; message fTestDisk, <"Start Disk Write", CR, LF> 18 <1> ; message fTestINIT, <"Begin BDS initialization"> 19 <1> ; 20 <1> ; 21 <1> ; MNUM Print the value in a register or memory location on 22 <1> ; the screen. Value is displayed in hex. 23 <1> ; Usage: 24 <1> ; MNUM bitpattern, valueLocation 25 <1> ; 26 <1> ; valueLocation is typically a regester: 27 <1> ; 28 <1> ; mnum fTestCom, AX 29 <1> ; mnum fTestDisk, DX 30 <1> ; 31 <1> ; ValueLocation can also be a memory location: 32 <1> ; 33 <1> ; mnum fTestINIT, Final_Dos_Location 34 <1> ; 35 <1> ; If no valueLocation is given the macro defaults to 36 <1> ; the BX register. 37 <1> ; 38 <1> ; ZWAIT Stops the program until any key is pressed. 39 <1> ; 40 <1> ; 41 <1> ; The three macros preserve all register values. If "test" is zero 42 <1> ; defined during assembly then the marco produce no code. 43 <1> ; 44 <1> 45 <1> %IF itest ;3.30 46 <1> EXTRN MSGOUT:NEAR,MSGNUM:NEAR ;3.30 47 <1> EXTRN NUMBUF:BYTE,DIGITS:BYTE,FTESTBITS:WORD ;3.30 48 <1> EXTRN DUMPBYTES:NEAR,OUTCHAR:NEAR,HEX_TO_ASCII:NEAR ;3.30 49 <1> 50 <1> 51 <1> fTestALL equ 1111111111111111b ; watch everything 52 <1> fTestHARD equ 0000000000000001b ; watch hard disk initialization 53 <1> fTest96 equ 0000000000000010b ; watch 96 tpi activity 54 <1> FTEST13 EQU 0000000000000100B ; WATCH INT 13 ACTIVITY ;3.30 55 <1> FTESTCOM EQU 0000000000001000B ; WATCH PACKET ACTIVITY ;3.30 56 <1> FTESTINIT EQU 0000000000010000B ; WATCH INITIALIZATION MESSAGES ;3.30 57 <1> FTESTDISK EQU 0000000000100000B ; WATCH DISK DEVICE DRIVER CALLS ;3.30 58 <1> FTESTCON EQU 0000000001000000B ; WATCH SYSTEM WAIT ACTIVITY IN CO;3.30 NSOLE 59 <1> FtestClock equ 0000000010000000b ; wathc clock device 5/2/86 ;3.30 60 <1> 61 <1> ; NASM original macros 62 <1> 63 <1> ; 64 <1> ; message macro -- see above for description 65 <1> ; 66 <1> 67 <1> %unimacro stripangles 2+.nolist 68 <1> 69 <1> %imacro stripangles 2+.nolist 70 <1> %defstr %%param %2 71 <1> %rep 16 72 <1> %substr %%opening %%param 1 73 <1> %ifidn %%opening, '<' 74 <1> %substr %%param %%param 2,-1 75 <1> %endif 76 <1> %endrep 77 <1> %rep 16 78 <1> %strlen %%length %%param 79 <1> %substr %%closing %%param %%length 80 <1> %ifidn %%closing, '>' 81 <1> %substr %%param %%param 1,-2 82 <1> %endif 83 <1> %endrep 84 <1> %deftok %%token %%param 85 <1> %1 %%token 86 <1> %endmacro 87 <1> 88 <1> %imacro MESSAGE 2+ 89 <1> jmp short %%b 90 <1> %%a: 91 <1> stripangles db, %2 92 <1> db 0 93 <1> %%b: push SI 94 <1> push AX 95 <1> mov AX, %1 96 <1> mov SI, OFFSET %%a 97 <1> call MSGOUT 98 <1> pop AX 99 <1> pop SI 100 <1> %endmacro 101 <1> 102 <1> 103 <1> ; 104 <1> ; mnum macro -- see above for description 105 <1> ; 106 <1> 107 <1> %imacro MNum 1-2 108 <1> push AX 109 <1> %ifempty %2 110 <1> mov AX,%1 111 <1> call MSGNUM 112 <1> %else 113 <1> push BX 114 <1> mov BX,%2 115 <1> mov AX,%1 116 <1> call MSGNUM 117 <1> pop BX 118 <1> %endif 119 <1> pop AX 120 <1> %endmacro 121 <1> 122 <1> 123 <1> ; 124 <1> ; zwait macro -- see above for description 125 <1> ; 126 <1> 127 <1> %imacro ZWAIT 0 128 <1> Message fTestALL,<"? "> 129 <1> CALL ZWAITrtn 130 <1> %endmacro 131 <1> 132 <1> ZWAITrtn: 133 <1> pushf ; save the flags 134 <1> push AX ; preserve AX 135 <1> xor AH, AH ; set command to get character ;3.30* 136 <1> int 16h ; call rom keyboard routine ;3.30* 137 <1> pop AX ; restore AX 138 <1> popf ; restore the flags 139 <1> ret 140 <1> 141 <1> ;Dump_byte dumps the memory contents in hex. ;3.30 142 <1> ;DUMPOFFLABEL should be a label or a variable defined in DUMPSEG. ;3.30 143 <1> %imacro DUMP_BYTE 3 144 <1> push es ;3.30 145 <1> PUSH DS ;3.30 146 <1> PUSH SI ;3.30 147 <1> PUSH CX ;3.30 148 <1> ;3.30 149 <1> MOV CX, %1 ;3.30 150 <1> MOV DS, CX ;3.30 151 <1> MOV SI, OFFSET %2 ;3.30 152 <1> MOV CX, %3 ;3.30 153 <1> call dumpbytes ;3.30 154 <1> ;3.30 155 <1> POP CX ;3.30 156 <1> POP SI ;3.30 157 <1> POP DS ;3.30 158 <1> pop es ;3.30 159 <1> %endmacro ;3.30 160 <1> ;3.30 161 <1> ;Dump_Byte_Reg dumps the memory contents in hex. - 4/9/86 ;3.30 162 <1> ;DUMPOFFREG should be a register contains the offset value in DUMPSEG. ;3.30 163 <1> %imacro DUMP_BYTE_REG 3 164 <1> DUMP_BYTE_REG MACRO DUMPSEG, DUMPOFFREG, BYTELENGTH ;3.30 165 <1> push es ;3.30 166 <1> PUSH DS ;3.30 167 <1> PUSH SI ;3.30 168 <1> PUSH CX ;3.30 169 <1> ;3.30 170 <1> MOV CX, %1 ;3.30 171 <1> MOV DS, CX ;3.30 172 <1> MOV SI, %2 ;3.30 173 <1> MOV CX, %3 ;3.30 174 <1> call dumpbytes ;3.30 175 <1> ;3.30 176 <1> POP CX ;3.30 177 <1> POP SI ;3.30 178 <1> POP DS ;3.30 179 <1> pop es ;3.30 180 <1> %endmacro ;3.30 181 <1> 182 <1> %else 183 <1> ; if test is not defined then make macro into null statements 184 <1> %imacro Message 0-1+.nolist 185 <1> %endmacro 186 <1> 187 <1> %imacro MNUM 0-1+.nolist 188 <1> %endmacro 189 <1> 190 <1> %imacro ZWAIT 0-1+.nolist 191 <1> %endmacro 192 <1> 193 <1> %imacro DUMP_BYTE 0-1+.nolist 194 <1> %endmacro 195 <1> 196 <1> %imacro DUMP_BYTE_REG 0-1+.nolist 197 <1> %endmacro 198 <1> 199 <1> %endif 200 <1> 201 <1> %unimacro PATHSTART 2 202 <1> %unimacro PATHEND 2 203 <1> 204 <1> %imacro PATHSTART 2 205 <1> %IF PATHGEN ;3.30 206 <1> PUBLIC %2%1S,%2%1E ;3.30 207 <1> %2%1S LABEL BYTE ;3.30 208 <1> %ENDIF ;3.30 209 <1> %endmacro ;3.30 210 <1> ;3.30 211 <1> %imacro PATHEND 2 212 <1> %IF PATHGEN ;3.30 213 <1> %2%1E LABEL BYTE ;3.30 214 <1> %ENDIF ;3.30 215 <1> %endmacro ;3.30 35 %include "devsym.mac" 1 <1> %warning out: DEVSYM.INC... 1 ****************** <1> warning: out: DEVSYM.INC... [-w+user] 2 <1> ; SCCSID = @(#)DEVSYM.ASM 1.10 85/09/04 3 <1> ; SCCSID = @(#)DEVSYM.ASM 1.10 85/09/04 4 <1> 5 <1> ; THE DEVICE TABLE LIST HAS THE FORM: 6 <1> SYSDEV STRUC 0 000080B0 ???????? SDEVNEXT DD ? ;POINTER TO NEXT DEVICE HEADER 0 000080B4 ???? SDEVATT DW ? ;ATTRIBUTES OF THE DEVICE 0 000080B6 ???? SDEVSTRAT DW ? ;STRATEGY ENTRY POINT 0 000080B8 ???? SDEVINT DW ? ;INTERRUPT ENTRY POINT 0 000080BA ???????????????? SDEVNAME DB 8 DUP (?) ;NAME OF DEVICE (ONLY FIRST BYTE USED FOR BLOCK) 12 <1> SYSDEV ENDS 13 <1> 14 <1> ; 15 <1> ; ATTRIBUTE BIT MASKS 16 <1> ; 17 <1> ; CHARACTER DEVICES: 18 <1> ; 19 <1> ; BIT 15 -> MUST BE 1 20 <1> ; 14 -> 1 IF THE DEVICE UNDERSTANDS IOCTL CONTROL STRINGS 21 <1> ; 13 -> 1 IF THE DEVICE SUPPORTS OUTPUT-UNTIL-BUSY 22 <1> ; 12 -> UNUSED 23 <1> ; 11 -> 1 IF THE DEVICE UNDERSTANDS OPEN/CLOSE 24 <1> ; 10 -> MUST BE 0 25 <1> ; 9 -> MUST BE 0 26 <1> ; 8 -> UNUSED 27 <1> ; 7 -> UNUSED 28 <1> ; 6 -> UNUSED 29 <1> ; 5 -> UNUSED 30 <1> ; 4 -> 1 IF DEVICE IS RECIPIENT OF INT 29H 31 <1> ; 3 -> 1 IF DEVICE IS CLOCK DEVICE 32 <1> ; 2 -> 1 IF DEVICE IS NULL DEVICE 33 <1> ; 1 -> 1 IF DEVICE IS CONSOLE OUTPUT 34 <1> ; 0 -> 1 IF DEVICE IS CONSOLE INPUT 35 <1> ; 36 <1> ; BLOCK DEVICES: 37 <1> ; 38 <1> ; BIT 15 -> MUST BE 0 39 <1> ; 14 -> 1 IF THE DEVICE UNDERSTANDS IOCTL CONTROL STRINGS 40 <1> ; 13 -> 1 IF THE DEVICE DETERMINES MEDIA BY EXAMINING THE FAT ID BYTE. 41 <1> ; THIS REQUIRES THE FIRST SECTOR OF THE FAT TO *ALWAYS* RESIDE IN 42 <1> ; THE SAME PLACE. 43 <1> ; 12 -> UNUSED 44 <1> ; 11 -> 1 IF THE DEVICE UNDERSTANDS OPEN/CLOSE/REMOVABLE MEDIA 45 <1> ; 10 -> MUST BE 0 46 <1> ; 9 -> MUST BE 0 47 <1> ; 8 -> UNUSED 48 <1> ; 7 -> UNUSED 49 <1> ; 6 -> IF DEVICE HAS SUPPORT FOR GETMAP/SETMAP OF LOGICAL DRIVES. 50 <1> ; IF THE DEVICE UNDERSTANDS GENERIC IOCTL FUNCTION CALLS. 51 <1> ; 5 -> UNUSED 52 <1> ; 4 -> UNUSED 53 <1> ; 3 -> UNUSED 54 <1> ; 2 -> UNUSED 55 <1> ; 1 -> UNUSED 56 <1> ; 0 -> UNUSED 57 <1> ; 58 <1> 59 <1> DEVTYP EQU 8000H ; BIT 15 - 1 IF CHAR, 0 IF BLOCK 60 <1> CHARDEV EQU 8000H 61 <1> DEVIOCTL EQU 4000H ; BIT 14 - CONTROL MODE BIT 62 <1> ISFATBYDEV EQU 2000H ; BIT 13 - DEVICE USES FAT ID BYTES, 63 <1> ; COMP MEDIA. 64 <1> OUTTILBUSY EQU 2000H ; OUTPUT UNTIL BUSY IS ENABLED 65 <1> ISNET EQU 1000H ; BIT 12 - 1 IF A NET DEVICE, 0 IF 66 <1> ; NOT. CURRENTLY BLOCK ONLY. 67 <1> DEVOPCL EQU 0800H ; BIT 11 - 1 IF THIS DEVICE HAS 68 <1> ; OPEN,CLOSE AND REMOVABLE MEDIA 69 <1> ; ENTRY POINTS, 0 IF NOT 70 <1> 71 <1> EXTENTBIT EQU 0400H ; BIT 10 - CURRENTLY 0 ON ALL DEVS 72 <1> ; THIS BIT IS RESERVED FOR FUTURE USE 73 <1> ; TO EXTEND THE DEVICE HEADER BEYOND 74 <1> ; ITS CURRENT FORM. 75 <1> 76 <1> ; NOTE BIT 9 IS CURRENTLY USED ON IBM SYSTEMS TO INDICATE "DRIVE IS SHARED". 77 <1> ; SEE IOCTL FUNCTION 9. THIS USE IS NOT DOCUMENTED, IT IS USED BY SOME 78 <1> ; OF THE UTILITIES WHICH ARE SUPPOSED TO FAIL ON SHARED DRIVES ON SERVER 79 <1> ; MACHINES (FORMAT,CHKDSK,RECOVER,..). 80 <1> 81 <1> DEV320 EQU 0040H ;BIT 6 - FOR BLOCK DEVICES, THIS 82 <1> ;DEVICE SUPPORTS SET/GET MAP OF 83 <1> ;LOGICAL DRIVES, AND SUPPORTS 84 <1> ;GENERIC IOCTL CALLS. 85 <1> ;FOR CHARACTER DEVICES, THIS 86 <1> ;DEVICE SUPPORTS GENERIC IOCTL. 87 <1> ;THIS IS A DOS 3.2 DEVICE DRIVER. 88 <1> ISSPEC EQU 0010H ;BIT 4 - THIS DEVICE IS SPECIAL 89 <1> ISCLOCK EQU 0008H ;BIT 3 - THIS DEVICE IS THE CLOCK DEVICE. 90 <1> ISNULL EQU 0004H ;BIT 2 - THIS DEVICE IS THE NULL DEVICE. 91 <1> ISCOUT EQU 0002H ;BIT 1 - THIS DEVICE IS THE CONSOLE OUTPUT. 92 <1> ISCIN EQU 0001H ;BIT 0 - THIS DEVICE IS THE CONSOLE INPUT. 93 <1> EXTDRVR EQU 0002H ;BIT 1 - BLOCK DEVICE EXTNDED DRIVER 94 <1> 95 <1> ;STATIC REQUEST HEADER 96 <1> SRHEAD STRUC 0 000080B0 ?? REQLEN DB ? ;LENGTH IN BYTES OF REQUEST BLOCK 0 000080B1 ?? REQUNIT DB ? ;DEVICE UNIT NUMBER 0 000080B2 ?? REQFUNC DB ? ;TYPE OF REQUEST 0 000080B3 ???? REQSTAT DW ? ;STATUS WORD 0 000080B5 ???????????????? DB 8 DUP(?) ;RESERVED FOR QUEUE LINKS 102 <1> SRHEAD ENDS 103 <1> 104 <1> ;STATUS WORD MASKS 105 <1> STERR EQU 8000H ;BIT 15 - ERROR 106 <1> STBUI EQU 0200H ;BIT 9 - BUISY 107 <1> STDON EQU 0100H ;BIT 8 - DONE 108 <1> STECODE EQU 00FFH ;ERROR CODE 109 <1> ; 2/12/KK 110 <1> ; Interim character identifier 2/12/KK 111 <1> Ddkey EQU 0000010000000000B ; 2/12/KK 112 <1> 113 <1> ;FUNCTION CODES 114 <1> DEVINIT EQU 0 ;INITIALIZATION 115 <1> DINITHL EQU 26 ;SIZE OF INIT HEADER 116 <1> DEVMDCH EQU 1 ;MEDIA CHECK 117 <1> DMEDHL EQU 15 ;SIZE OF MEDIA CHECK HEADER 118 <1> DEVBPB EQU 2 ;GET BPB 119 <1> DEVRDIOCTL EQU 3 ;IOCTL READ 120 <1> DBPBHL EQU 22 ;SIZE OF GET BPB HEADER 121 <1> DEVRD EQU 4 ;READ 122 <1> DRDWRHL EQU 22 ;SIZE OF RD/WR HEADER 123 <1> DEVRDND EQU 5 ;NON DESTRUCTIVE READ NO WAIT (CHARACTER DEVS) 124 <1> DRDNDHL EQU 14 ;SIZE OF NON DESTRUCTIVE READ HEADER 125 <1> DEVIST EQU 6 ;INPUT STATUS 126 <1> DSTATHL EQU 13 ;SIZE OF STATUS HEADER 127 <1> DEVIFL EQU 7 ;INPUT FLUSH 128 <1> DFLSHL EQU 15 ;SIZE OF FLUSH HEADER 129 <1> DEVWRT EQU 8 ;WRITE 130 <1> DEVWRTV EQU 9 ;WRITE WITH VERIFY 131 <1> DEVOST EQU 10 ;OUTPUT STATUS 132 <1> DEVOFL EQU 11 ;OUTPUT FLUSH 133 <1> DEVWRIOCTL EQU 12 ;IOCTL WRITE 134 <1> DEVOPN EQU 13 ;DEVICE OPEN 135 <1> DEVCLS EQU 14 ;DEVICE CLOSE 136 <1> DOPCLHL EQU 13 ;SIZE OF OPEN/CLOSE HEADER 137 <1> DEVRMD EQU 15 ;REMOVABLE MEDIA 138 <1> REMHL EQU 13 ;SIZE OF REMOVABLE MEDIA HEADER 139 <1> GENIOCTL EQU 19 140 <1> ; THE NEXT THREE ARE USED IN DOS 4.0 141 <1> ; 20 142 <1> ; 21 143 <1> ; 22 144 <1> DEVGETOWN EQU 23 ;GET DEVICE OWNER 145 <1> DEVSETOWN EQU 24 ;SET DEVICE OWNER 146 <1> OWNHL EQU 13 ;SIZE OF DEVICE OWNER HEADER 147 <1> 148 <1> DEVOUT EQU 16 ; OUTPUT UNTIL BUSY. 149 <1> DEVOUTL EQU DEVWRT ; LENGTH OF OUTPUT UNTIL BUSY 150 <1> 151 <1> ; GENERIC IOCTL REQUEST STRUCTURE 152 <1> ; SEE THE DOS 4.0 DEVICE DRIVER SPEC FOR FURTHER ELABORATION. 153 <1> ; 154 <1> IOCTL_REQ STRUC 155 00000000 <1> DB (SRHEAD_struc_size) DUP(?) 156 <1> ; GENERIC IOCTL ADDITION. 0 000080BD ?? MAJORFUNCTION DB ? ;FUNCTION CODE 0 000080BE ?? MINORFUNCTION DB ? ;FUNCTION CATEGORY 0 000080BF ???? REG_SI DW ? 0 000080C1 ???? REG_DI DW ? 0 000080C3 ???????? GENERICIOCTL_PACKET DD ? ; POINTER TO DATA BUFFER 162 <1> IOCTL_REQ ENDS 163 <1> 164 <1> ; DEFINITIONS FOR IOCTL_REQ.MINORFUNCTION 165 <1> GEN_IOCTL_WRT_TRK EQU 40H 166 <1> GEN_IOCTL_RD_TRK EQU 60H 167 <1> GEN_IOCTL_FN_TST EQU 20H ; USED TO DIFF. BET READS AND WRTS 168 <1> 169 <1> ;; 32-bit absolute read/write input list structure 170 <1> 171 <1> ABS_32RW STRUC 0 000080B0 ???????? SECTOR_RBA DD ? ; relative block address 0 000080B4 ???? ABS_RW_COUNT DW ? ; number of sectors to be transferred 0 000080B6 ???????? BUFFER_ADDR DD ? ; data addrress 175 <1> ABS_32RW ENDS 176 <1> 177 <1> ;; media ID info 178 <1> 179 <1> MEDIA_ID_INFO STRUC 0 000080B0 ???? MEDIA_level DW ? ; info level 0 000080B2 ???????? MEDIA_Serial DD ? ; serial # 182 00000006 <1> MEDIA_Label DB 11 dup (?) ;volume label 0 000080C1 ???????????????? MEDIA_System DB 8 dup (?) ;system type 184 <1> MEDIA_ID_INFO ENDS 185 <1> 186 <1> ;; equates for DOS34_FLAG 187 <1> 188 <1> IFS_ABSRW EQU 00001H ;IFS absolute read/write 189 <1> NO_IFS_ABSRW EQU 0FFFEH ;no IFS absolute read/write 190 <1> IFS_DRIVE_RESET EQU 00002H ;IFS drvive reset 191 <1> NO_IFS_DRIVE_RESET EQU 0FFFDH ;no IFS drive reset 192 <1> FROM_DISK_RESET EQU 00004H ;from disk reset 193 <1> NO_FROM_DISK_RESET EQU 0FFFBH ;not from disk reset 194 <1> From_String_Output EQU 00008H ;from con string output 195 <1> NO_From_String_Output EQU 0FFF7H ;not from con string output 196 <1> From_DOS_WRITE EQU 00010H ;from dos_write 197 <1> NO_From_DOS_WRITE EQU 0FFEFH ;not from dos_write 198 <1> Force_I24_Fail EQU 00020H ;form IFS CALL BACK 199 <1> NO_Force_I24_Fail EQU 0FFDFH ;not form IFS CALL BACK 200 <1> Disable_EOF_I24 EQU 00040H ;disable EOF int24 for input status 201 <1> NO_Disable_EOF_I24 EQU 0FFBFH ;disable EOF int24 for input status 202 <1> DBCS_VOLID EQU 00080H ;indicate from volume id 203 <1> DBCS_VOLID2 EQU 00100H ;indicate 8th char is DBCS 204 <1> CTRL_BREAK_FLAG EQU 00200H ;indicate control break is input 205 <1> NO_CTRL_BREAK_FLAG EQU 0FDFFH ;reset control break 206 <1> SEARCH_FASTOPEN EQU 00400H ;set fastopen flag for search 207 <1> X25_special EQU 00800H ;flag for X25 driver 36 %include "msdskpr.mac" 1 <1> ; The following structure defines the disk parameter table 2 <1> ; pointed to by Interrupt vector 1EH (location 0:78H) 3 <1> 4 <1> DISK_PARMS STRUC 0 000080B0 ?? DISK_SPECIFY_1 DB ? 0 000080B1 ?? DISK_SPECIFY_2 DB ? 0 000080B2 ?? DISK_MOTOR_WAIT DB ? ; Wait till motor off 0 000080B3 ?? DISK_SECTOR_SIZ DB ? ; Bytes/Sector (2 = 512) 0 000080B4 ?? DISK_EOT DB ? ; Sectors per track (MAX) 0 000080B5 ?? DISK_RW_GAP DB ? ; Read Write Gap 0 000080B6 ?? DISK_DTL DB ? 0 000080B7 ?? DISK_FORMT_GAP DB ? ; Format Gap Length 0 000080B8 ?? DISK_FILL DB ? ; Format Fill Byte 0 000080B9 ?? DISK_HEAD_STTL DB ? ; Head Settle Time (MSec) 0 000080BA ?? DISK_MOTOR_STRT DB ? ; Motor start delay 16 <1> DISK_PARMS ENDS 17 <1> 18 <1> ROMStatus equ 1 19 <1> ROMRead equ 2 20 <1> ROMWrite equ 3 21 <1> ROMVerify equ 4 22 <1> ROMFormat equ 5 37 %include "biostruc.mac" 1 <1> %warning out: BIOSTRUC.INC... 1 ****************** <1> warning: out: BIOSTRUC.INC... [-w+user] 2 <1> ; SCCSID = @(#)BIOSTRUC.INC 1.0 86/09/30 3 <1> ; ROM BIOS CALL PACKET STRUCTURES 4 <1> 5 <1> ;******************************* 6 <1> ;System Service call ( Int 15h ) 7 <1> ;******************************* 8 <1> ;Function AH = 0C0h, Return system configuration 9 <1> ;For PC and PCJR on return: 10 <1> ; (AH) = 80h 11 <1> ; (CY) = 1 12 <1> ;For PCXT, PC PORTABLE and PCAT on return: 13 <1> ; (AH) = 86h 14 <1> ; (CY) = 1 15 <1> ;For all others: 16 <1> ; (AH) = 0 17 <1> ; (CY) = 0 18 <1> ; (ES:BX) = pointer to system descriptor vector in ROS 19 <1> ; System descriptor : 20 <1> ; DW xxxx length of descriptor in bytes, 21 <1> ; minimum length = 8 22 <1> ; DB xx model byte 23 <1> ; 0FFh = PC 24 <1> ; 0FEh = PC/XT, Portable 25 <1> ; 0FDh = PC/JR 26 <1> ; 0FCh = PC/AT, 6Mhz PC/AT, 27 <1> ; 6Mhz PC/AT running coprocessor(?), 28 <1> ; PS/2 Model 50, 50 z 29 <1> ; 0FAh = PS/2 Model 25, 30 30 <1> ; 0F9h = PC Convertible 31 <1> ; 0F8h = PS/2 Model 80 32 <1> ; 0F7h = Nova 33 <1> ; 0E0 thru 0EFh = reserved 34 <1> ; 35 <1> ; DB xx secondary model byte 36 <1> ; 000h = PC1 37 <1> ; 000h = PC/XT, Portable 38 <1> ; 000h = PC/JR 39 <1> ; 000h = PC/AT 40 <1> ; 001h = 6Mhz PC/AT 41 <1> ; 003h = 6Mhz PC/AT running coprocessor(?) 42 <1> ; 004h = PS/2 Model 50, 50z 43 <1> ; 001h = PS/2 Model 25 44 <1> ; 000h = PC Convertible 45 <1> ; 000h = PS/2 Model 80 46 <1> ; 000h = Nova 47 <1> ; 48 <1> ; DB xx bios revision level 49 <1> ; 00 for first release, subsequent release 50 <1> ; of code with same model byte and 51 <1> ; secondary model byte require revison level 52 <1> ; to increase by one. 53 <1> ; 54 <1> ; DB xx feature information byte 1 55 <1> ; X0000000 = 1, bios use DMA channel 3 56 <1> ; = 0, DMA channel 3 not used 57 <1> ; 58 <1> ; 0X000000 = 1, 2nd Interrupt chip present 59 <1> ; = 0, 2nd Interrupt chip not present 60 <1> ; 61 <1> ; 00X00000 = 1, Real Time Clock present 62 <1> ; = 0, Real Time Clock not present 63 <1> ; 64 <1> ; 000X0000 = 1, Keyboard escape sequence(INT15h) 65 <1> ; called in keyboard interrupt 66 <1> ; (Int 09h). 67 <1> ; = 0, Keyboard escape sequence not 68 <1> ; called. 69 <1> ; 0000XXXX reserved 70 <1> ; 71 <1> ; DB xx feature information byte 2 - reserved 72 <1> ; 73 <1> ; DB xx feature information byte 2 - reserved 74 <1> ; 75 <1> ; DB xx feature information byte 2 - reserved 76 <1> ; 77 <1> ; DB xx feature information byte 2 - reserved 78 <1> ; 79 <1> 80 <1> BIOS_SYSTEM_DESCRIPTOR struc 0 000080B0 ???? bios_SD_leng dw ? 0 000080B2 ?? bios_SD_modelbyte db ? 0 000080B3 ?? bios_SD_scnd_modelbyte db ? 0 000080B4 ?? db ? 0 000080B5 ?? bios_SD_featurebyte1 db ? 0 000080B6 ???????? db 4 dup (?) 87 <1> BIOS_SYSTEM_DESCRIPTOR ends 88 <1> 89 <1> ;FeatureByte1 bit map equates 90 <1> DMAchannel3 equ 10000000b 91 <1> ScndIntController equ 01000000b 92 <1> RealTimeClock equ 00100000b 93 <1> KeyEscapeSeq equ 00010000b 94 <1> ; 95 <1> ;Model Byte 96 <1> MDL_PC1 EQU 0FFH 97 <1> MDL_XT EQU 0FEH 98 <1> MDL_JR EQU 0FDH 99 <1> MDL_AT EQU 0FCH 100 <1> MDL_CONVERT EQU 0F9H 101 <1> 102 <1> mdl_ps2_30 equ 0fah 103 <1> mdl_ps2_80 equ 0f8h 38 %include "entryseg.nas" 1 <1> === Switch to base=000000h -> "DOSENTRY" 2 <1> section DOSENTRY class=%[DOSENTRY] === Switch to base=000000h -> "DOSENTRY" 3 <1> section DOSENTRY 39 %include "lmacros2.mac" 1 <1> [list -] 1 ****************** <1> warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi] 14 <1> [list -] 40 41 extern biocode_get_ds_dosentry, biocode_get_es_dosentry 42 43 EXTRN INT2F_DISK:FAR ;MSBIO2 44 EXTRN MEDIACHECK:NEAR ;96TPI 45 EXTRN HASCHANGE:NEAR ;96TPI 46 EXTRN MEDIA_SET_VID:NEAR ;96TPI 47 EXTRN HIDENSITY:NEAR ;96TPI 48 EXTRN CHECKLATCHIO:NEAR ;96TPI 49 EXTRN CHECKIO:NEAR ;96TPI 50 EXTRN SET_CHANGED_DL:NEAR ;96TPI 51 EXTRN SET_VOLUME_ID:NEAR ;MSVOLID 52 EXTRN SWPDSK:NEAR ;MSBIO2 53 EXTRN CMDERR:NEAR ;MSBIO1 54 EXTRN STRATEGY:NEAR ;MSBIO1 55 EXTRN ERR$CNT:NEAR ;MSBIO1 56 EXTRN DSK$IN:NEAR ;MSBIO1 57 EXTRN EXIT:NEAR ;MSBIO1 58 EXTRN BUS$EXIT:NEAR ;MSBIO1 59 EXTRN ERR$EXIT:NEAR ;MSBIO1 60 extrn ResetChanged:near ;AN000; MS96TPI 61 62 ;DATA 63 EXTRN OLD13:DWORD ;MSBIO2 64 EXTRN PTRSAV:DWORD ;MSBIO1 65 EXTRN COM1DEV:WORD ;MSAUX 66 EXTRN DAYCNT:WORD ;MSCLOCK 67 EXTRN TIM_DRV:BYTE ;MSDATA 68 EXTRN ACCESSCOUNT:BYTE ;MSDATA 69 EXTRN SM92:BYTE ;MSDATA 70 EXTRN DISKSECTOR:BYTE ;MSDATA 71 EXTRN MEDIABYTE:BYTE ;MSDATA 72 EXTRN SECPERCLUSINSECTOR:BYTE ;MSDATA 73 EXTRN BPB_IN_SECTOR:WORD ;MSDATA 74 EXTRN DISKSECTOR:BYTE ;MSDATA 75 EXTRN STEP_DRV:BYTE ;MSDATA 76 EXTRN START_BDS:WORD ;MSDATA 77 EXTRN PHYS_DRV:BYTE ;MSDATA 78 EXTRN WRTVERIFY:WORD ;MSDATA 79 EXTRN FSETOWNER:BYTE ;MSDATA 80 EXTRN SINGLE:BYTE ;MSDATA 81 EXTRN RFLAG:BYTE ;MSDATA 82 EXTRN MEDBYT:BYTE ;MSDATA 83 EXTRN SPSAV:WORD ;MSDATA 84 EXTRN SECCNT:WORD ;MSDATA 85 EXTRN DPT:DWORD ;MSDATA 86 EXTRN CURSEC:BYTE,CURHD:BYTE ;MSDATA 87 EXTRN CURTRK:WORD ;MSDATA 88 EXTRN EOT:BYTE ;MSDATA 89 EXTRN MOTORSTARTUP:BYTE,SETTLECURRENT:BYTE,SETTLESLOW:BYTE ;MSDATA 90 EXTRN CURHD:BYTE ;MSDATA 91 EXTRN LSTERR:BYTE ;MSDATA 92 EXTRN ERRIN:BYTE,ERROUT:BYTE ;MSDATA 93 EXTRN PREVOPER:WORD ;MSDATA 94 EXTRN ORIG13:DWORD ;MSDATA 95 EXTRN FLAGBITS:WORD ;MSDATA 96 EXTRN NUMBER_OF_SEC:BYTE ;MSDATA 97 EXTRN FHAVE96:BYTE ;MSDATA 98 EXTRN NEW_ROM:BYTE ;MSDATA 99 EXTRN FORMT_EOT:BYTE,HDNUM:BYTE,TRKNUM:WORD,GAP_PATCH:BYTE ;MSDATA 100 EXTRN NEXT2F_13:WORD ;MSDATA 101 extrn Save_head_sttl:byte ;msbdata 102 extrn Secrete_Code:word ;msbdata J.K. 11/7/86 Secrete code for DOS 3.3 MSBIO 103 extrn Ext_Boot_Sig:byte ;AN000; msbdata 104 extrn Boot_Serial_L:word ;AN000; msbdata 105 extrn Boot_Serial_H:word ;AN000; msbdata 106 extrn Boot_Volume_Label:byte ;AN000; msbdata 107 extrn Boot_System_ID:byte ;AN000; msbdata 108 extrn Model_Byte:Byte ;MSBIO2 109 extrn Secondary_Model_Byte:Byte ;MSBIO2 110 111 ;----------------------------------------------------------------- 112 ; 113 ; DISK INTERFACE ROUTINES 114 ; 115 ; DEVICE ATTRIBUTE BITS: 116 ; BIT 6 - GET/SET MAP FOR LOGICAL DRIVES AND GENERIC IOCTL. 117 ; 118 119 MAXERR equ 5 120 LSTDRV equ 504H 121 122 ; SOME FLOPPIES DO NOT HAVE CHANGELINE. AS A RESULT, MEDIA-CHECK WOULD 123 ; NORMALLY RETURN I-DON'T-KNOW, THE DOS WOULD CONTINUALLY REREAD THE FAT, AND 124 ; DISCARD CACHED DATA. WE OPTIMIZE THIS BY IMPLEMENTING A LOGICAL DOOR- 125 ; LATCH: IT IS PHYSICALLY IMPOSSIBLE TO CHANGE A DISK IN UNDER 2 SECONDS. WE 126 ; RETAIN THE TIME OF THE LAST SUCCESSFUL DISK OPERATION AND COMPARE IT WITH 127 ; THE CURRENT TIME DURING MEDIA-CHECK. IF < 2 SECONDS AND AT LEAST 1 TIMER 128 ; TICK HAS PASSED, THE WE SAY NO CHANGE. IF > 2 SECONDS THEN WE SAY I- 129 ; DON'T-KNOW. FINALLY, SINCE WE CANNOT TRUST THE TIMER TO BE ALWAYS 130 ; AVAILABLE, WE RECORD THE NUMBER OF MEDIA CHECKS THAT HAVE OCCURRED WHEN NO 131 ; APPARENT TIME HAS ELAPSED. WHILE THIS NUMBER IS < A GIVEN THRESHOLD, WE SAY 132 ; NO CHANGE. WHEN IT EXCEEDS THAT THRESHOLD, WE SAY I-DON'T-KNOW AND RESET 133 ; THE COUNTER TO 0. WHEN WE STORE THE TIME OF LAST SUCCESSFUL ACCESS, IF WE 134 ; SEE THAT TIME HAS PASSED TOO, WE RESET THE COUNTER. 135 ; 136 ACCESSMAX equ 5 137 ; 138 ; DUE TO VARIOUS BOGOSITIES, WE NEED TO CONTINUALLY ADJUST WHAT THE HEAD 139 ; SETTLE TIME IS. THE FOLLOWING ALGORITHM IS USED: 140 ; 141 ; GET THE CURRENT HEAD SETTLE VALUE. 142 ; IF IT IS 0, THEN 143 ; SET SLOW = 15 144 ; ELSE 145 ; SET SLOW = VALUE 146 ; ... 147 ;********************************************* 148 ;************ OLD ALGORITHM ****************** 149 ;* IF WE ARE SEEKING AND WRITING THEN 150 ;* USE SLOW 151 ;* ELSE 152 ;* USE FAST 153 ;********************************************* 154 ;*********** IBM'S REQUESTED LOGIC *********** 155 ; IF WE ARE SEEKING AND WRITING AND NOT ON AN AT THEN 156 ; USE SLOW 157 ; ELSE 158 ; USE FAST 159 ; ... 160 ; RESTORE CURRENT HEAD SETTLE VALUE 161 ; 162 163 === Switch to base=008400h -> "BIOCODE" 164 section BIOCODE 165 166 public Fat_12_ID 0 000080B0 464154313220202000 Fat_12_ID DB "FAT12 ",0 ;AN000; Default System ID for floppy. 168 public Fat_16_ID 0 000080B9 464154313620202000 Fat_16_ID DB "FAT16 ",0 ;AN000; 170 public Vol_No_Name 0 000080C2 4E4F204E414D452020 Vol_No_Name db "NO NAME ",0 ;AN000; 0 000080CB 202000 172 173 === Switch to base=000000h -> "DOSENTRY" 174 section DOSENTRY 175 176 MULTRK_ON EQU 10000000B ;User spcified Mutitrack=on, or System turns 177 ; it on after handling CONFIG.SYS file as a 178 ; default value, if MulTrk_flag = MULTRK_OFF1. 179 MULTRK_OFF1 EQU 00000000B ;initial value. No "Multitrack=" command entered. 180 MULTRK_OFF2 EQU 00000001B ;User specified Multitrack=off. 181 182 extern Set_ID_Flag, Saved_Word 183 extern VRetry_Cnt, Soft_ECC_Cnt, MultiTrk_Format_Flag 184 185 extern lbapacket 186 extern Temp_H 187 extern Start_Sec_H 188 extern MulTrk_Flag 189 extern EC35_Flag 190 191 === Switch to base=008400h -> "BIOCODE" 192 section BIOCODE 193 194 PUBLIC MEDIA$CHK 195 MEDIA$CHK PROC NEAR 196 MESSAGE FTESTDISK,<"DISK MEDIA CHECK "> 197 MNUM FTESTDISK,AX 198 MESSAGE FTESTDISK, 0 000080CE E8C703 CALL SETDRIVE 200 0 000080D1 1E push ds 0 000080D2 E8[0000] call biocode_get_ds_dosentry 0 000080D5 813E[0000]6B6A cmp word [Secrete_Code], 'kj' ;J.K.11/7/86 Secrete code for DOS 3.3 IBMBIO. ; NASM port swapped text literals 0 000080DB 1F pop ds 205 media$done equ MEDIA$DONE ; NASM port label 0 000080DC 7553 jne media$done ;J.K.11/7/86 207 208 ; FOR NON-REMOVABLE DISKS ONLY RETURN CHANGED IF CHANGED BY FORMAT, OTHERWISE 209 ; RETURN 'NOT CHANGED'. 0 000080DE BE0100 MOV SI,1 ; ASSUME NO CHANGE 0 000080E1 F745230001 TEST WORD PTR [DI + FLAGS],FCHANGED_BY_FORMAT 0 000080E6 741B JZ WEARENOTFAKINGIT 0 000080E8 816523FFFE AND WORD PTR [DI + FLAGS],~ FCHANGED_BY_FORMAT ; RESET FLAG 214 ; IF MEDIA HAS BEEN CHANGED BY FORMAT, WE MUST ASK THE ROM. CANNOT RELY ON THE 215 ; 2 SECOND TIME CHECK. 0 000080ED 1E push ds 0 000080EE E8[0000] call biocode_get_ds_dosentry 0 000080F1 C606[0000]FF MOV byte [TIM_DRV],-1 ; ENSURE THAT WE ASK THE ROM IF MEDIA 219 ; HAS CHANGED 0 000080F6 1F pop ds 0 000080F7 F745230100 TEST WORD PTR [DI + FLAGS],FNON_REMOVABLE 0 000080FC 740C JZ WEHAVEAFLOPPY 0 000080FE BEFFFF MOV SI,-1 ; INDICATE MEDIA CHANGED 0 00008101 EB2E JMP SHORT MEDIA$DONE 225 ; 226 ; WE NEED TO RETURN 'NOT CHANGED' IF WE HAVE A HARD FILE. 227 ; 228 WEARENOTFAKINGIT: 0 00008103 F745230100 TEST WORD PTR [DI + FLAGS],FNON_REMOVABLE 0 00008108 7527 JNZ MEDIA$DONE 231 WEHAVEAFLOPPY: 0 0000810A 31F6 XOR SI,SI ; PRESUME "I DON'T KNOW" 233 ; 234 ; IF WE HAVE A FLOPPY WITH CHANGELINE SUPPORT, WE ASK THE ROM TO DETERMINE IF 235 ; MEDIA HAS CHANGED. WE DO NOT PERFORM THE 2 SECOND CHECK FOR THESE DRIVES. 236 ;----------------------------------------| 237 ; WARNING: DO NOT CHANGE THE FOLLOWING. ;| 238 ; IT GETS PATCHED IN MSINIT ;| 0 0000810C E83813 call ispatched 0 0000810F 720A jc @F 241 PUBLIC MEDIA_PATCH ;| 242 MEDIA_PATCH: ;| 0 00008111 E8[0000] CALL MEDIACHECK ;| 0 00008114 7241 JC ERR$EXITJ ;| 0 00008116 E8[0000] CALL HASCHANGE ;| 0 00008119 7516 JNZ MEDIA$DONE ;| 247 @@: 248 ;----------------------------------------| 249 ; IF WE COME HERE, WE HAVE A FLOPPY WITH NO CHANGELINE SUPPORT 0 0000811B BE0100 MOV SI,1 ; PRESUME NO CHANGE 0 0000811E 1E push ds 0 0000811F E8[0000] call biocode_get_ds_dosentry 0 00008122 A0[0000] MOV AL,[TIM_DRV] ; LAST DRIVE ACCESSED 0 00008125 1F pop ds 0 00008126 3A4504 CMP AL,BYTE PTR [DI + DRIVENUM] ;IS DRIVE OF LAST ACCESS THE SAME? 0 00008129 7505 JNZ MEDIA$UNK ; NO, THEN "I DON'T KNOW" 257 ; 258 ; CHECK TO SEE IF THIS DRIVE HAS BEEN ACCESSED IN THE LAST 2 SECONDS. 0 0000812B E82F00 CALL CHECK_TIME_OF_ACCESS ; SETS SI CORRECTLY 0 0000812E EB01 JMP SHORT MEDIA$DONE 261 262 MEDIA$UNK: 0 00008130 4E DEC SI ; RETURN "I DON'T KNOW" 264 ; 265 ; SI NOW CONTAINS THE CORRECT VALUE FOR MEDIA CHANGE. CLEAN UP THE LEFT OVERS 266 ; 267 MEDIA$DONE: 0 00008131 E8[0000] call biocode_get_es_dosentry 0 00008134 26C41E[0000] LES BX,[es:PTRSAV] ; GET ORIGINAL PACKET 0 00008139 2689770E MOV WORD PTR [ES:BX + TRANS],SI 0 0000813D 85F6 test SI,SI 0 0000813F 7803 JS INIT_PATCH_before 0 00008141 E9[0000] JMP EXIT 274 MEDIA$CHK ENDP 275 ;----------------------------------------| 276 ; WARNING: DO NOT CHANGE THE FOLLOWING. ;| 277 ; IT GETS PATCHED IN MSINIT ;| 278 INIT_PATCH_before: 0 00008144 E80013 call ispatched 0 00008147 7203 jc @F 281 PUBLIC INIT_PATCH ;| 282 INIT_PATCH PROC NEAR ;| 0 00008149 E8[0000] CALL MEDIA_SET_VID ;| 284 @@: 285 ;----------------------------------------| 0 0000814C E8[0000] call biocode_get_ds_dosentry 0 0000814F C606[0000]FF MOV byte [TIM_DRV], -1 ; MAKE SURE WE ASK ROM FOR MEDIA CHECK 288 VOLIDOK: 0 00008154 E9[0000] JMP EXIT 290 INIT_PATCH ENDP 291 292 ERR$EXITJ PROC NEAR 293 294 MESSAGE FTESTCOM,<"ERR$EXITJ: "> 295 MNUM FTESTCOM,AX 296 MESSAGE FTESTCOM,<" == "> 0 00008157 E86E08 CALL MAPERROR 298 MNUM FTESTCOM,AX 299 MESSAGE FTESTCOM, 0 0000815A E9[0000] JMP ERR$EXIT 301 ERR$EXITJ ENDP 302 303 ; 304 ; PERFORM A CHECK ON THE TIME PASSED SINCE THE LAST ACCESS FOR THIS PHYSICEL 305 ; DRIVE. 306 ; WE ARE ACCESSING THE SAME DRIVE. IF THE TIME OF LAST SUCCESSFUL ACCESS WAS 307 ; LESS THAN 2 SECONDS AGO, THEN WE MAY PRESUME THAT THE DISK WAS NOT CHANGED. 308 ; RETURNS IN SI: 309 ; 0 - IF TIME OF LAST ACCESS WAS >= 2 SECONDS 310 ; 1 - IF TIME WAS < 2 SECONDS (I.E NO MEDIA CHANGE ASSUMED) 311 ; REGISTERS AFFECTED AX,CX,DX, FLAGS. 312 ; 313 CHECK_TIME_OF_ACCESS PROC NEAR 314 PUBLIC CHECK_TIME_OF_ACCESS 315 0 0000815D BE0100 MOV SI,1 ; PRESUME NO CHANGE. 317 ;SB33014************************************************************* 0 00008160 30E4 xor AH,AH ; set command to read time 0 00008162 CD1A int 1Ah ; call rom-bios clock routine 320 ;SB33014************************************************************* 321 ; 322 ; NOW THAT WE ARE READING THE TIME, WE MUST MAKE SURE THAT WE DO NOT LOSE A 323 ; DATE WRAP. THE ROM WILL RETURN THE VALUE ONLY ONCE, SO WE NEED TO NOTE THIS 324 ; FACT. 325 ; 0 00008164 06 push es 0 00008165 E8[0000] call biocode_get_es_dosentry 0 00008168 D0E8 SHR AL,1 0 0000816A 268316[0000]00 ADC word [es:DAYCNT],0 ; ADD IT IN TO OUR REMEMBERED DAY COUNT 330 ; 331 ; COMPUTE ELAPSED TIME 332 ; 0 00008170 8B4547 MOV AX,WORD PTR [DI + TIM_LO] ; GET STORED TIME 0 00008173 29C2 SUB DX,AX 0 00008175 8B4549 MOV AX,WORD PTR [DI + TIM_HI] 0 00008178 19C1 SBB CX,AX 337 ; 338 ; CX:DX IS THE ELAPSED TIME 339 ; 0 0000817A 751D JNZ TIMECHECK_UNK ; CX <> 0 => > 1 HOUR 0 0000817C 85D2 test DX,DX ; TIME MUST PASS 0 0000817E 7514 JNZ TIMEPASSED ; YES, EXAMINE MAX VALUE 343 ; 344 ; NO NOTICEABLE TIME HAS PASSED. WE CANNOT TRUST THE COUNTER TO BE ALWAYS 345 ; AVAILABLE AS THERE ARE BOGUS PROGRAMS THAT GO AND REPROGRAM THE THING. WE 346 ; KEEP A COUNT OF THE NUMBER OF MEDIA CHECKS THAT WE'VE SEEN THAT DO NOT HAVE 347 ; ANY TIME PASSING. IF WE EXCEED A GIVE THRESHOLD, WE GIVE UP ON THE TIMER. 348 ; 0 00008180 26FE06[0000] INC BYTE [es:ACCESSCOUNT] 0 00008185 26803E[0000]05 CMP BYTE [es:ACCESSCOUNT],ACCESSMAX 0 0000818B 720D JB TIMECHECK_RET ; IF COUNT IS LESS THAN THRESHOLD, OK 0 0000818D 26FE0E[0000] DEC BYTE [es:ACCESSCOUNT] ; DON'T LET THE COUNT WRAP 0 00008192 EB05 JMP SHORT TIMECHECK_UNK ; "I DON'T KNOW" IF MEDIA CHANGED 354 ; 355 ; 18.2 TICS PER SECOND. 356 ; 357 TIMEPASSED: 0 00008194 83FA24 CMP DX,18 * 2 ; MIN ELAPSED TIME? 0 00008197 7601 JBE TIMECHECK_RET ; YES, PRESUME NO CHANGE 360 ; 361 ; EVERYTHING INDICATES THAT WE DO NOT KNOW WHAT HAS HAPPENED. 362 ; 363 TIMECHECK_UNK: 0 00008199 4E DEC SI ; PRESUME I DON'T KNOW 365 TIMECHECK_RET: 0 0000819A 07 pop es 0 0000819B C3 RET 368 CHECK_TIME_OF_ACCESS ENDP 369 0 0000819C EBB9 ERR$EXITJ2: JMP ERR$EXITJ 371 ; 372 ; BUILD A VALID BPB FOR THE DISK IN THE DRIVE. 373 ; 374 PUBLIC GET$BPB 375 GET$BPB PROC NEAR 376 MESSAGE FTESTDISK,<"DISK BUILD BPB "> 377 MNUM FTESTDISK,AX 378 MESSAGE FTESTDISK, 0 0000819E 268A25 MOV AH,BYTE PTR [ES:DI] ;GET FAT ID BYTE READ BY DOS 0 000081A1 E8F402 CALL SETDRIVE ; GET THE CORRECT BDS FOR THE DRIVE 0 000081A4 F745230100 TEST WORD PTR [DI + FLAGS],FNON_REMOVABLE 0 000081A9 752B JNZ ALREADY_GOTBPB ; NO NEED TO BUILD FOR FIXED DISKS 383 ;J.K. Let's set the default value for VOLID,Vol_Serial,FileSys_ID in BDS table 0 000081AB E84200 call Clear_IDs ;AN000; 0 000081AE 1E push ds 0 000081AF E8[0000] call biocode_get_ds_dosentry 0 000081B2 C606[0000]01 mov byte [Set_ID_Flag],1 ;AN000; Indicate to set system id in BDS 0 000081B7 1F pop ds 0 000081B8 E86E00 CALL GETBP ;BUILD A BPB IF NECESSARY. 0 000081BB 72DF JC ERR$EXITJ2 ;AN000; If error, Set_ID_flag is set to 0 already. 0 000081BD 1E push ds 0 000081BE E8[0000] call biocode_get_ds_dosentry 0 000081C1 803E[0000]02 cmp byte [Set_ID_Flag],2 ;AN000; Already, volume_Label set from Boot record 0 000081C6 C606[0000]00 mov byte [Set_ID_Flag],0 ;AN000; to BDS table? 0 000081CB 1F pop ds 396 Already_GotBPB equ ALREADY_GOTBPB ; NASM port label 0 000081CC 7408 je Already_GotBPB ;AN000; Then do not set it again from Root directory. 398 ;AN000; Otherwise, conventional Boot record. 399 GET$BPB ENDP 400 ;----------------------------------------| 401 ; WARNING: DO NOT CHANGE THE FOLLOWING. ;| 402 ; IT GETS PATCHED IN MSINIT ;| 0 000081CE E87612 call ispatched 0 000081D1 7203 jc @F 405 PUBLIC SET_PATCH ;| 406 SET_PATCH PROC NEAR ;| 0 000081D3 E8[0000] CALL SET_VOLUME_ID ;| 408 @@: 409 ;----------------------------------------| 410 MESSAGE FTESTDISK,<"SET VOLUME ID"> 411 MNUM FTESTDISK,DI 412 MESSAGE FTESTDISK,<" "> 413 MNUM FTESTDISK,DS 414 MESSAGE FTESTDISK, 415 416 ALREADY_GOTBPB: 0 000081D6 83C706 ADD DI,BYTEPERSEC ; RETURN THE BPB THAT IS IN THE CURRENT BDS 418 419 PUBLIC SETPTRSAV 420 SETPTRSAV: ; RETURN POINT FOR DSK$INIT 0 000081D9 E8[0000] call biocode_get_es_dosentry 0 000081DC 26C41E[0000] LES BX,[es:PTRSAV] 0 000081E1 2688670D MOV [ES:BX + MEDIA],AH 0 000081E5 26897F12 MOV [ES:BX + COUNT],DI 0 000081E9 268C5F14 MOV [ES:BX + COUNT + 2],DS 0 000081ED E9[0000] JMP EXIT 427 SET_PATCH ENDP 428 429 ;J.K. Clear IDs in BDS table. Only applied for Floppies. 430 ;Input: DS:DI -> BDS table 431 ;Output: VOLID set to "NO NAME " 432 ; VOL_SERIAL set to 0. 433 ; FileSys_ID set to "FAT12 " or "FAT16 " 434 ; depending on the flag FATSIZE in BDS. 435 ;All registers saved. 436 public Clear_IDs 437 Clear_IDs proc near ;AN000; 0 000081F0 1E push ds ;AN000; 0 000081F1 57 push di ;AN000; 0 000081F2 06 push es ;AN000; 0 000081F3 56 push si ;AN000; 0 000081F4 51 push cx ;AN000; 443 0 000081F5 31C9 xor cx, cx ;AN000; no serial number 0 000081F7 894D57 mov word ptr [di + VOL_SERIAL],cx ;AN000; 0 000081FA 894D59 mov word ptr [di + VOL_SERIAL + 2],cx ;AN000; 447 0 000081FD 1E push ds ;AN000; 0 000081FE 07 pop es ;AN000; es -> bds 0 000081FF 0E push cs ;AN000; get => DOSCODE 0 00008200 1F pop ds ;AN000; ds = cs => BIOCODE / DOSCODE 452 0 00008201 B10B mov cl, BOOT_VOLUME_LABEL_SIZE ;AN000; =11 454 VOL_NO_NAME equ Vol_No_Name ; NASM port label 0 00008203 BE[1200] mov si, offset VOL_NO_NAME ;AN000; 0 00008206 57 push di ;AN000; save BDS pointer 0 00008207 83C74B add di, VOLID ;AN000; points to VOLID field 0 0000820A F3A4 rep movsb ;AN000; 0 0000820C 5F pop di ;AN000; restore BDS pointer 0 0000820D 26F6451F40 test byte [es:di + FATSIZ], FBIG ;AN000; 0 00008212 7505 jnz CI_BigFat ;AN000; small fat 462 FAT_12_ID equ Fat_12_ID ; NASM port label 0 00008214 BE[0000] mov si, offset FAT_12_ID ;AN000; 0 00008217 EB03 jmp CI_Filesys ;AN000; 465 466 CI_BigFat: ;AN000; 467 FAT_16_ID equ Fat_16_ID ; NASM port label 0 00008219 BE[0900] mov si, offset FAT_16_ID ;AN000; big fat 469 CI_Filesys: ;AN000; 0 0000821C B108 mov cl, BOOT_SYSTEM_ID_SIZE ;AN000; =8 471 FILESYS_ID equ FILESYS_Id ; NASM port equate 0 0000821E 83C75B add di, FILESYS_ID ;AN000; points to FILESYS_ID field 0 00008221 F3A4 rep movsb ;AN000; 474 0 00008223 59 pop cx ;AN000; 0 00008224 5E pop si ;AN000; 0 00008225 07 pop es ;AN000; 0 00008226 5F pop di ;AN000; 0 00008227 1F pop ds ;AN000; 0 00008228 C3 ret ;AN000; 481 Clear_IDs endp ;AN000; 482 483 484 ; GETBP - RETURN BPB FROM THE DRIVE SPECIFIED BY THE BDS. 485 ; IF THE RETURN_FAKE_BPB FLAG IS SET, THEN IT DOES NOTHING. 486 ; NOTE THAT WE NEVER COME HERE FOR FIXED DISKS. 487 ; FOR ALL OTHER CASES, 488 ; - IT READS BOOT SECTOR TO PULL OUT THE BPB 489 ; - IF NO VALID BPB IS FOUND, IT THEN READS THE FAT SECTOR, 490 ; TO GET THE FAT ID BYTE TO BUILD THE BPB FROM THERE. 491 ; 492 ; INPUTS: DS:DI POINT TO CORRECT BDS. 493 ; 494 ; OUTPUTS: FILLS IN BPB IN CURRENT BDS IF VALID BPB OR FAT ID ON DISK. 495 ; CARRY SET, AND AL=7 IF INVALID DISK. 496 ; CARRY SET AND ERROR CODE IN AL IF OTHER ERROR. 497 ; If failed to recognize the Boot Record, then will set the 498 ; Set_ID_Flag to 0. 499 ; J.K. This routine will only work for a floppy diskette. 500 ; For a fixed disk, it will just return. 501 502 PUBLIC GETBP 503 GETBP PROC NEAR 504 ; IF RETURNING FAKE BPB THEN RETURN BPB AS IS. 0 00008229 F745230500 TEST WORD PTR [DI + FLAGS],RETURN_FAKE_BPB | FNON_REMOVABLE 0 0000822E 7403 JZ GETBP1 0 00008230 E9F400 JMP GETRET_EXIT 508 509 GETBP1: 510 MESSAGE FTESTDISK,<"BUILDING BPB FROM SCRATCH",CR,LF> 0 00008233 51520653 SAVEREG 512 ; 513 ; ATTEMPT TO READ IN BOOT SECTOR AND DETERMINE BPB. 514 ; WE ASSUME THAT THE 2.X AND GREATER DOS DISKS ALL HAVE A VALID BOOT SECTOR. 515 ; 516 RDBOOT: 0 00008237 E80C01 CALL READBOOTSEC 518 GETBP_ERR_RET_brdg equ Getbp_err_ret_brdg ; NASM port label 0 0000823A 7261 JC GETBP_ERR_RET_brdg ; CARRY SET IF THERE WAS ERROR. 0 0000823C 83FB00 CMP BX,0 ; BX IS 0 IF BOOT SECTOR IS VALID. 0 0000823F 755F JNZ DOFATBPB 522 523 ; MOVES THE BPB READ FROM THE BOOT SECTOR INTO REGISTERS FOR USE BY 524 ; GETBP ROUTINE AT HAS1 525 ;J.K.- 526 ; If the Set_ID_Flag is 1, and if an extended Boot Record, then set Volume 527 ; Serial Number, Volume Label, File System ID in BDS according to 528 ; the BOOT reocrd. After that, this routine will set the Set_ID_Flag to 2 529 ; to signal that VOLUME Label is set already from the Extended BOOT record 530 ; (so, don't set it again by calling "SET_VOLUME_ID" routine which uses 531 ; the volume label in the root directory. 532 533 ; CALL MOVBPB ; MOVE BPB INTO REGISTERS. 534 ;MOVBPB PROC NEAR 0 00008241 26A1[0600] mov ax, word [es:BPB_IN_SECTOR + DIRNUM] 0 00008245 89450C mov word [di + CDIR], ax 0 00008248 26A1[0B00] mov ax, word [es:BPB_IN_SECTOR + FATSIZE] 0 0000824C 894511 mov word [di + CSECFAT], ax 0 0000824F 26A1[0300] mov ax, word [es:BPB_IN_SECTOR + RESNUM] 0 00008253 894509 mov word [di + RESSEC], ax 0 00008256 26A0[0500] mov al, byte [es:BPB_IN_SECTOR + FATNUM] 0 0000825A 88450B mov byte [di + CFAT], al 543 0 0000825D 1E57 SAVEREG 0 0000825F 06 PUSH es 0 00008260 1F POP DS 0 00008261 BF[0000] MOV DI,OFFSET BPB_IN_SECTOR 0 00008264 8A7502 MOV DH,BYTE PTR [DI + SECALL] ;SECTORS PER UNIT 0 00008267 8A7D06 MOV BH,BYTE PTR [DI + DIRNUM] ;NUMBER OF DIRECTORY ENTRIES 0 0000826A 8B4D08 MOV CX,WORD PTR [DI + SECNUM] ;SIZE OF DRIVE 0 0000826D 8A650A MOV AH,BYTE PTR [DI + FATID] ;MEDIA DESCRIPTOR 0 00008270 8A450B MOV AL,BYTE PTR [DI + FATSIZE] ;NUMBER OF FAT SECTORS 0 00008273 8A5D0D MOV BL,BYTE PTR [DI + SLIM] ;SECTORS PER TRACK 0 00008276 8A550F MOV DL,BYTE PTR [DI + HLIM] ;NUMBER OF HEADS 0 00008279 5F1F RESTOREREG 0 0000827B 26803E[0000]01 cmp byte [es:Set_ID_Flag], 1 ;AC008 called by GET$BPB? 0 00008281 7516 jne MovBPB_Ret ;AC008 0 00008283 E83401 call Mov_Media_IDs ;AC008 0 00008286 7206 jc MovBPB_Conv ;AC008 Conventional boot record? 0 00008288 26C606[0000]02 mov byte [es:Set_ID_Flag],2 ;AC008 signals that Volume ID is set. 561 MovBPB_Conv: ;AC008 562 fHave96 equ FHAVE96 ; NASM port label 0 0000828E 26803E[0000]01 cmp byte [es:fHave96], 1 ;AC008 0 00008294 7503 jne MovBPB_Ret ;AC008 0 00008296 E8[0000] call ResetChanged ;AC008 Reset Flags in BDS to NOT fCHANGED. 566 MovBPB_Ret: ;AC008 0 00008299 F8 clc ;AC008 568 ;MOVBPB ENDP ;AC008 0 0000829A EB61 JMP HAS1 0 0000829C 90 nop ; identicalise 571 572 Getbp_err_ret equ GETBP_ERR_RET ; NASM port label 0 0000829D E98800 Getbp_err_ret_brdg: jmp Getbp_err_ret 574 ; 575 ; WE HAVE A 1.X DISKETTE. 576 ; IN THIS CASE READ IN THE FAT ID BYTE AND FILL IN BPB FROM THERE. 577 ; 578 DOFATBPB: 0 000082A0 E85D01 CALL READFAT ; PUTS MEDIA DESCRIPTOR BYTE IN AH 580 GETBP_ERR_RET_Brdg equ Getbp_err_ret_brdg ; NASM port label 0 000082A3 72F8 JC GETBP_ERR_RET_Brdg 582 ;----------------------------------------| 583 ; WARNING: DO NOT CHANGE THE FOLLOWING. ;| 584 ; IT GETS PATCHED IN MSINIT ;| 0 000082A5 E89F11 call ispatched 0 000082A8 7203 jc @F 587 PUBLIC GETBP1_PATCH ;| 588 GETBP1_PATCH: ;| 0 000082AA E8[0000] CALL HIDENSITY ;| 590 @@: 591 ;----------------------------------------| 592 ;TEST FOR A VALID 3.5" MEDIUM 0 000082AD 807D2202 CMP byte [DI + FORMFACTOR],FFSMALL 0 000082B1 751C JNZ IS_FLOPPY 0 000082B3 80FCF9 CMP AH,0F9H ; IS IT A VALID FAT ID BYTE FOR 3.5" ? 0 000082B6 757F jnz short GOT_UNKNOWN_MEDIUM 0 000082B8 BB[0000] MOV BX,OFFSET SM92 ; POINTER TO CORRECT BPB 0 000082BB E8[0000] call biocode_get_es_dosentry 599 600 ASSUME ES:BIOCODE 601 ;J.K. DS points to segment of BDS. The following should be modified 602 ;J.K. to get spf,csec,spa,spt correctly. It had been wrong if DRIVER.SYS 603 ;J.K. is loaded since the BDS is inside the driver.sys. 0 000082BE 268A07 MOV AL,[es:BX + SPF] 0 000082C1 268B4F03 MOV CX,[es:BX + CSEC] 0 000082C5 268B5705 MOV DX,WORD PTR [es:BX + SPA] 0 000082C9 268B5F01 MOV BX,WORD PTR [es:BX + SPT] 0 000082CD EB2E JMP SHORT HAS1 609 ; MUST BE A 5.25" FLOPPY IF WE COME HERE 610 IS_FLOPPY: 0 000082CF 88E1 MOV CL,AH ;SAVE MEDIA 0 000082D1 80E1F8 AND CL,0F8H ;NORMALIZE 0 000082D4 80F9F8 CMP CL,0F8H ;COMPARE WITH GOOD MEDIA BYTE 0 000082D7 755E JNZ GOT_UNKNOWN_MEDIUM 615 616 GOODID: 0 000082D9 B001 MOV AL,1 ;SET NUMBER OF FAT SECTORS 0 000082DB BB0840 MOV BX,64*256+8 ;SET DIR ENTRIES AND SECTOR MAX 0 000082DE B94001 MOV CX,40*8 ;SET SIZE OF DRIVE 0 000082E1 BA0101 MOV DX,01*256+1 ;SET HEAD LIMIT AND SEC/ALL UNIT 0 000082E4 F6C402 TEST AH,00000010B ;TEST FOR 8 OR 9 SECTOR 0 000082E7 7507 JNZ HAS8 ;NZ = HAS 8 SECTORS 0 000082E9 FEC0 INC AL ;INC NUMBER OF FAT SECTORS 0 000082EB FEC3 INC BL ;INC SECTOR MAX 0 000082ED 83C128 ADD CX,40 ;INCREASE SIZE 626 HAS8: 0 000082F0 F6C401 TEST AH,00000001B ;TEST FOR 1 OR 2 HEADS 0 000082F3 7408 JZ HAS1 ;Z = 1 HEAD 0 000082F5 01C9 ADD CX,CX ;DOUBLE SIZE OF DISK 0 000082F7 B770 MOV BH,112 ;INCREASE NUMBER OF DIRECTORY ENTRIES 0 000082F9 FEC6 INC DH ;INC SEC/ALL UNIT 0 000082FB FEC2 INC DL ;INC HEAD LIMIT 633 634 HAS1: 635 PUBLIC HAS1 636 0 000082FD 887508 MOV BYTE PTR [DI + SECPERCLUS],DH 0 00008300 887D0C MOV BYTE PTR [DI + CDIR],BH 0 00008303 894D0E MOV WORD PTR [DI + DRVLIM],CX 0 00008306 886510 MOV BYTE PTR [DI + MEDIAD],AH 0 00008309 884511 MOV BYTE PTR [DI + CSECFAT],AL 0 0000830C 885D13 MOV BYTE PTR [DI + SECLIM],BL 0 0000830F B600 mov dh, 0 0 00008311 895515 MOV word PTR [DI + HDLIM], dx 645 ;SB34DISK001******************************************************************* 646 ;SB the HIDSEC_H field and HIDSEC_L field and the 647 ;SB DRVLIM_H fields need to be set to 0 since this code here is for floppies 648 ;SB 3 LOCS 649 0 00008314 C745190000 mov word ptr [di + HIDSEC_H],0 0 00008319 C745170000 mov word ptr [di + HIDSEC_L],0 0 0000831E C7451D0000 mov word ptr [di + DRVLIM_H],0 653 654 ;SB34DISK001******************************************************************* 655 GETRET: 0 00008323 5B POP BX 0 00008324 075A59 RESTOREREG 658 659 ASSUME ES:NOTHING 660 661 GETRET_EXIT: 0 00008327 C3 RET 663 664 GETBP_ERR_RET: 665 ;J.K. Before doing anything else, set Set_ID_Flag to 0. 0 00008328 1E push ds 0 00008329 E8[0000] call biocode_get_ds_dosentry 0 0000832C C606[0000]00 mov byte [Set_ID_Flag], 0 ;AN000; 0 00008331 1F pop ds 0 00008332 E89306 CALL MAPERROR 0 00008335 EBEC JMP SHORT GETRET 672 ; 673 ; WE HAVE A 3.5" DISKETTE FOR WHICH WE CANNOT BUILD A BPB. WE DO NOT ASSUME ANY 674 ; TYPE OF BPB FOR THIS MEDIUM. 675 ; 676 GOT_UNKNOWN_MEDIUM: 0 00008337 1E push ds 0 00008338 E8[0000] call biocode_get_ds_dosentry 0 0000833B C606[0000]00 mov byte [Set_ID_Flag], 0 ;AN000; 0 00008340 1F pop ds 0 00008341 B007 MOV AL,ERROR_UNKNOWN_MEDIA 0 00008343 F9 STC 0 00008344 EBDD JMP SHORT GETRET 684 GETBP ENDP 685 686 BPBTYPE STRUC 0 000080B0 ?? SPF DB ? 0 000080B1 ?? SPT DB ? 0 000080B2 ?? CDIRE DB ? 0 000080B3 ???? CSEC DW ? 0 000080B5 ?? SPA DB ? 0 000080B6 ?? CHEAD DB ? 693 BPBTYPE ENDS 694 695 ; 696 ; READ IN THE BOOT SECTOR. SET CARRY IF ERROR IN READING SECTOR. 697 ; BX IS SET TO 1 IF THE BOOT SECTOR IS INVALID, OTHERWISE IT IS 0. 698 ; 699 READBOOTSEC PROC NEAR 0 00008346 B600 MOV DH,0 ;HEAD 0 0 00008348 B90100 MOV CX,0001 ;CYLINDER 0, SECTOR 1 0 0000834B E8C400 CALL READ_SECTOR 0 0000834E 7269 JC ERR_RET 0 00008350 31DB XOR BX,BX ; ASSUME VALID BOOT SECTOR. 705 706 ;******************************************************************************* 707 ; PUT A SANITY CHECK FOR THE BOOT SECTOR IN HERE TO DETECT BOOT SECTORS THAT 708 ; DO NOT HAVE VALID BPBS. 709 ; WE EXAMINE THE FIRST TWO BYTES - THEY MUST CONTAIN A LONG JUMP (69H) OR A 710 ; SHORT JUMP (EBH) FOLLOWED BY A NOP (90H), OR A SHORT JUMP (E9H). 711 ; IF THIS TEST IS PASSED, WE FURTHER CHECK BY EXAMINING THE SIGNATURE AT 712 ; THE END OF THE BOOT SECTOR FOR THE WORD AA55H. 713 ; IF THE SIGNATURE IS NOT PRESENT, WE EXAMINE THE MEDIA DESCRIPTOR BYTE TO 714 ; SEE IF IT IS VALID. 715 ;J.K. 10/15/86 DCR00012. For DOS 3.3, this logic is modified a little bit. 716 ; We are not going to check Signature. Instead we are going to sanity 717 ; check the media byte in BPB regardless of the validity of signature. 718 ; This is to save the already developed commercial products that have 719 ; good jump instruction and signature but with the false BPB informations 720 ; that will crash the diskette drive operation. (For example, Symphony diskette). 721 ;****************************************************************************** 0 00008352 26803E[0000]69 CMP BYTE PTR [es:DISKSECTOR],069H ; IS IT A DIRECT JUMP? 0 00008358 7418 JE Check_bpb_MediaByte ; DON'T NEED TO FIND A NOP 0 0000835A 26803E[0000]E9 CMP BYTE PTR [es:DISKSECTOR],0E9H ; DOS 2.0 JUMP? 0 00008360 7410 JE Check_bpb_MediaByte ; NO NEED FOR NOP 0 00008362 26803E[0000]EB CMP BYTE PTR [es:DISKSECTOR],0EBH ; HOW ABOUT A SHORT JUMP. 0 00008368 754C JNE INVALIDBOOTSEC 0 0000836A 26803E[0200]90 CMP BYTE PTR [es:DISKSECTOR + 2],090H ; IS NEXT ONE A NOP? 0 00008370 7544 JNE INVALIDBOOTSEC 730 731 732 ;J.K. 10/15/86 Don't have to perform the following signature check since 733 ; we need to check the media byte even with the good signatured diskette. 734 ;CHECK_SIGNATURE: 735 ; CMP WORD PTR [es:DISKSECTOR+1FEH],0AA55H ; SEE IF NON-IBM DISK OR 1.X 736 ; ; MEDIA. 737 ; JZ CHECKSINGLESIDED ; GO SEE IF SINGLE SIDED MEDIUM. MAY 738 ; ; NEED SOME SPECIAL HANDLING 739 ; 740 ; CHECK FOR NON-IBM DISKS WHICH DO NOT HAVE THE SIGNATURE AA55 AT THE 741 ; END OF THE BOOT SECTOR, BUT STILL HAVE A VALID BOOT SECTOR. THIS IS DONE 742 ; BY EXAMINING THE MEDIA DESCRIPTOR IN THE BOOT SECTOR. 743 ; 744 745 Check_bpb_MediaByte: 746 0 00008372 26A0[0000] MOV AL,BYTE PTR [es:MEDIABYTE] 0 00008376 24F0 AND AL,0F0H 0 00008378 3CF0 CMP AL,0F0H ; ALLOW FOR STRANGE MEDIA 0 0000837A 753A JNZ INVALIDBOOTSEC 751 ; 752 ; THERE WERE SOME (APPARENTLY A LOT OF THEM) DISKETTES THAT HAD BEEN FORMATTED 753 ; UNDER DOS 3.1 AND EARLIER VERSIONS WHICH HAVE INVALID BPBS IN THEIR BOOT 754 ; SECTORS. THESE ARE SPECIFICALLY DISKETTES THAT WERE FORMATTED IN DRIVES 755 ; WITH ONE HEAD, OR WHOSE SIDE 0 WAS BAD. THESE CONTAIN BPBS IN THE BOOT 756 ; SECTOR THAT HAVE THE SEC/CLUS FIELD SET TO 2 INSTEAD OF 1, AS IS STANDARD 757 ; IN DOS. IN ORDER TO SUPPORT THEM, WE HAVE TO INTRODUCE A "HACK" THAT WILL 758 ; HELP OUR BUILD BPB ROUTINE TO RECOGNISE THESE SPECIFIC CASES, AND TO 759 ; SET UP OUT COPY OF THE BPB ACCORDINGLY. 760 ; WE DO THIS BY CHECKING TO SEE IF THE BOOT SECTOR IS OFF A DISKETTE THAT 761 ; IS SINGLE-SIDED AND IS A PRE-DOS 3.20 DISKETTE. IF IT IS, WE SET THE 762 ; SEC/CLUS FIELD TO 1. IF NOT, WE CARRY ON AS NORMAL. 763 CHECKSINGLESIDED: 0 0000837C 26A0[0000] MOV AL,BYTE PTR [es:MEDIABYTE] 0 00008380 A801 TEST AL,0001H ; IS LOW BIT SET? - INDICATES DOUBLE SIDED 0 00008382 7533 JNZ GOODDSK 0 00008384 26803E[0000]02 cmp BYTE PTR [es:SECPERCLUSINSECTOR], 2 0 0000838A 752B jne GOODDSK 0 0000838C 26813E[0800]322E CMP WORD PTR [es:DISKSECTOR+8],("." << 8) + "2" 0 00008393 7419 je MUSTBEEARLIER 0 00008395 26813E[0800]332E CMP WORD PTR [es:DISKSECTOR+8],("." << 8) + "3" 0 0000839C 7519 jne GOODDSK 0 0000839E 26803E[0A00]30 CMP BYTE PTR [es:DISKSECTOR+10],"0" 0 000083A4 7211 jb GOODDSK 0 000083A6 26803E[0A00]32 CMP BYTE PTR [es:DISKSECTOR+10],"2" 0 000083AC 7309 JAE GOODDSK 777 778 ; WE MUST HAVE A PRE-3.20 DISKETTE. SET THE SEC/CLUS FIELD TO 1 779 MUSTBEEARLIER: 0 000083AE 26C606[0000]01 MOV BYTE PTR [es:SECPERCLUSINSECTOR],1 0 000083B4 EB01 JMP SHORT GOODDSK 782 ;****************************************************************************** 783 784 INVALIDBOOTSEC: 0 000083B6 43 INC BX ; INDICATE THAT BOOT SECTOR INVALID 786 GOODDSK: ; CARRY ALREADY RESET 0 000083B7 F8 CLC 0 000083B8 C3 RET 789 790 ERR_RET: ; CARRY IS ALREADY SET ON ENTRY HERE 791 MESSAGE FTESTDISK,<"ERROR IN READBOOT",CR,LF> 0 000083B9 C3 RET 793 READBOOTSEC ENDP 794 795 ; 796 public Mov_Media_IDs 797 Mov_Media_IDs Proc near ;AN000; 798 ;copy the boot_serial number, Volume id, and Filesystem id from the 799 ;***Extended Boot record*** in DOSENTRY:DiskSector to the BDS table pointed 800 ;by DS:DI. 801 ;In.) DS:DI -> BDS 802 ; DOSENTRY:DiskSector = Valid extended boot record. 803 ;Out.) Vol_Serial, Volid and System_Id in BDS are set according to 804 ; the boot record information. 805 ; Carry flag set if not an extended BPB. 806 ; All registers saved except the flag. 807 0 000083BA 06 push es ;AN000; 0 000083BB E8[0000] call biocode_get_es_dosentry 0 000083BE 26803E[0000]29 cmp byte [es:Ext_Boot_Sig], EXT_BOOT_SIGNATURE ;AN000; = 41 0 000083C4 7537 jne MMI_Not_Ext ;AN000; 0 000083C6 51 push cx ;AN000; 0 000083C7 268B0E[0000] mov cx, [es:Boot_Serial_L] ;AN000; 0 000083CC 894D57 mov word ptr [di + VOL_SERIAL],cx ;AN000; 0 000083CF 268B0E[0000] mov cx, [es:Boot_Serial_H] ;AN000; 0 000083D4 894D59 mov word ptr [di + VOL_SERIAL+2],cx ;AN000; 0 000083D7 1E push ds ;AN000; Save regs. 0 000083D8 57 push di ;AN000; 0 000083D9 56 push si ;AN000; 820 0 000083DA 06 push es 0 000083DB 1E push ds ; swap es, ds 0 000083DC 07 pop es ; es => UPB 0 000083DD 1F pop ds ; ds => DOSENTRY 825 0 000083DE B90B00 mov cx, BOOT_VOLUME_LABEL_SIZE ;AN000; 0 000083E1 BE[0000] mov si, offset Boot_Volume_Label;AN000; 0 000083E4 57 push di 0 000083E5 83C74B add di, VOLID ;AN000; 0 000083E8 F3A4 rep movsb ;AN000; 0 000083EA 5F pop di 0 000083EB B90800 mov cx, BOOT_SYSTEM_ID_SIZE ;AN000; =8 0 000083EE BE[0000] mov si, offset Boot_System_ID ;AN000; 0 000083F1 83C75B add di, FILESYS_ID ;AN000; 0 000083F4 F3A4 rep movsb ;AN000; 836 0 000083F6 5E pop si ;AN000; 0 000083F7 5F pop di ;AN000; 0 000083F8 1F pop ds ;AN000; 0 000083F9 59 pop cx ;AN000; 0 000083FA F8 clc ;AN000; 842 MMI_Ret: ;AN000; 0 000083FB 07 pop es ;AN000; 0 000083FC C3 ret ;AN000; 845 MMI_Not_Ext: ;AN000; 0 000083FD 07 pop es ;AN000; 0 000083FE F9 stc ;AN000; 0 000083FF C3 ret ;AN000; 849 Mov_Media_IDs endp ;AN000; 850 851 852 ; READ IN THE FAT SECTOR AND GET THE MEDIA BYTE FROM IT. 853 ; INPUT : AL CONTAINS LOGICAL DRIVE. 854 ; OUTPUT: 855 ; CARRY SET IF AN ERROR OCCURS, AX CONTAINS ERROR CODE. 856 ; OTHERWISE, AH CONTAINS MEDIA BYTE ON EXIT. AL IS PRESERVED. 857 858 READFAT PROC NEAR 0 00008400 50 PUSH AX ; PRESERVE LOGICAL DRIVE IN AL 0 00008401 B600 MOV DH,0 ; HEAD 0 0 00008403 B90200 MOV CX,0002 ; CYLINDER 0, SECTOR 2 0 00008406 E80900 CALL READ_SECTOR ; es:BX POINTS TO FAT SECTOR 0 00008409 7205 JC BAD_FAT_RET 0 0000840B 58 POP AX ; RESET LOGICAL DRIVE 0 0000840C 268A27 MOV AH,BYTE PTR [es:BX] ; MEDIA BYTE 0 0000840F C3 RET 867 868 BAD_FAT_RET: ; CARRY SET ON ENTRY 869 MESSAGE FTESTDISK,<"ERROR IN FAT READ",CR,LF> 0 00008410 59 POP CX ; CLEAR STACK 0 00008411 C3 RET 872 READFAT ENDP 873 874 ; READ A SINGLE SECTOR INTO THE TEMP BUFFER. 875 ; PERFORM THREE RETRIES IN CASE OF ERROR. 876 ; INPUTS: DRIVE HAS PHYSICAL DRIVE TO USE 877 ; CX HAS SECTOR AND CYLINDER 878 ; DH HAS HEAD 879 ; OUTPUTS: CARRY CLEAR 880 ; es:BX POINT TO SECTOR 881 ; CARRY SET 882 ; AX HAS ROM ERROR CODE 883 ; REGISTERS ES AND BP ARE PRESERVED. 884 ; OUT: es => DOSENTRY 885 886 READ_SECTOR PROC NEAR 887 PUBLIC READ_SECTOR 888 0 00008412 55 PUSH BP 0 00008413 BD0300 MOV BP,3 ; MAKE 3 ATTEMPTS 891 ;SB33015***************************************************************** 892 DriveNum equ DRIVENUM ; NASM port equate 0 00008416 8A5504 mov DL, byte ptr [di + DriveNum] ;SB;3.30* 894 DiskSector equ DISKSECTOR ; NASM port label 0 00008419 BB[0000] mov BX, offset DiskSector ; Get ES:BX to point to buffer ;SB;3.30* 0 0000841C E8[0000] call biocode_get_es_dosentry ; now ES:BX is correct ;SB;3.30* 897 ;SB33015***************************************************************** 898 RD_RET: 899 ;SB33016***************************************************************** 0 0000841F B80102 mov AX, 0201h ; number of sectors to 1 (AL=1);SB;3.30* 0 00008422 CD13 int 13h ; call rom-bios disk routines ;SB;3.30* 902 903 ;SB33016***************************************************************** 0 00008424 734E JNC OKRET2 905 Rd_rty: 0 00008426 E82C0D CALL AGAIN ; RESET DISK, DECREMENT BP, PRESERVE AX 907 Err_RD_RET equ ERR_RD_RET ; NASM port label 0 00008429 7446 jz Err_RD_RET 909 flags equ FLAGS ; NASM port equate 910 fNon_Removable equ FNON_REMOVABLE ; NASM port equate 0 0000842B F745230100 test word ptr [di + flags],fNon_Removable 0 00008430 75ED JNZ RD_RET 913 Media_Set_For_Format equ MEDIA_SET_FOR_FORMAT ; NASM port label 0 00008432 26803E[FF00]00 cmp byte [es:Media_Set_For_Format], 0 ;AN012; 0 00008438 7514 jne Rd_Skip1_DPT ;AN012; 0 0000843A 1E push ds ;J.K. 11/7/86 For retry, set the head settle time 0 0000843B 50 push ax ;to 0Fh. PTM845. 0 0000843C 26C536[0000] lds si,[es:DPT] 919 disk_head_sttl equ DISK_HEAD_STTL ; NASM port equate 0 00008441 8A4409 mov al, [si + disk_head_sttl] 921 save_head_sttl equ Save_head_sttl ; NASM port label 0 00008444 26A2[0000] mov [es:save_head_sttl],al 923 NormSettle equ NORMSETTLE ; NASM port equate 0 00008448 C644090F mov byte ptr [si + disk_head_sttl], NormSettle 0 0000844C 58 pop ax 0 0000844D 1F pop ds 927 Rd_Skip1_DPT: ;AN012; 928 ;SB33017***************************************************************** 929 ; SET CMD TO READ (AH=2) AND ;SB ;3.30 0 0000844E B80102 MOV AX, 0201h ; NUM OF SECTORS TO 1 (AL=1) ;SB ;3.30 0 00008451 CD13 INT 13h ; CALL ROM-BIOS DISK ROUTINES ;SB ;3.30 932 ;SB33017***************************************************************** 0 00008453 9C pushf ;AN012; 0 00008454 26803E[FF00]00 cmp byte [es:Media_Set_For_Format], 0 ;AN012; 0 0000845A 7510 jne Rd_Skip2_DPT ;AN012; 0 0000845C 1E push ds 0 0000845D 50 push ax 0 0000845E 26C536[0000] lds si,[es:DPT] 0 00008463 26A0[0000] mov al, [es:save_head_sttl] 0 00008467 884409 mov byte ptr [si + disk_head_sttl], al 0 0000846A 58 pop ax 0 0000846B 1F pop ds 943 Rd_Skip2_DPT: ;AN012; 0 0000846C 9D popf ;AN012; 0 0000846D 7305 jnc OKRET2 0 0000846F EBB5 jmp Rd_rty 947 ERR_RD_RET: 0 00008471 B2FF MOV DL,-1 ; MAKE SURE WE ASK ROM IF MEDIA HAS CHANGED 0 00008473 F9 STC ; RETURN ERROR 950 ; UPDATE INFORMATION PERTAINING TO LAST DRIVE ACCESSED, TIME OF ACCESS, LAST 951 ; TRACK ACCESSED IN THAT DRIVE. 952 OKRET2: 0 00008474 268816[0000] MOV [es:STEP_DRV],DL ; SET UP FOR HEAD SETTLE LOGIC IN DISK. 0 00008479 268816[0000] MOV [es:TIM_DRV],DL ;SAVE DRIVE LAST ACCESSED 0 0000847E 886D46 MOV BYTE PTR [DI + TRACK],CH ; SAVE LAST TRACK ACCESSED ON THIS DRIVE 0 00008481 9C PUSHF ; PRESERVE FLAGS IN CASE ERROR OCCURRED 0 00008482 E85D05 CALL SET_TIM 0 00008485 9D POPF ; RESTORE FLAGS 0 00008486 5D POP BP 0 00008487 C3 RET 961 READ_SECTOR ENDP 962 963 ;----------------------------------------------------------- 964 ; 965 ; DISK REMOVABLE ROUTINE ARR 2.41 966 ; 967 968 DSK$REM PROC NEAR ;ARR 2.41 969 PUBLIC DSK$REM 970 971 MESSAGE FTESTDISK,<"DISK REMOVABLE "> 972 MNUM FTESTDISK,AX 973 MESSAGE FTESTDISK, 974 ; AL IS UNIT # 0 00008488 E80D00 CALL SETDRIVE ; GET BDS FOR THIS DRIVE 0 0000848B F745230100 TEST WORD PTR [DI + FLAGS],FNON_REMOVABLE 0 00008490 7503 JNZ NON_REM 0 00008492 E9[0000] JMP EXIT 979 980 NON_REM: 0 00008495 E9[0000] JMP BUS$EXIT ;ARR 2.41 982 DSK$REM ENDP 983 984 ; SETDRIVE SCANS THROUGH THE DATA STRUCTURE OF BDSS, AND RETURNS A POINTER TO 985 ; THE ONE THAT BELONGS TO THE DRIVE SPECIFIED. CARRY IS SET IF NONE EXISTS FOR 986 ; THE DRIVE. 987 ; IF THE BYTE [PHYS_DRV] IS 0 THEN 988 ; ON ENTRY, AL CONTAINS THE LOGICAL DRIVE NUMBER. 989 ; ON EXIT, DS:DI POINTS TO CORRECT BDS FOR THE DRIVE IF CARRY CLEAR. 990 991 ; ELSE IF THE BYTE [PHYS_DRV] IS 1 THEN (ONLY USED FOR FIXED DISKS WHEN AN ECC 992 ; ERROR OCCURS) 993 ; ON ENTRY, DL CONTAINS THE PYHSICAL DRIVE NUMBER. 994 ; ON EXIT, DS:DI POINTS TO CORRECT BDS FOR THE DRIVE IF CARRY CLEAR. 995 996 PUBLIC SETDRIVE 997 SETDRIVE PROC NEAR 998 MESSAGE FTESTDISK,<"SETDRIVE",CR,LF> 0 00008498 53 PUSH BX 1000 ASSUME DS:NOTHING 0 00008499 E8[0000] call biocode_get_ds_dosentry 0 0000849C C53E[0000] lds di, [START_BDS] 1003 SCAN_LOOP: 0 000084A0 83FFFF CMP DI,-1 0 000084A3 741C je SCAN_NONE 0 000084A5 1E push ds 0 000084A6 E8[0000] call biocode_get_ds_dosentry 0 000084A9 803E[0000]01 CMP BYTE PTR [PHYS_DRV], 1 ; DOES AL HAVE PHYSICAL DRIVE? 0 000084AE 1F pop ds 0 000084AF 7207 JB USE_LOGICAL_DRV 0 000084B1 384504 CMP BYTE PTR [DI + DRIVENUM],AL 0 000084B4 740C JE SETDRV 0 000084B6 EB05 JMP SHORT GET_NXT_BDS 1014 USE_LOGICAL_DRV: 0 000084B8 384505 CMP BYTE PTR [DI + DRIVELET],AL 0 000084BB 7405 JE SETDRV 1017 GET_NXT_BDS: 0 000084BD C53D lds di, [DI + LINK] ; GO TO NEXT BDS 0 000084BF EBDF jmp SCAN_LOOP 1020 1021 SCAN_NONE: 0 000084C1 F9 STC 1023 SETDRV: 0 000084C2 5B POP BX 0 000084C3 C3 RET 1026 SETDRIVE ENDP 1027 1028 ;----------------------------------------------------------- 1029 ; 1030 ; DISK I/O ROUTINES 1031 ; 1032 1033 DSK$WRITV PROC NEAR 1034 PUBLIC DSK$WRITV 1035 1036 MESSAGE FTESTDISK,<"DISK WRITE WITH VERIFY "> 1037 MNUM FTESTDISK,AX 1038 MESSAGE FTESTDISK,<" "> 1039 MNUM FTESTDISK,DX 1040 MESSAGE FTESTDISK,<" FOR "> 1041 MNUM FTESTDISK,CX 1042 MESSAGE FTESTDISK, 0 000084C4 E8[0000] call biocode_get_ds_dosentry 0 000084C7 C706[0000]0301 MOV word [WRTVERIFY],103H 1045 ; needn't preserve ds, DISKIO overwrites its INP:ds 0 000084CD EB09 JMP SHORT DSK$CL 1047 1048 DSK$WRIT: 1049 PUBLIC DSK$WRIT 1050 MESSAGE FTESTDISK,<"DISK WRITE "> 1051 MNUM FTESTDISK,AX 1052 MESSAGE FTESTDISK,<" "> 1053 MNUM FTESTDISK,DX 1054 MESSAGE FTESTDISK,<" FOR "> 1055 MNUM FTESTDISK,CX 1056 MESSAGE FTESTDISK, 0 000084CF E8[0000] call biocode_get_ds_dosentry 0 000084D2 C706[0000]0300 MOV word [WRTVERIFY],ROMWRITE 1059 ; needn't preserve ds, DISKIO overwrites its INP:ds 1060 DSK$CL: 0 000084D8 E89100 CALL DISKIO 1062 DSK$IO: 0 000084DB 7203 JC DSKBAD 0 000084DD E9[0000] JMP EXIT 1065 DSKBAD: 0 000084E0 E9[0000] JMP ERR$CNT 1067 DSK$WRITV ENDP 1068 1069 DSK$READ PROC NEAR 1070 PUBLIC DSK$READ 1071 MESSAGE FTESTDISK,<"DISK READ "> 1072 MNUM FTESTDISK,AX 1073 MESSAGE FTESTDISK,<" "> 1074 MNUM FTESTDISK,DX 1075 MESSAGE FTESTDISK,<" FOR "> 1076 MNUM FTESTDISK,CX 1077 MESSAGE FTESTDISK, 0 000084E3 E87E00 CALL DISKRD 0 000084E6 EBF3 JMP DSK$IO 1080 DSK$READ ENDP 1081 1082 ; MISCELLANEOUS ODD JUMP ROUTINES. MOVED OUT OF MAINLINE FOR SPEED. 1083 1084 1085 ; IF WE HAVE A SYSTEM WHERE WE HAVE VIRTUAL DRIVES, WE NEED TO PROMPT THE 1086 ; USER TO PLACE THE CORRECT DISK IN THE DRIVE. 1087 1088 CHECKSINGLE PROC NEAR 1089 PUBLIC CHECKSINGLE 1090 0 000084E8 50 PUSH AX 0 000084E9 8B4523 MOV ax,WORD PTR [DI + FLAGS] 1093 ; IF HARD DRIVE, CANNOT CHANGE DISK. 1094 ; IF CURRENT OWNER OF PHYSICAL DRIVE, NO NEED TO CHANGE DISKETTE. 0 000084EC A821 TEST al,FNON_REMOVABLE | FI_OWN_PHYSICAL 0 000084EE 7560 JNZ SINGLERET 0 000084F0 A810 TEST al,FI_AM_MULT ; IS THERE A DRIVE SHARING THIS 1098 ; PHYSICAL DRIVE? 0 000084F2 745C JZ SINGLERET 1100 ; LOOK FOR THE PREVIOUS OWNER OF THIS PHYSICAL DRIVE AND RESET ITS OWNERSHIP 1101 ; FLAG. 0 000084F4 8A4504 MOV AL,[DI + DRIVENUM] ; GET PHYSICAL DRIVE NUMBER 0 000084F7 1E PUSH DS ; PRESERVE POINTER TO CURRENT BDS 0 000084F8 57 PUSH DI 0 000084F9 E8[0000] call biocode_get_ds_dosentry 0 000084FC BF[0000] MOV DI,OFFSET START_BDS 1107 SCAN_LIST: 0 000084FF C53D lds di, [di + LINK] ; GO TO NEXT BDS 1109 ASSUME DS:NOTHING 1110 0 00008501 83FFFF CMP DI,-1 ; END OF LIST? 0 00008504 744C je SINGLE_ERR_RET ; MUST BE ERROR 0 00008506 384504 CMP BYTE PTR [DI + DRIVENUM],AL 0 00008509 75F4 jne SCAN_LIST 1115 1116 CHECK_OWN: 0 0000850B F6452320 test byte [DI + FLAGS], FI_OWN_PHYSICAL 0 0000850F 74EE JZ SCAN_LIST 1119 1120 ; MS-DOS v5 flips these flags before the 2F.4A00 callout 0 00008511 806523DF and byte [DI + FLAGS], ~ FI_OWN_PHYSICAL; RESET OWNERSHIP FLAG 0 00008515 8A6505 MOV ah, [DI + DRIVELET] ; ah = wanted DOS drive letter 0 00008518 5F POP DI ; RESTORE POINTER TO CURRENT BDS 0 00008519 1F POP DS 0 0000851A 804D2320 or byte [DI + FLAGS], FI_OWN_PHYSICAL ; ESTABLISH CURRENT BDS AS OWNER 1126 1127 ; 1128 ; WE EXAMINE THE FSETOWNER FLAG. IF IT IS SET, THEN WE ARE USING THE CODE IN 1129 ; CHECKSINGLE TO JUST SET THE OWNER OF A DRIVE. WE MUST NOT ISSUE THE PROMPT 1130 ; IN THIS CASE. 1131 ; 0 0000851E 1E push ds 0 0000851F E8[0000] call biocode_get_ds_dosentry 0 00008522 803E[0000]01 CMP BYTE PTR [FSETOWNER],1 0 00008527 1F pop ds 0 00008528 7426 JZ SINGLERET 1137 ; TO SUPPORT "BACKWARD" COMPATIBILITY WITH IBM'S "SINGLE DRIVE STATUS BYTE" 1138 ; WE NOW CHECK TO SEE IF WE ARE IN A SINGLE DRIVE SYSTEM AND THE APPLICATION 1139 ; HAS "CLEVERLY" DIDDLED THE SDSB 0 0000852A 1E push ds 0 0000852B E8[0000] call biocode_get_ds_dosentry 0 0000852E 803E[0000]02 CMP byte [SINGLE],2 ; IF (SINGLE_DRIVE_SYSTEM) 0 00008533 1F pop ds 0 00008534 7517 JNE SHORT IGNORE_SDSB 0 00008536 1E5750 SAVEREG ; THEN 0 00008539 8A4505 MOV AL,[DI + DRIVELET] ; IF (CURR_DRV == REQ_DRV) 0 0000853C 88C4 MOV AH,AL 0 0000853E 31FF XOR DI,DI 0 00008540 8EDF MOV DS,DI ; => 0 0 00008542 86060405 XCHG AL,BYTE PTR [LSTDRV] ; THEN SWAP(CURR_DRV,REQ_DRV) 0 00008546 38C4 CMP AH,AL ; ELSE 0 00008548 585F1F RESTOREREG ; SWAP(CURR_DRV,REQ_DRV) 0 0000854B 7403 JE SINGLERET ; ISSUE SWAP_DSK_MSG 1154 1155 IGNORE_SDSB: 0 0000854D E8[0000] CALL SWPDSK ; ASK USER FOR CORRECT DISK 1157 SINGLERET: 0 00008550 58 POP AX 0 00008551 C3 RET 1160 1161 SINGLE_ERR_RET: 0 00008552 F9 STC 0 00008553 5F POP DI ; RESTORE CURRENT BDS 0 00008554 1F POP DS 0 00008555 EBF9 JMP SHORT SINGLERET 1166 1167 BADDRIVE: 0 00008557 B008 MOV AL,8 ;Sector not found 0 00008559 EB02 jmp short BadDrive_Ret ;AN004;AN005;AN006; 1170 UnformattedDrive: ;AN004;AN005;AN006; 0 0000855B B007 mov al,7 ;AN004;Unknown media;AN005;AN006; 1172 BadDrive_Ret: 0 0000855D F9 STC 0 0000855E C3 IORET: RET 1175 1176 BOGUSSETTLE: 0 0000855F B00F MOV AL,NORMSETTLE ; SOMEONE HAS DIDDLED THE SETTLE 0 00008561 E93302 JMP GOTSLOWSETTLE 1179 CHECKSINGLE ENDP 1180 ;------------------------------------------------------------ 1181 ; 1182 ; DISK I/O HANDLER 1183 ; 1184 ; AL = DRIVE NUMBER (0-6) 1185 ; AH = MEDIA DESCRIPTOR 1186 ; CX = SECTOR COUNT 1187 ; DX = FIRST SECTOR (low) 1188 ; [Start_Sec_H] = FIRST SECTOR (high) ;J.K. 32 bit calculation. 1189 ; ES:DI = TRANSFER ADDRESS 1190 ; [RFLAG]=OPERATION (2=READ, 3=WRITE) 1191 ; [VERIFY]=1 FOR VERIFY AFTER WRITE 1192 ; 1193 ; IF SUCCESSFUL CARRY FLAG = 0 1194 ; ELSE CF=1 AND AL CONTAINS ERROR CODE 1195 ; 1196 PUBLIC DISKRD 1197 DISKRD PROC NEAR 0 00008564 E8[0000] call biocode_get_ds_dosentry 0 00008567 C606[0000]02 MOV byte [RFLAG],ROMREAD 1200 ; SETDRIVE overwrites ds, so no need to restore 1201 1202 DISKIO: 0 0000856C 89FB MOV BX,DI ; ES:BX = TRANSFER ADDRESS 0 0000856E E827FF CALL SETDRIVE ; MAP LOGICAL AND PHYSICAL 0 00008571 8A4510 MOV AL,BYTE PTR [DI + MEDIAD] 0 00008574 1E push ds 0 00008575 E8[0000] call biocode_get_ds_dosentry 0 00008578 A2[0000] MOV [MEDBYT],AL ; PRESERVE MEDIA BYTE FOR DRIVE FOR USE 1209 ; IN DETERMINING MEDIA CHANGE. 0 0000857B 1F pop ds 0 0000857C E3E0 JCXZ IORET 1212 ;SB34DISK006****************************************************************** 1213 ;SB See if the Media is formatted or not by checking the flags field in 1214 ;SB in the BDS. If it is unformatted we cannot allow I/O, so we should 1215 ;SB go to the error exit at label UnformattedDrive. 2LOCS 1216 0 0000857E F745230002 test word ptr [di + FLAGS], UNFORMATTED_MEDIA 0 00008583 75D6 jnz UnformattedDrive 1219 ;SB34DISK006****************************************************************** 0 00008585 1E push ds 0 00008586 E8[0000] call biocode_get_ds_dosentry 0 00008589 890E[0000] mov [SECCNT],CX ;save sector count 0 0000858D 8926[0000] MOV [SPSAV],SP ; SAVE SP 0 00008591 1F pop ds 1225 1226 ; ENSURE THAT WE ARE TRYING TO ACCESS VALID SECTORS ON THE DRIVE 1227 ; 1228 0 00008592 89D0 mov ax,dx ;AN000; save DX to AX 0 00008594 31F6 xor si,si ;AN000; 0 00008596 01CA add dx,cx ;AN000; 0 00008598 83D600 adc si,0 ;AN000; 1233 DrvLim equ DRVLIM ; NASM port equate 0 0000859B 837D0E00 cmp word [di + DrvLim], 0 ;AN000; Is this drive > 32 bit sector ? 0 0000859F 740C je Sanity32 ;AN000; 0 000085A1 83FE00 cmp si,0 ;AN000; 0 000085A4 75B1 jne BADDRIVE ;AN000; 0 000085A6 3B550E cmp dx, [di + DrvLim] ;AN000; 0 000085A9 77AC ja BADDRIVE ;AN000; 0 000085AB EB15 jmp short SanityOK ;AN000; 1241 Sanity32: ;AN000; 0 000085AD 1E push ds 0 000085AE E8[0000] call biocode_get_ds_dosentry 0 000085B1 0336[0000] add si, [Start_Sec_H] ;AN000; 0 000085B5 1F pop ds 1246 DrvLim_H equ DRVLIM_H ; NASM port equate 0 000085B6 3B751D cmp si, [di + DrvLim_H] ;AN000; 0 000085B9 7207 jb SanityOK ;AN000; 0 000085BB 779A ja BADDRIVE ;AN000; 1250 DrvLim_L equ DRVLIM_L ; NASM port equate 0 000085BD 3B551B cmp dx, [di + DrvLim_L] ;AN000; 0 000085C0 7795 ja BADDRIVE ;AN000; 1253 SanityOK: ;AN000; 0 000085C2 1E push ds 0 000085C3 E8[0000] call biocode_get_ds_dosentry 0 000085C6 8B16[0000] mov dx,[Start_Sec_H] ;AN000; 0 000085CA 1F pop ds 0 000085CB 034517 add ax,word ptr [di + HIDSEC_L] ;AN000; 1259 Hidsec_H equ HIDSEC_H ; NASM port equate 0 000085CE 135519 adc dx,word ptr [di + Hidsec_H] ;AN000; 1261 ;J.K. Now DX;AX have the physical first sector. 1262 ;Since the following procedures is going to destroy AX, let's 1263 ;save it temporarily to SAVED_WORD. 0 000085D1 1E push ds 0 000085D2 E8[0000] call biocode_get_ds_dosentry 0 000085D5 A3[0000] mov [Saved_Word], ax ;AN000; Save the sector number (low) 1267 1268 ; MOV SI,DX 1269 ; ADD SI,CX 1270 ; ADD DX,WORD PTR [DI].HIDSEC ; ADD IN THE HIDDEN SECTORS 1271 ; CMP SI,WORD PTR [DI].DRVLIM ; COMPARE AGAINST DRIVE MAX 1272 ; JA BADDRIVE 1273 1274 ; SET UP POINTER TO DISK BASE TABLE IN [DPT]. WE CANNOT ASSUME THAT IOSETUP 1275 ; WILL DO IT BECAUSE WE WILL SKIP THE SET UP STUFF WITH HARD DISKS. 0 000085D8 31C0 XOR AX,AX 0 000085DA 8ED8 MOV DS,AX 0 000085DC FF367A00 push word [DSKADR + 2] 0 000085E0 8B367800 mov SI, [DSKADR] ; CURRENT DISK PARM TABLE 0 000085E4 E8[0000] call biocode_get_ds_dosentry 0 000085E7 8936[0000] MOV WORD PTR [DPT],SI 0 000085EB 8F06[0200] pop WORD PTR [DPT+2] 0 000085EF 1F POP DS 0 000085F0 F745230100 TEST WORD PTR [DI + FLAGS],FNON_REMOVABLE 0 000085F5 750E JNZ SKIP_SETUP 0 000085F7 E8EEFE CALL CHECKSINGLE 1287 ; 1288 ; CHECK TO SEE IF WE HAVE PREVIOUSLY NOTED A CHANGE LINE. THE ROUTINE 1289 ; RETURNS IF EVERYTHING IS OK. OTHERWISE, IT POPS OFF THE STACK AND RETURNS 1290 ; THE PROPER ERROR CODE. 1291 ; 1292 ;----------------------------------------| 1293 ; WARNING: DO NOT CHANGE THE FOLLOWING. ;| 1294 ; IT GETS PATCHED IN MSINIT ;| 0 000085FA E84A0E call ispatched 0 000085FD 7203 jc @F 1297 PUBLIC DISKIO_PATCH ;| 1298 DISKIO_PATCH: ;| 0 000085FF E8[0000] CALL CHECKLATCHIO ;| 1300 @@: 1301 ;----------------------------------------| 1302 ; 1303 ; SET UP TABLES AND VARIABLES FOR I/O 0 00008602 E84D01 CALL IOSETUP 1305 ; 1306 ; NOW THE SETTLE VALUES ARE CORRECT FOR THE FOLLOWING CODE 1307 ; 1308 SKIP_SETUP: 1309 ;J.K. 32 bit sector calculation. 1310 ; DX;[Saved_Word] = starting sector number. 1311 0 00008605 F745230100 test word ptr [di + FLAGS], fNon_Removable ;Fixed disk? - J.K. 4/7/86 0 0000860A 741C jz DISK_NOT_MINI ;no, skip this. - J.K. 4/7/86 0 0000860C 837D4701 cmp word [di + IsMini], 1 ;Is this a mini disk? - J.K. 4/7/86 0 00008610 7516 jnz DISK_NOT_MINI ;No. continue to next.- J.K. 4/7/86 0 00008612 89D1 mov cx, dx ; cx = high word sector number 0 00008614 8B4513 mov ax, [di + SECLIM] ; ax = number of CHS sectors 0 00008617 F76515 mul word ptr [di + HDLIM] ; ax = sectors per cylinder (dx == zero) 0 0000861A F76549 mul word ptr [di + Hidden_Trks] ; dx:ax = how many hidden sectors to add 0 0000861D 1E push ds 0 0000861E E8[0000] call biocode_get_ds_dosentry 0 00008621 0106[0000] add word ptr [Saved_Word], ax 0 00008625 1F pop ds 0 00008626 11CA adc dx, cx ; add hidden sectors amount matching cyls 1325 DISK_NOT_MINI: 0 00008628 F745230004 test word ptr [di + FLAGS], F_LBA 0 0000862D 7517 jnz diskio_lba ; --> (NC) 0 0000862F E8BF00 call lbatochs_saved_word 0 00008632 720F jc BADDRIVE_Brdg 1330 ; 1331 ; WE ARE NOW SET UP FOR THE I/O. NORMALLY, WE CONSIDER THE DMA BOUNDARY 1332 ; VIOLATIONS HERE. NOT TRUE. WE PERFORM THE OPERATION AS IF EVERYTHING IS 1333 ; SYMMETRIC; LET THE INT 13 HANDLER WORRY ABOUT THE DMA VIOLATIONS. 1334 ; 0 00008634 1E push ds 0 00008635 E8[0000] call biocode_get_ds_dosentry 0 00008638 A1[0000] MOV AX, [SECCNT] 0 0000863B 1F pop ds 0 0000863C E89C01 CALL BLOCK 1340 diskio_done: 0 0000863F E85D01 CALL DONE 0 00008642 C3 RET 1343 1344 ; 1345 Baddrive equ BADDRIVE ; NASM port label 0 00008643 E911FF BADDRIVE_Brdg:jmp Baddrive 1347 ; 1348 1349 diskio_lba: 0 00008646 1E push ds 0 00008647 E8[0000] call biocode_get_ds_dosentry 0 0000864A A1[0000] mov ax, word ptr [Saved_Word] 0 0000864D 8B0E[0000] mov cx, word ptr [SECCNT] 0 00008651 1F pop ds 1355 diskio_lba_loop: 0 00008652 E3EB jcxz diskio_done 0 00008654 81F98000 cmp cx, 128 0 00008658 7226 jb diskio_lba_call_simple 0 0000865A 51 push cx 0 0000865B B97F00 mov cx, 127 0 0000865E E82400 call diskio_lba_simple 0 00008661 59 pop cx 0 00008662 8CC0 mov ax, es 0 00008664 05E00F add ax, 127 * 512 / 16 0 00008667 8EC0 mov es, ax 0 00008669 83E97F sub cx, 127 0 0000866C 1E push ds 0 0000866D E8[0000] call biocode_get_ds_dosentry 0 00008670 A1[0800] mov ax, word ptr [lbapacket + lpSector] 0 00008673 8B16[0A00] mov dx, word ptr [lbapacket + lpSector + 2] 0 00008677 1F pop ds 0 00008678 83C07F add ax, 127 0 0000867B 83D200 adc dx, 0 0 0000867E EBD2 jmp diskio_lba_loop 1375 1376 diskio_lba_call_simple: 0 00008680 E80200 call diskio_lba_simple 0 00008683 EBBA jmp diskio_done 1379 1380 diskio_lba_simple: 0 00008685 8A6D04 mov ch, byte ptr [di + DRIVENUM] 0 00008688 1E push ds 0 00008689 56 push si 0 0000868A E8AD00 call lba_packet_setup 0 0000868D BD0500 MOV BP,MAXERR ; SET UP RETRY COUNT 0 00008690 1E push ds 0 00008691 E8[0000] call biocode_get_ds_dosentry 0 00008694 892E[0000] mov [VRetry_Cnt], BP ;AN003;Verify op. retry cnt for Write-Verify. 0 00008698 892E[0000] mov [Soft_ECC_Cnt], BP ;AN003;Soft ECC error retry count. 1390 diskio_lba_retry: 0 0000869C B440 mov ah, 40h ; 42h, 43h, 44h 0 0000869E 0A26[0000] or ah, [RFLAG] ; GET READ/WRITE INDICATOR 0 000086A2 1F pop ds 0 000086A3 FF7402 push word ptr [si + lpCount] 0 000086A6 88EA mov dl, ch 0 000086A8 CD13 int 13h 0 000086AA 8F4402 pop word ptr [si + lpCount] 0 000086AD 5E pop si 0 000086AE 1F pop ds 0 000086AF 7201 jc diskio_lba_error 0 000086B1 C3 retn 1402 1403 diskio_lba_error: 0 000086B2 E8A00A CALL AGAIN 1405 lba_DskErr0: ;AN003; 0 000086B5 742E JZ lba_HARDERR 0 000086B7 F745230100 test word ptr [di + FLAGS], fNon_Removable ;AN009; 0 000086BC 7505 jnz lba_Skip_TimeOut_Chk ;AN009; 0 000086BE 80FC80 CMP AH,80H ;TIMEOUT? 0 000086C1 7422 JZ lba_HARDERR ;*** 1411 lba_Skip_TimeOut_Chk: ;AN009; 0 000086C3 1E push ds 0 000086C4 E8[0000] call biocode_get_ds_dosentry 0 000086C7 80FCCC cmp ah, 0cch ;AN003;Write Fault error? 0 000086CA 7414 jz lba_Write_Fault_Err ;AN003; Then, don't retry. 0 000086CC C706[0000]0500 mov word [Soft_ECC_Cnt], MAXERR ;AN003;Set Soft_ECC_Cnt back to MAXERR 1417 lba_DSKERR1: 0 000086D2 1F pop ds 0 000086D3 8A6D04 mov ch, byte ptr [di + DRIVENUM] 0 000086D6 1E push ds 0 000086D7 56 push si 0 000086D8 E8[0000] call biocode_get_ds_dosentry 0 000086DB BE[0000] mov si, offset lbapacket 0 000086DE EBBC JMP diskio_lba_retry 1425 1426 lba_Write_Fault_Err: ;AN003; 0 000086E0 BD0100 mov bp, 1 ;AN003;Just retry only once for Write Fault error. 1428 lba_DskErr1 equ lba_DSKERR1 ; NASM port label 0 000086E3 EBED jmp lba_DskErr1 ;AN003; 1430 1431 lba_HARDERR: 0 000086E5 E98002 jmp HARDERR 1433 1434 DISKRD ENDP 1435 1436 1437 ; INP: dx:ax = LBA 1438 ; ds:di -> UPB 1439 ; OUT: word [DOSENTRY:CURTRK] = cylinder 1440 ; byte [DOSENTRY:CURHD] = head 1441 ; byte [DOSENTRY:CURSEC] = sector (1-based) 1442 ; CY if overflow 1443 ; CHG: dx, ax, cx 1444 public lbatochs 1445 lbatochs: 0 000086E8 06 push es 0 000086E9 E8[0000] call biocode_get_es_dosentry 0 000086EC 26A3[0000] mov word ptr [es:Saved_Word], ax 0 000086F0 A8 db __TEST_IMM8 ; skip push 1450 lbatochs_saved_word: 0 000086F1 06 push es 0 000086F2 E8[0000] call biocode_get_es_dosentry 0 000086F5 92 xchg ax, dx ; ax = high word, dx clobbered 0 000086F6 31D2 xor dx,dx ;AN000; 0 000086F8 F77513 DIV WORD PTR [DI + SECLIM] ;DIVIDE BY SEC PER TRACK 0 000086FB 26A3[0000] mov [es:Temp_H],ax ;AN000; 0 000086FF 26A1[0000] mov ax, [es:Saved_Word] ;AN000; Restore the lower word 1458 SecLim equ SECLIM ; NASM port equate 0 00008703 F77513 div word ptr [di + SecLim] ;AN000; 1460 ;Now, [Temp_H],AX = track #, DX = sector 0 00008706 FEC2 INC DL ;Sector number is 1 based. 0 00008708 268816[0000] MOV [es:CURSEC],DL ;SAVE CURRENT SECTOR 0 0000870D 8B4D15 MOV CX,WORD PTR [DI + HDLIM] ;GET NUMBER OF HEADS 1464 0 00008710 50 push ax ;AN000; 0 00008711 31D2 XOR DX,DX ;DIVIDE TRACKS BY HEADS PER CYLINDER 0 00008713 26A1[0000] mov ax, [es:Temp_H] ;AN000; 0 00008717 F7F1 DIV CX 0 00008719 26A3[0000] mov [es:Temp_H],ax ;AN000; 0 0000871D 58 pop ax ;AN000; 0 0000871E F7F1 div cx ;AN000; 1472 ;Now, [Temp_H],AX = cyliner #, DX = head 0 00008720 26833E[0000]00 cmp word [es:Temp_H],0 ;AN000; 0 00008726 770F ja lbatochs_cy ;AN000; 0 00008728 3D0004 cmp AX, 1024 ;AN000; 2**10 currently maxium for track #. 0 0000872B 730A jae lbatochs_cy ;AN000; 0 0000872D 268816[0000] MOV [es:CURHD],DL ;SAVE CURRENT HEAD 0 00008732 26A3[0000] MOV [es:CURTRK],AX ;SAVE CURRENT TRACK 0 00008736 A8 db 0A8h ; test al, imm8 - skip stc and NC 1480 1481 lbatochs_cy: 0 00008737 F9 stc 0 00008738 07 pop es 0 00008739 C3 ret 1485 1486 1487 public lba_packet_setup 1488 lba_packet_setup: 0 0000873A E8[0000] call biocode_get_ds_dosentry 0 0000873D BE[0000] mov si, offset lbapacket 0 00008740 884C02 mov byte ptr [si + lpCount], cl 0 00008743 895C04 mov word ptr [si + lpBuffer], bx 0 00008746 8C4406 mov word ptr [si + lpBuffer + 2], es 0 00008749 894408 mov word ptr [si + lpSector + 0], ax 0 0000874C 89540A mov word ptr [si + lpSector + 2], dx 0 0000874F B442 mov ah, 42h 0 00008751 C3 retn 1498 1499 1500 ; SET THE DRIVE-LAST-ACCESSED FLAG FOR DISKETTE ONLY. WE KNOW THAT THE HARD 1501 ; DISK WILL NOT BE REMOVED. 1502 ; DS:DI -> CURRENT BDS. 1503 ; AX,CX,SI ARE DESTROYED. 1504 ; 1505 PUBLIC IOSETUP 1506 IOSETUP PROC NEAR 0 00008752 8A4504 MOV AL,[DI + DRIVENUM] 0 00008755 06 push es 0 00008756 E8[0000] call biocode_get_es_dosentry 0 00008759 26A2[0000] MOV [es:TIM_DRV],AL ; SAVE DRIVE LETTER 1511 ; 1512 ; DETERMINE PROPER HEAD SETTLE VALUES 1513 ; 0 0000875D 26803E[FF00]00 cmp byte [es:Media_Set_For_Format], 0 ;AN012; 0 00008763 7538 jne Skip_DPT_Setting ;AN012; 0 00008765 8CD9 MOV CX,DS 0 00008767 26C536[0000] LDS SI,[es:DPT] ; GET POINTER TO DISK BASE TABLE 0 0000876C 26A0[0000] MOV AL,[es:EOT] 0 00008770 884404 MOV [SI + DISK_EOT],AL ; BUMP FOR US 0 00008773 8A440A MOV AL,[SI + DISK_MOTOR_STRT] ; PRESERVE OLD MOTOR START TIME 0 00008776 26A2[0000] MOV [es:MOTORSTARTUP],AL 1522 ; 1523 ; FOR 3.5" DRIVES, BOTH EXTERNAL AS WELL AS ON THE K09, WE NEED TO SET THE 1524 ; MOTOR START TIME TO 4. THIS CHECKING FOR EVERY I/O IS GOING TO AFFECT 1525 ; PERFORMANCE ACROSS THE BOARD, BUT IS NECESSARY!! - RS 1526 ; 0 0000877A 06 PUSH ES 0 0000877B 8EC1 MOV ES,CX ; ES:DI -> TO CURRENT BDS 0 0000877D 26807D2202 CMP BYTE PTR [ES:DI + FORMFACTOR],FFSMALL 0 00008782 7505 JNZ MOTOR_START_OK 0 00008784 B004 MOV AL,4 0 00008786 86440A XCHG AL,[SI + DISK_MOTOR_STRT] 1533 MOTOR_START_OK: 0 00008789 07 POP ES 1535 ; 1536 ; DS:SI NOW POINTS TO DISK PARAMETER TABLE. GET CURRENT SETTLE AND SET FAST 1537 ; SETTLE 1538 ; 0 0000878A 30C0 XOR AL,AL 0 0000878C FEC0 INC AL ; IBM WANTS FAST SETTLE TO BE 1 - RS. 0 0000878E 864409 XCHG AL,[SI + DISK_HEAD_STTL] ; GET SETTLE AND SET UP FOR FAST 0 00008791 26A2[0000] MOV [es:SETTLECURRENT],AL 0 00008795 B00F MOV AL,NORMSETTLE ; SOMEONE HAS DIDDLED THE SETTLE 1544 GOTSLOWSETTLE: 0 00008797 8ED9 MOV DS,CX 0 00008799 26A2[0000] MOV [es:SETTLESLOW],AL 1547 Skip_DPT_Setting: ;AN012; 0 0000879D 07 pop es 0 0000879E C3 RET 1550 ; 1551 ; SET TIME OF LAST ACCESS, AND RESET DEFAULT VALUES IN THE DPT. 1552 ; 1553 DONE: 0 0000879F F745230100 TEST WORD PTR [DI + FLAGS],FNON_REMOVABLE 0 000087A4 7534 JNZ RETZ ; DO NOT SET FOR NON-REMOVABLE MEDIA 0 000087A6 E83902 CALL SET_TIM ; SET TIME OF LAST ACCESS FOR DRIVE 1557 ; 1558 ; RESTORE HEAD SETTLE AND EOT VALUES 1559 ; 1560 DIDDLEBACK: 0 000087A9 9C pushf ;AN013;Save flag 0 000087AA 06 push es 0 000087AB E8[0000] call biocode_get_es_dosentry 0 000087AE 26803E[FF00]00 cmp byte [es:Media_Set_For_Format], 0 ;AN012; 0 000087B4 7522 jne NoDiddleBack ;AN012; 0 000087B6 50 PUSH AX 0 000087B7 8CDA MOV DX,DS 0 000087B9 26A0[0000] MOV AL,[es:SETTLECURRENT] 0 000087BD 268A26[0000] MOV AH,[es:MOTORSTARTUP] 0 000087C2 26C536[0000] LDS SI,[es:DPT] 1571 ; MOV [SI].DISK_EOT,9 ;J.K. 4/25/86. Should not change the EOT value 1572 ;of diskbase to 9. This cause a problem 1573 ;with 1.44M diskette in Polaris when the user 1574 ;issue INT 13 with the default system 1575 ;diskbase. 0 000087C7 C6440409 mov byte [si + DISK_EOT],9 ;J.K. 11/5/86. For compatibility reason, return 1577 ;back to set it to 9 ( PTM826 ). 0 000087CB 884409 MOV [SI + DISK_HEAD_STTL],AL 0 000087CE C6440302 MOV byte [SI + DISK_SECTOR_SIZ],2 0 000087D2 88640A MOV [SI + DISK_MOTOR_STRT],AH 0 000087D5 8EDA MOV DS,DX 0 000087D7 58 POP AX 1583 NoDiddleBack: ;AN013; 0 000087D8 07 pop es 0 000087D9 9D popf ;AN013;Restore flag 1586 RETZ: 0 000087DA C3 RET 1588 1589 ;READ THE NUMBER OF SECTORS SPECIFIED IN AX, HANDLING TRACK BOUNDARIES 1590 ;DS:DI -> BDS FOR THIS DRIVE 1591 BLOCK: 0 000087DB 85C0 test AX,AX ;SEE IF ANY SECTORS TO READ 0 000087DD 74FB JZ RETZ 1594 ;Fixed disk will not be restricted to the track-by-track basis. -J.K.4/10/86 1595 Flags equ FLAGS ; NASM port equate 0 000087DF F745230100 test word ptr [di + Flags], fNon_Removable ;J.K. Fixed disk? 0 000087E4 7413 jz BLOCK_FLOPPY ;J.K. 1598 ;SB34DISK002***************************************************************** 1599 ;SB Check to see if multi track operation is allowed. If not 1600 ;SB we have to go to the block_floppy below to break up the operation. 1601 ;SB 2 LOCS 0 000087E6 1E push ds 0 000087E7 E8[0000] call biocode_get_ds_dosentry 1604 MulTrk_ON equ MULTRK_ON ; NASM port equate 0 000087EA F706[0000]8000 test word [MulTrk_Flag], MulTrk_ON 0 000087F0 1F pop ds 0 000087F1 7406 jz BLOCK_FLOPPY 1608 ;SB34DISK002***************************************************************** 0 000087F3 E84800 call DISK ;J.K. 0 000087F6 31C0 xor ax,ax 0 000087F8 C3 RET ;J.K. 1612 BLOCK_FLOPPY: ;J.K.4/10/86 1613 ; 1614 ; READ AT MOST 1 TRACK WORTH. PERFORM MINIMIZATION AT SECTOR / TRACK 1615 ; 0 000087F9 8A4D13 MOV CL,BYTE PTR [DI + SECLIM] 0 000087FC FEC1 INC CL 0 000087FE 1E push ds 0 000087FF E8[0000] call biocode_get_ds_dosentry 0 00008802 2A0E[0000] SUB CL,[CURSEC] ; LEEAC 3.20 ADD SEGMENT OVERRIDE 0 00008806 1F pop ds 0 00008807 30ED XOR CH,CH 0 00008809 39C8 CMP AX,CX 0 0000880B 7302 JAE GOTMIN 0 0000880D 89C1 MOV CX,AX 1626 GOTMIN: 1627 ; 1628 ; AX IS THE REQUESTED NUMBER OF SECTORS TO READ 1629 ; CX IS THE NUMBER THAT WE CAN DO ON THIS TRACK 1630 ; 0 0000880F 50 PUSH AX 0 00008810 51 PUSH CX 0 00008811 89C8 MOV AX,CX ; AL IS NUMBER OF SECTORS TO READ 0 00008813 E82800 CALL DISK 0 00008816 59 POP CX 0 00008817 58 POP AX 1637 ; 1638 ; CX IS THE NUMBER OF SECTORS JUST TRANSFERRED 1639 ; 0 00008818 29C8 SUB AX,CX ; REDUCE SECTORS-REMAINING BY LAST I/O 0 0000881A D0E1 SHL CL,1 0 0000881C 00CF ADD BH,CL ; ADJUST TRANSFER ADDRESS 0 0000881E EBBB JMP BLOCK 1644 IOSETUP ENDP 1645 1646 DskErr equ DSKERR ; NASM port label 0 00008820 E9FF00 DskErr_Brdg: jmp DskErr ;AN003; 1648 1649 1650 ; INP: variables from lbatochs 1651 ; ds:di -> UPB 1652 ; OUT: cx:dx = tuple value 1653 public chstotuple 1654 chstotuple: 0 00008823 1E push ds 0 00008824 E8[0000] call biocode_get_ds_dosentry 0 00008827 8B0E[0000] MOV cx, [CURTRK] ;LOAD CURRENT CYLINDER 0 0000882B D0CD ROR ch, 1 0 0000882D D0CD ROR ch, 1 1660 0 0000882F 0A2E[0000] OR ch, [CURSEC] 0 00008833 86E9 XCHG CH,CL ; CL = SECTOR, CH = CYLINDER 0 00008835 8A36[0000] MOV DH,BYTE PTR [CURHD] ; LOAD CURRENT HEAD NUMBER AND 0 00008839 1F pop ds 0 0000883A 8A5504 MOV DL,BYTE PTR [DI + DRIVENUM] ; PHYSICAL DRIVE NUMBER 0 0000883D C3 ret 1667 1668 ; 1669 ;PERFORM DISK I/O WITH RETRIES 1670 ; AL = NUMBER OF SECTORS (1-8, ALL ON ONE TRACK) 1671 ; DI POINT TO DRIVE PARAMETERS 1672 ; ES:BX = TRANSFER ADDRESS (MUST NOT CROSS A 64K PHYSICAL BOUNDARY) 1673 ; [RFLAG] = 2 IF READ, 3 IF WRITE 1674 ; [VERIFY] = 0 FOR NORMAL, 1 FOR VERIFY AFTER WRITE 1675 1676 PUBLIC DISK 1677 DISK PROC NEAR 0 0000883E BD0500 MOV BP,MAXERR ; SET UP RETRY COUNT 0 00008841 1E push ds 0 00008842 E8[0000] call biocode_get_ds_dosentry 0 00008845 892E[0000] mov [VRetry_Cnt], BP ;AN003;Verify op. retry cnt for Write-Verify. 0 00008849 892E[0000] mov [Soft_ECC_Cnt], BP ;AN003;Soft ECC error retry count. 0 0000884D 8A26[0000] MOV AH,[RFLAG] ;GET READ/WRITE INDICATOR 0 00008851 1F pop ds 1685 1686 RETRY: 0 00008852 50 PUSH AX 1688 0 00008853 E8CDFF call chstotuple 0 00008856 807D2205 CMP BYTE PTR [DI + FORMFACTOR],FFHARDFILE 0 0000885A 7419 JZ DO_FAST ; HARD FILES USE FAST SPEED 1692 ; IF WE HAVE [STEP_DRV] SET TO -1, WE USE THE SLOW SETTLE TIME. 1693 ; THIS HELPS WHEN WE HAVE JUST DONE A RESED DISK OPERATION AND THE HEAD HAS 1694 ; BEEN MOVED TO ANOTHER CYLINDER - THE PROBLEM CROPS UP WITH 3.5" DRIVES. 0 0000885C 1E push ds 0 0000885D E8[0000] call biocode_get_ds_dosentry 0 00008860 803E[0000]FF CMP byte [STEP_DRV],-1 0 00008865 1F pop ds 0 00008866 740A JZ DO_WRITEJ 0 00008868 80FC02 CMP AH,ROMREAD ; ARR 2.20 0 0000886B 7408 JE DO_FAST 0 0000886D 80FC04 CMP AH, ROMVERIFY 0 00008870 7403 JE DO_FAST 1704 DO_WRITEJ: 1705 ; READS ALWAYS FAST, UNLESS WE HAVE JUST DONE A DISK RESET OPERATION 0 00008872 EB6B JMP DO_WRITE ; ARR 2.20 READS ALWAYS FAST 0 00008874 90 nop ; identicalise 1708 DO_FAST: ; ARR 2.20 0 00008875 E84201 CALL FASTSPEED ; MZ 2.21 CHANGE SETTLE MODE 1710 TESTERR: ; MZ 2.21 1711 DSKERR_brdg equ DskErr_Brdg ; NASM port label 0 00008878 72A6 JC DSKERR_brdg 1713 ; SET DRIVE AND TRACK OF LAST ACCESS 0 0000887A 886D46 MOV BYTE PTR [DI + TRACK],CH ; ARR 2.20 SAVE TRACK 0 0000887D 1E push ds 0 0000887E E8[0000] call biocode_get_ds_dosentry 0 00008881 8816[0000] MOV [STEP_DRV],DL ; ARR 2.20 SET DRIVE 0 00008885 813E[0000]0301 CMP word [WRTVERIFY],103H ; CHECK FOR WRITE AND VERIFY 0 0000888B 1F pop ds 0 0000888C 7466 JZ DOVERIFY 1721 NOVERIFY: 0 0000888E 58 POP AX 1723 1724 ;SB34DISK003***************************************************************** 1725 ;SB Check the flags word in the BDS to see if the drive is non removable 1726 ;SB If not we needn't do anything special 1727 ;SB If it is a hard disk then check to see if multi-track operation 1728 ;SB is specified. If specified we don't have to calculate for the next 1729 ;SB track since we are already done. So we can go to the exit of this 1730 ;SB routine. 5 LOCS 1731 1732 fNON_REMOVABLE equ FNON_REMOVABLE ; NASM port equate 0 0000888F F745230100 test word ptr [di + FLAGS], fNON_REMOVABLE 0 00008894 1E push ds 0 00008895 E8[0000] call biocode_get_ds_dosentry 0 00008898 7408 jz ITS_REMOVABLE 0 0000889A F706[0000]8000 test word [MulTrk_Flag], MulTrk_ON 0 000088A0 753A jnz DISK_RET 1739 ITS_REMOVABLE: 1740 ;SB34DISK003***************************************************************** 0 000088A2 80E13F AND CL,03FH ; ELIMINATE CYLINDER BITS FROM SECTOR 0 000088A5 30E4 XOR AH,AH 0 000088A7 2906[0000] SUB [SECCNT],AX ; REDUCE COUNT OF SECTORS TO GO 0 000088AB 00C1 ADD CL,AL ; NEXT SECTOR 0 000088AD 880E[0000] MOV [CURSEC],CL 0 000088B1 1F pop ds 0 000088B2 1E push ds 0 000088B3 3A4D13 CMP CL,BYTE PTR [DI + SECLIM] ; SEE IF SECTOR/TRACK LIMIT REACHED 0 000088B6 E8[0000] call biocode_get_ds_dosentry 0 000088B9 7621 JBE DISK_RET 1751 NEXTTRACK: 0 000088BB C606[0000]01 MOV byte [CURSEC],1 ; START WITH FIRST SECTOR OF NEXT TRACK 0 000088C0 8A36[0000] MOV DH,[CURHD] 0 000088C4 FEC6 INC DH 0 000088C6 740A jz nexttrack_xor 0 000088C8 1F pop ds 0 000088C9 1E push ds 0 000088CA 3A7515 CMP DH,BYTE PTR [DI + HDLIM] 0 000088CD E8[0000] call biocode_get_ds_dosentry 0 000088D0 7206 JB NOXOR 1761 nexttrack_xor: 0 000088D2 30F6 XOR DH,DH 0 000088D4 FF06[0000] INC word [CURTRK] ;NEXT TRACK 1764 NOXOR: 0 000088D8 8836[0000] MOV [CURHD],DH 1766 DISK_RET: 0 000088DC 1F pop ds 0 000088DD F8 CLC ; LEEAC 0 000088DE C3 RET 1770 DISK ENDP 1771 1772 1773 ; THE REQUEST IS FOR WRITE. DETERMINE IF WE ARE TALKING ABOUT THE SAME 1774 ; TRACK AND DRIVE. IF SO, USE THE FAST SPEED. 1775 1776 DO_WRITE PROC NEAR 0 000088DF 1E push ds 0 000088E0 E8[0000] call biocode_get_ds_dosentry 0 000088E3 3A16[0000] CMP DL,[STEP_DRV] ; ARR 2.20 0 000088E7 1F pop ds 0 000088E8 7505 JNZ DO_NORM ; WE HAVE CHANGED DRIVES 1782 0 000088EA 3A6D46 CMP CH,BYTE PTR [DI + TRACK] ; ARR 2.20 0 000088ED 7486 JZ DO_FAST ; WE ARE STILL ON THE SAME TRACK 1785 1786 DO_NORM: 0 000088EF E89600 CALL NORMSPEED 0 000088F2 EB84 JMP SHORT TESTERR ; MZ 2.21 TEST FOR ERROR 1789 DO_WRITE ENDP 1790 ; 1791 ; WE HAVE A VERIFY REQUEST ALSO. GET STATE INFO AND GO VERIFY 1792 ; 1793 1794 DOVERIFY PROC NEAR 0 000088F4 58 POP AX ; RESTORE SECTOR COUNT 0 000088F5 50 PUSH AX 0 000088F6 B404 MOV AH,ROMVERIFY ; REQUEST VERIFY 0 000088F8 E8BF00 CALL FASTSPEED ; MZ 2.21 CHANGE SETTLE MODE 0 000088FB 7391 JNC NOVERIFY 1800 1801 ;SB34DISK004************************************************************** 1802 ;SB check the error returned in AH to see if it is a SOFT ECC error. 1803 ;SB If it is not we needn't do anything special. If it is a SOFT 1804 ;SB ECC error then decrement the SOFT_ECC_CNT error retry count. If 1805 ;SB this retry count becomes 0 then we just ignore the error and go to 1806 ;SB No_verify but if we can still try then we call the routine to reset 1807 ;SB the disk and go to DSKerr1 to retry the operation. 6 LOCS 1808 0 000088FD 80FC11 cmp ah,11h ;SOFT ECC error ? 0 00008900 7511 jnz Not_SoftECC_Err 1811 SOFT_ECC_CNT equ Soft_ECC_Cnt ; NASM port label 0 00008902 1E push ds 0 00008903 E8[0000] call biocode_get_ds_dosentry 0 00008906 FF0E[0000] dec word [SOFT_ECC_CNT] 0 0000890A 1F pop ds 1816 NoVerify equ NOVERIFY ; NASM port label 0 0000890B 7481 jz NoVerify ;no more retry 1818 ResetDisk equ RESETDISK ; NASM port label 0 0000890D E84A08 call ResetDisk ;reset disk 1820 DskErr1 equ DSKERR1 ; NASM port label 0 00008910 EB4D jmp DskErr1 ;retry 0 00008912 90 nop ; identicalise 1823 1824 ;SB34DISK004************************************************************** 1825 1826 Not_SoftECC_Err: ;AN003;Other error. 0 00008913 E84408 call ResetDisk ;AN003; 0 00008916 1E push ds 0 00008917 E8[0000] call biocode_get_ds_dosentry 0 0000891A FF0E[0000] dec word [VRetry_Cnt] ;AN003; 0 0000891E 1F pop ds 0 0000891F EB20 jmp DskErr0 ;AN003; 0 00008921 90 nop ; identicalise 1834 DOVERIFY ENDP 1835 ; 1836 ; NEED TO SPECIAL CASE THE CHANGE-LINE ERROR AH=06H. IF WE GET THIS, WE 1837 ; NEED TO RETURN IT. 1838 ; 1839 ;----------------------------------------| 1840 ; WARNING: DO NOT CHANGE THE FOLLOWING. ;| 1841 ; IT GETS PATCHED IN MSINIT ;| 1842 PUBLIC DSKERR ;| 1843 DSKERR PROC NEAR ;| 0 00008922 E8220B call ispatched 0 00008925 7203 jc @F 1846 PUBLIC DSKERR_PATCH 1847 DSKERR_PATCH: 0 00008927 E8[0000] CALL CHECKIO ;| 1849 @@: 1850 ;---------------------------------------;| 1851 0 0000892A 1E push ds 0 0000892B E8[0000] call biocode_get_ds_dosentry 0 0000892E 803E[0000]01 cmp byte [MultiTrk_Format_Flag], 1 ;AN007;Multi trk format request? 0 00008933 7508 jne DoChkAgain ;AN007; 0 00008935 BD0100 mov bp, 1 ;AN007;No more retry. 0 00008938 C606[0000]00 mov byte [MultiTrk_Format_Flag], 0 ;AN007;Clear the flag. 1858 DoChkAgain: ;AN007; 0 0000893D 1F pop ds 0 0000893E E81408 CALL AGAIN 1861 DskErr0: ;AN003; 0 00008941 7425 JZ HARDERR 0 00008943 F745230100 test word ptr [di + FLAGS], fNon_Removable ;AN009; 0 00008948 7505 jnz Skip_TimeOut_Chk ;AN009; 0 0000894A 80FC80 CMP AH,80H ;TIMEOUT? 0 0000894D 7419 JZ HARDERR ;*** 1867 Skip_TimeOut_Chk: ;AN009; 0 0000894F 80FCCC cmp ah, 0cch ;AN003;Write Fault error? 0 00008952 740F jz Write_Fault_Err ;AN003; Then, don't retry. 0 00008954 1E push ds 0 00008955 E8[0000] call biocode_get_ds_dosentry 0 00008958 C706[0000]0500 mov word [Soft_ECC_Cnt], MAXERR ;AN003;Set Soft_ECC_Cnt back to MAXERR 0 0000895E 1F pop ds 1874 DSKERR1: 0 0000895F 58 POP AX ;RESTORE SECTOR COUNT 0 00008960 E9EFFE JMP RETRY 1877 1878 Write_Fault_Err: ;AN003; 0 00008963 BD0100 mov bp, 1 ;AN003;Just retry only once for Write Fault error. 0 00008966 EBF7 jmp DskErr1 ;AN003; 1881 1882 HARDERR: 1883 PUBLIC HARDERR 1884 0 00008968 E85D00 CALL MAPERROR 1886 1887 HARDERR2: ; FOR ROUTINES THAT CALL MAPERROR THEMSELVES 1888 PUBLIC HARDERR2 1889 0 0000896B 1E push ds 0 0000896C E8[0000] call biocode_get_ds_dosentry 0 0000896F 8F06[0000] pop word [dosentry_temp_ds] 0 00008973 C606[0000]FF MOV byte [TIM_DRV],-1 ;FORCE A MEDIA CHECK THROUGH ROM 0 00008978 8B0E[0000] MOV CX,[SECCNT] ;GET COUNT OF SECTORS TO GO 0 0000897C 8B26[0000] MOV SP,[SPSAV] ;RECOVER ENTRY STACK POINTER 0 00008980 8E1E[0000] mov ds, word [dosentry_temp_ds] 1897 ; 1898 ; SINCE WE ARE PERFORMING A NON-LOCAL GOTO, RESTORE THE DISK PARAMETERS 1899 ; 1900 MEDBYT_OK: 0 00008984 E822FE CALL DIDDLEBACK 0 00008987 C3 RET ;AND RETURN 1903 DSKERR ENDP 1904 1905 ; 1906 ; CHANGE SETTLE VALUE FROM SETTLECURRENT TO WHATEVER IS APPROPRIATE 1907 ; NOTE THAT THIS ROUTINE IS NEVER CALLED FOR A FIXED DISK. 1908 ; 1909 NORMSPEED PROC NEAR 0 00008988 06 push es 0 00008989 E8[0000] call biocode_get_es_dosentry 0 0000898C 26803E[FF00]00 cmp byte [es:Media_Set_For_Format], 0 ;AN012; 0 00008992 7525 jne FASTSPEED_es ;AN012; 0 00008994 1E PUSH DS 0 00008995 50 PUSH AX 0 00008996 26A0[0000] MOV AL,[es:SETTLESLOW] 0 0000899A 26C536[0000] LDS SI,[es:DPT] ; CURRENT DISK PARM TABLE 0 0000899F 884409 MOV [SI + DISK_HEAD_STTL],AL 0 000089A2 58 POP AX 0 000089A3 1F POP DS 0 000089A4 07 pop es 0 000089A5 E81200 CALL FASTSPEED 0 000089A8 06 push es 0 000089A9 E8[0000] call biocode_get_es_dosentry 0 000089AC 1E PUSH DS 0 000089AD 26C536[0000] LDS SI,[es:DPT] 0 000089B2 C6440901 MOV byte [SI + DISK_HEAD_STTL],1 ; 1 IS FAST SETTLE VALUE 0 000089B6 1F POP DS 0 000089B7 07 pop es 0 000089B8 C3 RET 1931 NORMSPEED ENDP 1932 1933 FASTSPEED_es: 0 000089B9 07 pop es 1935 FASTSPEED PROC NEAR 1936 ; 1937 ; IF THE DRIVE HAS BEEN MARKED AS TOO BIG (I.E. STARTING SECTOR OF THE 1938 ; PARTITION IS > 16 BITS, THEN ALWAYS RETURN DRIVE NOT READY. 1939 ; 0 000089BA F6451F80 TEST BYTE PTR [DI + FATSIZ],FTOOBIG 1941 %IF itest 1942 JZ READY 1943 JMP NOTREADY 1944 READY: 1945 %ELSE 0 000089BE 7503 JNZ NOTREADY 1947 %ENDIF 1948 1949 MESSAGE FTESTINIT,<"<"> 1950 MNUM FTESTINIT,AX 1951 MESSAGE FTESTINIT,<","> 1952 MNUM FTESTINIT,ES 1953 MESSAGE FTESTINIT,<":"> 1954 MNUM FTESTINIT 1955 MESSAGE FTESTINIT,<","> 1956 MNUM FTESTINIT,CX 1957 MESSAGE FTESTINIT,<","> 1958 MNUM FTESTINIT,DX 1959 MESSAGE FTESTINIT,<">"> 0 000089C0 CD13 INT 13H 1961 DEATH: 0 000089C2 C3 RET 1963 NOTREADY: 0 000089C3 F9 STC 0 000089C4 B480 MOV AH,80H 0 000089C6 EBFA JMP DEATH 1967 FASTSPEED ENDP 1968 1969 ; MAP ERROR RETURNED BY ROM IN AH INTO CORRESPONDING CODE TO BE RETURNED TO 1970 ; DOS IN AL. 1971 ; 1972 MAPERROR PROC NEAR 1973 PUBLIC MAPERROR 1974 0 000089C8 51 PUSH CX ; SAVE CX 0 000089C9 E8[0000] call biocode_get_es_dosentry 1977 ;MAKE ES THE LOCAL SEGMENT 0 000089CC 88E0 MOV AL,AH ;PUT ERROR CODE IN AL 0 000089CE 26A2[0000] MOV [es:LSTERR],AL ;TERMINATE LIST WITH ERROR CODE 0 000089D2 B9[0000] MOV CX,NUMERR ;NUMBER OF POSSIBLE ERROR CONDITIONS 0 000089D5 BF[0000] MOV DI,OFFSET ERRIN ;POINT TO ERROR CONDITIONS 0 000089D8 F2AE REPNE SCASB 0 000089DA 268A85[FFFF] MOV AL,[es:DI + NUMERR - 1] ;GET TRANSLATION 0 000089DF 59 POP CX ; RESTORE CX 0 000089E0 F9 STC ;FLAG ERROR CONDITION 0 000089E1 C3 RET 1987 MAPERROR ENDP 1988 1989 ; SET THE TIME OF LAST ACCESS FOR THIS DRIVE. THIS IS DONE ONLY FOR REMOVABLE 1990 ; MEDIA. 1991 1992 PUBLIC SET_TIM 1993 SET_TIM PROC NEAR 0 000089E2 50 PUSH AX 1995 ;SB33018****************************************************************** 0 000089E3 30E4 xor AH, AH ; set command to get time ;SB;3.30* 0 000089E5 CD1A int 1Ah ; call rom-bios timer function ;SB;3.30* 1998 ;SB33018****************************************************************** 0 000089E7 08C0 OR AL,AL 0 000089E9 7409 JZ NOROLL3 0 000089EB 1E push ds 0 000089EC E8[0000] call biocode_get_ds_dosentry 0 000089EF FF06[0000] INC word [DAYCNT] ; CATCH ROLLOVER 0 000089F3 1F pop ds 2005 NOROLL3: 2006 ; WE HAVE THE NEW TIME. IF WE SEE THAT THE TIME HAS PASSED, THEN WE RESET 2007 ; THE THRESHOLD COUNTER... 0 000089F4 3B5547 CMP DX,WORD PTR [DI + TIM_LO] 0 000089F7 7505 JNZ SETACCESS 0 000089F9 3B4D49 CMP CX,WORD PTR [DI + TIM_HI] 0 000089FC 7410 JZ DONE_SET 2012 SETACCESS: 0 000089FE 1E push ds 0 000089FF E8[0000] call biocode_get_ds_dosentry 0 00008A02 C606[0000]00 MOV BYTE PTR [ACCESSCOUNT],0 0 00008A07 1F pop ds 0 00008A08 895547 MOV WORD PTR [DI + TIM_LO],DX ;SAVE IT 0 00008A0B 894D49 MOV WORD PTR [DI + TIM_HI],CX 2019 DONE_SET: 0 00008A0E F8 CLC 0 00008A0F 58 POP AX 0 00008A10 C3 RET 2023 SET_TIM ENDP 2024 2025 ASSUME CS:BIOCODE,DS:NOTHING,ES:NOTHING,SS:NOTHING 2026 2027 ; 2028 ; THIS IS THE TRUE INT 13 HANDLER. WE PARSE THE REQUEST TO SEE IF THERE IS 2029 ; A DMA VIOLATION. IF SO, DEPENDING ON THE FUNCTION, WE: 2030 ; READ/WRITE BREAK THE REQUEST INTO THREE PIECES AND MOVE THE MIDDLE ONE 2031 ; INTO OUR INTERNAL BUFFER. 2032 ; FORMAT COPY THE FORMAT TABLE INTO THE BUFFER 2033 ; VERIFY POINT THE TRANSFER ADDRESS INTO THE BUFFER 2034 ; 2035 ; THIS IS THE BIGGEST BOGOSITY OF ALL. THE IBM CONTROLLER DOES NOT HANDLE 2036 ; OPERATIONS THAT CROSS PHYSICAL 64K BOUNDARIES. IN THESE CASES, WE COPY 2037 ; THE OFFENDING SECTOR INTO THE BUFFER BELOW AND DO THE I/O FROM THERE. 2038 ; 2039 2040 2041 INT13FRAME STRUC 0 000080B0 ???? OLDBP DW ? 0 000080B2 ???? OLDAX DW ? 0 000080B4 ???? OLDBX DW ? 0 000080B6 ???? OLDCX DW ? 0 000080B8 ???? OLDDX DW ? 0 000080BA ???????? OLDDD DD ? 0 000080BE ???? OLDF DW ? 2049 INT13FRAME ENDS 2050 === Switch to base=000000h -> "DOSENTRY" 2051 section DOSENTRY 2052 2053 extern Prev_DX, dosentry_temp_ds 2054 2055 === Switch to base=008400h -> "BIOCODE" 2056 section BIOCODE 2057 2058 ; ENTRY CONDITIONS: 2059 ; AH = FUNCTION 2060 ; AL = NUMBER OF SECTORS 2061 ; ES:BX = DMA ADDRESS 2062 ; CX = PACKED TRACK AND SECTOR 2063 ; DX = HEAD AND DRIVE 2064 ; OUTPUT CONDITIONS: 2065 ; NO DMA VIOLATION. 2066 ; 2067 relocated msdisk_i13 2068 PUBLIC BLOCK13 2069 BLOCK13 PROC FAR 2070 ; 2071 ; LET THE OPPERATION PROCEED. IF THERE IS A DMA VIOLATION, THEN WE DO THINGS. 2072 ; 0 00008A11 1E push ds 0 00008A12 E8[0000] call biocode_get_ds_dosentry 0 00008A15 A3[0000] MOV [PREVOPER],AX ; SAVE REQUEST 0 00008A18 1F pop ds 0 00008A19 9C PUSHF 0 00008A1A 80FC05 CMP AH,ROMFORMAT 0 00008A1D 750D JNZ NOT_FORMAT 2080 ; SET CHANGED BY FORMAT BIT FOR ALL LOGICAL DRIVES USING THIS PHYSICAL DRIVE 2081 ;---------------------------------------------------------| 2082 ; WARNING: DO NOT CHANGE THE FOLLOWING. 2083 ; IT GETS PATCHED IN AT INIT TIME | 0 00008A1F 53 push bx 0 00008A20 BB4001 MOV bx,FCHANGED_BY_FORMAT+FCHANGED 0 00008A23 E8210A call ispatched 0 00008A26 7203 jc @F 2088 PUBLIC CHANGED_PATCH 2089 CHANGED_PATCH: 0 00008A28 E8[0000] CALL SET_CHANGED_DL ; INDICATE THAT MEDIA CHANGED BY FORMAT 2091 @@: 0 00008A2B 5B pop bx 2093 ; | 2094 ;---------------------------------------------------------| 2095 NOT_FORMAT: 0 00008A2C 1E push ds 0 00008A2D E8[0000] call biocode_get_ds_dosentry 0 00008A30 F6C280 test dl, 80h ; floppy or hard disk? 0 00008A33 7529 jnz not_floppy ; if hard, skip this nonsense 0 00008A35 803E[0000]00 cmp byte [EC35_Flag], 0 ; any electrically compat. drives? 0 00008A3A 7422 jz not_floppy ; no; proceed unhindered 0 00008A3C 505351 SAVEREG 0 00008A3F 88D1 mov cl, dl ; turn drive number into bit map: 0 00008A41 B001 mov al, 1 ; assume drive 0 0 00008A43 D2E0 shl al, cl ; shift over correct number of times 0 00008A45 8406[0000] test al, [EC35_Flag] ; is THIS drive an electrically compatible 3.5 incher? 0 00008A49 7410 jz not_EC35 ; no; don't change anything 0 00008A4B 88D3 mov bl, dl ; which drive was it? 0 00008A4D 30FF xor bh, bh ; need only one byte of index 0 00008A4F B84000 mov ax, 40h ; the machine state byte is in the... 0 00008A52 1E push ds 0 00008A53 8ED8 mov ds, ax ; ...segment at 40h 0 00008A55 C687900093 mov byte ptr [90h+bx], 93H ; establish drive type as: (360k disk in 360k drive, no double-stepping, 250 kbs transfer rate) 0 00008A5A 1F pop ds 2115 not_EC35: 0 00008A5B 595B58 RESTOREREG 2117 not_floppy: 2118 model_byte equ Model_Byte ; NASM port label 0 00008A5E 803E[0000]FA cmp byte [model_byte], mdl_ps2_30 ; is this a ps2/30? 0 00008A63 750A jne not_ps2_30 ; if not, just do normal call 0 00008A65 80FC08 cmp ah, 8 ;J.K. 1/30/87 Read Driver Parm ? 0 00008A68 7412 je ps2_30_Problem ;J.K. 1/30/87 0 00008A6A 80FC15 cmp ah, 15h 0 00008A6D 740D je ps2_30_Problem 2125 not_ps2_30: 0 00008A6F 1F pop ds 0 00008A70 9A[0000][0000] call DOSENTRY:transfer_orig13 ; SIMULATE INT 13 0 00008A75 7203 JC GOTERR13_br ; ERROR? 0 00008A77 E9[0000] jmp Leave13 ; NO, RETURN AND CLEAR FLAGS 2130 2131 Goterr13 equ GOTERR13 ; NASM port label 0 00008A7A EB32 GOTERR13_br: jmp Goterr13 2133 === Switch to base=000000h -> "DOSENTRY" 2134 section DOSENTRY 2135 2136 extern transfer_orig13 2137 2138 === Switch to base=008400h -> "BIOCODE" 2139 section BIOCODE 2140 2141 extern Leave13 2142 2143 2144 ;J.K.1/30/87 ps2_30 machine has some problem with AH=8h(Read Drive Parm), Int 13h. 2145 ;This function does not reset the common buses after the execution. 2146 ;To solve this problem, when we detect AH=8h, then we will save the result and 2147 ;will issue AH=1 (Read Status) call to reset the buses. 2148 2149 ps2_30_Problem: ;J.K. 1/30/87; ps2_30 = PS2 Model 30. 0 00008A7C 8916[0000] mov [Prev_DX], DX ;save orignal drive number 0 00008A80 1F pop ds 2152 Orig13 equ ORIG13 ; NASM port label 0 00008A81 9A[0000][0000] call DOSENTRY:transfer_orig13 ;Do "Read drive parm" 2154 0 00008A86 50 push ax 0 00008A87 53 push bx 0 00008A88 51 push cx 0 00008A89 52 push dx 0 00008A8A 57 push di 0 00008A8B 56 push si 0 00008A8C 55 push bp 0 00008A8D 1E push ds 0 00008A8E 06 push es 0 00008A8F 9C pushf 0 00008A90 E8[0000] call biocode_get_ds_dosentry 0 00008A93 8B16[0000] mov dx, [Prev_DX] ;restore orignal drive 0 00008A97 B401 mov ah, 1 ;Read Status. 0 00008A99 9C pushf 0 00008A9A 9A[0000][0000] call DOSENTRY:transfer_orig13 ;Reset the bus as a side effect of this call. 2170 0 00008A9F 9D popf 0 00008AA0 07 pop es 0 00008AA1 1F pop ds 0 00008AA2 5D pop bp 0 00008AA3 5E pop si 0 00008AA4 5F pop di 0 00008AA5 5A pop dx 0 00008AA6 59 pop cx 0 00008AA7 5B pop bx 0 00008AA8 58 pop ax 2181 GotErr13 equ GOTERR13 ; NASM port label 0 00008AA9 7203 jc GotErr13 ;AH=8 had been an error? 0 00008AAB E9[0000] jmp Leave13 2184 2185 ; 2186 ; SOME KIND OF ERROR OCCURRED. SEE IF IT IS DMA VIOLATION 2187 ; 2188 GOTERR13: 0 00008AAE 9C PUSHF 0 00008AAF 80FC09 cmp ah, 09h ;AN011; DMA error? 0 00008AB2 7408 je Chk_ValidMedia_ERR13 ;AN011; 0 00008AB4 80FC11 cmp ah, 11h ;AN011; ECC error? 0 00008AB7 7403 je Chk_ValidMedia_ERR13 ;AN011; 0 00008AB9 EB53 jmp Skip_Ecc_Check ;AN011; Other error. Just return back. 0 00008ABB 90 nop ; identicalise 2196 2197 Chk_ValidMedia_ERR13: ;AN011;If SetDrive fails, then just 0 00008ABC 1E push ds ;AN011; return back to INT 13h caller, 0 00008ABD 57 push di ;AN011; without performing ECC, DMA 0 00008ABE 50 push ax ;AN011; error handling. 0 00008ABF E8[0000] call biocode_get_ds_dosentry 2202 Phys_Drv equ PHYS_DRV ; NASM port label 0 00008AC2 C606[0000]01 mov byte ptr [Phys_Drv], 1 ;AN011; 0 00008AC7 88D0 mov al, dl ;AN011; 2205 SetDrive equ SETDRIVE ; NASM port label 0 00008AC9 E8CCF9 call SetDrive ;AN011; 0 00008ACC E8[0000] call biocode_get_ds_dosentry 0 00008ACF C606[0000]00 mov byte ptr [Phys_Drv], 0 ;AN011; 0 00008AD4 58 pop ax ;AN011; 0 00008AD5 5F pop di ;AN011; 0 00008AD6 1F pop ds ;AN011; 0 00008AD7 7235 jc Skip_Ecc_Check ;AN011; 2213 2214 ; TEST OF BIT PATTERN 08H LET OTHER ERRORS BE PASSED AS DMA ERRORS - PTR 32D0519 2215 ; TEST AH,08H ; DMA BIT 0 00008AD9 80FC09 CMP AH, 09H ; DMA ERROR CODE 0 00008ADC 7503 JNZ CHECK_ECC 0 00008ADE E98A00 JMP GOTDMAERR 2219 CHECK_ECC: 2220 ;J.K. AN003; Soft ECC bug is only applied to PC1 and PC-XT. So, we will enforce 2221 ;this ECC error handler for them. Also, since CMC hardfiles in PC AT also 2222 ;generate a lot of unnecessary ECC errors, we will still cover PC ATs as 2223 ;it is done in the earlier version of MSBIO. 2224 ;During Format/Verify operation, we are going to consider any Soft Ecc as a 2225 ;hard error. 2226 2227 ;SB34DISK005***************************************************************** 2228 ;SB See if the machine we are operating on is a PC, XT or AT by checking 2229 ;SB the model byte. The soft ECC bug is only on these machines and if 2230 ;SB the machine we are operating on is not one of these three then we 2231 ;SB needn't do anything special. If we are operating one these however 2232 ;SB we check to see if the error occured during format by checking 2233 ;SB media_set_for_format. If it did occur during format we cannot do 2234 ;SB anything but if not during format then check to see if the error 2235 ;SB returned in AH is the SOFT_ECC error and if so go to OK11 since 2236 ;SB the error can be ignored. 6 LOCS 2237 0 00008AE1 1E push ds 0 00008AE2 E8[0000] call biocode_get_ds_dosentry 0 00008AE5 803E[FF00]01 cmp byte [Media_Set_For_Format], 1 ; formatting? 0 00008AEA 7421 je Skip_Ecc_Check_pop 0 00008AEC 803E[0000]FE cmp byte [Model_Byte], 0FEh ; PC or XT? 0 00008AF1 7315 jae Go_Chk_Ecc 0 00008AF3 803E[0000]FB cmp byte [Model_Byte], 0FBh ; XT? 0 00008AF8 740E je Go_Chk_Ecc 0 00008AFA 803E[0000]FC cmp byte [Model_Byte], 0FCh 0 00008AFF 750D jne Skip_Ecc_Check 0 00008B01 803E[0000]02 cmp byte [Secondary_Model_Byte], 2 ; AT? 0 00008B06 7706 ja Skip_Ecc_Check 2250 Go_Chk_Ecc: ; for PC, XT, AT 0 00008B08 80FC11 CMP AH,11H 0 00008B0B 7405 JZ OK11 2253 Skip_Ecc_Check_pop: 0 00008B0D 1F pop ds 2255 Skip_Ecc_Check: ;AN003; Just return back to INT 13h caller. 2256 2257 ;SB34DISK005***************************************************************** 2258 0 00008B0E 9D POPF 0 00008B0F E9[0000] jmp Leave13 2261 ; 2262 ; WE HAVE AN ERROR STATUS 11H. THIS INDICATES AN ECC-CORRECTED ERROR. NOTE 2263 ; THAT THIS INDICATES THAT THE DATA IS PROBABLY CORRECT BUT NOT CERTAINLY 2264 ; CORRECT. THE ROMS ON PC-1S AND PC_XTS HAVE A 'BUG' IN THAT IF AN ECC ERROR 2265 ; OCCURS FOR A MULTI-SECTOR READ, ONLY THE SECTORS UP TO THE ONE WHERE THE 2266 ; ERROR OCCURRED ARE READ IN. WE HAVE NO WAY OF KNOWING HOW MANY WERE READ IN 2267 ; THIS CASE, SO WE REDO THE OPERATION, READING ONE SECTOR AT A TIME. IF WE 2268 ; GET AN ECC ERROR ON READING ONE SECTOR, WE IGNORE THE ERROR BECAUSE THE 2269 ; SECTOR HAS BEEN READ IN. 2270 ; 2271 PUBLIC OK11 2272 OK11: 0 00008B12 1F pop ds 2274 ; POPF 2275 ;J.K. 8/29/86 Here, it is better reset the system. So, we are going to 2276 ;call Orig13 again 2277 0 00008B13 30E4 xor ah, ah 0 00008B15 9A[0000][0000] call DOSENTRY:transfer_orig13 ;reset. Don't care about the result 2280 0 00008B1A 1E push ds 0 00008B1B E8[0000] call biocode_get_ds_dosentry 0 00008B1E A1[0000] MOV AX,[PREVOPER] ; RETRIEVE REQUEST 2284 ; 2285 ; THIS WILL PROVIDE A TERMINATION POINT. 2286 ; 0 00008B21 3C01 CMP AL,1 ; IF REQUEST FOR ONE SECTOR, ASSUME OK 0 00008B23 7506 JNZ ECC_ERR_HANDLE 0 00008B25 1F pop ds 0 00008B26 30E4 XOR AH,AH ; CLEAR CARRY TOO! 0 00008B28 E9[0000] jmp Leave13 2292 2293 PUBLIC ECC_ERR_HANDLE 2294 ECC_ERR_HANDLE: 0 00008B2B 535152 SAVEREG 0 00008B2E A2[0000] MOV [NUMBER_OF_SEC],AL 2297 LOOP_ECC: 0 00008B31 A1[0000] MOV AX,[PREVOPER] 0 00008B34 B001 MOV AL,1 ; REQUEST FOR ONE SECTOR ONLY 2300 ; 2301 ; WE DO READS ONE SECTOR AT A TIME. THIS ENSURES THAT WE WILL EVENTUALLY 2302 ; FINISH THE REQUEST SINCE ECC ERRORS ON ONE SECTOR DO READ IN THAT SECTOR. 2303 ; 2304 ; WE NEED TO PUT IN SOME "INTELLIGENCE" INTO THE ECC HANDLER TO HANDLE READS 2305 ; THAT ATTEMPT TO READ MORE SECTORS THAN ARE AVAILABLE ON A PARTICULAR 2306 ; TRACK. 2307 ; WE CALL CHECK_WRAP TO SET UP THE SECTOR #, HEAD # AND CYLINDER # FOR 2308 ; THIS REQUEST. 2309 ; AT THIS POINT, ALL REGISTERS ARE SET UP FOR THE CALL TO ORIG13, EXCEPT 2310 ; THAT THERE MAY BE A STARTING SECTOR NUMBER THAT IS BIGGER THAN THE NUMBER 2311 ; OF SECTORS ON A TRACK. 2312 ; 0 00008B36 E82C08 CALL CHECK_WRAP ; GET CORRECT PARAMETERS FOR INT 13 0 00008B39 1F pop ds 0 00008B3A 9C PUSHF 0 00008B3B 9A[0000][0000] call DOSENTRY:transfer_orig13 0 00008B40 730F JNC OK11_OP 0 00008B42 80FC11 CMP AH,11H ; ONLY ALLOW ECC ERRORS 0 00008B45 751C JNZ OK11_EXIT_err ;J.K. 8/26/86 Other error? 0 00008B47 B400 mov ah, 0 ;J.K. ECC error. Reset the system again. 0 00008B49 9C pushf 0 00008B4A 9A[0000][0000] call DOSENTRY:transfer_orig13 0 00008B4F 31C0 xor ax, ax ; clear the error code so that if this 2324 ; was the last sector, no error code 2325 ; will be returned for the corrected 2326 ; read. (clear carry too.) 2327 OK11_OP: 0 00008B51 1E push ds 0 00008B52 E8[0000] call biocode_get_ds_dosentry 0 00008B55 FE0E[0000] DEC byte [NUMBER_OF_SEC] 0 00008B59 7409 JZ OK11_EXIT ; ALL DONE? 0 00008B5B FEC1 INC CL ; ADVANCE SECTOR NUMBER 0 00008B5D FEC7 INC BH ; ADD 200H TO ADDRESS 0 00008B5F FEC7 INC BH 0 00008B61 EBCE JMP SHORT LOOP_ECC 2336 OK11_EXIT_err: 0 00008B63 F9 stc ;J.K. 8/28/86 Set carry bit again. 2338 OK11_EXIT: 0 00008B64 1F pop ds 0 00008B65 5A595B RESTOREREG 0 00008B68 E9[0000] jmp Leave13 2342 ; 2343 ; WE TRULY HAVE A DMA VIOLATION. RESTORE REGISTER AX AND RETRY THE 2344 ; OPERATION AS BEST WE CAN. 2345 ; 2346 GOTDMAERR: 0 00008B6B 58 POP AX ; CLEAN UP STACK 0 00008B6C 1E push ds 0 00008B6D E8[0000] call biocode_get_ds_dosentry 0 00008B70 A1[0000] MOV AX,[PREVOPER] 0 00008B73 1F pop ds 0 00008B74 FB STI 0 00008B75 80FC02 CMP AH,ROMREAD ; SAVE USER FLAGS 0 00008B78 7268 JB INTDONE 0 00008B7A 80FC04 CMP AH,ROMVERIFY 0 00008B7D 7439 JZ INTVERIFY 0 00008B7F 80FC05 CMP AH,ROMFORMAT 0 00008B82 7447 JZ INTFORMAT 0 00008B84 775C JA INTDONE 2360 ; 2361 ; WE ARE DOING A READ/WRITE CALL. CHECK FOR DMA PROBLEMS 2362 ; 0 00008B86 52515350 SAVEREG 0 00008B8A 55 PUSH BP 0 00008B8B 89E5 MOV BP,SP 0 00008B8D 8CC2 MOV DX,ES ; CHECK FOR 64K BOUNDARY ERROR 2367 0 00008B8F D1E2 SHL DX,1 0 00008B91 D1E2 SHL DX,1 0 00008B93 D1E2 SHL DX,1 0 00008B95 D1E2 SHL DX,1 ; SEGMENT CONVERTED TO ABSOLUTE ADDRESS 2372 0 00008B97 01DA ADD DX,BX ; COMBINE WITH OFFSET 0 00008B99 81C2FF01 ADD DX,511 ; SIMULATE A TRANSFER 2375 ; 2376 ; IF CARRY IS SET, THEN WE ARE WITHIN 512 BYTES OF THE END OF THE SEGMENT. 2377 ; WE SKIP THE FIRST TRANSFER AND PERFORM THE REMAINING BUFFERING AND TRANSFER 2378 ; 0 00008B9D 7306 JNC NO_SKIP_FIRST 0 00008B9F 8A7609 MOV DH,BYTE PTR [BP + OLDDX+1] ; SET UP HEAD NUMBER 0 00008BA2 E9A300 JMP BUFFER ;J.K. 4/10/86 2382 ; JMP SHORT BUFFER 2383 ; 2384 ; DX IS THE PHYSICAL 16 BITS OF START OF TRANSFER. COMPUTE REMAINING 2385 ; SECTORS IN SEGMENT. 2386 ; 2387 NO_SKIP_FIRST: 0 00008BA5 D0EE SHR DH,1 ; DH = NUMBER OF SECTORS BEFORE ADDRESS 0 00008BA7 B480 MOV AH,128 ; AH = MAX NUMBER OF SECTORS IN SEGMENT 0 00008BA9 28F4 SUB AH,DH 2391 ; 2392 ; AH IS NOW THE NUMBER OF SECTORS THAT WE CAN SUCCESSFULLY WRITE IN THIS 2393 ; SEGMENT. IF THIS NUMBER IS ABOVE OR EQUAL TO THE REQUESTED NUMBER, THEN WE 2394 ; CONTINUE THE OPERATION AS NORMAL. OTHERWISE, WE BREAK IT INTO PIECES. 2395 ; 0 00008BAB 38C4 CMP AH,AL ; CAN WE FIT IT IN? 2397 DOBLOCK equ DoBlock ; NASM port label 0 00008BAD 7238 JB DOBLOCK ; NO, PERFORM BLOCKING. 2399 ; 2400 ; YES, THE REQUEST FITS. LET IT HAPPEN 2401 ; 0 00008BAF 8A7609 MOV DH,BYTE PTR [BP + OLDDX+1] ; SET UP HEAD NUMBER 0 00008BB2 E87908 CALL DOINT 0 00008BB5 E9FD00 JMP BAD13 2405 ; 2406 ; VERIFY THE GIVEN SECTORS. PLACE THE BUFFER POINTER INTO OUR SPACE. 2407 ; 2408 INTVERIFY: 0 00008BB8 0653 SAVEREG 0 00008BBA E8[0000] call biocode_get_es_dosentry 2411 DOSIMPLE: 0 00008BBD BB[0000] MOV BX,OFFSET DISKSECTOR 0 00008BC0 9C PUSHF 0 00008BC1 9A[0000][0000] call DOSENTRY:transfer_orig13 0 00008BC6 5B07 RESTOREREG 0 00008BC8 E9[0000] jmp Leave13 2417 2418 ; 2419 ; FORMAT OPERATION. COPY THE PARAMETER TABLE INTO MEMORY 2420 ; 2421 INTFORMAT: 0 00008BCB 0653 SAVEREG 0 00008BCD 56571E SAVEREG 0 00008BD0 06 PUSH ES 0 00008BD1 E8[0000] call biocode_get_es_dosentry 0 00008BD4 1F POP DS 0 00008BD5 89DE MOV SI,BX 0 00008BD7 BF[0000] MOV DI,OFFSET DISKSECTOR 0 00008BDA E84508 CALL MOVE 0 00008BDD 1F5F5E RESTOREREG 0 00008BE0 EBDB JMP DOSIMPLE 2432 ; 2433 ; INLINE CONTINUATION OF OPERATION 2434 ; 2435 INTDONE: 0 00008BE2 EA[0000][0000] jmp DOSENTRY:transfer_orig13 2437 2438 ; 2439 ; We can't fit the request into the entire block. Perform the operation on 2440 ; the first block. 2441 ; 2442 ; DoBlock is modified to correctly handle multi-sector disk I/O. -J.K. 4/10/86 2443 ; Old DoBlock had added the number of sectors I/Oed (Ah in Old DoBlock) after 2444 ; the DoInt call to CL. Observing only the lower 6 bits of CL(=max. 64) can 2445 ; represent a starting sector, if AH was big, then CL would be clobbered. 2446 ; By the way, we still are going to use CL for this purpose since Checkwrap 2447 ; routine will use it as an input. To prevent CL from being clobbered, a 2448 ; safe number of sectors should be calculated like "63 - # of sectors/track". 2449 ; DoBlock will handle the first block of requested sectors within the 2450 ; boundary of this safe value. - J.K. 2/28/86 2451 2452 DoBlock: 2453 ;Try to get the # of sectors/track from BDS via Rom drive number. 2454 ;For any mini disks installed, here we have to pray that they have the 2455 ;same # of sector/track as the main DOS partition disk drive. 2456 2457 Message ftestDisk,<"!!!DMA DoBlock!!!"> 2458 2459 olddx equ OLDDX ; NASM port equate 0 00008BE7 8B5608 mov dx, word ptr [bp + olddx] ;set head # 0 00008BEA 57 push di 0 00008BEB 1E push ds 0 00008BEC 50 push ax ;AH - # of sectors before DMA boundary 2464 ;AL - User requeseted # of sectors for I/O. 2465 phys_drv equ PHYS_DRV ; NASM port label 0 00008BED E8[0000] call biocode_get_ds_dosentry 0 00008BF0 C606[0000]01 mov byte ptr [phys_drv],1 0 00008BF5 88D0 mov al, dl 0 00008BF7 E89EF8 call SetDrive ;get BDS pointer for this DISK. 0 00008BFA 58 pop ax 0 00008BFB 1E push ds 0 00008BFC E8[0000] call biocode_get_ds_dosentry 0 00008BFF C606[0000]00 mov byte ptr [phys_drv],0 0 00008C04 1F pop ds 0 00008C05 F745230100 test word ptr [DI + Flags], fNon_Removable ;don't have to worry 0 00008C0A 7504 jnz DoBlockHard ;about floppies. They are track by track operation. 0 00008C0C 88E0 mov al, ah ;set al = ah for floppies 0 00008C0E EB0D jmp short DoBlockCont 2479 DoBlockHard: 0 00008C10 51 push cx 0 00008C11 8B4D13 mov cx, [DI + SecLim] ;# of sectors/track 0 00008C14 B53F mov ch, 63 0 00008C16 28CD sub ch, cl 0 00008C18 88E8 mov al, ch 0 00008C1A 86E0 xchg ah, al ;now ah - safe # of sectors 2486 ;al - # of sectors before DMA boundary 0 00008C1C 59 pop cx 2488 DoBlockCont: 0 00008C1D 1F pop ds 0 00008C1E 5F pop di 2491 DoBlockContinue: 2492 Message ftestDisk,<"%%DMA DoBlock Loop%%"> 0 00008C1F 38C4 cmp ah, al ;if safe_# >= #_of_sectors_to_go_before DMA, 0 00008C21 7305 jae DoBlocklast ;then #_of_sectors_to_go as it is for DoInt. 0 00008C23 50 push ax ;save AH, AL 0 00008C24 88E0 mov al, ah ;Otherwise, set al to ah to operate. 0 00008C26 EB03 jmp short DoBlockDoInt ;DoInt will set AH to a proper function in [BP.Oldax] 2498 DoBlocklast: 0 00008C28 88C4 mov ah, al 0 00008C2A 50 push ax ;save AH 2501 DoBlockDoInt: ;let AH = AL = # of sectors for this shot 2502 DoInt equ DOINT ; NASM port label 0 00008C2B E80008 CALL DoInt 0 00008C2E 7303E98200 JC BAD13 ;something happened, bye! 0 00008C33 58 pop ax 2506 oldax equ OLDAX ; NASM port equate 0 00008C34 286602 SUB BYTE PTR [BP + oldax], AH ;decrement by the successful operation 0 00008C37 00E1 ADD CL,AH ;advance sector number. Safety gauranteed. 0 00008C39 00E7 ADD BH,AH ;advance DMA address 0 00008C3B 00E7 ADD BH,AH ;twice for 512 byte sectors. 0 00008C3D 38C4 cmp ah, al ;check the previous value 2512 Buffer equ BUFFER ; NASM port label 0 00008C3F 7407 je Buffer ;if #_of_sectors_to_go < safe_#, then we are done already. 0 00008C41 28E0 sub al, ah ;otherwise, #_sector_to_go = #_of_sector_to_go - safe_# 2515 Check_Wrap equ CHECK_WRAP ; NASM port label 0 00008C43 E81F07 call Check_Wrap ;get new CX, DH for the next operation. 0 00008C46 EBD7 jmp short DoBlockContinue ;handles next sectors left. 2518 ;End of modificaion of DoBlock - J.K. 2/28/86 2519 ;The following is the original one. 2520 ; PUSH AX 2521 ; MOV AL,AH ; get max to operate on 2522 ; MOV AH,BYTE PTR [BP.oldax+1]; get function 2523 ; mov dh,byte ptr [BP.olddx+1] ; set up head number 2524 ; CALL DoInt 2525 ; JC Bad13 ; something happened, bye! 2526 ; POP AX 2527 ; SUB BYTE PTR [BP.oldax],AH ; decrement by the successful operation 2528 ; ADD CL,AH ; advance sector number 2529 ; ADD BH,AH ; advance DMA address 2530 ; ADD BH,AH ; twice for 512 byte sectors. 2531 2532 ; 2533 ; THE NEXT REQUEST WILL WRAP THE 64K BOUNDARY. IF WE ARE WRITING, THEN COPY 2534 ; THE OFFENDING SECTOR INTO OUR SPACE. 2535 ; 2536 ; ES:BX POINTS TO THE SECTOR 2537 ; CX,DX CONTAIN THE CORRECT TRACK/SECTOR/HEAD/DRIVE INFO 2538 ; [BP.OLDAX] HAS CORRECT FUNCTION CODE 2539 ; 2540 BUFFER: 0 00008C48 53 PUSH BX 0 00008C49 8A6603 MOV AH,BYTE PTR [BP + OLDAX+1] 0 00008C4C 80FC03 CMP AH,ROMWRITE 0 00008C4F 7526 JNZ DOREAD 2545 ; 2546 ; COPY THE OFFENDING SECTOR INTO LOCAL BUFFER 2547 ; 0 00008C51 1E065657 SAVEREG 0 00008C55 06 PUSH ES 0 00008C56 1F POP DS ; ds => user buffer 0 00008C57 E8[0000] call biocode_get_es_dosentry ; es => DOSENTRY 0 00008C5A BF[0000] MOV DI,OFFSET DISKSECTOR ; WHERE TO MOVE 0 00008C5D 57 PUSH DI ; SAVE IT 0 00008C5E 89DE MOV SI,BX ; SOURCE 0 00008C60 E8BF07 CALL MOVE 0 00008C63 5B POP BX ; NEW TRANSFER ADDRESS 0 00008C64 5F5E RESTOREREG 0 00008C66 B001 MOV AL,1 2559 ; SEE IF WE ARE WRAPPING AROUND A TRACK OR HEAD 0 00008C68 8A5608 MOV DL,BYTE PTR [BP + OLDDX] ; GET DRIVE NUMBER 0 00008C6B E8F706 CALL CHECK_WRAP ; SETS UP REGISTERS IF WRAP-AROUND 2562 ; 2563 ; AH IS FUNCTION 2564 ; AL IS 1 FOR SINGLE SECTOR TRANSFER 2565 ; ES:BX IS LOCAL TRANSFER ADDRES 2566 ; CX IS TRACK/SECTOR NUMBER 2567 ; DX IS HEAD/DRIVE NUMBER 2568 ; SI,DI UNCHANGED 2569 ; 0 00008C6E E8BD07 CALL DOINT 0 00008C71 071F RESTOREREG 0 00008C73 7240 JC BAD13 ; GO CLEAN UP 0 00008C75 EB28 JMP SHORT DOTAIL 2574 ; 2575 ; READING A SECTOR. DO INT FIRST, THEN MOVE THINGS AROUND 2576 ; 2577 DOREAD: 0 00008C77 0653 SAVEREG 0 00008C79 E8[0000] call biocode_get_es_dosentry 0 00008C7C BB[0000] MOV BX,OFFSET DISKSECTOR 0 00008C7F B001 MOV AL,1 2582 ; SEE IF OUR REQUEST WILL WRAP A TRACK OR HEAD BOUNDARY 0 00008C81 8A5608 MOV DL,BYTE PTR [BP + OLDDX] ; GET DRIVE NUMBER 0 00008C84 E8DE06 CALL CHECK_WRAP ; SETS UP REGISTERS IF WRAP-AROUND 2585 ; 2586 ; AH = FUNCTION 2587 ; AL = 1 FOR SINGLE SECTOR 2588 ; ES:BX POINTS TO LOCAL BUFFER 2589 ; CX, DX ARE TRACK/SECTOR, HEAD/DRIVE 2590 ; 0 00008C87 E8A407 CALL DOINT 0 00008C8A 5B07 RESTOREREG 0 00008C8C 7227 JC BAD13 ; ERROR => CLEAN UP 0 00008C8E 1E5657 SAVEREG 0 00008C91 E8[0000] call biocode_get_ds_dosentry 0 00008C94 89DF MOV DI,BX 0 00008C96 BE[0000] MOV SI,OFFSET DISKSECTOR 0 00008C99 E88607 CALL MOVE 0 00008C9C 5F5E1F RESTOREREG 2600 ; 2601 ; NOTE THE FACT THAT WE'VE DONE 1 MORE SECTOR 2602 ; 2603 DOTAIL: 0 00008C9F 5B POP BX ; RETRIEVE NEW DMA AREA 0 00008CA0 80C702 ADD BH,2 ; ADVANCE OVER SECTOR 0 00008CA3 41 INC CX 0 00008CA4 8A4602 MOV AL,BYTE PTR [BP + OLDAX] 0 00008CA7 F8 CLC 0 00008CA8 FEC8 DEC AL 0 00008CAA 7409 JZ BAD13 ; NO MORE I/O 2611 ; SEE IF WE WRAP AROUND A TRACK OR HEAD BOUNDARY WITH STARTING SECTOR 2612 ; WE ALREADY HAVE THE CORRECT HEAD NUMBER TO PASS TO CHECK_WRAP 0 00008CAC 8A5608 MOV DL,BYTE PTR [BP + OLDDX] ; GET DRIVE NUMBER 0 00008CAF E8B306 CALL CHECK_WRAP ; SETS UP REGISTERS IF WRAP-AROUND 0 00008CB2 E87907 CALL DOINT 2616 ; 2617 ; WE ARE DONE. AX HAS THE FINAL CODE; WE THROW AWAY WHAT WE GOT BEFORE 2618 ; 2619 BAD13: 0 00008CB5 89EC MOV SP,BP 0 00008CB7 5D5B5B595A RESTOREREG 0 00008CBC E9[0000] jmp Leave13 2623 BLOCK13 ENDP 2624 ; PAGE 2625 ;=== Push trace listing source: msioctl.nas 2626 %include "msioctl.nas" ; NASM included file 1 <1> %warning out: MSIOCTL.SIL... 1 ****************** <1> warning: out: MSIOCTL.SIL... [-w+user] 2 <1> %include "ioctl.mac" 1 <2> 2 <2> %warning out: IOCTL.INC... 2 ****************** <2> warning: out: IOCTL.INC... [-w+user] 3 <2> ; THESE ARE ALL THE IMPORTANT STRUCTURES AND EQUATES FOR IOCTL 4 <2> ;============================================================================== 5 <2> ;REVISION HISTORY: 6 <2> ;AN000 - New for DOS Version 4.00 - J.K. 7 <2> ;AC000 - Changed for DOS Version 4.00 - J.K. 8 <2> ;AN00x - PTM number for DOS Version 4.00 - J.K. 9 <2> ;============================================================================== 10 <2> ;AN001; D241 Provide support of Multi-track Format/Verify 9/23/87 J.K. 11 <2> ;AN002; P1535 Unformatted hard file problem 10/15/87 J.K. 12 <2> ;AN003; D490 IOCTL subfunction 63h,43h,64h,44h conflicts with OS2 2/26/88 J.K. 13 <2> ;============================================================================== 14 <2> 15 <2> ;*** J.K. 16 <2> ;General Guide - 17 <2> ;Category Code: 18 <2> ; 0... .... DOS Defined 19 <2> ; 1... .... User defined 20 <2> ; .xxx xxxx Code 21 <2> 22 <2> ;Function Code: 23 <2> ; 0... .... Return error if unsupported 24 <2> ; 1... .... Ignore if unsupported 25 <2> ; .0.. .... Intercepted by DOS 26 <2> ; .1.. .... Passed to driver 27 <2> ; ..0. .... Sends data/commands to device 28 <2> ; ..1. .... Quries data/info from device 29 <2> ; ...x .... Subfunction 30 <2> ; 31 <2> ; Note that "Sends/queries" data bit is intended only to regularize the 32 <2> ; function set. It plays no critical role; some functions may contain both 33 <2> ; command and query elements. The convention is that such commands are 34 <2> ; defined as "sends data". 35 <2> 36 <2> ;*****************************;* 37 <2> ; BLOCK DRIVERS ;* 38 <2> ;*****************************;* 39 <2> 40 <2> ; IOCTL SUB-FUNCTIONS 41 <2> IOCTL_GET_DEVICE_INFO EQU 0 42 <2> IOCTL_SET_DEVICE_INFO EQU 1 43 <2> IOCTL_READ_HANDLE EQU 2 44 <2> IOCTL_WRITE_HANDLE EQU 3 45 <2> IOCTL_READ_DRIVE EQU 4 46 <2> IOCTL_WRITE_DRIVE EQU 5 47 <2> IOCTL_GET_INPUT_STATUS EQU 6 48 <2> IOCTL_GET_OUTPUT_STATUS EQU 7 49 <2> IOCTL_CHANGEABLE? EQU 8 50 <2> IOCTL_DeviceLocOrRem? EQU 9 51 <2> IOCTL_HandleLocOrRem? EQU 0Ah ;10 52 <2> IOCTL_SHARING_RETRY EQU 0Bh ;11 53 <2> GENERIC_IOCTL_HANDLE EQU 0Ch ;12 54 <2> GENERIC_IOCTL EQU 0Dh ;13 55 <2> 56 <2> ; GENERIC IOCTL CATEGORY CODES 57 <2> IOC_OTHER EQU 0 ; Other device control J.K. 4/29/86 58 <2> IOC_SE EQU 1 ; SERIAL DEVICE CONTROL 59 <2> IOC_TC EQU 2 ; TERMINAL CONTROL 60 <2> IOC_SC EQU 3 ; SCREEN CONTROL 61 <2> IOC_KC EQU 4 ; KEYBOARD CONTROL 62 <2> IOC_PC EQU 5 ; PRINTER CONTROL 63 <2> IOC_DC EQU 8 ; DISK CONTROL (SAME AS RAWIO) 64 <2> 65 <2> ; GENERIC IOCTL SUB-FUNCTIONS 66 <2> RAWIO EQU 8 67 <2> 68 <2> ; RAWIO SUB-FUNCTIONS 69 <2> GET_DEVICE_PARAMETERS EQU 60H 70 <2> SET_DEVICE_PARAMETERS EQU 40H 71 <2> READ_TRACK EQU 61H 72 <2> WRITE_TRACK EQU 41H 73 <2> VERIFY_TRACK EQU 62H 74 <2> FORMAT_TRACK EQU 42H 75 <2> GET_MEDIA_ID EQU 66h ;AN000;AN003;changed from 63h 76 <2> SET_MEDIA_ID EQU 46h ;AN000;AN003;changed from 43h 77 <2> GET_ACCESS_FLAG EQU 67h ;AN002;AN003;Unpublished function.Changed from 64h 78 <2> SET_ACCESS_FLAG EQU 47h ;AN002;AN003;Unpublished function.Changed from 44h 79 <2> 80 <2> ; SPECIAL FUNCTION FOR GET DEVICE PARAMETERS 81 <2> BUILD_DEVICE_BPB EQU 000000001B 82 <2> 83 <2> ; SPECIAL FUNCTIONS FOR SET DEVICE PARAMETERS 84 <2> INSTALL_FAKE_BPB EQU 000000001B 85 <2> ONLY_SET_TRACKLAYOUT EQU 000000010B 86 <2> TRACKLAYOUT_IS_GOOD EQU 000000100B 87 <2> 88 <2> ; SPECIAL FUNCTION FOR FORMAT TRACK 89 <2> STATUS_FOR_FORMAT EQU 000000001B 90 <2> DO_FAST_FORMAT equ 000000010B ;AN001; 91 <2> ; CODES RETURNED FROM FORMAT STATUS CALL 92 <2> FORMAT_NO_ROM_SUPPORT EQU 000000001B 93 <2> FORMAT_COMB_NOT_SUPPORTED EQU 000000010B 94 <2> 95 <2> ; DEVICETYPE VALUES 96 <2> MAX_SECTORS_IN_TRACK EQU 63 ; MAXIMUM SECTORS ON A DISK.(Was 40 in DOS 3.2) 97 <2> DEV_5INCH EQU 0 98 <2> DEV_5INCH96TPI EQU 1 99 <2> DEV_3INCH720KB EQU 2 100 <2> DEV_8INCHSS EQU 3 101 <2> DEV_8INCHDS EQU 4 102 <2> DEV_HARDDISK EQU 5 103 <2> DEV_OTHER EQU 7 104 <2> 105 <2> MAX_DEV_TYPE EQU 7 ; MAXIMUM DEVICE TYPE THAT WE 106 <2> ; CURRENTLY SUPPORT. 107 <2> 108 <2> %include "bpb.mac" 1 <3> %warning out: BPB.INC... 1 ****************** <3> warning: out: BPB.INC... [-w+user] 2 <3> ; SCCSID = @(#)BPB.ASM 1.1 85/04/29 3 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 4 <3> ; C A V E A T P R O G R A M M E R ; 5 <3> ; ; 6 <3> 7 <3> ; BIOS PARAMETER BLOCK DEFINITION 8 <3> ; THIS STRUCTURE IS USED TO BUILD A FULL DPB 9 <3> 10 <3> BPBLOCK STRUC 0 000080B0 ???? BPSECSZ DW ? ; SIZE IN BYTES OF PHYSICAL SECTOR 0 000080B2 ?? BPCLUS DB ? ; SECTORS/ALLOC UNIT 0 000080B3 ???? BPRES DW ? ; NUMBER OF RESERVED SECTORS 0 000080B5 ?? BPFTCNT DB ? ; NUMBER OF FATS 0 000080B6 ???? BPDRCNT DW ? ; NUMBER OF DIRECTORY ENTRIES 0 000080B8 ???? BPSCCNT DW ? ; TOTAL NUMBER OF SECTORS 0 000080BA ?? BPMEDIA DB ? ; MEDIA DESCRIPTOR BYTE 0 000080BB ???? BPFTSEC DW ? ; NUMBER OF SECTORS TAKEN UP BY ONE FAT 19 <3> BPBLOCK ENDS 20 <3> 21 <3> A_BPB STRUC 0 000080B0 ???? BPB_BYTESPERSECTOR DW ? 0 000080B2 ?? BPB_SECTORSPERCLUSTER DB ? 0 000080B3 ???? BPB_RESERVEDSECTORS DW ? 0 000080B5 ?? BPB_NUMBEROFFATS DB ? 0 000080B6 ???? BPB_ROOTENTRIES DW ? 0 000080B8 ???? BPB_TOTALSECTORS DW ? 0 000080BA ?? BPB_MEDIADESCRIPTOR DB ? 0 000080BB ???? BPB_SECTORSPERFAT DW ? 0 000080BD ???? BPB_SECTORSPERTRACK DW ? 0 000080BF ???? BPB_HEADS DW ? 0 000080C1 ???? BPB_HIDDENSECTORS DW ? 0 000080C3 ???? DW ? 0 000080C5 ???? BPB_BIGTOTALSECTORS DW ? 0 000080C7 ???? DW ? 0 000080C9 ???????????? DB 6 DUP(?) 37 <3> A_BPB ENDS 38 <3> ; ; 39 <3> ; C A V E A T P R O G R A M M E R ; 40 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 41 <3> 109 <2> 110 <2> A_SECTORTABLE STRUC 0 000080B0 ???? ST_SECTORNUMBER DW ? 0 000080B2 ???? ST_SECTORSIZE DW ? 113 <2> A_SECTORTABLE ENDS 114 <2> 115 <2> A_DEVICEPARAMETERS STRUC 0 000080B0 ?? DP_SPECIALFUNCTIONS DB ? 0 000080B1 ?? DP_DEVICETYPE DB ? 0 000080B2 ???? DP_DEVICEATTRIBUTES DW ? 0 000080B4 ???? DP_CYLINDERS DW ? 0 000080B6 ?? DP_MEDIATYPE DB ? 121 00000007 <2> DP_BPB DB A_BPB_struc_size DUP (?) 0 000080D6 ???? DP_TRACKTABLEENTRIES DW ? 123 00000028 <2> DP_SECTORTABLE DB MAX_SECTORS_IN_TRACK * A_SECTORTABLE_struc_size DUP (?) 124 <2> A_DEVICEPARAMETERS ENDS 125 <2> 126 <2> A_TRACKREADWRITEPACKET STRUC 0 000080B0 ?? TRWP_SPECIALFUNCTIONS DB ? 0 000080B1 ???? TRWP_HEAD DW ? 0 000080B3 ???? TRWP_CYLINDER DW ? 0 000080B5 ???? TRWP_FIRSTSECTOR DW ? 0 000080B7 ???? TRWP_SECTORSTOREADWRITE DW ? 0 000080B9 ???????? TRWP_TRANSFERADDRESS DD ? 133 <2> A_TRACKREADWRITEPACKET ENDS 134 <2> 135 <2> ;AN001; - FP_TRACKCOUNT is only meaningful when FP_SPECIALFUNCTIONS bit 1 = 1. 136 <2> A_FORMATPACKET STRUC 0 000080B0 ?? FP_SPECIALFUNCTIONS DB ? 0 000080B1 ???? FP_HEAD DW ? 0 000080B3 ???? FP_CYLINDER DW ? 0 000080B5 ???? FP_TRACKCOUNT DW ? ;1 141 <2> A_FORMATPACKET ENDS 142 <2> 143 <2> A_VERIFYPACKET STRUC 0 000080B0 ?? VP_SPECIALFUNCTIONS DB ? 0 000080B1 ???? VP_HEAD DW ? 0 000080B3 ???? VP_CYLINDER DW ? 147 <2> A_VERIFYPACKET ENDS 148 <2> 149 <2> A_MEDIA_ID_INFO STRUC 0 000080B0 ???? MI_LEVEL DW ? ;0 ;J.K. 87 Info. level 0 000080B2 ???????? MI_SERIAL DD ? ;J.K. 87 Serial # 152 00000006 <2> MI_LABEL DB 11 DUP (?) ;(' ') ;J.K. 87 volume label 0 000080C1 ???????????????? MI_SYSTEM DB 8 DUP (?) ;(' ') ;J.K. 87 File system type 154 <2> A_MEDIA_ID_INFO ENDS 155 <2> 156 <2> A_DISKACCESS_CONTROL STRUC ;AN002; Unpublished function. Only for Hard file. 0 000080B0 ?? DAC_SPECIALFUNCTIONS DB ? ;0 ;AN002; Always 0 0 000080B1 ?? DAC_ACCESS_FLAG DB ? ;0 ;AN002; Non Zero - allow disk I/O to unformatted hard file 159 <2> A_DISKACCESS_CONTROL ENDS ;AN002; 0 - Disallow disk I/O to unformatted hard file 160 <2> 161 <2> ;********************************;* 162 <2> ; CHARACTER DEVICES (PRINTERS) ;* 163 <2> ;********************************;* 164 <2> 165 <2> ;RAWIO SUB-FUNCTIONS 166 <2> GET_RETRY_COUNT EQU 65H 167 <2> SET_RETRY_COUNT EQU 45H 168 <2> 169 <2> A_RETRYCOUNT STRUC 0 000080B0 ???? RC_COUNT DW ? 171 <2> A_RETRYCOUNT ENDS 172 <2> 173 <2> ;********************************;* ;J.K. 4/29/86 174 <2> ; CHARACTER DEVICES (SCREEN) ;* 175 <2> ;********************************;* ;J.K. 4/29/86 176 <2> ; 177 <2> ;SC_MODE_INFO struc 178 <2> ;SC_INFO_LENGTH DW 9 179 <2> ;SC_MODE DB 0 180 <2> ;SC_COLORS DW 0 181 <2> ;SC_WIDTH DW 0 182 <2> ;SC_LENGTH DW 0 183 <2> ;SC_MODE_INFO ends 184 <2> ; 185 <2> ;SC_INFO_PACKET_LENGTH EQU 9 ;LENGTH OF THE INFO PACKET. 186 <2> 187 <2> ;SUBFUNCTIONS FOR CON$GENIOCTL 188 <2> ;GET_SC_MODE EQU 60h 189 <2> ;SET_SC_MODE EQU 40h 190 <2> ;The following subfunctions are reserved for installable CODE PAGE switch 191 <2> ;console devices. - J.K. 4/29/86 192 <2> ;Get_active_codepage equ 6Ah 193 <2> ;Invoke_active_codepage equ 4Ah 194 <2> ;Start_designate_codepage equ 4Ch 195 <2> ;End_designate_codepage equ 4Dh 196 <2> ;Get_list_of_designated_codepage equ 6Bh 197 <2> ;J.K. 4/29/86 *** End of Con$genioctl equates & structures 3 <1> ; $SALUT $ioctl$ 4 <1> 5 <1> ;============================================================================== 6 <1> ;REVISION HISTORY: 7 <1> ;AN000 - New for DOS Version 4.00 - J.K. 8 <1> ;AC000 - Changed for DOS Version 4.00 - J.K. 9 <1> ;AN00x - PTM number for DOS Version 4.00 - J.K. 10 <1> ;============================================================================== 11 <1> ;AN001 - P58 Diskcopy format fails when error occurs during format op.6/26/87 J.K. 12 <1> ;AN002; - d24 MultiTrack= command added. 6/29/87 J.K. 13 <1> ;AN003; - p155 Format intermittant failre due to haed settle time 8/18/87 J.K. 14 <1> ;AN004; D113 Disable I/O access to unformatted media 9/03/87 J.K. 15 <1> ;AN005; P985 Allow I/O access to unformtted media 9/14/87 J.K. 16 <1> ;AN006; D241 Provide support of Multi-track Format/Verify 9/23/87 J.K. 17 <1> ;AN007; P1535 Unformatted hard file problem 10/15/87 J.K. 18 <1> ;AN008; P2590 Change the recommended BPB info. after AFS format 11/20/87 J.K. 19 <1> ;AN009; P2828 Do not retry for multi-track format request 12/08/87 J.K. 20 <1> ;AN010; P2781 Changeline error behavior incompatibile with DOS 3.3. 1/06/88 J.K. 21 <1> ;AN011; P3178 Set Media ID should update media info in BDS table. 1/21/88 J.K. 22 <1> ;AN012; D490 IOCTL subfunction 63h,43h,64h,44h conflicts with OS2 2/26/88 J.K. 23 <1> ;============================================================================== 24 <1> 25 <1> ;J.K. 10/15/87 26 <1> ;NOTE: GetAccessFlag/SetAccessFlag is unpublished function. 27 <1> ; This function is intended to give the user to control the 28 <1> ; BDS table FLAGS of UNFORMATTED_MEDIA bit. 29 <1> ; GetAccessFlag will show the status - 30 <1> ; A_DISKACCESS_CONTROL.DAC_ACCESS_FLAG = 0 DISK I/O not allowed 31 <1> ; 1 DISK I/O allowed 32 <1> ; SetAccessFlag will Set/Reset the UNFORMATTED_MEDIA bit in FLAGS - 33 <1> ; A_DISKACCESS_CONTROL.DAC_ACCESS_FLAG = 0 Allow disk I/O 34 <1> ; 1 Disallow disk I/O 35 <1> ;------------------------------------------------------------------------------ 36 <1> === Switch to base=008400h -> "BIOCODE" 37 <1> section BIOCODE 38 <1> 39 <1> 0 00008CBF 00 align 2, db 0 0 00008CC0 00 db 0 42 <1> ; GENERIC IOCTL DISPATCH TABLES 43 <1> ; 0 00008CC1 07 IOREADJUMPTABLE DB 7 ;AN012;maximum number (0 based) 0 00008CC2 [770C] DW OFFSET GETDEVICEPARAMETERS ;60h 0 00008CC4 [3D0F] DW OFFSET READTRACK ;61h 0 00008CC6 [DC0E] DW OFFSET VERIFYTRACK ;62h 0 00008CC8 [730C] dw Cmd_Err_Proc ;AN012;Overlapped with OS2 subfunction 0 00008CCA [730C] dw Cmd_Err_Proc ;AN012; 0 00008CCC [730C] dw Cmd_Err_Proc ;AN012; 0 00008CCE [AF11] dw GetMediaID ;AN000;AN012;66h 0 00008CD0 [8D12] dw GetAccessFlag ;AN007;AN012;67h Unpublished function 53 <1> 0 00008CD2 00 db 0 0 00008CD3 07 IOWRITEJUMPTABLE DB 7 ;AN012; 0 00008CD4 [B30C] DW OFFSET SETDEVICEPARAMETERS ;40h 0 00008CD6 [490F] DW OFFSET WRITETRACK ;41h 0 00008CD8 [220E] DW OFFSET FORMATTRACK ;42h 0 00008CDA [730C] dw Cmd_Err_Proc ;AN012; 0 00008CDC [730C] dw Cmd_Err_Proc ;AN012; 0 00008CDE [730C] dw Cmd_Err_Proc ;AN012; 0 00008CE0 [EA11] dw SetMediaID ;AN000;AN012;46h 0 00008CE2 [A112] dw SetAccessFlag ;AN007;AN012;47h Unpublished function 64 <1> 65 <1> === Switch to base=000000h -> "DOSENTRY" 66 <1> section DOSENTRY 67 <1> 68 <1> ; 69 <1> ; TRACKTABLE CONTAINS A 4-TUPLES (C,H,R,N) FOR EACH SECTOR IN A TRACK 70 <1> ; C = CYLINDER NUMBER, H = HEAD NUMBER, R = SECTOR ID, N = BYTES PER SECTOR 71 <1> ; N BYTES PER SECTOR 72 <1> ; --- ---------------- 73 <1> ; 0 128 74 <1> ; 1 256 75 <1> ; 2 512 76 <1> ; 3 1024 77 <1> ; 78 <1> MAX_SECTORS_CURR_SUP EQU 63 ; CURRENT MAXIMUM SEC/TRK THAT 79 <1> ; WE SUPPORT (Was 40 in DOS 3.2) 80 <1> 81 <1> align 2, db 0 0 00000648 2400 SECTORSPERTRACK DW 36 0 0000064A 00000102 TRACKTABLE DB 0,0,1,2 0 0000064E 00000202 DB 0,0,2,2 0 00000652 00000302 DB 0,0,3,2 0 00000656 00000402 DB 0,0,4,2 0 0000065A 00000502 DB 0,0,5,2 0 0000065E 00000602 DB 0,0,6,2 0 00000662 00000702 DB 0,0,7,2 0 00000666 00000802 DB 0,0,8,2 0 0000066A 00000902 DB 0,0,9,2 0 0000066E 00000A02 DB 0,0,10,2 0 00000672 00000B02 DB 0,0,11,2 0 00000676 00000C02 DB 0,0,12,2 0 0000067A 00000D02 DB 0,0,13,2 0 0000067E 00000E02 DB 0,0,14,2 0 00000682 00000F02 DB 0,0,15,2 0 00000686 00001002 db 0,0,16,2 0 0000068A 00001102 db 0,0,17,2 0 0000068E 00001202 db 0,0,18,2 0 00000692 00001302 db 0,0,19,2 0 00000696 00001402 db 0,0,20,2 0 0000069A 00001502 db 0,0,21,2 0 0000069E 00001602 db 0,0,22,2 0 000006A2 00001702 db 0,0,23,2 0 000006A6 00001802 db 0,0,24,2 0 000006AA 00001902 db 0,0,25,2 0 000006AE 00001A02 db 0,0,26,2 0 000006B2 00001B02 db 0,0,27,2 0 000006B6 00001C02 db 0,0,28,2 0 000006BA 00001D02 db 0,0,29,2 0 000006BE 00001E02 db 0,0,30,2 0 000006C2 00001F02 db 0,0,31,2 0 000006C6 00002002 db 0,0,32,2 0 000006CA 00002102 db 0,0,33,2 0 000006CE 00002202 db 0,0,34,2 0 000006D2 00002302 db 0,0,35,2 0 000006D6 00002402 db 0,0,36,2 0 000006DA 000000000000000000 DB 4*MAX_SECTORS_CURR_SUP - ($ - TRACKTABLE) DUP (0) 0 000006E3 000000000000000000 0 000006EC 000000000000000000 0 000006F5 000000000000000000 0 000006FE 000000000000000000 0 00000707 000000000000000000 0 00000710 000000000000000000 0 00000719 000000000000000000 0 00000722 000000000000000000 0 0000072B 000000000000000000 0 00000734 000000000000000000 0 0000073D 000000000000000000 120 <1> 121 <1> 122 <1> ; THIS IS A REAL UGLY PLACE TO PUT THIS 123 <1> ; IT SHOULD REALLY GO IN THE BDS 0 00000746 00 MEDIATYPE DB 0 125 <1> 0 00000747 00 MEDIA_SET_FOR_FORMAT DB 0 ; 1 IF WE HAVE DONE AN INT 13 SET MEDIA 127 <1> ; TYPE FOR FORMAT CALL 0 00000748 00 Had_Format_Error db 0 ; 1 if the previous format operation 129 <1> ; failed. - J.K. 7/8/86 130 <1> Dsk_time_out_Err equ 80h ; Time out error (No media present). 131 <1> Dsk_change_line_Err equ 6h ; Change line error 132 <1> Dsk_illegal_combination equ 0Ch ; Return code of ah=18h function. 133 <1> 0 00000749 00 align 2, db 0 135 <1> ; TEMP DISK BASE TABLE. IT HOLDS THE THE CURRENT DPT WHICH IS THEN REPLACED BY 136 <1> ; THE ONE PASSED BY "NEW ROMS" BEFORE WE PERFORM A FORMAT OPERATION. THE OLD 137 <1> ; DPT IS RESTORED IN RESTOREOLDDPT. THE FIRST ENTRY (DISK_SPECIFY_1) IS -1 IF 138 <1> ; THIS TABLE DOES NOT CONTAIN THE PREVIOUSLY SAVED DPT. 0 0000074A FFFFFFFF TEMPDPT DD -1 140 <1> 141 <1> === Switch to base=008400h -> "BIOCODE" 142 <1> section BIOCODE 143 <1> 144 <1> ; 145 <1> ; GENERIC$IOCTL: 146 <1> ; PERFORM GENERIC IOCTL REQUEST 147 <1> ; INPUT: 148 <1> ; AL - UNIT NUMBER 149 <1> ; OUTPUT: 150 <1> ; IF CARRY SET THEN AL CONTAINS ERROR CODE 151 <1> ; 152 <1> PUBLIC GENERIC$IOCTL 153 <1> GENERIC$IOCTL: 154 <1> MESSAGE FTESTDISK,<"GENERIC IOCTL",CR,LF> 0 00008CE4 E8[0000] call biocode_get_es_dosentry 0 00008CE7 26C41E[0000] LES BX,[es:PTRSAV] ; ES:BX POINTS TO REQUEST HEADER. 0 00008CEC E8A9F7 CALL SETDRIVE ; DS:DI POINTS TO BDS FOR DRIVE. 158 <1> ; 159 <1> ; AT THIS POINT: 160 <1> ; ES:BX - POINTS TO THE REQUEST HEADER 161 <1> ; DS:DI POINTS TO THE BDS FOR THE DRIVE 162 <1> ; 0 00008CEF 26807F0D08 CMP byte [ES:BX + MAJORFUNCTION], RAWIO 0 00008CF4 752A JNE IOCTL_FUNC_ERR 0 00008CF6 268A470E MOV AL, [ES:BX + MINORFUNCTION] 0 00008CFA BE[110C] MOV SI, OFFSET IOREADJUMPTABLE 0 00008CFD A820 TEST AL, GEN_IOCTL_FN_TST ; TEST OF REQ. FUNCTION 0 00008CFF 7503 JNZ NOTGENERICIOCTLWRITE ; FUNCTION IS A READ. 0 00008D01 BE[230C] MOV SI, OFFSET IOWRITEJUMPTABLE 170 <1> NOTGENERICIOCTLWRITE: 171 <1> ; AND AL, 0FH 0 00008D04 249F and al, 9fH ;AN000; Try to check other than 6x, 4x. 0 00008D06 2E3A04 CMP AL, [CS:SI] 0 00008D09 7715 JA IOCTL_FUNC_ERR 0 00008D0B 98 CBW 0 00008D0C D1E0 SHL AX, 1 0 00008D0E 46 INC SI 0 00008D0F 01C6 ADD SI,AX 0 00008D11 26C45F13 LES BX, [ES:BX + GENERICIOCTL_PACKET] 0 00008D15 2EFF14 CALL [CS:SI] 0 00008D18 7203 JC FAILGENERIC$IOCTL 0 00008D1A E9[0000] JMP EXIT 183 <1> 184 <1> FAILGENERIC$IOCTL: 0 00008D1D E9[0000] JMP ERR$EXIT 186 <1> 187 <1> IOCTL_FUNC_ERR: 0 00008D20 E9[0000] JMP CMDERR 189 <1> Cmd_Err_Proc: ;AN012; 0 00008D23 5A pop dx ;AN012;clear up stack 0 00008D24 5A pop dx ;AN012;clear up stack 0 00008D25 EBF9 jmp IOCTL_FUNC_ERR ;AN012;Cmd error 193 <1> ; 194 <1> ; GETDEVICEPARAMETERS: 195 <1> ; 196 <1> ; INPUT: DS:DI POINTS TO BDS FOR DRIVE 197 <1> ; ES:BX POINTS TO DEVICE PARAMETER PACKET 198 <1> ; 199 <1> PUBLIC GETDEVICEPARAMETERS 200 <1> GETDEVICEPARAMETERS PROC NEAR 201 <1> ; COPY INFO FROM BDS TO THE DEVICE PARAMETERS PACKET 0 00008D27 8A4522 MOV AL, BYTE PTR [DI + FORMFACTOR] 0 00008D2A 26884701 MOV BYTE PTR [ES:BX + DP_DEVICETYPE], AL 0 00008D2E 8B4523 MOV AX, WORD PTR [DI + FLAGS] 0 00008D31 83E003 AND AX,FNON_REMOVABLE+FCHANGELINE ; MASK OFF OTHER BITS 0 00008D34 26894702 MOV WORD PTR [ES:BX + DP_DEVICEATTRIBUTES], AX 0 00008D38 8B4525 MOV AX, WORD PTR [DI + CCYLN] 0 00008D3B 26894704 MOV WORD PTR [ES:BX + DP_CYLINDERS], AX 209 <1> 210 <1> ; SET MEDIA TYPE TO DEFAULT 0 00008D3F 30C0 XOR AL, AL 0 00008D41 26884706 MOV BYTE PTR [ES:BX + DP_MEDIATYPE], AL 213 <1> 214 <1> ; COPY RECOMMENDED BPB 0 00008D45 8D7527 LEA SI, [DI + RBYTEPERSEC] 0 00008D48 26F60701 TEST BYTE PTR [ES:BX + DP_SPECIALFUNCTIONS], BUILD_DEVICE_BPB 0 00008D4C 740B JZ USE_BPB_PRESENT 218 <1> ; GET THE CORRECT DISK IN THE DRIVE 0 00008D4E E897F7 CALL CHECKSINGLE 220 <1> ; BUILD THE BPB FROM SCRATCH 0 00008D51 E8D5F4 CALL GETBP 0 00008D54 720C JC GET_PARM_RET 0 00008D56 8D7506 LEA SI,[DI + BYTEPERSEC] 224 <1> USE_BPB_PRESENT: 0 00008D59 8D7F07 LEA DI, [BX + DP_BPB] 0 00008D5C B91900 MOV CX, BPB_TYPE_struc_size ; FOR NOW USE 'SMALL' BPB 0 00008D5F F3A4 REP MOVSB 0 00008D61 F8 CLC 229 <1> GET_PARM_RET: 0 00008D62 C3 RET 231 <1> GETDEVICEPARAMETERS ENDP 232 <1> 233 <1> ; 234 <1> ; SETDEVICEPARAMETERS: 235 <1> ; 236 <1> ; INPUT: DS:DI POINTS TO BDS FOR DRIVE 237 <1> ; ES:BX POINTS TO DEVICE PARAMETER PACKET 238 <1> ; 239 <1> PUBLIC SETDEVICEPARAMETERS 240 <1> SETDEVICEPARAMETERS PROC NEAR 241 <1> ; MAKE SURE THE FCHANGED_BY_FORMAT FLAG GETS SET TO KICK DOS INTO LOOKING AT 242 <1> ; THE BPB 0 00008D63 814D234001 OR WORD PTR [DI + FLAGS], FCHANGED_BY_FORMAT | FCHANGED 0 00008D68 26F60702 TEST BYTE PTR [ES:BX + DP_SPECIALFUNCTIONS], ONLY_SET_TRACKLAYOUT 0 00008D6C 7403 JZ SHORT SETDEVPARM_1 0 00008D6E EB79 JMP SETTRACKTABLE ; ORIGINALLY TRACKLAYOUT 0 00008D70 90 nop ; identicalise 248 <1> 249 <1> SETDEVPARM_1: 250 <1> ; COPY INFO FROM THE DEVICE PARAMETERS PACKET TO BDS 0 00008D71 268A4701 MOV AL, BYTE PTR [ES:BX + DP_DEVICETYPE] 0 00008D75 884522 MOV BYTE PTR [DI + FORMFACTOR], AL 253 <1> 0 00008D78 268B4704 MOV AX, WORD PTR [ES:BX + DP_CYLINDERS] 0 00008D7C 894525 MOV WORD PTR [DI + CCYLN], AX 256 <1> 257 <1> ; IF CHANGE LINE IS NOT LOADED THEN IGNORE CHANGELING FLAG 0 00008D7F 268B4702 MOV AX, WORD PTR [ES:BX + DP_DEVICEATTRIBUTES] 0 00008D83 1E push ds 0 00008D84 E8[0000] call biocode_get_ds_dosentry 0 00008D87 803E[0000]00 CMP byte [FHAVE96],0 0 00008D8C 1F pop ds 0 00008D8D 7503 JNZ HAVE_CHANGE 0 00008D8F 83E0FD AND AX,~ FCHANGELINE 265 <1> HAVE_CHANGE: 266 <1> ; IGNORE ALL BITS EXCEPT NON_REMOVABLE AND CHANGELINE 0 00008D92 83E003 AND AX,FNON_REMOVABLE | FCHANGELINE 0 00008D95 8B4D23 MOV CX, WORD PTR [DI + FLAGS] 269 <1> ; AND CX, NOT (FNON_REMOVABLE OR FCHANGELINE OR GOOD_TRACKLAYOUT) 0 00008D98 81E1F4FD AND CX, ~ (FNON_REMOVABLE | FCHANGELINE | GOOD_TRACKLAYOUT | UNFORMATTED_MEDIA) ;AN004;AN005;AN007; 0 00008D9C 09C8 OR AX, CX 0 00008D9E 894523 MOV WORD PTR [DI + FLAGS], AX 273 <1> 274 <1> ; SET MEDIA TYPE 0 00008DA1 268A4706 MOV AL, BYTE PTR [ES:BX + DP_MEDIATYPE] 0 00008DA5 1E push ds 0 00008DA6 E8[0000] call biocode_get_ds_dosentry 0 00008DA9 A2[FE00] MOV [MEDIATYPE], AL 0 00008DAC 1F pop ds 280 <1> ; THE MEDIA CHANGED (MAYBE) SO WE WILL HAVE TO DO A SETDASD THE NEXT TIME 281 <1> ; WE FORMAT A TRACK 0 00008DAD 814D238000 OR WORD PTR [DI + FLAGS], SET_DASD_TRUE 283 <1> 0 00008DB2 1E570653 SAVEREG 285 <1> ; FIGURE OUT WHAT WE ARE SUPPOSED TO DO WITH THE BPB 286 <1> 287 <1> ; WERE WE ASKED TO INSTALL A FAKE BPB? 0 00008DB6 26F60701 TEST BYTE PTR [ES:BX + DP_SPECIALFUNCTIONS], INSTALL_FAKE_BPB 0 00008DBA 7513 JNZ SHORT INSTALLFAKEBPB 290 <1> 291 <1> ; WERE WE RETURNING A FAKE BPB WHEN ASKED TO BUILD A BPB? 0 00008DBC F745230400 TEST WORD PTR [DI + FLAGS], RETURN_FAKE_BPB 0 00008DC1 7404 JZ SHORT INSTALLRECOMMENDEDBPB 294 <1> 295 <1> ; WE WERE RETURNING A FAKE BPB BUT WE CAN STOP NOW 0 00008DC3 836523FB AND WORD PTR [DI + FLAGS], ~ RETURN_FAKE_BPB 297 <1> ; JMP DONEWITHBPBSTUFF ;AN008; Comment out this instruction. 298 <1> 299 <1> INSTALLRECOMMENDEDBPB: 0 00008DC7 B91F00 MOV CX, A_BPB_struc_size 0 00008DCA 8D7D27 LEA DI, [DI + RBYTEPERSEC] 0 00008DCD EB0A JMP SHORT COPYTHEBPB 303 <1> 304 <1> INSTALLFAKEBPB: 305 <1> return_fake_bpb equ RETURN_FAKE_BPB ; NASM port equate 0 00008DCF 834D2304 or word ptr [di + flags], return_fake_bpb ;AN000; Problem 307 <1> ;reported by WHS. 0 00008DD3 B91900 MOV CX, BPB_TYPE_struc_size ; MOVE 'SMALLER' BPB 0 00008DD6 8D7D06 LEA DI, [DI + BYTEPERSEC] 310 <1> COPYTHEBPB: 0 00008DD9 8D7707 LEA SI, [BX + DP_BPB] 312 <1> ; EXCHANGE ES AND DS 0 00008DDC 06 PUSH ES 0 00008DDD 1E PUSH DS 0 00008DDE 07 POP ES 0 00008DDF 1F POP DS 317 <1> 0 00008DE0 F3A4 REP MOVSB 319 <1> 320 <1> DONEWITHBPBSTUFF: 0 00008DE2 E84E04 CALL RESTOREOLDDPT ; RESTORE THE OLD DPT FROM TEMPDPT 0 00008DE5 5B075F1F RESTOREREG 323 <1> 324 <1> ; SET UP TRACK TABLE (IF NECCESSARY) 325 <1> SETTRACKTABLE: 0 00008DE9 268B4F26 MOV CX, WORD PTR [ES:BX + DP_TRACKTABLEENTRIES] 0 00008DED 1E push ds 0 00008DEE E8[0000] call biocode_get_ds_dosentry 0 00008DF1 890E[0000] MOV [SECTORSPERTRACK], CX 0 00008DF5 1F pop ds 0 00008DF6 836523F7 AND WORD PTR [DI + FLAGS], ~ GOOD_TRACKLAYOUT 0 00008DFA 26F60704 TEST BYTE PTR [ES:BX + DP_SPECIALFUNCTIONS], TRACKLAYOUT_IS_GOOD 0 00008DFE 7404 JZ UGLYTRACKLAYOUT 0 00008E00 834D2308 OR WORD PTR [DI + FLAGS], GOOD_TRACKLAYOUT 335 <1> 336 <1> UGLYTRACKLAYOUT: 0 00008E04 83F93F CMP CX, MAX_SECTORS_IN_TRACK 0 00008E07 771C JA TOOMANYSECTORSPERTRACK 0 00008E09 E318 JCXZ SECTORINFOSAVED 0 00008E0B BF[0200] MOV DI, OFFSET TRACKTABLE 0 00008E0E 8D7728 LEA SI, [BX + DP_SECTORTABLE] 0 00008E11 06 PUSH ES 0 00008E12 1F POP DS 0 00008E13 E8[0000] call biocode_get_es_dosentry 345 <1> STORESECTORINFO: 0 00008E16 AF scasw ; di += 2 347 <1> ;INC DI ; SKIP OVER CYLINDER 348 <1> ;INC DI ; SKIP OVER HEAD 0 00008E17 AD LODSW ; GET SECTOR ID 0 00008E18 50 PUSH AX ; SAVE IT 0 00008E19 AD LODSW ; GET SECTOR SIZE 0 00008E1A E8B302 CALL SECTORSIZETOSECTORINDEX 0 00008E1D 5A POP DX ; GET SECTOR ID BACK 0 00008E1E 88D0 MOV AL, DL ; AH = SECTOR SIZE INDEX 355 <1> ; AL = SECTOR ID 0 00008E20 AB STOSW 0 00008E21 E2F3 LOOP STORESECTORINFO 358 <1> 359 <1> SECTORINFOSAVED: 0 00008E23 F8 CLC 0 00008E24 C3 RET 362 <1> 363 <1> TOOMANYSECTORSPERTRACK: 0 00008E25 B00C MOV AL, 0CH 0 00008E27 F9 STC 0 00008E28 C3 RET 367 <1> 368 <1> SETDEVICEPARAMETERS ENDP 369 <1> 370 <1> ; 371 <1> ; SET MEDIA TYPE FOR FORMAT 372 <1> ; PERFORMS THE INT 13 WITH AH = 18H TO SEE IF THE MEDIUM DESCRIBED IN THE 373 <1> ; BPB AREA IN THE BDS CAN BE HANDLED BY THE ROM. 374 <1> ; ON INPUT, DS:DI -> CURRENT BDS. 375 <1> ; THE STATUS OF THE OPERATION IS RETURNED IN AL 376 <1> ; - 0 - IF THE SUPPORT IS AVAILABLE, AND THE COMBINATION IS VALID. 377 <1> ; - 1 - NO ROM SUPPORT 378 <1> ; - 2 - ILLEGAL COMBINATION 379 <1> ; - 3 - No media present (ROM support exists but cannot determine now) 380 <1> ; FLAGS ALSO MAY BE ALTERED. ALL OTHER REGISTERS PRESERVED. 381 <1> ; IF THE CALL TO ROM RETURNS NO ERROR, THEN THE CURRENT DPT IS "REPLACED" BY 382 <1> ; THE ONE RETURNED BY THE ROM. THIS IS DONE BY CHANGING THE POINTER IN [DPT] 383 <1> ; TO THE ONE RETURNED. THE ORIGINAL POINTER TO THE DISK BASE TABLE IS STORED 384 <1> ; IN TEMPDPT, UNTIL IT IS RESTORED. 385 <1> ; 386 <1> PUBLIC SET_MEDIA_FOR_FORMAT 387 <1> SET_MEDIA_FOR_FORMAT PROC NEAR 0 00008E29 5152 SAVEREG 0 00008E2B 31C0 XOR AX,AX 0 00008E2D 1E push ds 0 00008E2E E8[0000] call biocode_get_ds_dosentry 0 00008E31 803E[0001]01 cmp byte [Had_Format_Error],1 ;Did we have a format error before? 0 00008E36 7503 jne No_Form_Err ;AN001; 0 00008E38 E81F03 call ResetDisk 395 <1> No_Form_Err: ;AN001; 0 00008E3B 803E[FF00]01 CMP BYTE PTR [MEDIA_SET_FOR_FORMAT],1 0 00008E40 1F pop ds 0 00008E41 7503 jne Do_Set_Media_for_Format 0 00008E43 E98900 jmp SET_MED_RET ; MEDIA ALREADY SET 400 <1> Do_Set_Media_for_Format: 0 00008E46 1E56 SAVEREG 0 00008E48 8ED8 MOV DS,AX 0 00008E4A C5367800 LDS SI,[DSKADR] ; GET POINTER TO DISK BASE TABLE 404 <1> ;SB34IOCTL000****************************************************************** 405 <1> ;SB Initialise the head settle time to 0fh. See the offsets given in 406 <1> ;SB DSKPRM.INC. 1 LOC. 407 <1> 0 00008E4E C644090F mov byte [si + DISK_HEAD_STTL], 0Fh 409 <1> ;SB34IOCTL000****************************************************************** 0 00008E52 1E push ds 0 00008E53 E8[0000] call biocode_get_ds_dosentry 0 00008E56 8936[0000] MOV WORD PTR [DPT],SI 0 00008E5A 8F06[0200] pop WORD PTR [DPT+2], ; SAVE POINTER TO TABLE 0 00008E5E C606[0000]01 mov byte [New_Rom], 1 ;assume a new ROM. 0 00008E63 5E1F RESTOREREG 416 <1> New_Rom equ NEW_ROM ; NASM port label 0 00008E65 30C0 XOR AL,AL 418 <1> ;SB33031**************************************************************** 419 <1> ccyln equ CCYLN ; NASM port equate 0 00008E67 8B4D25 mov cx,[di + ccyln] ;get number of cylinders ;SB ;3.30* 0 00008E6A 49 dec cx ;cylinder must be zero based ;SB ;3.30* 0 00008E6B 80E503 and ch,03h ; blank out unnecessary bits 0 00008E6E D0CD ror ch,1 ;put in int form ;SB ;3.30* 0 00008E70 D0CD ror ch,1 ; ;SB ;3.30* 0 00008E72 86E9 xchg ch,cl ; ;SB ;3.30* 426 <1> seclim equ SECLIM ; NASM port equate 0 00008E74 0A4D13 or cl,byte ptr [di + seclim] ;get number of sectors ;SB ;3.30* 428 <1> drivenum equ DRIVENUM ; NASM port equate 0 00008E77 8A5504 mov dl,[di + drivenum] ;get drive number ;SB ;3.30* 0 00008E7A B418 mov ah,18h ;set media for format ;SB ;3.30* 0 00008E7C 061E5657 SAVEREG 0 00008E80 CD13 int 13h ;call rom bios ;SB ;3.30* 433 <1> ;SB33031**************************************************************** 0 00008E82 722B JC FORMAT_STAT_ERR 435 <1> ; ES:DI POINTS TO A DISK BASE TABLE FOR THIS COMBINATION FOR THIS DRIVE. 0 00008E84 31C9 XOR CX,CX 0 00008E86 8ED9 MOV DS,CX ; HAVE DS -> SEGMENT 0 0 00008E88 C5367800 LDS SI,[DSKADR] ; GET CURRENT DISK BASE TABLE 0 00008E8C 893E7800 MOV WORD PTR [DSKADR],DI 0 00008E90 8C067A00 MOV WORD PTR [DSKADR+2],ES ; REPLACE WITH ONE RETURNED BY ROM 0 00008E94 E8[0000] call biocode_get_es_dosentry 0 00008E97 268936[0201] MOV WORD PTR [es:TEMPDPT],SI 0 00008E9C 268C1E[0401] MOV WORD PTR [es:TEMPDPT+2],DS ; SAVE IT 0 00008EA1 26C606[FF00]01 MOV BYTE PTR [es:MEDIA_SET_FOR_FORMAT],1 0 00008EA7 30C0 XOR AL,AL ; LEGAL COMBINATION + ROM SUPPORT CODE 0 00008EA9 26A2[0001] mov [es:Had_Format_Error],al ;reset the flag 0 00008EAD EB1C JMP SHORT POP_STAT_RET 448 <1> 449 <1> FORMAT_STAT_ERR: 0 00008EAF 80FC0C cmp ah, Dsk_illegal_combination ;J.K. illegal combination = 0ch 0 00008EB2 7411 je Format_stat_illegal_comb 452 <1> Dsk_Time_Out_Err equ Dsk_time_out_Err ; NASM port equate 0 00008EB4 80FC80 cmp ah, Dsk_Time_Out_Err ;J.K. = 80h 0 00008EB7 7410 je Format_stat_Time_out 0 00008EB9 B001 mov al, 1 ;Function not supported. 0 00008EBB E8[0000] call biocode_get_ds_dosentry 0 00008EBE C606[0000]00 mov byte [New_Rom], 0 ;So, it is an old rom. 458 <1> Pop_stat_ret equ POP_STAT_RET ; NASM port label 0 00008EC3 EB06 jmp short Pop_stat_ret 460 <1> Format_stat_illegal_comb: ;J.K. Function supported, but 0 00008EC5 B002 MOV AL,2 ;J.K. illegal sect/trk, trk combination. 0 00008EC7 EB02 jmp short Pop_stat_ret 463 <1> Format_stat_Time_out: ;J.K. Function supported, but 0 00008EC9 B003 mov al, 3 ;J.K. media not present. 465 <1> POP_STAT_RET: 0 00008ECB 5F5E1F07 RESTOREREG 467 <1> SET_MED_RET: 0 00008ECF 5A59 RESTOREREG 0 00008ED1 C3 RET 470 <1> 471 <1> SET_MEDIA_FOR_FORMAT ENDP 472 <1> 473 <1> ; 474 <1> ; FORMATTRACK: 475 <1> ; IF SPECIALFUNCTION BYTE IS 1, THEN THIS IS A STATUS CALL TO SEE IF THERE IS 476 <1> ; ROM SUPPORT FOR THE COMBINATION OF SEC/TRK AND # OF CYLN, AND IF THE 477 <1> ; COMBINATION IS LEGAL. IF SPECIALFUNCTION BYTE IS 0, THEN FORMAT THE TRACK. 478 <1> ; 479 <1> ; INPUT: DS:DI POINTS TO BDS FOR DRIVE 480 <1> ; ES:BX POINTS TO FORMAT PACKET 481 <1> ; 482 <1> ; OUTPUT: 483 <1> ; FOR STATUS CALL: 484 <1> ; SPECIALFUNCTION BYTE SET TO: 485 <1> ; 0 - ROM SUPPORT + LEGAL COMBINATION 486 <1> ; 1 - NO ROM SUPPORT 487 <1> ; 2 - ILLEGAL COMBINATION 488 <1> ; 3 - no media present ;J.K. 7/8/86 489 <1> ; CARRY CLEARED. 490 <1> ; 491 <1> ; FOR FORMAT TRACK: 492 <1> ; CARRY SET IF ERROR 493 <1> ; 494 <1> PUBLIC FORMATTRACK 495 <1> FORMATTRACK PROC NEAR 0 00008ED2 26F60701 TEST BYTE PTR [ES:BX + DP_SPECIALFUNCTIONS],STATUS_FOR_FORMAT 0 00008ED6 7408 JZ DO_FORMAT_TRACK 0 00008ED8 E84EFF CALL SET_MEDIA_FOR_FORMAT ; ALSO MOVES CURRENT DPT TO TEMPDPT 499 <1> STAT_RET: 0 00008EDB 268807 MOV BYTE PTR [ES:BX + DP_SPECIALFUNCTIONS],AL 0 00008EDE F8 CLC 0 00008EDF C3 RET 503 <1> 504 <1> DO_FORMAT_TRACK: 0 00008EE0 807D2205 CMP BYTE PTR [DI + FORMFACTOR], DEV_HARDDISK 0 00008EE4 7503 jne Do_Format_Diskette 507 <1> DoVerifyTrack equ DOVERIFYTRACK ; NASM port label 0 00008EE6 E99800 jmp DoVerifyTrack 509 <1> Do_Format_Diskette: 0 00008EE9 1E570653 SAVEREG 511 <1> ;SB34IOCTL001************************************************************* 512 <1> ;SB check the special functions word to see if DO_FAST_FORMAT has been 513 <1> ;SB specified. If so it is an error and we need to finish this operation 514 <1> ;SB by indicating the error value 1 in register ah and going to the 515 <1> ;SB the code at DO_MAP_IT to map the error. This is because we cannot 516 <1> ;SB allow multitrack format on floppies - 5 LOCS 517 <1> 0 00008EED 26F60702 test byte ptr [es:bx + FP_SPECIALFUNCTIONS],DO_FAST_FORMAT 0 00008EF1 7405 jz NO_FAST_FORMAT 0 00008EF3 B401 mov ah, 1 521 <1> DO_MAP_IT equ Do_Map_it ; NASM port label 0 00008EF5 EB78 jmp DO_MAP_IT 0 00008EF7 90 nop ; identicalise 524 <1> NO_FAST_FORMAT: 525 <1> ;SB34IOCTL001************************************************************* 0 00008EF8 E82EFF CALL SET_MEDIA_FOR_FORMAT ; ALSO MOVES CURRENT DPT TO TEMPDPT 0 00008EFB 3C01 CMP AL,1 ; DO WE HAVE ROM SUPPORT FOR sector/trk, # trks combination? 0 00008EFD 7407 JZ Need_Set_DASD ;Old ROM. 0 00008EFF 3C03 cmp al,3 ;time out error? 530 <1> No_Set_DASD equ NO_SET_DASD ; NASM port label 0 00008F01 7506 jnz No_Set_DASD ;No, fine.(At this point, don't care about the illegal combination.) 0 00008F03 EB5D jmp Format_Failed 0 00008F05 90 nop ; identicalise 534 <1> Need_Set_DASD: 0 00008F06 E8DA01 CALL SETDASD ;AH=17h, INT 13h 536 <1> ; 537 <1> ; STORE CYLINDER,HEAD IN TRACK TABLE 538 <1> ; ***** ASSUMPTION ******* 539 <1> ; SINCE FORMAT REQUESTS ON FIXED MEDIA ARE CONVERTED TO VERIFIES, WE 540 <1> ; ASSUME THAT WE ARE FORMATTING A FLOPPY AND HENCE HAVE 255 OR LESS 541 <1> ; TRACKS AND HEADS. WE THEREFORE MUST CHANGE THE CYLINDER, HEAD DATA 542 <1> ; FROM THE REQUEST PACKET SIZE TO THAT OF THE TRACKTABLE (SEE INT 13 543 <1> ; INTERFACE IN IBM'S TECH REF.). 544 <1> 545 <1> NO_SET_DASD: 546 <1> ; CHECK TO ENSURE CORRECT DISK IS IN DRIVE 0 00008F09 E8DCF5 CALL CHECKSINGLE 548 <1> 0 00008F0C 268B4703 MOV AX, WORD PTR [ES:BX + FP_CYLINDER] 0 00008F10 268B4F01 MOV CX, WORD PTR [ES:BX + FP_HEAD] 0 00008F14 E8[0000] call biocode_get_es_dosentry 0 00008F17 26A3[0000] MOV WORD PTR [es:TRKNUM],AX 0 00008F1B 26880E[0000] MOV BYTE PTR [es:HDNUM],CL 0 00008F20 88CC MOV AH,CL 555 <1> 0 00008F22 57 PUSH DI ; SAVE PTR TO BDS 0 00008F23 BF[0200] MOV DI, OFFSET TRACKTABLE 0 00008F26 268B0E[0000] MOV CX, [es:SECTORSPERTRACK] 559 <1> STORECYLINDERHEAD: 0 00008F2B AB STOSW 0 00008F2C 47 INC DI ; SKIP SECTOR ID 0 00008F2D 47 INC DI ; SKIP SECTOR SIZE 0 00008F2E E2FB LOOP STORECYLINDERHEAD 0 00008F30 5F POP DI ; RESTORE PTR TO BDS 565 <1> 0 00008F31 B90500 MOV CX, MAXERR ; SET UP RETRY COUNT 567 <1> FORMATRETRY: 0 00008F34 51 PUSH CX 0 00008F35 BB[0200] MOV BX, OFFSET TRACKTABLE 0 00008F38 E8[0000] call biocode_get_es_dosentry 0 00008F3B 26A1[0000] MOV AX, [es:SECTORSPERTRACK] 0 00008F3F B405 MOV AH, ROMFORMAT 0 00008F41 E82702 CALL TO_ROM 0 00008F44 59 POP CX 0 00008F45 7330 JNC FORMATOK 576 <1> resetdisk equ RESETDISK ; NASM port label 0 00008F47 E81002 call resetdisk 0 00008F4A 26C606[0001]01 mov byte [es:Had_Format_Error],1 0 00008F50 50 push ax 0 00008F51 51 push cx 0 00008F52 52 push dx 582 <1> Set_Media_For_Format equ SET_MEDIA_FOR_FORMAT ; NASM port label 0 00008F53 E8D3FE call Set_Media_For_Format 0 00008F56 3C01 cmp al, 1 0 00008F58 7503 jnz While_Err 586 <1> SetDASD equ SETDASD ; NASM port label 0 00008F5A E88601 call SetDASD 588 <1> While_Err: 0 00008F5D 5A pop dx 0 00008F5E 59 pop cx 0 00008F5F 58 pop ax 0 00008F60 E2D2 LOOP FORMATRETRY 593 <1> ;SB33106******************************************************************* 594 <1> Format_Failed: 0 00008F62 26C606[0001]01 mov byte [es:Had_Format_Error], 1 ;set the format error flag. 596 <1> Dsk_Change_Line_Err equ Dsk_change_line_Err ; NASM port equate 0 00008F68 80FC06 cmp ah, Dsk_Change_Line_Err ;=06h. Convert change line 0 00008F6B 7502 jne Do_Map_it ;error to Time Out error. 0 00008F6D B480 mov ah, Dsk_Time_Out_Err ;=80h 600 <1> ;SB33106******************************************************************* 601 <1> Do_Map_it: 0 00008F6F E856FA CALL MAPERROR 0 00008F72 5B075F1F RESTOREREG 0 00008F76 C3 RET 605 <1> 606 <1> FORMATOK: 0 00008F77 26C606[0001]00 mov byte [es:Had_Format_Error],0 ;reset the format error flag. 0 00008F7D 5B075F1F RESTOREREG 609 <1> 610 <1> DOVERIFYTRACK: 0 00008F81 E80800 CALL VERIFYTRACK 0 00008F84 C3 RET 613 <1> 614 <1> FORMATTRACK ENDP 615 <1> 616 <1> VerifyTrack_Err: ;AN006; 0 00008F85 B401 mov ah, 1 ;AN006; 618 <1> MapError equ MAPERROR ; NASM port label 0 00008F87 E83EFA call MapError ;AN006; 0 00008F8A 1F pop ds 0 00008F8B C3 ret ;AN006; 622 <1> 623 <1> ; 624 <1> ; VERIFYTRACK: 625 <1> ; 626 <1> ; INPUT: DS:DI POINTS TO BDS FOR DRIVE 627 <1> ; ES:BX POINTS TO VERIFY PACKET 628 <1> ; 629 <1> PUBLIC VERIFYTRACK 630 <1> VERIFYTRACK PROC NEAR 0 00008F8C 1E push ds 0 00008F8D E8[0000] call biocode_get_ds_dosentry 0 00008F90 C606[0000]04 MOV byte [RFLAG], ROMVERIFY 0 00008F95 268B4703 MOV AX, WORD PTR [ES:BX + VP_CYLINDER] 0 00008F99 A3[0000] MOV [CURTRK], AX 0 00008F9C 268B4701 MOV AX, WORD PTR [ES:BX + VP_HEAD] 637 <1> 638 <1> ; ****** ASSUMPTION ****** 639 <1> ; WE ASSUME THAT WE HAVE LESS THAN 256 HEADS, AND THAT THE REQUEST 640 <1> ; HEADER DATA STRUCTURE IS UNNECCESSARILY BIG 0 00008FA0 A2[0000] MOV [CURHD], AL 0 00008FA3 8B0E[0000] MOV CX, [SECTORSPERTRACK] ;CL = sectors/track 643 <1> ;SB34IOCTL005************************************************************* 644 <1> ;SB 645 <1> ;SB Check SPECIALFUNCTIONS to see if DO_FAST_FORMAT has been specified 646 <1> ;SB If not we should go to the normal track verification routine. If 647 <1> ;SB fast format has been specified we should get the number of tracks 648 <1> ;SB to be verified and check it to see if it is > 255. If it is then 649 <1> ;SB it is an error and we should go to VerifyTrack_Err. If not multiply 650 <1> ;SB the number of tracks by the sectors per track to get the total 651 <1> ;SB number of sectors to be verified. This should also be less than 652 <1> ;SB equal to 255 otherwise we go to same error exit. If everything 653 <1> ;SB is okay we initalise cx to the total sectors. use ax as a temporary 654 <1> ;SB register. 9 LOCS 655 <1> 0 00008FA7 26F60702 test byte ptr [es:bx + FP_SPECIALFUNCTIONS],DO_FAST_FORMAT 0 00008FAB 742B jz Norm_VerifyTrack 0 00008FAD 268B4705 mov ax,[es:bx + FP_TRACKCOUNT] ;ax <- tracks to be verify 0 00008FB1 3DFF00 cmp ax,0FFh 0 00008FB4 77CF ja VerifyTrack_Err ;#tracks > 255 0 00008FB6 F6E1 mul cl 0 00008FB8 3DFF00 cmp ax,0FFh ;#sectors > 255 0 00008FBB 77C8 ja VerifyTrack_Err 0 00008FBD 89C1 mov cx,ax ;#sectors to verify 665 <1> ;SB34IOCTL005************************************************************* 666 <1> 0 00008FBF 1F pop ds 0 00008FC0 1E push ds ; -> UPB 669 <1> 670 <1> ;Set the multi track request flag 0 00008FC1 F745230100 test word ptr [di + Flags], fNON_REMOVABLE ;AN009;hard disk? 0 00008FC6 7410 jz Norm_VerifyTrack ;AN009; 673 <1> Multrk_Flag equ MulTrk_Flag ; NASM port label 0 00008FC8 E8[0000] call biocode_get_ds_dosentry 0 00008FCB F706[0000]8000 test word [Multrk_Flag], MULTRK_ON ;AN009;MultiTrack operation = on? 0 00008FD1 7405 jz Norm_VerifyTrack ;AN009; 677 <1> Multitrk_Format_Flag equ MultiTrk_Format_Flag ; NASM port label 0 00008FD3 C606[0000]01 mov byte [Multitrk_Format_Flag], 1 ;AN009; then set the flag 679 <1> Norm_VerifyTrack: ;AN006; 0 00008FD8 31C0 XOR AX, AX ;1st sector 681 <1> ; USE 0:0 AS THE TRANSFER ADDRESS FOR VERIFY 0 00008FDA 31DB XOR BX, BX 0 00008FDC 8EC3 MOV ES, BX 0 00008FDE 1F pop ds 0 00008FDF E84600 CALL TRACKIO 0 00008FE2 1E push ds 0 00008FE3 E8[0000] call biocode_get_ds_dosentry 0 00008FE6 C606[0000]00 mov byte [Multitrk_Format_Flag], 0 ;AN009;Reset the flag. 0 00008FEB 1F pop ds 0 00008FEC C3 RET 691 <1> VERIFYTRACK ENDP 692 <1> 693 <1> ; 694 <1> ; READTRACK: 695 <1> ; 696 <1> ; INPUT: DS:DI POINTS TO BDS FOR DRIVE 697 <1> ; ES:BX POINTS TO READ PACKET 698 <1> ; 699 <1> PUBLIC READTRACK 700 <1> READTRACK: 0 00008FED 1E push ds 0 00008FEE E8[0000] call biocode_get_ds_dosentry 0 00008FF1 C606[0000]02 MOV byte [RFLAG], ROMREAD 0 00008FF6 1F pop ds 0 00008FF7 EB0C JMP READWRITETRACK 706 <1> 707 <1> ; 708 <1> ; WRITETRACK: 709 <1> ; 710 <1> ; INPUT: DS:DI POINTS TO BDS FOR DRIVE 711 <1> ; ES:BX POINTS TO WRITE PACKET 712 <1> ; 713 <1> PUBLIC WRITETRACK 714 <1> WRITETRACK: 0 00008FF9 1E push ds 0 00008FFA E8[0000] call biocode_get_ds_dosentry 0 00008FFD C606[0000]03 MOV byte [RFLAG], ROMWRITE 0 00009002 1F pop ds 0 00009003 EB00 JMP READWRITETRACK 720 <1> 721 <1> ; 722 <1> ; READWRITETRACK: 723 <1> ; 724 <1> ; INPUT: 725 <1> ; DS:DI POINTS TO BDS FOR DRIVE 726 <1> ; ES:BX POINTS TO WRITE PACKET 727 <1> ; RFLAG - 2 FOR READ, 3 FOR WRITE 728 <1> ; 729 <1> PUBLIC READWRITETRACK 730 <1> READWRITETRACK PROC NEAR 0 00009005 1E push ds 0 00009006 E8[0000] call biocode_get_ds_dosentry 0 00009009 268B4703 MOV AX, WORD PTR [ES:BX + TRWP_CYLINDER] 0 0000900D A3[0000] MOV [CURTRK], AX 0 00009010 268B4701 MOV AX, WORD PTR [ES:BX + TRWP_HEAD] 736 <1> 737 <1> ; ****** ASSUMPTION ****** 738 <1> ; WE ASSUME THAT WE HAVE LESS THAN 256 HEADS, AND THAT THE REQUEST 739 <1> ; HEADER DATA STRUCTURE IS UNNECCESSARILY BIG 0 00009014 A2[0000] MOV [CURHD], AL 0 00009017 268B4705 MOV AX, WORD PTR [ES:BX + TRWP_FIRSTSECTOR] 0 0000901B 268B4F07 MOV CX, WORD PTR [ES:BX + TRWP_SECTORSTOREADWRITE] 0 0000901F 26C45F09 LES BX, [ES:BX + TRWP_TRANSFERADDRESS] 0 00009023 1F pop ds 0 00009024 E80100 CALL TRACKIO 0 00009027 C3 RET 747 <1> READWRITETRACK ENDP 748 <1> 749 <1> 750 <1> ; 751 <1> ; TRACKIO: 752 <1> ; PERFORMS TRACK READ/WRITE/VERIFY 753 <1> ; 754 <1> ; INPUT: 755 <1> ; RFLAG - 2 = READ 756 <1> ; 3 = WRITE 757 <1> ; 4 = VERIFY 758 <1> ; AX - INDEX INTO TRACK TABLE OF FIRST SECTOR TO IO 759 <1> ; CX - NUMBER OF SECTORS TO IO 760 <1> ; ES:BX - TRANSFER ADDRESS 761 <1> ; DS:DI - POINTER TO BDS 762 <1> ; CURTRK - CURRENT CYLINDER 763 <1> ; CURHD - CURRENT HEAD 764 <1> ; 765 <1> PUBLIC TRACKIO 766 <1> TRACKIO PROC NEAR 767 <1> ; PROCEDURE `DISK' WILL POP STACK TO SPSAV AND RETURN IF ERROR 0 00009028 1E push ds 0 00009029 E8[0000] call biocode_get_ds_dosentry 0 0000902C 8926[0000] MOV [SPSAV], SP 0 00009030 1F pop ds 772 <1> ; ENSURE CORRECT DISK IS IN DRIVE 0 00009031 E8B4F4 CALL CHECKSINGLE 774 <1> ; SEE IF WE HAVE ALREADY SET THE DISK BASE TABLE 0 00009034 1E push ds 0 00009035 E8[0000] call biocode_get_ds_dosentry 0 00009038 803E[FF00]01 CMP BYTE PTR [MEDIA_SET_FOR_FORMAT],1 0 0000903D 1F pop ds 0 0000903E 7407 JZ DPTALREADYSET 780 <1> ; 781 <1> ; SET UP TABLES AND VARIABLES FOR I/O 782 <1> ; 0 00009040 5051 SAVEREG 0 00009042 E80DF7 CALL IOSETUP 0 00009045 5958 RESTOREREG 786 <1> ; 787 <1> ; POINT SI AT THE TABLE ENTRY OF THE FIRST SECTOR TO BE IO'D 788 <1> ; 789 <1> DPTALREADYSET: 0 00009047 BE[0200] MOV SI, OFFSET TRACKTABLE 0 0000904A D1E0 SHL AX, 1 0 0000904C D1E0 SHL AX, 1 0 0000904E 01C6 ADD SI, AX 794 <1> ; 795 <1> ; WE WANT: 796 <1> ; CX TO BE THE NUMBER OF TIMES WE HAVE TO LOOP 797 <1> ; DX TO BE THE NUMBER OF SECTORS WE READ ON EACH ITERATION 0 00009050 BA0100 MOV DX, 1 0 00009053 F745230800 TEST WORD PTR [DI + FLAGS], GOOD_TRACKLAYOUT 0 00009058 7402 JZ IONEXTSECTOR 801 <1> 802 <1> ; HEY! WE CAN READ ALL THE SECTORS IN ONE BLOW 0 0000905A 87D1 XCHG DX, CX 804 <1> 805 <1> IONEXTSECTOR: 0 0000905C 51 PUSH CX 0 0000905D 52 PUSH DX 0 0000905E 1E push ds 0 0000905F E8[0000] call biocode_get_ds_dosentry 810 <1> ; SKIP OVER THE CYLINDER AND HEAD IN THE TRACK TABLE 0 00009062 46 INC SI 0 00009063 46 INC SI 813 <1> ; GET SECTOR ID FROM TRACK TABLE 0 00009064 AC LODSb 0 00009065 A2[0000] MOV [CURSEC], AL 816 <1> ;*** For a Fixed disk multi-track disk I/O - J.K. 4/14/86 817 <1> ;Assumptions: 1). In the input CX (# of sectors to go) to TRACKIO, only CL is 818 <1> ;valid. 2). Sector size should be set to 512 bytes. 3). GOODTRACKLAYOUT. 819 <1> ; 0 00009068 1F pop ds 0 00009069 1E push ds 0 0000906A F745230100 test word ptr [di + Flags], fNon_Removable ;Fixed disk? - J.K. 0 0000906F 7419 jz IOREMOVABLE ;no -J.K. 0 00009071 E8[0000] call biocode_get_ds_dosentry 0 00009074 F706[0000]8000 test word [MulTrk_Flag], MULTRK_ON ;AN002; Allow multi-track operation? 826 <1> IORemovable equ IOREMOVABLE ; NASM port label 0 0000907A 740E jz IORemovable ;AN002; No, don't do that. 828 <1> seccnt equ SECCNT ; NASM port label 0 0000907C 8916[0000] mov [seccnt], dx ;# of sectors to I/O -J.K. 0 00009080 89D0 mov ax, dx ;J.K. 0 00009082 1F pop ds 832 <1> disk equ DISK ; NASM port label 0 00009083 E8B8F7 call disk ;J.K. 0 00009086 5A pop dx ;J.K. 0 00009087 59 pop cx ;J.K. 0 00009088 F8 clc ;J.K. 0 00009089 C3 ret ;J.K. 838 <1> IOREMOVABLE: ;J.K. 839 <1> ; GET SECTOR SIZE INDEX FROM TRACK TABLE AND SAVE IT 0 0000908A E8[0000] call biocode_get_ds_dosentry 0 0000908D AC LODSb 0 0000908E 8F06[0000] pop word [dosentry_temp_ds] 0 00009092 50 PUSH AX 844 <1> ; PATCH SECTOR SIZE IN DPT 0 00009093 56 PUSH SI 0 00009094 1E PUSH DS 0 00009095 C536[0000] LDS SI, [DPT] 0 00009099 884403 MOV BYTE PTR [SI + DISK_SECTOR_SIZ],AL 0 0000909C 1E push ds 0 0000909D E8[0000] call biocode_get_ds_dosentry 0 000090A0 A0[0000] MOV AL,[EOT] 0 000090A3 1F pop ds 0 000090A4 884404 MOV [SI + DISK_EOT],AL ; SET UP THE MAX NUMBER OF SEC/TRACK 0 000090A7 1F POP DS 0 000090A8 88D0 MOV AL, DL 856 <1> DOTHEIO: 0 000090AA A3[0000] MOV [SECCNT],AX ; SET UP THE COUNT OF SECTORS TO I/O 0 000090AD 8E1E[0000] mov ds, word [dosentry_temp_ds] 0 000090B1 E88AF7 CALL DISK 860 <1> ; ADVANCE BUFFER POINTER BY ADDING SECTOR SIZE 0 000090B4 5E POP SI 0 000090B5 58 POP AX 0 000090B6 E82200 CALL SECTORSIZEINDEXTOSECTORSIZE 0 000090B9 01C3 ADD BX, AX 0 000090BB 5A POP DX 0 000090BC 59 POP CX 0 000090BD E29D LOOP IONEXTSECTOR 0 000090BF 1E push ds 0 000090C0 E8[0000] call biocode_get_ds_dosentry 0 000090C3 803E[FF00]01 cmp byte ptr [Media_Set_For_Format], 1 ;AN001; 0 000090C8 1F pop ds 0 000090C9 7403 je No_Need_Done ;AN001; 0 000090CB E8D1F6 CALL DONE ; SET TIME OF LAST ACCESS, AND RESET 874 <1> No_Need_Done: ;AN001; 0 000090CE F8 CLC ; ENTRIES IN DPT. 0 000090CF C3 RET 877 <1> 878 <1> TRACKIO ENDP 879 <1> ; 880 <1> ; THE SECTOR SIZE IN BYTES NEEDS TO BE CONVERTED TO AN INDEX VALUE FOR THE IBM 881 <1> ; ROM. (0=>128, 1=>256,2=>512,3=>1024). IT IS ASSUMED THAT ONLY THESE VALUES 882 <1> ; ARE PERMISSIBLE. 883 <1> ; ON INPUT AX CONTAINS SECTOR SIZE IN BYTES 884 <1> ; ON OUTPUT AL CONTAINS INDEX 885 <1> ; 886 <1> PUBLIC SECTORSIZETOSECTORINDEX 887 <1> SECTORSIZETOSECTORINDEX PROC NEAR 0 000090D0 80FC02 CMP AH,2 ; EXAMINE UPPER BYTE ONLY 0 000090D3 7703 JA ONEK 0 000090D5 88E0 MOV AL,AH ; VALUE IN AH IS THE INDEX! 0 000090D7 C3 RET 892 <1> ONEK: 0 000090D8 B003 MOV AL,3 0 000090DA C3 RET 895 <1> SECTORSIZETOSECTORINDEX ENDP 896 <1> 897 <1> SECTORSIZEINDEXTOSECTORSIZE PROC NEAR 0 000090DB 88C1 MOV CL, AL 0 000090DD B88000 MOV AX,128 0 000090E0 D3E0 SHL AX, CL 0 000090E2 C3 RET 902 <1> SECTORSIZEINDEXTOSECTORSIZE ENDP 903 <1> 904 <1> ; 905 <1> ; SET UP THE ROM FOR FORMATTING. 906 <1> ; WE HAVE TO TELL THE ROM BIOS WHAT TYPE OF DISK IS IN THE DRIVE. 907 <1> ; ON INPUT - DS:DI - POINTS TO BDS 908 <1> ; 909 <1> PUBLIC SETDASD 910 <1> SETDASD: 911 <1> ; SEE IF WE HAVE PREVIOUSLY SET DASD TYPE 912 <1> ;SB33114****************************************************************** 0 000090E3 1E push ds 0 000090E4 E8[0000] call biocode_get_ds_dosentry 0 000090E7 803E[0001]01 cmp byte [Had_Format_Error],1 0 000090EC 1F pop ds 0 000090ED 740C je DoSetDasd 918 <1> ;SB33114****************************************************************** 0 000090EF F745238000 TEST WORD PTR [DI + FLAGS], SET_DASD_TRUE 0 000090F4 7452 JZ DASDHASBEENSET 0 000090F6 8165237FFF AND WORD PTR [DI + FLAGS], ~ SET_DASD_TRUE 922 <1> ;SB33115****************************************************************** 923 <1> DoSetDasd: 0 000090FB 1E push ds 0 000090FC E8[0000] call biocode_get_ds_dosentry 0 000090FF C606[0001]00 mov byte [Had_Format_Error],0 ;reset it 927 <1> ;SB33115****************************************************************** 0 00009104 C606[0000]50 MOV byte [GAP_PATCH],50H ; FORMAT GAP FOR 48TPI DISKS 0 00009109 1F pop ds 0 0000910A B004 MOV AL,4 0 0000910C 807D2202 CMP BYTE PTR [DI + FORMFACTOR],DEV_3INCH720KB 0 00009110 741F JZ DO_SET 0 00009112 807D2201 CMP BYTE PTR [DI + FORMFACTOR], DEV_5INCH96TPI 0 00009116 7404 JZ GOT_BIG 0 00009118 B001 MOV AL,1 ; 160/320K IN A 160/320K DRIVE 0 0000911A EB15 JMP SHORT DO_SET 937 <1> GOT_BIG: 0 0000911C B002 MOV AL,2 ; 160/320K IN A 1.2 MEG DRIVE 0 0000911E 1E push ds 0 0000911F E8[0000] call biocode_get_ds_dosentry 0 00009122 803E[FE00]00 CMP byte [MEDIATYPE], 0 0 00009127 7507 JNE DO_SET_b 0 00009129 B003 MOV AL,3 ; 1.2MEG IN A 1.2MEG DRIVE 0 0000912B C606[0000]54 MOV byte [GAP_PATCH],54H 945 <1> DO_SET_b: 0 00009130 1F pop ds 947 <1> DO_SET: 0 00009131 1E push ds ;AN003; 0 00009132 56 push si ;AN003; 950 <1> ;SB34IOCTL002**************************************************************** 951 <1> ;SB Get the disk parameter table address (dword address) from the location 952 <1> ;SB 0:[DSKADR] and fix the head settle time in this to be 0fh. 4 LOCS 953 <1> 0 00009133 31F6 xor si, si 0 00009135 8EDE mov ds, si 0 00009137 C5367800 lds si, [DSKADR] 0 0000913B C644090F mov byte [si + DISK_HEAD_STTL], 0Fh 958 <1> ;SB34IOCTL002**************************************************************** 0 0000913F 5E pop si ;AN003; 0 00009140 1F pop ds ;AN003; 961 <1> ;SB33032****************************************************************** 0 00009141 B417 mov AH, 17h ; set command to Set DASD type;SB ;3.30* 0 00009143 8A5504 mov DL, [di + DriveNum] ; set drive number ;SB ;3.30* 0 00009146 CD13 int 13h ; call rom-bios ;SB ;3.30* 965 <1> ;SB33032****************************************************************** 966 <1> DASDHASBEENSET: 0 00009148 8A6513 MOV AH,BYTE PTR [DI + SECLIM] 0 0000914B 1E push ds 0 0000914C E8[0000] call biocode_get_ds_dosentry 0 0000914F 8826[0000] MOV [FORMT_EOT],AH 0 00009153 1F pop ds 0 00009154 C3 RET 973 <1> 974 <1> ; 975 <1> ; THIS ROUTINE IS CALLED IF AN ERROR OCCURS WHILE FORMATTING OR VERIFYING. 976 <1> ; IT RESETS THE DRIVE, AND DECREMENTS THE RETRY COUNT. 977 <1> ; ON ENTRY - DS:DI - POINTS TO BDS FOR THE DRIVE 978 <1> ; BP - CONTAINS RETRY COUNT 979 <1> ; ON EXIT FLAGS INDICATE RESULT OF DECREMENTING RETRY COUNT 980 <1> ; 981 <1> AGAIN: 0 00009155 E80200 CALL RESETDISK 983 <1> 984 <1> ;(deleted section here, as requested by D.L.) 985 <1> 0 00009158 4D DEC BP ; DECREMENT RETRY COUNT 0 00009159 C3 RET 988 <1> 989 <1> 990 <1> ; RESET THE DRIVE. 991 <1> ; WE ALSO SET [STEP_DRV] TO -1 TO FORCE THE MAIN DISK ROUTINE TO USE THE 992 <1> ; SLOW HEAD SETTLE TIME FOR THE NEXT OPERATION. THIS IS BECAUSE THE RESET 993 <1> ; OPERATION MOVES THE HEAD TO CYLINDER 0, SO WE NEED TO DO A SEEK THE NEXT 994 <1> ; TIME AROUND - THERE IS A PROBLEM WITH 3.5" DRIVES IN THAT THE HEAD DOES 995 <1> ; NOT SETTLE DOWN IN TIME, EVEN FOR READ OPERATIONS!! 996 <1> ; 997 <1> PUBLIC RESETDISK 998 <1> RESETDISK: 0 0000915A 50 SAVEREG 1000 <1> ;SB33033****************************************************************** 0 0000915B 30E4 xor AH, AH ; set command to reset disk ;SB ;3.30* 0 0000915D CD13 int 13h ; call the rom-bios ;SB ;3.30* 1003 <1> ;SB33033****************************************************************** 0 0000915F 1E push ds 0 00009160 E8[0000] call biocode_get_ds_dosentry 0 00009163 C606[0000]FF MOV byte [STEP_DRV],-1 ; ZAP UP THE SPEED 0 00009168 1F pop ds 0 00009169 58 RESTOREREG 0 0000916A C3 RET 1010 <1> 1011 <1> ; 1012 <1> ; THIS ROUTINE SETS UP THE DRIVE PARAMETER TABLE WITH THE VALUES NEEDED FOR 1013 <1> ; FORMAT, DOES AN INT 13. VALUES IN DPT ARE RESTORED AFTER A VERIFY IS DONE. 1014 <1> ; 1015 <1> ; ON ENTRY - DS:DI - POINTS TO BDS FOR THE DRIVE 1016 <1> ; ES:BX - POINTS TO TRKBUF 1017 <1> ; AL - NUMBER OF SECTORS 1018 <1> ; AH - INT 13 FUNCTION CODE 1019 <1> ; CL - SECTOR NUMBER FOR VERIFY 1020 <1> ; ON EXIT - DS,DI,ES,BX REMAIN UNCHANGED. 1021 <1> ; AX AND FLAGS ARE THE RESULTS OF THE INT 13 1022 <1> ; 1023 <1> PUBLIC TO_ROM 1024 <1> TO_ROM: 0 0000916B 1E57065356 SAVEREG 0 00009170 1E push ds 0 00009171 E8[0000] call biocode_get_ds_dosentry 0 00009174 F606[0000]01 TEST BYTE PTR [NEW_ROM],1 0 00009179 1F pop ds 0 0000917A 753D JNZ GOT_VALID_DPT 0 0000917C 50 PUSH AX 0 0000917D 8CDA MOV DX,DS ; SAVE DS:DI-> BDS 0 0000917F 31C0 XOR AX,AX 0 00009181 8ED8 MOV DS,AX 0 00009183 C5367800 LDS SI,[DSKADR] ; GET POINTER TO DISK BASE TABLE 0 00009187 06 push es 0 00009188 E8[0000] call biocode_get_es_dosentry 0 0000918B 268936[0000] MOV WORD PTR [es:DPT],SI 0 00009190 268C1E[0200] MOV WORD PTR [es:DPT+2],DS ; SAVE POINTER TO TABLE 0 00009195 26A0[0000] MOV AL,[es:FORMT_EOT] 0 00009199 884404 MOV [SI + DISK_EOT],AL 0 0000919C 26A0[0000] MOV AL,[es:GAP_PATCH] 0 000091A0 884407 MOV [SI + DISK_FORMT_GAP],AL ; IMPORTANT FOR FORMAT 0 000091A3 C644090F MOV byte [SI + DISK_HEAD_STTL],15 ; ASSUME WE ARE DOING A SEEK OPERATION 1045 <1> ; SET UP MOTOR START CORRECTLY FOR 3.5" DRIVES. 0 000091A7 8EC2 MOV ES,DX 0 000091A9 26807D2202 CMP BYTE PTR [ES:DI + FORMFACTOR],FFSMALL ; IS IT A 3.5" DRIVE? 0 000091AE 7505 JNZ MOTORSTRTOK 0 000091B0 B004 MOV AL,4 0 000091B2 86440A XCHG AL,[SI + DISK_MOTOR_STRT] 1051 <1> MOTORSTRTOK: 0 000091B5 07 POP ES 1053 <1> ;---------------------------------------------------------------------------- 1054 <1> ; THE FOLLOWING TWO LINES ARE NO LONGER NECESSARY SINCE THEY ARE ONLY USEFUL 1055 <1> ; FOR A VERIFY OPERATION. 1056 <1> ; MOV AL,[CS:SECTOR_SIZ_IND] 1057 <1> ; MOV [SI].DISK_SECTOR_SIZ,AL ; IMPORTANT FOR VERIFY 1058 <1> ;---------------------------------------------------------------------------- 0 000091B6 8EDA MOV DS,DX ; RESTORE DS:DI-> BDS 0 000091B8 58 POP AX 1061 <1> GOT_VALID_DPT: 1062 <1> ;SB33034******************************************************************* 1063 <1> trknum equ TRKNUM ; NASM port label 0 000091B9 1E push ds 0 000091BA E8[0000] call biocode_get_ds_dosentry 0 000091BD 8B16[0000] mov dx, [trknum] ; set track number ;SB ;3.30* 0 000091C1 88D5 mov ch,dl ; set low 8 bits in ch ;SB ;3.30* 0 000091C3 8A36[0000] mov DH, [HDNUM] ; set head number ;SB ;3.30* 0 000091C7 1F pop ds 0 000091C8 8A5504 mov DL, [di + DriveNum] ; set drive number ;SB ;3.30* 0 000091CB CD13 int 13h ; call the rom-bios routines ;SB ;3.30* 1072 <1> ;SB33034******************************************************************* 0 000091CD 5E5B075F1F RESTOREREG 0 000091D2 C3 RET 1075 <1> 1076 <1> ; 1077 <1> ; GET THE OWNER OF THE PHYSICAL DRIVE REPRESENTED BY THE LOGICAL DRIVE IN BL. 1078 <1> ; THE ASSUMPTION IS THAT WE **ALWAYS** KEEP TRACK OF THE OWNER OF A DRIVE!! 1079 <1> ; IF THIS IS NOT THE CASE, THE SYSTEM MAY HANG, JUST FOLLOWING THE LINKED LIST. 1080 <1> ; 1081 <1> PUBLIC IOCTL$GETOWN 1082 <1> IOCTL$GETOWN: 0 000091D3 E8C2F2 CALL SETDRIVE 0 000091D6 8A4504 MOV AL,BYTE PTR [DI + DRIVENUM] ; GET PHYSICAL DRIVE NUMBER 0 000091D9 E8[0000] call biocode_get_ds_dosentry 0 000091DC C53E[0000] lds di, [START_BDS] 1087 <1> OWN_LOOP: 0 000091E0 384504 CMP BYTE PTR [DI + DRIVENUM],AL 0 000091E3 7507 JNE GETNEXTBDS 0 000091E5 F745232000 TEST WORD PTR [DI + FLAGS],FI_OWN_PHYSICAL 0 000091EA 7506 JNZ DONE_GETOWN 1092 <1> GETNEXTBDS: 0 000091EC C53D lds di, [DI + LINK] 0 000091EE 8CDB mov bx, ds 0 000091F0 EBEE JMP SHORT OWN_LOOP 1096 <1> DONE_GETOWN: 0 000091F2 EB25 JMP SHORT EXIT_OWN 1098 <1> 1099 <1> ; 1100 <1> ; SET THE OWNERSHIP OF THE PHYSICAL DRIVE REPRESENTED BY THE LOGICAL DRIVE IN 1101 <1> ; BL TO BL. 1102 <1> ; 1103 <1> PUBLIC IOCTL$SETOWN 1104 <1> IOCTL$SETOWN: 0 000091F4 E8A1F2 CALL SETDRIVE 0 000091F7 1E push ds 0 000091F8 E8[0000] call biocode_get_ds_dosentry 0 000091FB C606[0000]01 MOV BYTE PTR [FSETOWNER],1 ; SET FLAG FOR CHECKSINGLE TO 0 00009200 1F pop ds 1110 <1> ; LOOK AT. 0 00009201 E8E4F2 CALL CHECKSINGLE ; SET OWNERSHIP OF DRIVE 0 00009204 1E push ds 0 00009205 E8[0000] call biocode_get_ds_dosentry 0 00009208 C606[0000]00 MOV BYTE PTR [FSETOWNER],0 ; RESET FLAG 0 0000920D 1F pop ds 0 0000920E 31DB XOR BX,BX 0 00009210 8EC3 MOV ES,BX 0 00009212 B1FF MOV CL,-1 0 00009214 26880E0405 MOV BYTE PTR [ES:LSTDRV],CL ; SET UP SDSB AS WELL 1120 <1> 1121 <1> EXIT_OWN: 1122 <1> ; IF THERE IS ONLY ONE LOGICAL DRIVE ASSIGNED TO THIS PHYSICAL DRIVE, RETURN 1123 <1> ; 0 TO USER TO INDICATE THIS. 0 00009219 30C9 XOR CL,CL 0 0000921B F745231000 TEST WORD PTR [DI + FLAGS],FI_AM_MULT 0 00009220 7404 JZ EXIT_NO_MULT 0 00009222 8A4D05 MOV CL,BYTE PTR [DI + DRIVELET] ; GET LOGICAL DRIVE NUMBER 0 00009225 41 inc cx ; GET IT 1-BASED 1129 <1> EXIT_NO_MULT: 0 00009226 E8[0000] call biocode_get_ds_dosentry 0 00009229 C51E[0000] lds bx, [PTRSAV] 0 0000922D 884F01 MOV BYTE PTR [BX + UNIT],CL 0 00009230 E9[0000] JMP EXIT 1134 <1> 1135 <1> 1136 <1> ; 1137 <1> ; MOVES THE OLD DPT THAT HAD BEEN SAVED IN TEMPDPT BACK TO DPT. THIS IS DONE 1138 <1> ; ONLY IF THE FIRST BYTE OF TEMPDPT IS NOT -1. 1139 <1> ; ALL REGISTERS (INCLUDING FLAGS) ARE PRESERVED. 1140 <1> ; 1141 <1> PUBLIC RESTOREOLDDPT 1142 <1> RESTOREOLDDPT: 1143 <1> ; IF WE HAVE ALREADY RESTORED THE DISK BASE TABLE EARLIER, DO NOT DO IT 1144 <1> ; AGAIN. 0 00009233 50 PUSH AX 0 00009234 30C0 XOR AL,AL 1147 <1> ; RESET FLAG AND GET CURRENT FLAG SETTING 0 00009236 1E push ds 0 00009237 E8[0000] call biocode_get_ds_dosentry 0 0000923A A2[0001] mov [Had_Format_Error],al 0 0000923D 8606[FF00] XCHG BYTE PTR [MEDIA_SET_FOR_FORMAT],AL 0 00009241 84C0 test AL,AL 0 00009243 7416 JZ DONTRESTORE 0 00009245 5606 SAVEREG 0 00009247 C536[0201] LDS SI,[TEMPDPT] 0 0000924B 31C0 XOR AX,AX 0 0000924D 8EC0 MOV ES,AX ; HAVE ES -> SEGMENT 0 0 0000924F 2689367800 MOV WORD PTR [ES:DSKADR],SI 0 00009254 268C1E7A00 MOV WORD PTR [ES:DSKADR+2],DS 0 00009259 075E RESTOREREG 1161 <1> DONTRESTORE: 0 0000925B 1F pop ds 0 0000925C 58 POP AX 0 0000925D F8 CLC ; CLEAR CARRY 0 0000925E C3 RET 1166 <1> 1167 <1> ;****************************************************************************** 1168 <1> ;AN000; Get Media ID 1169 <1> ;******************************************************************************* 1170 <1> ; * 1171 <1> ; Function: Get the volume label, the system id and the serial number from * 1172 <1> ; the media that has the extended boot record. * 1173 <1> ; For the conventional media, this routine will return "Unknown * 1174 <1> ; media type" error to DOS. * 1175 <1> ; * 1176 <1> ; Input : DS:DI -> BDS table for this drive. * 1177 <1> ; ES:BX -> Request packet (= A_Media_ID_INFO structure) * 1178 <1> ; * 1179 <1> ; Output: The request packet filled with the information, if not carry. * 1180 <1> ; If carry set, then AL contains the device driver error number * 1181 <1> ; that will be returned to DOS. * 1182 <1> ; Register DS,DX,AX,CX,DI,SI destroyed. * 1183 <1> ; Subroutines to be called: * 1184 <1> ; BOOT_IO:NEAR * 1185 <1> ; * 1186 <1> ; Logic: * 1187 <1> ; /*To recognize the extended boot record, this logic will actually */ * 1188 <1> ; /*access the boot sector even if it is a hard disk. */ * 1189 <1> ; /*NOTE:the valid extended bpb is recognized by looking at the mediabyte* 1190 <1> ; /*field of BPB and the extended Boot Signature. * 1191 <1> ; * 1192 <1> ; { * 1193 <1> ; Get logical drive number from BDS table; * 1194 <1> ; RFLAG = Read operation; * 1195 <1> ; BOOT_IO; /*Get the media boot record into the buffer*/ * 1196 <1> ; IF (no error) THEN * 1197 <1> ; IF (extended boot record) THEN * 1198 <1> ; { set Volume Label, Volume Serial number and System id * 1199 <1> ; of the Request packet to those of the boot record; * 1200 <1> ; }; * 1201 <1> ; ELSE /*Not an extended BPB */ * 1202 <1> ; { set Register AL to "Unknown media.." error code; * 1203 <1> ; set Carry bit; * 1204 <1> ; }; * 1205 <1> ; ELSE * 1206 <1> ; Exit; /*Already error code is set in the register AL* 1207 <1> ; * 1208 <1> ; Expected LOC: 40 (New) * 1209 <1> ;******************************************************************************* 1210 <1> 1211 <1> GetMediaID proc near ;AN000; 0 0000925F E8B400 call Changeline_Chk ;AN010; 0 00009262 8A4505 mov al, [DI + DRIVELET] ;AN000; logical drive number 1214 <1> RFlag equ RFLAG ; NASM port label 0 00009265 1E push ds 0 00009266 E8[0000] call biocode_get_ds_dosentry 0 00009269 C606[0000]02 mov byte [RFlag], ROMREAD ;AN000; read operation 0 0000926E E88800 call Boot_IO ;AN000; read boot sector into DOSENTRY:DiskSector 1219 <1> ; $IF NC ;AN000; 0 00009271 7225 JC $IOCTL$IF1_pop_ds 1221 <1> MediaByte equ MEDIABYTE ; NASM port label 0 00009273 8A0E[0000] mov cl, [MediaByte] ;AN000; Mediabyte in BPB 0 00009277 80E1F0 and cl, 0F0h ;AN000; 0 0000927A 80F9F0 cmp cl, 0F0h ;AN000; Is it a valid BPB? 1225 <1> ; $IF E,AND ;AN000; 0 0000927D 7516 JNE $IOCTL$IF2 0 0000927F 803E[0000]29 cmp byte [Ext_Boot_Sig], EXT_BOOT_SIGNATURE ;AN000; =90h 1228 <1> ; $IF E ;AN000; Extended Boot Record 0 00009284 750F JNE $IOCTL$IF2 0 00009286 BE[0000] mov si, offset Boot_Serial_L ;AN000; 0 00009289 89DF mov di, bx ;AN000; 0 0000928B 83C702 add di, MI_SERIAL ;AN000; 0 0000928E B91700 mov cx, BOOT_SERIAL_SIZE+BOOT_VOLUME_LABEL_SIZE+BOOT_SYSTEM_ID_SIZE 0 00009291 F3A4 rep movsb ;AN000; 1235 <1> ; $ELSE ;AN000; 0 00009293 EB03 JMP SHORT $IOCTL$EN2 1237 <1> $IOCTL$IF2: 0 00009295 B007 mov al, ERROR_UNKNOWN_MEDIA ;AN000; =7 0 00009297 F9 stc ;AN000; 1240 <1> ; $ENDIF ;End Extended Boot Record check. 1241 <1> $IOCTL$EN2: 1242 <1> ; $ENDIF ;Read boot sector failed. Hard error. 1243 <1> $IOCTL$IF1_pop_ds: 0 00009298 1F pop ds 0 00009299 C3 ret ;AN000; 1246 <1> GetMediaID endp 1247 <1> 1248 <1> ;****************************************************************************** 1249 <1> ;AN000; Set Media ID 1250 <1> ;******************************************************************************* 1251 <1> ; * 1252 <1> ; Function: Set the volume label, the system id and the serial number of * 1253 <1> ; the media that has the extended boot record. * 1254 <1> ; For the conventional media, this routine will return "Unknown * 1255 <1> ; media.." error to DOS. * 1256 <1> ; This routine will also set the corresponding informations in * 1257 <1> ; the BDS table. * 1258 <1> ; * 1259 <1> ; Input : DS:DI -> BDS table for this drive. * 1260 <1> ; ES:BX -> Request packet (= A_Media_ID_INFO structure) * 1261 <1> ; * 1262 <1> ; Output: The extended boot record in the media will be set according to * 1263 <1> ; the Request packet. * 1264 <1> ; If carry set, then AL contains the device driver error number * 1265 <1> ; that will be returned to DOS. * 1266 <1> ; * 1267 <1> ; Subroutines to be called: * 1268 <1> ; BOOT_IO:NEAR * 1269 <1> ; * 1270 <1> ; Logic: * 1271 <1> ; * 1272 <1> ; * 1273 <1> ; { * 1274 <1> ; Get Drive_Number from BDS; * 1275 <1> ; RFLAG = "Read operation"; * 1276 <1> ; BOOT_IO; * 1277 <1> ; IF (no error) THEN * 1278 <1> ; IF (extended boot record) THEN * 1279 <1> ; { set Volume Label, Volume Serial number and System id * 1280 <1> ; of the boot record to those of the Request packet; * 1281 <1> ; RFLAG = "Write operation"; * 1282 <1> ; Get Drive Number from BDS; * 1283 <1> ; BOOT_IO; /*Write it back*/ * 1284 <1> ; }; * 1285 <1> ; ELSE /*Not an extended BPB */ * 1286 <1> ; { set Register AL to "Unknown media.." error code; * 1287 <1> ; set Carry bit; * 1288 <1> ; Exit; /*Return back to caller */ * 1289 <1> ; }; * 1290 <1> ; ELSE * 1291 <1> ; Exit; /*Already error code is set */ * 1292 <1> ; * 1293 <1> ; Expected LOC: 45 (New) * 1294 <1> ;******************************************************************************* 1295 <1> 1296 <1> SetMediaID proc near 0 0000929A E87900 call Changeline_Chk ;AN010; 0 0000929D 8A4505 mov al, [DI + DRIVELET] ;AN000; logical drive number 0 000092A0 88C2 mov dl, al ;AN000; save it for the time being. 0 000092A2 1E push ds 0 000092A3 E8[0000] call biocode_get_ds_dosentry 0 000092A6 C606[0000]02 mov byte [RFlag], ROMREAD ;AN000; read operation 0 000092AB 52 push dx ;AN000; save drive number 0 000092AC E84A00 call Boot_IO ;AN000; read boot sector into DOSENTRY:DiskSector 0 000092AF 5A pop dx ;AN000; restore drive number 1306 <1> ; $IF NC ;AN000; 0 000092B0 7245 JC $IOCTL$IF6_pop_ds 0 000092B2 8A0E[0000] mov cl, [MediaByte] ;AN000; Mediabyte in BPB 0 000092B6 80E1F0 and cl, 0F0h ;AN000; 0 000092B9 80F9F0 cmp cl, 0F0h ;AN000; Is it a valid BPB? 1311 <1> ; $IF E,AND ;AN000; 0 000092BC 7536 JNE $IOCTL$IF7 0 000092BE 803E[0000]29 cmp byte [Ext_Boot_Sig], EXT_BOOT_SIGNATURE ;AN000; =41 (=29h) 1314 <1> ; $IF E ;AN000; Extended Boot Record 0 000092C3 752F JNE $IOCTL$IF7 0 000092C5 1F pop ds 0 000092C6 1E push ds ;AN011; save BDS pointer 0 000092C7 57 push di ;AN011; 0 000092C8 06 push es ;AN000; 0 000092C9 1F pop ds ;AN000;Now DS-> Request packet 0 000092CA E8[0000] call biocode_get_es_dosentry ;AN000;Now ES -> Boot Record 0 000092CD BF[0000] mov di, offset Boot_Serial_L ;AN000; 0 000092D0 89DE mov si, bx ;AN000; 1324 <1> MI_Serial equ MI_SERIAL ; NASM port equate 0 000092D2 83C602 add si, MI_Serial ;AN000; 0 000092D5 B91700 mov cx, BOOT_SERIAL_SIZE+BOOT_VOLUME_LABEL_SIZE+BOOT_SYSTEM_ID_SIZE 0 000092D8 F3A4 rep movsb ;AN000; 0 000092DA 5F pop di ;AN011;Restore BDS pointer 0 000092DB 1F pop ds ;AN011; 0 000092DC E8DBF0 call Mov_Media_IDs ;AN011; Update the BDS media ID info. 0 000092DF 88D0 mov al, dl ;AN000; set drive number for Boot_IO 0 000092E1 1E push ds 0 000092E2 E8[0000] call biocode_get_ds_dosentry 0 000092E5 C606[0000]03 mov byte [RFlag], ROMWRITE ;AN000; 0 000092EA E80C00 call Boot_IO ;AN000; write it back. 0 000092ED C606[0000]FF mov byte [TIM_DRV], -1 ;AN011; Make sure chk$media check the driver 1337 <1> ; $ELSE ;AN000; 0 000092F2 EB03 JMP SHORT $IOCTL$EN7_pop_ds 1339 <1> $IOCTL$IF7: 0 000092F4 B007 mov al, ERROR_UNKNOWN_MEDIA ;AN000; =7 0 000092F6 F9 stc ;AN000; 1342 <1> ; $ENDIF ;End Extended Boot Record check. 1343 <1> ; $ENDIF ;Read boot sector failed. Hard error. 1344 <1> $IOCTL$EN7_pop_ds: 1345 <1> $IOCTL$IF6_pop_ds: 0 000092F7 1F pop ds 0 000092F8 C3 ret ;AN000; 1348 <1> SetMediaID endp 1349 <1> 1350 <1> ;****************************************************************************** 1351 <1> ;AN000; Boot_IO 1352 <1> ;******************************************************************************* 1353 <1> ; * 1354 <1> ; Function: Read/Write the boot record into Boot sector. * 1355 <1> ; * 1356 <1> ; Input : * 1357 <1> ; AL=logical drive number * 1358 <1> ; RFLAG = operation (read/write) * 1359 <1> ; * 1360 <1> ; Output: For read operation, the boot record of the drive specified in BDS * 1361 <1> ; be read into the DISKSECTOR buffer. * 1362 <1> ; For write operation, the DISKSECTOR buffer image will be written * 1363 <1> ; to the drive specified in BDS. * 1364 <1> ; If carry set, then AL contains the device driver error number * 1365 <1> ; that will be returned to DOS. * 1366 <1> ; AX,CX,DX register destroyed. * 1367 <1> ; If carry set, then AL will contain the error code from DISKIO. * 1368 <1> ; * 1369 <1> ; Subroutines to be called: * 1370 <1> ; DISKIO:NEAR * 1371 <1> ; * 1372 <1> ; Logic: * 1373 <1> ; * 1374 <1> ; { * 1375 <1> ; First_Sector = 0; /*logical sector 0 is the boot sector */ * 1376 <1> ; SectorCount = 1; /*read 1 sector only */ * 1377 <1> ; Buffer = DISKSECTOR; /*read it into the disksector buffer */ * 1378 <1> ; Call DISKIO (RFLAG, Drive_Number,First_Sector,SectorCount,Buffer); * 1379 <1> ; } * 1380 <1> ; Expected LOC: 6 (New) * 1381 <1> ;******************************************************************************* 1382 <1> Boot_IO proc near ;AN000; 0 000092F9 1E push ds ;AN000; 0 000092FA 06 push es ;AN000; 0 000092FB 57 push di ;AN000; 0 000092FC 53 push bx ;AN000; 1387 <1> ;SB34IOCTL003************************************************************** 1388 <1> ;SB Call DISKIO to read/write the boot sector. The parameters which 1389 <1> ;SB need to be initialised for this subroutine out here are 1390 <1> ;SB - transfer address to DOSENTRY:DiskSector 1391 <1> ;SB - low sector needs to be initalised to 0. This is a reg. param 1392 <1> ;SB - hi sector in [DOSENTRY:Start_Sec_H] needs to be initialised to 0. 1393 <1> ;SB - number of sectors <-- 1 1394 <1> ;SB 7 LOCS 1395 <1> 0 000092FD E8[0000] call biocode_get_es_dosentry 0 00009300 06 push es 0 00009301 1F pop ds 0 00009302 BF[0000] mov di, offset DiskSector ;es:di -> transfer address 0 00009305 31D2 xor dx, dx ;first sector (H) -> 0 0 00009307 8916[0000] mov [Start_Sec_H], dx ;start sector (H) -> 0 0 0000930B B90100 mov cx, 1 ;one sector 0 0000930E E85BF2 call DISKIO 1404 <1> ;SB34IOCTL003************************************************************** 0 00009311 5B pop bx ;AN000; 0 00009312 5F pop di ;AN000; 0 00009313 07 pop es ;AN000; 0 00009314 1F pop ds ;AN000; 0 00009315 C3 ret ;AN000; 1410 <1> Boot_IO endp ;AN000; 1411 <1> 1412 <1> ;******************************************************************************* 1413 <1> ;AN010; Changeline_Chk 1414 <1> ;******************************************************************************* 1415 <1> ;When the user calls Get/Set media ID call before DOS establishes the media * 1416 <1> ;by calling "Media$Chk", the change line activity of the drive is going to be * 1417 <1> ;lost. This routine will check the change line activity and will save the * 1418 <1> ;history in the flags. * 1419 <1> ; * 1420 <1> ; Function: Check the change line error activity * 1421 <1> ; * 1422 <1> ; Input : DS:DI -> BDS table. * 1423 <1> ; * 1424 <1> ; Output: FLAG in BDS table will be updated if change line occurs. * 1425 <1> ; * 1426 <1> ; Subroutines to be called: * 1427 <1> ; SET_CHANGED_DL * 1428 <1> ; * 1429 <1> ;******************************************************************************* 1430 <1> Changeline_Chk proc near ;AN010; 0 00009316 8A5504 mov dl, byte ptr [di + DRIVENUM] ;AN010; 0 00009319 08D2 or dl, dl ;AN010;Fixed disk? 0 0000931B 781F js Chln_Chk_Ret ;AN010;Yes, skip it. 0 0000931D 1E push ds 0 0000931E E8[0000] call biocode_get_ds_dosentry 0 00009321 803E[0000]01 cmp byte [fHave96], 1 ;AN011;This ROM support change line? 0 00009326 1F pop ds 0 00009327 7513 jne Chln_Chk_Ret ;AN011; 1439 <1> HasChange equ HASCHANGE ; NASM port label 0 00009329 E8[0000] call HasChange ;AN011;This drive support change line? 0 0000932C 740E jz Chln_Chk_Ret ;AN011;do nothing 1442 <1> ;SB34IOCTL004***************************************************************** 1443 <1> ;SB Execute the ROM disk interrupt to check changeline activity. 2 LOCS 1444 <1> 0 0000932E B416 mov ah, 16h 0 00009330 CD13 int 13h 1447 <1> ;SB34IOCTL004***************************************************************** 0 00009332 7308 jnc Chln_Chk_Ret ;AN010;no change line activity? 0 00009334 53 push bx 0 00009335 BB4000 mov bx, FCHANGED ;AN010; 0 00009338 E8[0000] call SET_CHANGED_DL ;AN010;Update FLAG in BDS for this physical drive 0 0000933B 5B pop bx 1453 <1> Chln_Chk_Ret: ;AN010; 0 0000933C C3 ret ;AN010; 1455 <1> Changeline_Chk endp ;AN010; 1456 <1> 1457 <1> ;****************************************************************************** 1458 <1> ;AN007; GetAccessFlag 1459 <1> ;******************************************************************************* 1460 <1> ; * 1461 <1> ; Function: Get the status of UNFORMATTED_MEDIA bit of FLAGS in BDS table * 1462 <1> ; * 1463 <1> ; Input : * 1464 <1> ; es:bx -> A_DISKACCESS_CONTROL structure * 1465 <1> ; ds:di -> BDS table * 1466 <1> ; * 1467 <1> ; Output: A_DISKACCESS_CONTROL.DAC_ACCESS_FLAG = 0 if disk I/O not allowed. * 1468 <1> ; = 1 if disk I/O allowed. * 1469 <1> ;******************************************************************************* 1470 <1> GetAccessFlag proc ;AN007; 0 0000933D F745230002 test word ptr [di + FLAGS], UNFORMATTED_MEDIA ;AN007;Is it unformtted media? 0 00009342 7407 jz GAF_Allowed ;AN007;No, formatted media 0 00009344 26C6470100 mov byte [es:bx + DAC_ACCESS_FLAG], 0 ;AN007; 0 00009349 EB05 jmp short GAF_Done ;AN007; 1475 <1> GAF_Allowed: ;AN007; 0 0000934B 26C6470101 mov byte [es:bx + DAC_ACCESS_FLAG], 1 ;AN007; 1477 <1> GAF_Done: ;AN007; 0 00009350 C3 ret ;AN007; 1479 <1> GetAccessFlag endp ;AN007; 1480 <1> 1481 <1> ;****************************************************************************** 1482 <1> ;AN007; SetAccessFlag 1483 <1> ;******************************************************************************* 1484 <1> ; * 1485 <1> ; Function: Set/Reset the UNFORMATTED_MEDIA bit of FLAGS in BDS table * 1486 <1> ; * 1487 <1> ; Input : * 1488 <1> ; es:bx -> A_DISKACCESS_CONTROL structure * 1489 <1> ; ds:di -> BDS table * 1490 <1> ; * 1491 <1> ; Output: UNFORMTTED_MEDIA bit modified according to the user request * 1492 <1> ;******************************************************************************* 1493 <1> SetAccessFlag proc ;AN007; 0 00009351 26807F0100 cmp byte [es:bx + DAC_ACCESS_FLAG], 0 ;AN007; 0 00009356 7507 jne SAF_Allow_Access ;AN007; 0 00009358 814D230002 or word ptr [di + FLAGS], UNFORMATTED_MEDIA ;AN007; 0 0000935D EB05 jmp short SAF_Done ;AN007; 1498 <1> SAF_Allow_Access: ;AN007; 0 0000935F 816523FFFD and word ptr [di + FLAGS], ~ UNFORMATTED_MEDIA ;AN007; 1500 <1> SAF_Done: ;AN007; 0 00009364 C3 ret ;AN007; 1502 <1> SetAccessFlag endp ;AN007; 1503 <1> 1504 <1> 1505 <1> 2627 ;=== Pop trace listing source 2628 ; PAGE 2629 ; CHECK_WRAP IS A ROUTINE THAT ADJUSTS THE STARTING SECTOR, STARTING HEAD 2630 ; AND STARTING CYLINDER FOR AN INT 13 REQUEST THAT REQUESTS I/O OF A LOT 2631 ; OF SECTORS. IT ONLY DOES THIS FOR FIXED DISKS. IT IS USED IN THE SECTIONS 2632 ; OF CODE THAT HANDLE ECC ERRORS AND DMA ERRORS. IT IS NECESSARY, BECAUSE 2633 ; ORDINARILY THE ROM WOULD TAKE CARE OF WRAPS AROUND HEADS AND CYLINDERS, 2634 ; BUT WE BREAK DOWN A REQUEST WHEN WE GET AN ECC OR DMA ERROR INTO SEVERAL 2635 ; I/O OF ONE OR MORE SECTORS. IN THIS CASE, WE MAY ALREADY BE BEYOND THE 2636 ; NUMBER OF SECTORS ON A TRACK ON THE MEDIUM, AND THE REQUEST WOULD FAIL. 2637 ; 2638 ; INPUT CONDITIONS: 2639 ; ALL REGISTERS SET UP FOR AN INT 13 REQUEST. 2640 ; 2641 ; OUTPUT: 2642 ; DH - CONTAINS STARTING HEAD NUMBER FOR REQUEST 2643 ; CX - CONTAINS STARTING SECTOR AND CYLINDER NUMBERS 2644 ; (THE ABOVE MAY OR MAY NOT HAVE BEEN CHANGED, AND ARE 0-BASED) 2645 ; ALL OTHER REGISTERS PRESERVED. 2646 ; 2647 PUBLIC CHECK_WRAP 2648 CHECK_WRAP: 2649 Message ftestDisk,<"Entering Check_Wrap...",cr,lf> 0 00009365 50531E57 SAVEREG 0 00009369 E8[0000] call biocode_get_ds_dosentry 0 0000936C C606[0000]01 MOV BYTE PTR [PHYS_DRV],1 ; USE PHYSICAL DRIVE IN AL TO GET BDS 0 00009371 88D0 MOV AL,DL ; AL HAS PHYSICAL DRIVE NUMBER 0 00009373 E822F1 CALL SETDRIVE ; GET POINTER TO BDS FOR DRIVE 0 00009376 1E push ds 0 00009377 E8[0000] call biocode_get_ds_dosentry 0 0000937A C606[0000]00 MOV BYTE PTR [PHYS_DRV],0 ; RESTORE FLAG TO USE LOGICAL DRIVE 0 0000937F 1F pop ds 0 00009380 725E JC NO_WRAP ; DO NOTHING IF WRONG PHYSICAL DRIVE 0 00009382 F745230100 TEST WORD PTR [DI + FLAGS],FNON_REMOVABLE 0 00009387 7457 JZ NO_WRAP ; NO WRAPPING FOR REMOVABLE MEDIA 0 00009389 8B5D13 MOV BX,[DI + SECLIM] 0 0000938C 89C8 MOV AX,CX 0 0000938E 83E03F AND AX,003FH ; EXTRACT SECTOR NUMBER 0 00009391 39D8 CMP AX,BX ; ARE WE GOING TO WRAP? 0 00009393 764B JBE NO_WRAP 0 00009395 F6F3 DIV BL ; AH=NEW SECTOR #, AL=# OF HEAD WRAPS 2668 ; WE NEED TO BE CAREFUL HERE. IF THE NEW SECTOR # IS 0, THEN WE ARE ON THE 2669 ; LAST SECTOR ON THAT TRACK. 0 00009397 08E4 OR AH,AH 0 00009399 7504 JNZ NOT_ON_BOUND 0 0000939B 88DC MOV AH,BL ; SET SECTOR=SECLIM IF ON BOUNDARY 0 0000939D FEC8 DEC AL ; ALSO DECREMENT # OF HEAD WRAPS 2674 NOT_ON_BOUND: 0 0000939F 80E1C0 AND CL,0C0H ; ZERO OUT SECTOR # 0 000093A2 08E1 OR CL,AH ; OR IN NEW SECTOR # 0 000093A4 30E4 XOR AH,AH ; AX = # OF HEAD WRAPS 0 000093A6 40 INC AX 0 000093A7 00F0 ADD AL,DH ; ADD IN STARTING HEAD # 0 000093A9 80D400 ADC AH,0 ; CATCH ANY CARRY 0 000093AC 3B4515 CMP AX,[DI + HDLIM] ; ARE WE GOING TO WRAP AROUND A HEAD? 0 000093AF 7635 JBE NO_WRAP_HEAD ; DO NOT LOSE NEW HEAD NUMBER!! 0 000093B1 52 PUSH DX ; PRESERVE DRIVE NUMBER AND HEAD NUMBER 0 000093B2 31D2 XOR DX,DX 0 000093B4 8B5D15 MOV BX,[DI + HDLIM] 0 000093B7 F7F3 DIV BX ; DX=NEW HEAD #, AX=# OF CYLINDER WRAPS 2687 ; CAREFUL HERE! IF NEW HEAD # IS 0, THEN WE ARE ON THE LAST HEAD. 0 000093B9 85D2 test DX,DX 0 000093BB 7507 JNZ NO_HEAD_BOUND 0 000093BD 89DA MOV DX,BX ; ON BOUNDARY. SET TO HDLIM 2691 ; IF WE HAD SOME CYLINDER WRAPS, WE NEED TO REDUCE THEM BY ONE!! 0 000093BF 85C0 test AX,AX 0 000093C1 7401 JZ NO_HEAD_BOUND 0 000093C3 48 DEC AX ; REDUCE NUMBER OF CYLINDER WRAPS 2695 NO_HEAD_BOUND: 0 000093C4 88D7 MOV BH,DL ; BH HAS NEW HEAD NUMBER 0 000093C6 5A POP DX ; RESTORE DRIVE NUMBER AND HEAD NUMBER 0 000093C7 FECF DEC BH ; GET IT 0-BASED 0 000093C9 88FE MOV DH,BH ; SET UP NEW HEAD NUMBER IN DH 0 000093CB 88CF MOV BH,CL 0 000093CD 80E73F AND BH,3FH ; PRESERVE SECTOR NUMBER 0 000093D0 B306 MOV BL,6 0 000093D2 86CB XCHG CL,BL 0 000093D4 D2EB SHR BL,CL ; GET MS CYLINDER BITS TO LS END 0 000093D6 00C5 ADD CH,AL ; ADD IN CYLINDER WRAP 0 000093D8 10E3 ADC BL,AH ; ADD IN HIGH BYTE 0 000093DA D2E3 SHL BL,CL ; MOVE UP TO MS END 0 000093DC 86D9 XCHG BL,CL ; RESTORE CYLINDER BITS INTO CL 0 000093DE 08F9 OR CL,BH ; OR IN SECTOR NUMBER 2710 2711 NO_WRAP: 0 000093E0 F8 CLC ; RESET CARRY 0 000093E1 5F1F5B58 RESTOREREG 0 000093E5 C3 RET 2715 2716 NO_WRAP_HEAD: 0 000093E6 88C6 MOV DH,AL ; DO NOT LOSE NEW HEAD NUMBER 0 000093E8 FECE DEC DH ; GET IT 0-BASED 0 000093EA EBF4 JMP SHORT NO_WRAP 2720 2721 ; 2722 ; INT_2F_13: 2723 ; THIS CODE IS CHAINED INTO THE INT_2F INTERRUPT DURING BIOS 2724 ; INITIALIZATION. IT ALLOWS THE USER TO CHANGE THE ORIG13 INT_13 VECTOR 2725 ; AFTER BOOTING. THIS ALLOWS TESTING AND IMPLEMENTATION OF CUSTOM INT_13 2726 ; HANDLERS, WITHOUT GIVING UP MS-DOS ERROR RECOVERY 2727 ; 2728 ; ENTRY CONDITIONS 2729 ; AH == RESET_INT_13 (13H) 2730 ; DS:DX == ADDRESS OF NEW INT_13 HANDLER 2731 ; ES:BX == ADDRESS OF NEW INT_13 VECTOR USED BY WARM BOOT 2732 ; (INT 19) 2733 ; 2734 ; EXIT CONDITIONS 2735 ; ORIG13 == ADDRESS OF NEW INT_13 HANDLER 2736 ; DS:DX == OLD ORIG13 VALUE 2737 ; ES:BX == OLD OLD13 VALUE 2738 2739 ASSUME CS:BIOCODE,DS:NOTHING,ES:NOTHING,SS:NOTHING 2740 2741 relocated set_i13_i2F 2742 PUBLIC INT_2F_13 2743 INT_2F_13 PROC FAR 2744 0 000093EC 80FC13 CMP AH,13H ; IF (INTERRUPT_VALUE != RESET_INT_13) 0 000093EF 7405 JE CHG_ORIG13 0 000093F1 EA[0000][0000] jmp DOSENTRY:transfer_next2F_13 ; THEN CONTINUE ON INT_2F CHAIN 2748 2749 === Switch to base=000000h -> "DOSENTRY" 2750 section DOSENTRY 2751 2752 extern transfer_next2F_13 2753 2754 === Switch to base=008400h -> "BIOCODE" 2755 section BIOCODE 2756 2757 CHG_ORIG13: ; ELSE 0 000093F6 FA cli 0 000093F7 50 push ax 0 000093F8 8CD8 mov ax, ds 0 000093FA E8[0000] call biocode_get_ds_dosentry 0 000093FD FF36[0000] PUSH WORD PTR [ORIG13] ; SAVE OLD VALUE OF OLD13 AND 0 00009401 FF36[0200] PUSH WORD PTR [ORIG13 + 2]; ORIG13 SO THAT WE CAN 2764 0 00009405 FF36[0000] PUSH WORD PTR [OLD13] ; RETURN THEM TO CALLER 0 00009409 FF36[0200] PUSH WORD PTR [OLD13 + 2] 2767 0 0000940D 8916[0000] MOV WORD PTR [ORIG13],DX ; ORIG13 := ADDR. OF NEW INT_13 2769 ; VECTOR 0 00009411 A3[0200] MOV WORD PTR [ORIG13+2], ax 2771 0 00009414 891E[0000] MOV WORD PTR [OLD13],BX ; OLD13 := ADDR. OF NEW 2773 ; BOOT_13 VECTOR 0 00009418 8C06[0200] MOV WORD PTR [OLD13+2],ES 2775 0 0000941C 07 POP ES ; ES:BX := OLD OLD13 VECTOR 0 0000941D 5B POP BX 2778 0 0000941E 1F POP DS ; DS:DX := OLD ORIG13 VECTOR 0 0000941F 5A POP DX 0 00009420 58 pop ax 2782 0 00009421 CF IRET ; END ELSE 2784 2785 INT_2F_13 ENDP 2786 2787 MOVE PROC NEAR 0 00009422 FC CLD 0 00009423 51 PUSH CX 0 00009424 B90001 MOV CX,512/2 2791 ;J.K. Warning!!! Do not change the position of this label. 2792 ; The following three bytes will be NOPed out by MSINIT if the system 2793 ; does not support the DOUBLE WORD MOV instruction, i.e., (if 2794 ; not 386 base machine.) 2795 ;---------------------------------------------------------------------------- 2796 public DoubleWordMov 2797 DoubleWordMov: ;AN002; 0 00009427 D1E9 shr cx, 1 ;AN002;Make it a double word. 0 00009429 66 db 66h ;AN002;Machine code for double word mov 2800 ;---------------------------------------------------------------------------- 0 0000942A F3A5 REP MOVSW 0 0000942C 59 POP CX 0 0000942D C3 RET 2804 MOVE ENDP 2805 2806 DOINT PROC NEAR 0 0000942E 8A5608 MOV DL,BYTE PTR [BP + OLDDX] ; GET PHYSICAL DRIVE NUMBER 0 00009431 30E4 XOR AH,AH 0 00009433 84C0 test AL,AL 0 00009435 740F JZ DOINTDONE 0 00009437 8A6603 MOV AH,BYTE PTR [BP + OLDAX+1] ; GET REQUEST CODE 0 0000943A FF760E PUSH word [BP + OLDF] 0 0000943D 9A[0000][0000] call DOSENTRY:transfer_orig13 0 00009442 9C PUSHF 0 00009443 8F460E POP word [BP + OLDF] 2816 DOINTDONE: 0 00009446 C3 RET 2818 DOINT ENDP 2819 2820 2821 global ispatched 2822 ispatched: 0 00009447 1E push ds 0 00009448 E8[0000] call biocode_get_ds_dosentry 0 0000944B 803E[0000]01 cmp byte [FHAVE96], 1 ; CY if 0 0 00009450 1F pop ds 0 00009451 C3 retn 2828 2829 2830 ; (no prior section) ; CODE ENDS 2831 END === Trace listing source: msbio2.lst 1 ; PAGE ,132 ; 2 ; TITLE MSBIO2 - BIOS 3 4 %warning out: ...MSBIO2.ASM 4 ****************** warning: out: ...MSBIO2.ASM [-w+user] 5 6 ;============================================================================== 7 ;REVISION HISTORY: 8 ;AN000 - New for DOS Version 4.00 - J.K. 9 ;AC000 - Changed for DOS Version 4.00 - J.K. 10 ;AN00x - PTM number for DOS Version 4.00 - J.K. 11 ;============================================================================== 12 ;AN001; - P1820 New Message SKL file 10/20/87 J.K. 13 ;AN002; - P5045 New INT 2fh for Get BDS table vector for EMS 06/06/88 J.K. 14 ;============================================================================== 15 16 ROMSEGMENT EQU 0F000H 17 labelsize MODELBYTE, byte, 0FFFEH 18 MODELPCJR EQU 0FDH 19 20 itest equ 0 21 22 %include "msgroup.mac" ;DEFINE CODE SEGMENT 1 <1> EVBOUND equ 1 ;THIS VALUE BEING 0 DOES NO BOUNDARY ALLIGNMENT, VALUE 1 ;3.30 2 <1> ; ALIGNS TO EVEN ;3.30 3 <1> 4 <1> ; NASM original macros 5 <1> 6 <1> %include "dcodeseg.nas" 1 <2> 2 <2> %ifndef DCODESEGNAS 3 <2> %assign DCODESEGNAS 1 4 <2> === Switch to base=008400h -> "DOSCODETABLE" 5 <2> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <2> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=008400h -> "DOSCODECODE" 7 <2> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <2> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=008400h -> "DOSBIOCODE" 9 <2> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=008400h -> "BIOCODE" 10 <2> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <2> 12 <2> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <2> 14 <2> %endif 7 <1> 8 <1> %if EVBOUND ;;IF EVEN (WORD) ALLIGNMENT IS REQUESTED, ;3.30 9 <1> 10 <1> %imacro EVENB 0.nolist 11 <1> EVEN ;;ADJUST TO EVEN BOUNDARY 12 <1> %endmacro 13 <1> 14 <1> %imacro ODD 0.nolist 15 <1> %if (($ - $$) % 2) == 0 16 <1> db ? 17 <1> %endif 18 <1> %endmacro 19 <1> 20 <1> %else ;;SINCE EVEN ALLIGNMENT IS NOT DESIRED, JUST USE BYTE ALLI;3.30 GNMENT 21 <1> 22 <1> %imacro EVENB 0.nolist 23 <1> ;;REQUEST FOR WORD ALLIGNMENT DOES NOTHING ;3.30 24 <1> %endmacro 25 <1> 26 <1> %imacro ODD 0.nolist 27 <1> ;;REQUEST FOR ODD ALLIGNMENT DOES NOTHING ;3.30 28 <1> %endmacro 29 <1> 30 <1> %endif ;3.30 31 <1> 32 <1> %imacro CODE_SEGMENT 0.nolist === Switch to base=008400h -> "BIOCODE" 33 <1> section BIOCODE 34 <1> %endmacro 35 <1> 36 <1> ; end of NASM original macros 37 <1> 38 <1> CODE_SEGMENT ;3.30 39 <1> ASSUME CS:BIOCODE ;3.30 40 <1> ;3.30 23 %include "msequ.mac" 1 <1> %warning out: MSEQU.INC... 1 ****************** <1> warning: out: MSEQU.INC... [-w+user] 2 <1> ;============================================================================== 3 <1> 4 <1> FTOOBIG EQU 80H 5 <1> FBIG EQU 40H 6 <1> ROMSTATUS EQU 1 7 <1> ROMREAD EQU 2 8 <1> ROMWRITE EQU 3 9 <1> ROMVERIFY EQU 4 10 <1> ROMFORMAT EQU 5 11 <1> VID_SIZE EQU 12 12 <1> 13 <1> %include "msbds.mac" ; VARIOUS EQUATES FOR BDS 1 <2> 2 <2> %warning out: MSBDS.INC... 2 ****************** <2> warning: out: MSBDS.INC... [-w+user] 3 <2> ; SCCSID = @(#)IBMBDS.ASM 1.9 85/09/16 4 <2> ;============================================================================== 5 <2> ;REVISION HISTORY: 6 <2> ;AN000 - New for DOS Version 4.00 - J.K. 7 <2> ;AC000 - Changed for DOS Version 4.00 - J.K. 8 <2> ;AN00x - PTM number for DOS Version 4.00 - J.K. 9 <2> ;============================================================================== 10 <2> ;AN001; D113 Disable I/O access to unformatted media 9/03/87 J.K. 11 <2> ;============================================================================== 12 <2> 13 <2> ; VALUES FOR VARIOUS FLAGS IN BDS.FLAGS. 14 <2> 15 <2> FNON_REMOVABLE EQU 01H ;FOR NON-REMOVABLE MEDIA 16 <2> FCHANGELINE EQU 02H ;IF CHANGELINE SUPPORTED ON DRIVE 17 <2> RETURN_FAKE_BPB EQU 04H ; WHEN SET, DON'T DO A BUILD BPB 18 <2> ; JUST RETURN THE FAKE ONE 19 <2> GOOD_TRACKLAYOUT EQU 08H ; THE TRACK LAYOUT HAS NO FUNNY SECTORS 20 <2> ; FCHANGED_BY_FORMAT EQU 08H 21 <2> FI_AM_MULT EQU 10H ;IF MORE THAN ONE LOGICAL FOR THIS PHYSICAL 22 <2> FI_OWN_PHYSICAL EQU 20H ;SIGNIFY LOGICAL OWNER OF THIS PHYSICAL 23 <2> FCHANGED EQU 40H ;INDICATES MEDIA CHANGED 24 <2> SET_DASD_TRUE EQU 80H ; SET DASD BEFORE NEXT FORMAT 25 <2> FCHANGED_BY_FORMAT EQU 100H ;MEDIA CHANGED BY FORMAT 26 <2> UNFORMATTED_MEDIA EQU 200H ;AN001; Fixed disk only 27 <2> F_LBA equ 400h ; LBA supported 28 <2> 29 <2> LBAPACKETSTRUC struc 0 00009452 ???? lpSize dw ? 0 00009454 ???? lpCount dw ? 0 00009456 ???????? lpBuffer dd ? 0 0000945A ???????????????? lpSector dd ?,? 34 <2> LBAPACKETSTRUC ends 35 <2> 36 <2> ; 37 <2> ; VARIOUS FORM FACTORS TO DESCRIBE MEDIA 38 <2> ; 39 <2> FF48TPI EQU 0 40 <2> FF96TPI EQU 1 41 <2> FFSMALL EQU 2 42 <2> FFHARDFILE EQU 5 43 <2> FFOTHER EQU 7 44 <2> 45 <2> BDS_TYPE STRUC 0 00009452 ???????? LINK DD ? ; LINK TO NEXT BDS 0 00009456 ?? DRIVENUM DB ? ; INT 13 DRIVE NUMBER 0 00009457 ?? DRIVELET DB ? ; DOS DRIVE NUMBER 0 00009458 ???? BYTEPERSEC DW ? ; NUMBER OF BYTES/SEC 0 0000945A ?? SECPERCLUS DB ? ; SEC PER ALLOCATION UNIT 0 0000945B ???? RESSEC DW ? ; NUMBER OF RESERVED SECTORS 0 0000945D ?? CFAT DB ? ; NUMBER OF FATS 0 0000945E ???? CDIR DW ? ; NUMBER OF DIRECTORY ENTRIES 0 00009460 ???? DRVLIM DW ? ; NUMBER OF SECTORS ON MEDIUM 0 00009462 ?? MEDIAD DB ? ; MEDIA DESCRIPTOR BYTE 0 00009463 ???? CSECFAT DW ? ; NUMBER OF SECTORS/FAT 0 00009465 ???? SECLIM DW ? ; SECTORS PER TRACK 0 00009467 ???? HDLIM DW ? ; MAX NUMBER OF HEADS 0 00009469 ???? HIDSEC_L DW ? ; NUMBER OF HIDDEN SECTORS 0 0000946B ???? HIDSEC_H dw ? ;0 ;J.K.87 0 0000946D ???? DRVLIM_L dw ? ;0 ;J.K.87 0 0000946F ???? DRVLIM_H dw ? ;0 ;J.K.87 0 00009471 ?? FATSIZ DB ? ; FLAGS... 0 00009472 ???? OPCNT DW ? ; OPEN REF. COUNT 0 00009474 ?? FORMFACTOR DB ? ; FORM FACTOR INDEX 0 00009475 ???? FLAGS DW ? ; VARIOUS FLAGS 0 00009477 ???? CCYLN DW ? ; MAX NUMBER OF CYLINDERS 0 00009479 ???? RBYTEPERSEC DW ? ; RECOMMENDED BPB 0 0000947B ?? RSECPERCLUS DB ? 0 0000947C ???? RRESSEC DW ? 0 0000947E ?? RCFAT DB ? 0 0000947F ???? RCDIR DW ? 0 00009481 ???? RDRVLIM DW ? 0 00009483 ?? RMEDIAD DB ? 0 00009484 ???? RCSECFAT DW ? 0 00009486 ???? RSECLIM DW ? 0 00009488 ???? RHDLIM DW ? 0 0000948A ???? RHIDSEC_L DW ? 0 0000948C ???? RHIDSEC_H DW ? ;0 ;J.K.87 0 0000948E ???? RDRVLIM_L dw ? ;0 ;J.K.87 0 00009490 ???? RDRVLIM_H dw ? ;0 ;J.K.87 0 00009492 ???????????? RESERVE DB 6 DUP (?) ; RESERVED FOR FUTURE 0 00009498 ?? TRACK DB ? ; LAST TRACK ACCESSED ON DRIVE 0 00009499 ???? TIM_LO DW ? ; TIME OF LAST ACCESS. KEEP 0 0000949B ???? TIM_HI DW ? ; THESE CONTIGUOUS. 86 0000004B <2> VOLID DB 12 DUP (?) ; VOLUME ID OF MEDIUM 0 000094A9 ???????? VOL_SERIAL dd ? ;0 ;J.K.87 Current volume serial number from Boot record 88 0000005B <2> FILESYS_Id db 9 dup (?) ;(0) ;J.K.87 Current file system id from Boot record 89 <2> BDS_TYPE ENDS 90 <2> 91 <2> BPBSIZE equ TRACK - RBYTEPERSEC ; SIZE IN BYTES OF RECBPB AREA IN THE BDS 92 <2> 93 <2> 94 <2> ;********************************************************************* 95 <2> ; BDS structure for mini disk - J.K. 4/7/86 96 <2> ;********************************************************************* 97 <2> 98 <2> BDSM_type struc 0 00009452 ???? mlink DW ? ;-1 ;Link to next structure 0 00009454 ???? DW ? 0 00009456 ?? mdriveNum DB ? ;80 ;Int 13 Drive Number 0 00009457 ?? mdriveLet DB ? ;3 ;Logical Drive Number 0 00009458 ???? mBytePerSec DW ? ;512 0 0000945A ?? mSecPerClus DB ? ;1 ;Sectors/allocation unit 0 0000945B ???? mRESSEC DW ? ;1 ;Reserved sectors for DOS 0 0000945D ?? mcFAT DB ? ;2 ;No. of allocation tables 0 0000945E ???? mcDIR DW ? ;16 ;Number of directory entries 0 00009460 ???? mDRVLIM DW ? ;0 ;Number of sectors (at 512 bytes each) 0 00009462 ?? mMediad DB ? ;11111000B ;Media descriptor 0 00009463 ???? mcSecFat DW ? ;1 ;Number of FAT sectors 0 00009465 ???? mSECLIM DW ? ;0 ;Sector limit 0 00009467 ???? mHDLIM DW ? ;0 ;Head limit 0 00009469 ???? mHIDSEC_L DW ? ;0 ;Hidden sector count 0 0000946B ???? mHidsec_H dw ? ;0 ;J.K.87 0 0000946D ???? mDrvlim_L dw ? ;0 ;J.K.87 0 0000946F ???? mDrvlim_H dw ? ;0 ;J.K.87 0 00009471 ?? mFatSiz DB ? ;0 ;TRUE => bigfat 0 00009472 ???? mOPCNT DW ? ;0 ;Open Ref. Count 0 00009474 ?? mFormFactor DB ? ;3 ;Form Factor 0 00009475 ???? mFLAGS DW ? ;0020H ;Various Flags 0 00009477 ???? mcCyln dw ? ;40 ;max number of cylinders 122 00000027 <2> mRecBPB db 31 dup (?) ;(0) ;Recommended BPB for drive 0 00009498 ?? mTrack db ? ;-1 0 00009499 ???? IsMini dw ? ;1 ;Overlapping TIM_LOH 0 0000949B ???? Hidden_Trks dw ? ;0 ;Overlapping TIM_HIH 126 0000004B <2> mVOLID DB 11 dup (?) ;"NO NAME " ;Volume ID for this disk 0 000094A8 ?? DB ? ;0 ;ASCIZII for "NO NAME " 0 000094A9 ???????? mVol_Serial dd ? ;0 ;Current volume serial number from Boot record 0 000094AD ???????????????? mFileSys_Id db 8 dup (?) ;"FAT12 " ;Current file system id from Boot record 0 000094B5 ?? db ? ;0 131 <2> 132 <2> BDSM_type ENDS 133 <2> ;****************************************************************************** 134 <2> Max_mini_dsk_num equ 23 ;J.K. 4/7/86 - max # of mini disk ibmbio can support 135 <2> ; 136 <2> 14 <1> 15 <1> ;AN000; Extended BPB structure. 16 <1> BPB_TYPE STRUC 0 00009452 ???? SECSIZE DW ? 0 00009454 ?? SECALL DB ? 0 00009455 ???? RESNUM DW ? 0 00009457 ?? FATNUM DB ? 0 00009458 ???? DIRNUM DW ? 0 0000945A ???? SECNUM DW ? 0 0000945C ?? FATID DB ? 0 0000945D ???? FATSIZE DW ? 0 0000945F ???? SLIM DW ? 0 00009461 ???? HLIM DW ? 0 00009463 ???? HIDDEN_L DW ? 0 00009465 ???? HIDDEN_H dw ? ;0 ;J.K. 0 00009467 ???? SECNUM_L dw ? ;0 ;J.K. 0 00009469 ???? SECNUM_H dw ? ;0 ;J.K. 31 <1> BPB_TYPE ENDS 32 <1> 33 <1> ;;;;;;;;;;; 34 <1> BOOT_SERIAL_SIZE equ 4 ;J.K. 35 <1> BOOT_VOLUME_LABEL_SIZE equ 11 ;J.K. 36 <1> BOOT_SYSTEM_ID_SIZE equ 8 ;J.K. 37 <1> EXT_BOOT_SIGNATURE equ 41 ;J.K. 38 <1> RSINIT equ 0A3H ;RS232 INITIALIZATION 39 <1> ;9600 BAUD:NO PARITY:1 STOP:8 BIT WORD 40 <1> LF equ 10 ;LINE FEED 41 <1> CR equ 13 ;CARRIAGE RETURN 42 <1> BACKSP equ 8 ;BACKSPACE 43 <1> BRKADR equ 1BH * 4 ;006C 1BH BREAK VECTOR ADDRESS 44 <1> TIMADR equ 1CH * 4 ;0070 1CH TIMER INTERRUPT 45 <1> DSKADR equ 1EH * 4 ;ADDRESS OF PTR TO DISK PARAMETERS 46 <1> SEC9 equ 522H ;ADDRESS OF DISK PARAMETERS 47 <1> HEADSETTLE equ SEC9+9 ; ARR 2.20 ADDRESS OF HEAD SETTLE TIME 48 <1> NORMSETTLE equ 15 ; ARR 2.20 NORMAL HEAD SETTLE 49 <1> SPEEDSETTLE equ 0 ; ARR 2.20 SPEED UP SETTLE TIME 50 <1> INITSPOT equ 534H ; ARR IBM WANTS 4 ZEROS HERE 51 <1> AKPORT equ 20H 52 <1> EOI equ 20H 53 <1> CMDLEN equ 0 ;LENGTH OF THIS COMMAND 54 <1> UNIT equ 1 ;SUB UNIT SPECIFIER 55 <1> CMD equ 2 ;COMMAND CODE 56 <1> STATUS equ 3 ;STATUS 57 <1> MEDIA equ 13 ;MEDIA DESCRIPTOR 58 <1> TRANS equ 14 ;TRANSFER ADDRESS 59 <1> COUNT equ 18 ;COUNT OF BLOCKS OR CHARACTERS 60 <1> START equ 20 ;FIRST BLOCK TO TRANSFER 61 <1> EXTRA equ 22 ;USUALLY A POINTER TO VOL ID FOR ERROR 15 62 <1> CHROUT equ 29H 63 <1> MAXERR equ 5 64 <1> LSTDRV equ 504H 65 <1> 66 <1> NOTBUSYSTATUS equ 10000000B ; NOT BUSY 67 <1> ACKSTATUS equ 01000000B ; ACKNOWLEDGE (FOR WHAT?) 68 <1> NOPAPERSTATUS equ 00100000B ; NO MORE PAPER 69 <1> SELECTEDSTATUS equ 00010000B ; THE PRINTER SAID IT WAS SELECTED 70 <1> IOERRSTATUS equ 00001000B ; SOME KINDA ERROR 71 <1> RESERVED equ 00000110B ; NOPS 72 <1> TIMEOUTSTATUS equ 00000001B ; TIME OUT. 73 <1> ERROR_UNKNOWN_MEDIA equ 7 ; FOR USE IN BUILD BPB CALL 74 <1> 75 <1> PATHGEN equ 1 24 %include "devsym.mac" 1 <1> %warning out: DEVSYM.INC... 1 ****************** <1> warning: out: DEVSYM.INC... [-w+user] 2 <1> ; SCCSID = @(#)DEVSYM.ASM 1.10 85/09/04 3 <1> ; SCCSID = @(#)DEVSYM.ASM 1.10 85/09/04 4 <1> 5 <1> ; THE DEVICE TABLE LIST HAS THE FORM: 6 <1> SYSDEV STRUC 0 00009452 ???????? SDEVNEXT DD ? ;POINTER TO NEXT DEVICE HEADER 0 00009456 ???? SDEVATT DW ? ;ATTRIBUTES OF THE DEVICE 0 00009458 ???? SDEVSTRAT DW ? ;STRATEGY ENTRY POINT 0 0000945A ???? SDEVINT DW ? ;INTERRUPT ENTRY POINT 0 0000945C ???????????????? SDEVNAME DB 8 DUP (?) ;NAME OF DEVICE (ONLY FIRST BYTE USED FOR BLOCK) 12 <1> SYSDEV ENDS 13 <1> 14 <1> ; 15 <1> ; ATTRIBUTE BIT MASKS 16 <1> ; 17 <1> ; CHARACTER DEVICES: 18 <1> ; 19 <1> ; BIT 15 -> MUST BE 1 20 <1> ; 14 -> 1 IF THE DEVICE UNDERSTANDS IOCTL CONTROL STRINGS 21 <1> ; 13 -> 1 IF THE DEVICE SUPPORTS OUTPUT-UNTIL-BUSY 22 <1> ; 12 -> UNUSED 23 <1> ; 11 -> 1 IF THE DEVICE UNDERSTANDS OPEN/CLOSE 24 <1> ; 10 -> MUST BE 0 25 <1> ; 9 -> MUST BE 0 26 <1> ; 8 -> UNUSED 27 <1> ; 7 -> UNUSED 28 <1> ; 6 -> UNUSED 29 <1> ; 5 -> UNUSED 30 <1> ; 4 -> 1 IF DEVICE IS RECIPIENT OF INT 29H 31 <1> ; 3 -> 1 IF DEVICE IS CLOCK DEVICE 32 <1> ; 2 -> 1 IF DEVICE IS NULL DEVICE 33 <1> ; 1 -> 1 IF DEVICE IS CONSOLE OUTPUT 34 <1> ; 0 -> 1 IF DEVICE IS CONSOLE INPUT 35 <1> ; 36 <1> ; BLOCK DEVICES: 37 <1> ; 38 <1> ; BIT 15 -> MUST BE 0 39 <1> ; 14 -> 1 IF THE DEVICE UNDERSTANDS IOCTL CONTROL STRINGS 40 <1> ; 13 -> 1 IF THE DEVICE DETERMINES MEDIA BY EXAMINING THE FAT ID BYTE. 41 <1> ; THIS REQUIRES THE FIRST SECTOR OF THE FAT TO *ALWAYS* RESIDE IN 42 <1> ; THE SAME PLACE. 43 <1> ; 12 -> UNUSED 44 <1> ; 11 -> 1 IF THE DEVICE UNDERSTANDS OPEN/CLOSE/REMOVABLE MEDIA 45 <1> ; 10 -> MUST BE 0 46 <1> ; 9 -> MUST BE 0 47 <1> ; 8 -> UNUSED 48 <1> ; 7 -> UNUSED 49 <1> ; 6 -> IF DEVICE HAS SUPPORT FOR GETMAP/SETMAP OF LOGICAL DRIVES. 50 <1> ; IF THE DEVICE UNDERSTANDS GENERIC IOCTL FUNCTION CALLS. 51 <1> ; 5 -> UNUSED 52 <1> ; 4 -> UNUSED 53 <1> ; 3 -> UNUSED 54 <1> ; 2 -> UNUSED 55 <1> ; 1 -> UNUSED 56 <1> ; 0 -> UNUSED 57 <1> ; 58 <1> 59 <1> DEVTYP EQU 8000H ; BIT 15 - 1 IF CHAR, 0 IF BLOCK 60 <1> CHARDEV EQU 8000H 61 <1> DEVIOCTL EQU 4000H ; BIT 14 - CONTROL MODE BIT 62 <1> ISFATBYDEV EQU 2000H ; BIT 13 - DEVICE USES FAT ID BYTES, 63 <1> ; COMP MEDIA. 64 <1> OUTTILBUSY EQU 2000H ; OUTPUT UNTIL BUSY IS ENABLED 65 <1> ISNET EQU 1000H ; BIT 12 - 1 IF A NET DEVICE, 0 IF 66 <1> ; NOT. CURRENTLY BLOCK ONLY. 67 <1> DEVOPCL EQU 0800H ; BIT 11 - 1 IF THIS DEVICE HAS 68 <1> ; OPEN,CLOSE AND REMOVABLE MEDIA 69 <1> ; ENTRY POINTS, 0 IF NOT 70 <1> 71 <1> EXTENTBIT EQU 0400H ; BIT 10 - CURRENTLY 0 ON ALL DEVS 72 <1> ; THIS BIT IS RESERVED FOR FUTURE USE 73 <1> ; TO EXTEND THE DEVICE HEADER BEYOND 74 <1> ; ITS CURRENT FORM. 75 <1> 76 <1> ; NOTE BIT 9 IS CURRENTLY USED ON IBM SYSTEMS TO INDICATE "DRIVE IS SHARED". 77 <1> ; SEE IOCTL FUNCTION 9. THIS USE IS NOT DOCUMENTED, IT IS USED BY SOME 78 <1> ; OF THE UTILITIES WHICH ARE SUPPOSED TO FAIL ON SHARED DRIVES ON SERVER 79 <1> ; MACHINES (FORMAT,CHKDSK,RECOVER,..). 80 <1> 81 <1> DEV320 EQU 0040H ;BIT 6 - FOR BLOCK DEVICES, THIS 82 <1> ;DEVICE SUPPORTS SET/GET MAP OF 83 <1> ;LOGICAL DRIVES, AND SUPPORTS 84 <1> ;GENERIC IOCTL CALLS. 85 <1> ;FOR CHARACTER DEVICES, THIS 86 <1> ;DEVICE SUPPORTS GENERIC IOCTL. 87 <1> ;THIS IS A DOS 3.2 DEVICE DRIVER. 88 <1> ISSPEC EQU 0010H ;BIT 4 - THIS DEVICE IS SPECIAL 89 <1> ISCLOCK EQU 0008H ;BIT 3 - THIS DEVICE IS THE CLOCK DEVICE. 90 <1> ISNULL EQU 0004H ;BIT 2 - THIS DEVICE IS THE NULL DEVICE. 91 <1> ISCOUT EQU 0002H ;BIT 1 - THIS DEVICE IS THE CONSOLE OUTPUT. 92 <1> ISCIN EQU 0001H ;BIT 0 - THIS DEVICE IS THE CONSOLE INPUT. 93 <1> EXTDRVR EQU 0002H ;BIT 1 - BLOCK DEVICE EXTNDED DRIVER 94 <1> 95 <1> ;STATIC REQUEST HEADER 96 <1> SRHEAD STRUC 0 00009452 ?? REQLEN DB ? ;LENGTH IN BYTES OF REQUEST BLOCK 0 00009453 ?? REQUNIT DB ? ;DEVICE UNIT NUMBER 0 00009454 ?? REQFUNC DB ? ;TYPE OF REQUEST 0 00009455 ???? REQSTAT DW ? ;STATUS WORD 0 00009457 ???????????????? DB 8 DUP(?) ;RESERVED FOR QUEUE LINKS 102 <1> SRHEAD ENDS 103 <1> 104 <1> ;STATUS WORD MASKS 105 <1> STERR EQU 8000H ;BIT 15 - ERROR 106 <1> STBUI EQU 0200H ;BIT 9 - BUISY 107 <1> STDON EQU 0100H ;BIT 8 - DONE 108 <1> STECODE EQU 00FFH ;ERROR CODE 109 <1> ; 2/12/KK 110 <1> ; Interim character identifier 2/12/KK 111 <1> Ddkey EQU 0000010000000000B ; 2/12/KK 112 <1> 113 <1> ;FUNCTION CODES 114 <1> DEVINIT EQU 0 ;INITIALIZATION 115 <1> DINITHL EQU 26 ;SIZE OF INIT HEADER 116 <1> DEVMDCH EQU 1 ;MEDIA CHECK 117 <1> DMEDHL EQU 15 ;SIZE OF MEDIA CHECK HEADER 118 <1> DEVBPB EQU 2 ;GET BPB 119 <1> DEVRDIOCTL EQU 3 ;IOCTL READ 120 <1> DBPBHL EQU 22 ;SIZE OF GET BPB HEADER 121 <1> DEVRD EQU 4 ;READ 122 <1> DRDWRHL EQU 22 ;SIZE OF RD/WR HEADER 123 <1> DEVRDND EQU 5 ;NON DESTRUCTIVE READ NO WAIT (CHARACTER DEVS) 124 <1> DRDNDHL EQU 14 ;SIZE OF NON DESTRUCTIVE READ HEADER 125 <1> DEVIST EQU 6 ;INPUT STATUS 126 <1> DSTATHL EQU 13 ;SIZE OF STATUS HEADER 127 <1> DEVIFL EQU 7 ;INPUT FLUSH 128 <1> DFLSHL EQU 15 ;SIZE OF FLUSH HEADER 129 <1> DEVWRT EQU 8 ;WRITE 130 <1> DEVWRTV EQU 9 ;WRITE WITH VERIFY 131 <1> DEVOST EQU 10 ;OUTPUT STATUS 132 <1> DEVOFL EQU 11 ;OUTPUT FLUSH 133 <1> DEVWRIOCTL EQU 12 ;IOCTL WRITE 134 <1> DEVOPN EQU 13 ;DEVICE OPEN 135 <1> DEVCLS EQU 14 ;DEVICE CLOSE 136 <1> DOPCLHL EQU 13 ;SIZE OF OPEN/CLOSE HEADER 137 <1> DEVRMD EQU 15 ;REMOVABLE MEDIA 138 <1> REMHL EQU 13 ;SIZE OF REMOVABLE MEDIA HEADER 139 <1> GENIOCTL EQU 19 140 <1> ; THE NEXT THREE ARE USED IN DOS 4.0 141 <1> ; 20 142 <1> ; 21 143 <1> ; 22 144 <1> DEVGETOWN EQU 23 ;GET DEVICE OWNER 145 <1> DEVSETOWN EQU 24 ;SET DEVICE OWNER 146 <1> OWNHL EQU 13 ;SIZE OF DEVICE OWNER HEADER 147 <1> 148 <1> DEVOUT EQU 16 ; OUTPUT UNTIL BUSY. 149 <1> DEVOUTL EQU DEVWRT ; LENGTH OF OUTPUT UNTIL BUSY 150 <1> 151 <1> ; GENERIC IOCTL REQUEST STRUCTURE 152 <1> ; SEE THE DOS 4.0 DEVICE DRIVER SPEC FOR FURTHER ELABORATION. 153 <1> ; 154 <1> IOCTL_REQ STRUC 155 00000000 <1> DB (SRHEAD_struc_size) DUP(?) 156 <1> ; GENERIC IOCTL ADDITION. 0 0000945F ?? MAJORFUNCTION DB ? ;FUNCTION CODE 0 00009460 ?? MINORFUNCTION DB ? ;FUNCTION CATEGORY 0 00009461 ???? REG_SI DW ? 0 00009463 ???? REG_DI DW ? 0 00009465 ???????? GENERICIOCTL_PACKET DD ? ; POINTER TO DATA BUFFER 162 <1> IOCTL_REQ ENDS 163 <1> 164 <1> ; DEFINITIONS FOR IOCTL_REQ.MINORFUNCTION 165 <1> GEN_IOCTL_WRT_TRK EQU 40H 166 <1> GEN_IOCTL_RD_TRK EQU 60H 167 <1> GEN_IOCTL_FN_TST EQU 20H ; USED TO DIFF. BET READS AND WRTS 168 <1> 169 <1> ;; 32-bit absolute read/write input list structure 170 <1> 171 <1> ABS_32RW STRUC 0 00009452 ???????? SECTOR_RBA DD ? ; relative block address 0 00009456 ???? ABS_RW_COUNT DW ? ; number of sectors to be transferred 0 00009458 ???????? BUFFER_ADDR DD ? ; data addrress 175 <1> ABS_32RW ENDS 176 <1> 177 <1> ;; media ID info 178 <1> 179 <1> MEDIA_ID_INFO STRUC 0 00009452 ???? MEDIA_level DW ? ; info level 0 00009454 ???????? MEDIA_Serial DD ? ; serial # 182 00000006 <1> MEDIA_Label DB 11 dup (?) ;volume label 0 00009463 ???????????????? MEDIA_System DB 8 dup (?) ;system type 184 <1> MEDIA_ID_INFO ENDS 185 <1> 186 <1> ;; equates for DOS34_FLAG 187 <1> 188 <1> IFS_ABSRW EQU 00001H ;IFS absolute read/write 189 <1> NO_IFS_ABSRW EQU 0FFFEH ;no IFS absolute read/write 190 <1> IFS_DRIVE_RESET EQU 00002H ;IFS drvive reset 191 <1> NO_IFS_DRIVE_RESET EQU 0FFFDH ;no IFS drive reset 192 <1> FROM_DISK_RESET EQU 00004H ;from disk reset 193 <1> NO_FROM_DISK_RESET EQU 0FFFBH ;not from disk reset 194 <1> From_String_Output EQU 00008H ;from con string output 195 <1> NO_From_String_Output EQU 0FFF7H ;not from con string output 196 <1> From_DOS_WRITE EQU 00010H ;from dos_write 197 <1> NO_From_DOS_WRITE EQU 0FFEFH ;not from dos_write 198 <1> Force_I24_Fail EQU 00020H ;form IFS CALL BACK 199 <1> NO_Force_I24_Fail EQU 0FFDFH ;not form IFS CALL BACK 200 <1> Disable_EOF_I24 EQU 00040H ;disable EOF int24 for input status 201 <1> NO_Disable_EOF_I24 EQU 0FFBFH ;disable EOF int24 for input status 202 <1> DBCS_VOLID EQU 00080H ;indicate from volume id 203 <1> DBCS_VOLID2 EQU 00100H ;indicate 8th char is DBCS 204 <1> CTRL_BREAK_FLAG EQU 00200H ;indicate control break is input 205 <1> NO_CTRL_BREAK_FLAG EQU 0FDFFH ;reset control break 206 <1> SEARCH_FASTOPEN EQU 00400H ;set fastopen flag for search 207 <1> X25_special EQU 00800H ;flag for X25 driver 25 %include "pushpop.mac" 1 <1> ; NASM original macros 2 <1> 3 <1> %unimacro stripangles 2.nolist 4 <1> %assign ?stackdepth 0 5 <1> 6 <1> %imacro stripangles 2.nolist 7 <1> %defstr %%param %2 8 <1> %rep 16 9 <1> %substr %%opening %%param 1 10 <1> %ifidn %%opening, '<' 11 <1> %substr %%param %%param 2,-1 12 <1> %endif 13 <1> %endrep 14 <1> %rep 16 15 <1> %strlen %%length %%param 16 <1> %substr %%closing %%param %%length 17 <1> %ifidn %%closing, '>' 18 <1> %substr %%param %%param 1,-2 19 <1> %endif 20 <1> %endrep 21 <1> %deftok %%token %%param 22 <1> %1 %%token 23 <1> %endmacro 24 <1> 25 <1> ;BREAK 26 <1> 27 <1> %imacro SaveReg 0-*.nolist ;; push those registers 28 <1> %rep %0 29 <1> %assign ?stackdepth ?stackdepth + 1 30 <1> stripangles push, %1 31 <1> %rotate 1 32 <1> %endrep 33 <1> %endmacro 34 <1> ;.xcref SaveReg 35 <1> 36 <1> ;BREAK 37 <1> 38 <1> %imacro RestoreReg 0-*.nolist ;; pop those registers 39 <1> %rep %0 40 <1> %assign ?stackdepth ?stackdepth - 1 41 <1> stripangles pop, %1 42 <1> %rotate 1 43 <1> %endrep 44 <1> %endmacro 45 <1> ;.xcref RestoreReg 26 %include "msmacro.mac" 1 <1> === Switch to base=008400h -> "BIOCODE" 2 <1> section BIOCODE 3 <1> ; 4 <1> ; This file contains three macros used in debugging the system. If the 5 <1> ; variable "itest" (in msbio.asm) is nonzero code is included in the 6 <1> ; modules to print debugging messages. The level of debugging is controlled 7 <1> ; by the value of the variable fTestBits in msbio.asm. Specific bits in 8 <1> ; the variable determine which messages to print. The equ's below tell 9 <1> ; which bits control which funcitons. For example the fifth bit 10 <1> ; cooresponds to disk activity (see fTestDisk equ below). 11 <1> ; 12 <1> ; The macros in the file are: 13 <1> ; 14 <1> ; message Prints an ascii string on the screen. 15 <1> ; Example usage: 16 <1> ; 17 <1> ; message fTestDisk, <"Start Disk Write", CR, LF> 18 <1> ; message fTestINIT, <"Begin BDS initialization"> 19 <1> ; 20 <1> ; 21 <1> ; MNUM Print the value in a register or memory location on 22 <1> ; the screen. Value is displayed in hex. 23 <1> ; Usage: 24 <1> ; MNUM bitpattern, valueLocation 25 <1> ; 26 <1> ; valueLocation is typically a regester: 27 <1> ; 28 <1> ; mnum fTestCom, AX 29 <1> ; mnum fTestDisk, DX 30 <1> ; 31 <1> ; ValueLocation can also be a memory location: 32 <1> ; 33 <1> ; mnum fTestINIT, Final_Dos_Location 34 <1> ; 35 <1> ; If no valueLocation is given the macro defaults to 36 <1> ; the BX register. 37 <1> ; 38 <1> ; ZWAIT Stops the program until any key is pressed. 39 <1> ; 40 <1> ; 41 <1> ; The three macros preserve all register values. If "test" is zero 42 <1> ; defined during assembly then the marco produce no code. 43 <1> ; 44 <1> 45 <1> %IF itest ;3.30 46 <1> EXTRN MSGOUT:NEAR,MSGNUM:NEAR ;3.30 47 <1> EXTRN NUMBUF:BYTE,DIGITS:BYTE,FTESTBITS:WORD ;3.30 48 <1> EXTRN DUMPBYTES:NEAR,OUTCHAR:NEAR,HEX_TO_ASCII:NEAR ;3.30 49 <1> 50 <1> 51 <1> fTestALL equ 1111111111111111b ; watch everything 52 <1> fTestHARD equ 0000000000000001b ; watch hard disk initialization 53 <1> fTest96 equ 0000000000000010b ; watch 96 tpi activity 54 <1> FTEST13 EQU 0000000000000100B ; WATCH INT 13 ACTIVITY ;3.30 55 <1> FTESTCOM EQU 0000000000001000B ; WATCH PACKET ACTIVITY ;3.30 56 <1> FTESTINIT EQU 0000000000010000B ; WATCH INITIALIZATION MESSAGES ;3.30 57 <1> FTESTDISK EQU 0000000000100000B ; WATCH DISK DEVICE DRIVER CALLS ;3.30 58 <1> FTESTCON EQU 0000000001000000B ; WATCH SYSTEM WAIT ACTIVITY IN CO;3.30 NSOLE 59 <1> FtestClock equ 0000000010000000b ; wathc clock device 5/2/86 ;3.30 60 <1> 61 <1> ; NASM original macros 62 <1> 63 <1> ; 64 <1> ; message macro -- see above for description 65 <1> ; 66 <1> 67 <1> %unimacro stripangles 2+.nolist 68 <1> 69 <1> %imacro stripangles 2+.nolist 70 <1> %defstr %%param %2 71 <1> %rep 16 72 <1> %substr %%opening %%param 1 73 <1> %ifidn %%opening, '<' 74 <1> %substr %%param %%param 2,-1 75 <1> %endif 76 <1> %endrep 77 <1> %rep 16 78 <1> %strlen %%length %%param 79 <1> %substr %%closing %%param %%length 80 <1> %ifidn %%closing, '>' 81 <1> %substr %%param %%param 1,-2 82 <1> %endif 83 <1> %endrep 84 <1> %deftok %%token %%param 85 <1> %1 %%token 86 <1> %endmacro 87 <1> 88 <1> %imacro MESSAGE 2+ 89 <1> jmp short %%b 90 <1> %%a: 91 <1> stripangles db, %2 92 <1> db 0 93 <1> %%b: push SI 94 <1> push AX 95 <1> mov AX, %1 96 <1> mov SI, OFFSET %%a 97 <1> call MSGOUT 98 <1> pop AX 99 <1> pop SI 100 <1> %endmacro 101 <1> 102 <1> 103 <1> ; 104 <1> ; mnum macro -- see above for description 105 <1> ; 106 <1> 107 <1> %imacro MNum 1-2 108 <1> push AX 109 <1> %ifempty %2 110 <1> mov AX,%1 111 <1> call MSGNUM 112 <1> %else 113 <1> push BX 114 <1> mov BX,%2 115 <1> mov AX,%1 116 <1> call MSGNUM 117 <1> pop BX 118 <1> %endif 119 <1> pop AX 120 <1> %endmacro 121 <1> 122 <1> 123 <1> ; 124 <1> ; zwait macro -- see above for description 125 <1> ; 126 <1> 127 <1> %imacro ZWAIT 0 128 <1> Message fTestALL,<"? "> 129 <1> CALL ZWAITrtn 130 <1> %endmacro 131 <1> 132 <1> ZWAITrtn: 133 <1> pushf ; save the flags 134 <1> push AX ; preserve AX 135 <1> xor AH, AH ; set command to get character ;3.30* 136 <1> int 16h ; call rom keyboard routine ;3.30* 137 <1> pop AX ; restore AX 138 <1> popf ; restore the flags 139 <1> ret 140 <1> 141 <1> ;Dump_byte dumps the memory contents in hex. ;3.30 142 <1> ;DUMPOFFLABEL should be a label or a variable defined in DUMPSEG. ;3.30 143 <1> %imacro DUMP_BYTE 3 144 <1> push es ;3.30 145 <1> PUSH DS ;3.30 146 <1> PUSH SI ;3.30 147 <1> PUSH CX ;3.30 148 <1> ;3.30 149 <1> MOV CX, %1 ;3.30 150 <1> MOV DS, CX ;3.30 151 <1> MOV SI, OFFSET %2 ;3.30 152 <1> MOV CX, %3 ;3.30 153 <1> call dumpbytes ;3.30 154 <1> ;3.30 155 <1> POP CX ;3.30 156 <1> POP SI ;3.30 157 <1> POP DS ;3.30 158 <1> pop es ;3.30 159 <1> %endmacro ;3.30 160 <1> ;3.30 161 <1> ;Dump_Byte_Reg dumps the memory contents in hex. - 4/9/86 ;3.30 162 <1> ;DUMPOFFREG should be a register contains the offset value in DUMPSEG. ;3.30 163 <1> %imacro DUMP_BYTE_REG 3 164 <1> DUMP_BYTE_REG MACRO DUMPSEG, DUMPOFFREG, BYTELENGTH ;3.30 165 <1> push es ;3.30 166 <1> PUSH DS ;3.30 167 <1> PUSH SI ;3.30 168 <1> PUSH CX ;3.30 169 <1> ;3.30 170 <1> MOV CX, %1 ;3.30 171 <1> MOV DS, CX ;3.30 172 <1> MOV SI, %2 ;3.30 173 <1> MOV CX, %3 ;3.30 174 <1> call dumpbytes ;3.30 175 <1> ;3.30 176 <1> POP CX ;3.30 177 <1> POP SI ;3.30 178 <1> POP DS ;3.30 179 <1> pop es ;3.30 180 <1> %endmacro ;3.30 181 <1> 182 <1> %else 183 <1> ; if test is not defined then make macro into null statements 184 <1> %imacro Message 0-1+.nolist 185 <1> %endmacro 186 <1> 187 <1> %imacro MNUM 0-1+.nolist 188 <1> %endmacro 189 <1> 190 <1> %imacro ZWAIT 0-1+.nolist 191 <1> %endmacro 192 <1> 193 <1> %imacro DUMP_BYTE 0-1+.nolist 194 <1> %endmacro 195 <1> 196 <1> %imacro DUMP_BYTE_REG 0-1+.nolist 197 <1> %endmacro 198 <1> 199 <1> %endif 200 <1> 201 <1> %unimacro PATHSTART 2 202 <1> %unimacro PATHEND 2 203 <1> 204 <1> %imacro PATHSTART 2 205 <1> %IF PATHGEN ;3.30 206 <1> PUBLIC %2%1S,%2%1E ;3.30 207 <1> %2%1S LABEL BYTE ;3.30 208 <1> %ENDIF ;3.30 209 <1> %endmacro ;3.30 210 <1> ;3.30 211 <1> %imacro PATHEND 2 212 <1> %IF PATHGEN ;3.30 213 <1> %2%1E LABEL BYTE ;3.30 214 <1> %ENDIF ;3.30 215 <1> %endmacro ;3.30 27 %include "entryseg.nas" 1 <1> === Switch to base=000000h -> "DOSENTRY" 2 <1> section DOSENTRY class=%[DOSENTRY] === Switch to base=000000h -> "DOSENTRY" 3 <1> section DOSENTRY 28 %include "lmacros3.mac" 1 <1> [list -] 1 ****************** <1> warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi] 14 <2> [list -] 14 <1> [list -] 29 %include "dcodeseg.nas" 1 <1> 2 <1> %ifndef DCODESEGNAS 3 <1> %assign DCODESEGNAS 1 4 <1> === Switch to base=008400h -> "DOSCODETABLE" 5 <1> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <1> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=008400h -> "DOSCODECODE" 7 <1> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <1> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=008400h -> "DOSBIOCODE" 9 <1> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=008400h -> "BIOCODE" 10 <1> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <1> 12 <1> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <1> 14 <1> %endif 30 %include "codesw.mac" 1 <1> DOSCODE_HMA_SEGMENT equ 0FFFEh 2 <1> ; address DOSCODE at this segment when in HMA 3 <1> DOSCODE_HMA_start_at equ (10000h - DOSCODE_HMA_SEGMENT) * 10h 4 <1> ; offset from DOSCODE offset 0 to address 10_0000h 5 <1> DOSCODE_HMA_OFFSET equ DOSCODE_HMA_start_at + 30h 6 <1> ; 50h = 20h ROM-BIOS, 20h VDISK header, 10h HMCB 31 %include "entrysw.mac" 1 <1> 2 <1> DOSENTRYADJUSTSEGMENT equ 70h - 26h 3 <1> DOSENTRYADJUSTOFFSET equ DOSENTRYADJUSTSEGMENT * 16 32 === Switch to base=008400h -> "BIOCODE" 33 addsection BIOCODE 34 === Switch to base=002530h -> "SYSINITSEG" 35 addsection SYSINITSEG, PUBLIC class=INIT === Switch to base=002530h -> "SYSINITTRAIL" 36 addsection SYSINITTRAIL, PUBLIC class=INIT 37 38 group SYSINITGROUP SYSINITSEG SYSINITTRAIL 39 === Switch to base=008400h -> "BIOCODE" 40 usesection BIOCODE 41 42 ASSUME DS:NOTHING,ES:NOTHING 43 44 extern biocode_get_ds_dosentry, biocode_get_es_dosentry 45 extern dosbiocode_get_ds_dosentry, dosbiocode_get_es_dosentry 46 47 EXTRN DSK$IN:NEAR 48 EXTRN SETPTRSAV:NEAR 49 EXTRN OUTCHR:NEAR 50 EXTRN SETDRIVE:NEAR 51 EXTRN FLUSH:NEAR 52 EXTRN HARDERR:NEAR 53 EXTRN HARDERR2:NEAR 54 EXTRN MAPERROR:NEAR 55 EXTRN GETBP:NEAR 56 EXTRN CHECKSINGLE:NEAR 57 EXTRN CHECK_TIME_OF_ACCESS:NEAR 58 EXTRN EXIT:NEAR 59 EXTRN HAS1:NEAR 60 EXTRN READ_SECTOR:NEAR 61 extern set_i13_i2F 62 63 EXTRN OLD13:DWORD 64 65 ;DATA 66 EXTRN PTRSAV:DWORD ;IBMBIO1 67 EXTRN START_BDS:WORD 68 EXTRN FDRIVE1:WORD 69 EXTRN FDRIVE2:WORD 70 EXTRN FDRIVE3:WORD 71 EXTRN FDRIVE4:WORD 72 EXTRN FLAGBITS:WORD 73 EXTRN TIM_DRV:BYTE 74 EXTRN MEDBYT:BYTE 75 EXTRN DRVMAX:BYTE 76 extrn Ext_Boot_Sig:byte ;AN000; ibmbdata 77 extrn SecPerClusInSector:byte ;AN000; ibmbdata 78 extrn Boot_Serial_L:word ;AN000; ibmbdata 79 extrn Boot_Serial_H:word ;AN000; ibmbdata 80 === Switch to base=000000h -> "DOSENTRY" 81 section DOSENTRY 82 83 extern MODEL_BYTE 84 extern Secondary_Model_Byte 85 extern INT19SEM 86 %macro int19oldextern 1-* 87 %rep %0 88 extern Int19OLD%1 89 %rotate 1 90 %endrep 91 %endmacro 92 int19oldextern 02,08,09,0A,0B,0C,0D,0E,70,72,73,74,76,77 87 <1> %rep %0 88 <1> extern Int19OLD%1 89 <1> %rotate 1 90 <1> %endrep 88 <2> extern Int19OLD%1 89 <2> %rotate 1 88 <2> extern Int19OLD%1 89 <2> %rotate 1 88 <2> extern Int19OLD%1 89 <2> %rotate 1 88 <2> extern Int19OLD%1 89 <2> %rotate 1 88 <2> extern Int19OLD%1 89 <2> %rotate 1 88 <2> extern Int19OLD%1 89 <2> %rotate 1 88 <2> extern Int19OLD%1 89 <2> %rotate 1 88 <2> extern Int19OLD%1 89 <2> %rotate 1 88 <2> extern Int19OLD%1 89 <2> %rotate 1 88 <2> extern Int19OLD%1 89 <2> %rotate 1 88 <2> extern Int19OLD%1 89 <2> %rotate 1 88 <2> extern Int19OLD%1 89 <2> %rotate 1 88 <2> extern Int19OLD%1 89 <2> %rotate 1 88 <2> extern Int19OLD%1 89 <2> %rotate 1 93 extern dskdrvs_indirect 94 extern jmp_int_2f_next 95 extern INT_2F_NEXT 96 97 === Switch to base=008400h -> "DOSBIOCODE" 98 section DOSBIOCODE 99 100 ; INT19 101 ; 102 ; WE "HOOK" THE INT 19 VECTOR, BECAUSE CONTRARY TO IBM DOCUMENTATION, 103 ; IT DOES NOT "BOOTSTRAP" THE MACHINE. IT LEAVES MEMORY ALMOST UNTOUCHED. 104 ; SINCE THE BIOS_INIT CODE ASSUMES THAT CERTAIN INTERRUPT VECTORS POINT TO 105 ; THE ROM_BIOS WE MUST "UNHOOK" THEM BEFORE ISSUING THE ACTUAL INT_19. 106 ; CURRENTLY THE ONLY VECTORS THAT NEED TO BE UNHOOKED ARE INT_19, INT_13, 107 ; AND THE HARDWARE INTERRUPTS. 108 ; 109 relocated i19 110 INT19 PROC FAR 111 assume ds:nothing 112 assume es:nothing 113 114 extern InterruptRestorationTable 0 000079E6 FC cld 0 000079E7 E8[0000] call dosbiocode_get_ds_dosentry 117 ; ds => DOSENTRY 0 000079EA BE[0000] mov si, InterruptRestorationTable 119 .loop: 0 000079ED 31C0 xor ax, ax 0 000079EF 8EC0 mov es, ax ; es => IVT 0 000079F1 AC lodsb 0 000079F2 3CFF cmp al, -1 0 000079F4 7409 je .done 0 000079F6 97 xchg di, ax ; di = interrupt number 0 000079F7 01FF add di, di 0 000079F9 01FF add di, di ; es:di -> interrupt vector 0 000079FB A5 movsw 0 000079FC A5 movsw ; restore from IRT 0 000079FD EBEE jmp .loop 131 .done: 132 0 000079FF 06 push es 0 00007A00 1E push ds 0 00007A01 07 pop es 0 00007A02 1F pop ds ; swap, es => DOSENTRY, ds => IVT 137 0 00007A03 26803E[0000]00 CMP BYTE [es:INT19SEM], 0 0 00007A09 7503 JNZ INT19VECS 0 00007A0B E98C01 JMP DOINT19 141 142 %if 0 ; dead code 143 ; ON THE PCJR, DON'T REPLACE ANY VECTORS 144 ; MODEL BYTE DEFINITIONS FROM IBMSTACK.ASM 145 MOV AX,ROMSEGMENT 146 MOV DS,AX 147 MOV AL,MODELPCJR 148 149 CMP AL,[MODELBYTE] 150 JNE INT19VECS 151 JMP DOINT19 152 %endif 153 154 ;Stacks code has changed these hardware interrupt vectors 155 ;STKINIT in SYSINIT1 will initialzie Int19hOLDxx values. 156 INT19VECS: 0 00007A0E 31C0 XOR AX,AX 0 00007A10 8ED8 MOV DS,AX 159 160 161 %macro int19restore 1-* 162 %rep %0 163 call dosbiocode_get_es_dosentry 164 LES DI,[es:Int19OLD%1] 165 ;SB33103****************************************************************** 166 167 mov ax,es ; 168 cmp ax,-1 ;OPT 0ffffh is unlikely segment 169 je skip_int%1 ;OPT no need to check selector too 170 cmp di,-1 ;OPT 0ffffh is unlikely offset 171 je skip_int%1 172 173 ;SB33103****************************************************************** 174 MOV [%1H*4],DI 175 MOV [%1H*4+2],ES 176 skip_int%1: 177 %rotate 1 178 %endrep 179 %endmacro 180 181 int19restore 02,08,09,0A,0B,0C,0D,0E,70,72,73,74,76,77 162 <1> %rep %0 163 <1> call dosbiocode_get_es_dosentry 164 <1> LES DI,[es:Int19OLD%1] 165 <1> 166 <1> 167 <1> mov ax,es 168 <1> cmp ax,-1 169 <1> je skip_int%1 170 <1> cmp di,-1 171 <1> je skip_int%1 172 <1> 173 <1> 174 <1> MOV [%1H*4],DI 175 <1> MOV [%1H*4+2],ES 176 <1> skip_int%1: 177 <1> %rotate 1 178 <1> %endrep 0 00007A12 E8[0000] call dosbiocode_get_es_dosentry 0 00007A15 26C43E[0000] LES DI,[es:Int19OLD%1] 165 <2> 166 <2> 0 00007A1A 8CC0 mov ax,es 0 00007A1C 83F8FF cmp ax,-1 0 00007A1F 740D je skip_int%1 0 00007A21 83FFFF cmp di,-1 0 00007A24 7408 je skip_int%1 172 <2> 173 <2> 0 00007A26 893E0800 MOV [%1H*4],DI 0 00007A2A 8C060A00 MOV [%1H*4+2],ES 176 <2> skip_int%1: 177 <2> %rotate 1 0 00007A2E E8[0000] call dosbiocode_get_es_dosentry 0 00007A31 26C43E[0000] LES DI,[es:Int19OLD%1] 165 <2> 166 <2> 0 00007A36 8CC0 mov ax,es 0 00007A38 83F8FF cmp ax,-1 0 00007A3B 740D je skip_int%1 0 00007A3D 83FFFF cmp di,-1 0 00007A40 7408 je skip_int%1 172 <2> 173 <2> 0 00007A42 893E2000 MOV [%1H*4],DI 0 00007A46 8C062200 MOV [%1H*4+2],ES 176 <2> skip_int%1: 177 <2> %rotate 1 0 00007A4A E8[0000] call dosbiocode_get_es_dosentry 0 00007A4D 26C43E[0000] LES DI,[es:Int19OLD%1] 165 <2> 166 <2> 0 00007A52 8CC0 mov ax,es 0 00007A54 83F8FF cmp ax,-1 0 00007A57 740D je skip_int%1 0 00007A59 83FFFF cmp di,-1 0 00007A5C 7408 je skip_int%1 172 <2> 173 <2> 0 00007A5E 893E2400 MOV [%1H*4],DI 0 00007A62 8C062600 MOV [%1H*4+2],ES 176 <2> skip_int%1: 177 <2> %rotate 1 0 00007A66 E8[0000] call dosbiocode_get_es_dosentry 0 00007A69 26C43E[0000] LES DI,[es:Int19OLD%1] 165 <2> 166 <2> 0 00007A6E 8CC0 mov ax,es 0 00007A70 83F8FF cmp ax,-1 0 00007A73 740D je skip_int%1 0 00007A75 83FFFF cmp di,-1 0 00007A78 7408 je skip_int%1 172 <2> 173 <2> 0 00007A7A 893E2800 MOV [%1H*4],DI 0 00007A7E 8C062A00 MOV [%1H*4+2],ES 176 <2> skip_int%1: 177 <2> %rotate 1 0 00007A82 E8[0000] call dosbiocode_get_es_dosentry 0 00007A85 26C43E[0000] LES DI,[es:Int19OLD%1] 165 <2> 166 <2> 0 00007A8A 8CC0 mov ax,es 0 00007A8C 83F8FF cmp ax,-1 0 00007A8F 740D je skip_int%1 0 00007A91 83FFFF cmp di,-1 0 00007A94 7408 je skip_int%1 172 <2> 173 <2> 0 00007A96 893E2C00 MOV [%1H*4],DI 0 00007A9A 8C062E00 MOV [%1H*4+2],ES 176 <2> skip_int%1: 177 <2> %rotate 1 0 00007A9E E8[0000] call dosbiocode_get_es_dosentry 0 00007AA1 26C43E[0000] LES DI,[es:Int19OLD%1] 165 <2> 166 <2> 0 00007AA6 8CC0 mov ax,es 0 00007AA8 83F8FF cmp ax,-1 0 00007AAB 740D je skip_int%1 0 00007AAD 83FFFF cmp di,-1 0 00007AB0 7408 je skip_int%1 172 <2> 173 <2> 0 00007AB2 893E3000 MOV [%1H*4],DI 0 00007AB6 8C063200 MOV [%1H*4+2],ES 176 <2> skip_int%1: 177 <2> %rotate 1 0 00007ABA E8[0000] call dosbiocode_get_es_dosentry 0 00007ABD 26C43E[0000] LES DI,[es:Int19OLD%1] 165 <2> 166 <2> 0 00007AC2 8CC0 mov ax,es 0 00007AC4 83F8FF cmp ax,-1 0 00007AC7 740D je skip_int%1 0 00007AC9 83FFFF cmp di,-1 0 00007ACC 7408 je skip_int%1 172 <2> 173 <2> 0 00007ACE 893E3400 MOV [%1H*4],DI 0 00007AD2 8C063600 MOV [%1H*4+2],ES 176 <2> skip_int%1: 177 <2> %rotate 1 0 00007AD6 E8[0000] call dosbiocode_get_es_dosentry 0 00007AD9 26C43E[0000] LES DI,[es:Int19OLD%1] 165 <2> 166 <2> 0 00007ADE 8CC0 mov ax,es 0 00007AE0 83F8FF cmp ax,-1 0 00007AE3 740D je skip_int%1 0 00007AE5 83FFFF cmp di,-1 0 00007AE8 7408 je skip_int%1 172 <2> 173 <2> 0 00007AEA 893E3800 MOV [%1H*4],DI 0 00007AEE 8C063A00 MOV [%1H*4+2],ES 176 <2> skip_int%1: 177 <2> %rotate 1 0 00007AF2 E8[0000] call dosbiocode_get_es_dosentry 0 00007AF5 26C43E[0000] LES DI,[es:Int19OLD%1] 165 <2> 166 <2> 0 00007AFA 8CC0 mov ax,es 0 00007AFC 83F8FF cmp ax,-1 0 00007AFF 740D je skip_int%1 0 00007B01 83FFFF cmp di,-1 0 00007B04 7408 je skip_int%1 172 <2> 173 <2> 0 00007B06 893EC001 MOV [%1H*4],DI 0 00007B0A 8C06C201 MOV [%1H*4+2],ES 176 <2> skip_int%1: 177 <2> %rotate 1 0 00007B0E E8[0000] call dosbiocode_get_es_dosentry 0 00007B11 26C43E[0000] LES DI,[es:Int19OLD%1] 165 <2> 166 <2> 0 00007B16 8CC0 mov ax,es 0 00007B18 83F8FF cmp ax,-1 0 00007B1B 740D je skip_int%1 0 00007B1D 83FFFF cmp di,-1 0 00007B20 7408 je skip_int%1 172 <2> 173 <2> 0 00007B22 893EC801 MOV [%1H*4],DI 0 00007B26 8C06CA01 MOV [%1H*4+2],ES 176 <2> skip_int%1: 177 <2> %rotate 1 0 00007B2A E8[0000] call dosbiocode_get_es_dosentry 0 00007B2D 26C43E[0000] LES DI,[es:Int19OLD%1] 165 <2> 166 <2> 0 00007B32 8CC0 mov ax,es 0 00007B34 83F8FF cmp ax,-1 0 00007B37 740D je skip_int%1 0 00007B39 83FFFF cmp di,-1 0 00007B3C 7408 je skip_int%1 172 <2> 173 <2> 0 00007B3E 893ECC01 MOV [%1H*4],DI 0 00007B42 8C06CE01 MOV [%1H*4+2],ES 176 <2> skip_int%1: 177 <2> %rotate 1 0 00007B46 E8[0000] call dosbiocode_get_es_dosentry 0 00007B49 26C43E[0000] LES DI,[es:Int19OLD%1] 165 <2> 166 <2> 0 00007B4E 8CC0 mov ax,es 0 00007B50 83F8FF cmp ax,-1 0 00007B53 740D je skip_int%1 0 00007B55 83FFFF cmp di,-1 0 00007B58 7408 je skip_int%1 172 <2> 173 <2> 0 00007B5A 893ED001 MOV [%1H*4],DI 0 00007B5E 8C06D201 MOV [%1H*4+2],ES 176 <2> skip_int%1: 177 <2> %rotate 1 0 00007B62 E8[0000] call dosbiocode_get_es_dosentry 0 00007B65 26C43E[0000] LES DI,[es:Int19OLD%1] 165 <2> 166 <2> 0 00007B6A 8CC0 mov ax,es 0 00007B6C 83F8FF cmp ax,-1 0 00007B6F 740D je skip_int%1 0 00007B71 83FFFF cmp di,-1 0 00007B74 7408 je skip_int%1 172 <2> 173 <2> 0 00007B76 893ED801 MOV [%1H*4],DI 0 00007B7A 8C06DA01 MOV [%1H*4+2],ES 176 <2> skip_int%1: 177 <2> %rotate 1 0 00007B7E E8[0000] call dosbiocode_get_es_dosentry 0 00007B81 26C43E[0000] LES DI,[es:Int19OLD%1] 165 <2> 166 <2> 0 00007B86 8CC0 mov ax,es 0 00007B88 83F8FF cmp ax,-1 0 00007B8B 740D je skip_int%1 0 00007B8D 83FFFF cmp di,-1 0 00007B90 7408 je skip_int%1 172 <2> 173 <2> 0 00007B92 893EDC01 MOV [%1H*4],DI 0 00007B96 8C06DE01 MOV [%1H*4+2],ES 176 <2> skip_int%1: 177 <2> %rotate 1 182 183 184 DOINT19: 0 00007B9A 8CC8 mov ax, cs 0 00007B9C 83F8FE cmp ax, DOSCODE_HMA_SEGMENT 0 00007B9F 720D jb .done 188 189 ; clear the VDISK header in HMA 0 00007BA1 B8FFFF mov ax, -1 ; => HMA 0 00007BA4 8EC0 mov es, ax 0 00007BA6 BF1000 mov di, 10h ; -> start of HMA 0 00007BA9 89F9 mov cx, di ; 10h words = 20h bytes 0 00007BAB 40 inc ax ; = 0 0 00007BAC F3AB rep stosw ; re-initialise 196 .done: 0 00007BAE CD19 INT 19H 198 INT19 ENDP 199 200 === Switch to base=008400h -> "BIOCODE" 201 section BIOCODE 202 203 ASSUME DS:BIOCODE 204 PUBLIC DSK$INIT 205 DSK$INIT PROC NEAR 206 ; ds => DOSENTRY from ENTRY in msbio1.nas 0 00009452 8A26[0000] MOV AH,BYTE PTR [DRVMAX] 0 00009456 C53E[0000] lds di, [dskdrvs_indirect] 0 0000945A E9[0000] JMP SETPTRSAV 210 DSK$INIT ENDP 211 212 ; 213 ; INT 2F HANDLER FOR EXTERNAL BLOCK DRIVERS TO COMMUNICATE WITH THE INTERNAL 214 ; BLOCK DRIVER IN IBMDISK. THE MULTIPLEX NUMBER CHOSEN IS 8. THE HANDLER 215 ; SETS UP THE POINTER TO THE REQUEST PACKET IN [PTRSAV] AND THEN JUMPS TO 216 ; DSK$IN, THE ENTRY POINT FOR ALL DISK REQUESTS. 217 ; ON EXIT FROM THIS DRIVER (AT EXIT), WE WILL RETURN TO THE EXTERNAL DRIVER 218 ; THAT ISSUED THIS INT 2F, AND CAN THEN REMOVE THE FLAGS FROM THE STACK. 219 ; THIS SCHEME ALLOWS US TO HAVE A SMALL EXTERNAL DEVICE DRIVER, AND MAKES 220 ; THE MAINTAINANCE OF THE VARIOUS DRIVERS (DRIVER AND IBMBIO) MUCH EASIER, 221 ; SINCE WE ONLY NEED TO MAKE CHANGES IN ONE PLACE (MOST OF THE TIME). 222 ; 223 ; 06/03/88 J.K. When AL=3, return DS:DI -> Start of BDS table. 224 ; (EMS device driver hooks INT 13h to handle 16KB DMA overrun 225 ; problem. BDS table is going to be used to get head/sector 226 ; informations without calling Generic IOCTL Get Device Parm call.) 227 ; 228 ; AL CONTAINS THE INT2F FUNCTION: 229 ; 0 - CHECK FOR INSTALLED HANDLER - RESERVED 230 ; 1 - INSTALL THE BDS INTO THE LINKED LIST 231 ; 2 - DOS REQUEST 232 ; 3 - Get BDS vector ;06/03/88 J.K. 233 ; Return BDS table starting pointer in DS:DI 234 235 MYNUM EQU 8 236 237 PUBLIC INT2F_DISK 238 relocated disk_i2F 239 INT2F_DISK PROC FAR 0 0000945D 80FC08 CMP AH,MYNUM 0 00009460 7405 JE MINE 0 00009462 EA[0000][0000] jmp DOSENTRY:jmp_int_2f_next ; CHAIN TO NEXT INT 2F HANDLER 243 MINE: 0 00009467 3CF8 CMP AL,0F8H ; IRET ON RESERVED FUNCTIONS 0 00009469 7201 JB DO_FUNC 0 0000946B CF IRET 247 DO_FUNC: 0 0000946C 08C0 OR AL,AL ; A GET INSTALLED STATE REQUEST? 0 0000946E 7503 JNE DISP_FUNC 0 00009470 B0FF MOV AL,0FFH 0 00009472 CF IRET 252 DISP_FUNC: 253 MESSAGE FTESTINIT,<"INT2F_DISK",CR,LF> 0 00009473 3C01 CMP AL,1 ; REQUEST FOR INSTALLING BDS? 0 00009475 7504 JNE DO_DOS_REQ 0 00009477 E81D00 CALL INSTALL_BDS 0 0000947A CF IRET 258 259 DO_DOS_REQ: 260 ; SET UP POINTER TO REQUEST PACKET 0 0000947B 3C03 cmp al, 3 ;AN002; Get BDS vector? 0 0000947D 7410 je DO_Get_BDS_Vector ;AN002; 263 0 0000947F 1E push ds 0 00009480 E8[0000] call biocode_get_ds_dosentry 0 00009483 891E[0000] MOV WORD PTR [PTRSAV], BX ;othrwise DOS function. 0 00009487 8C06[0200] MOV WORD PTR [PTRSAV+2], ES 0 0000948B 1F pop ds 0 0000948C E9[0000] JMP DSK$IN 270 271 DO_Get_BDS_Vector: ;AN002; AL=3 0 0000948F E8[0000] call biocode_get_ds_dosentry 273 Start_BDS equ START_BDS ; NASM port label 0 00009492 C53E[0000] lds di, [Start_BDS] ;AN002; 0 00009496 CF IRET ;AN002; 276 277 INT2F_DISK ENDP 278 279 ; 280 ; INSTALL_BDS INSTALLS A BDS A LOCATION DS:DI INTO THE CURRENT LINKED LIST OF 281 ; BDS MAINTAINED BY THIS DEVICE DRIVER. IT PLACES THE BDS AT THE END OF THE 282 ; LIST. 283 PUBLIC INSTALL_BDS 284 INSTALL_BDS PROC NEAR 285 MESSAGE FTESTINIT,<"INSTALL BDS",CR,LF> 286 ; DS:DI POINT TO BDS TO BE INSTALLED 0 00009497 E8[0000] call biocode_get_es_dosentry 0 0000949A 26C436[0000] LES SI,[es:START_BDS] ; START AT BEGINNING OF LIST 0 0000949F 06 PUSH ES ; SAVE POINTER TO CURRENT BDS 0 000094A0 56 PUSH SI 291 ; ES:SI NOW POINT TO BDS IN LINKED LIST 292 LOOP_NEXT_BDS: 0 000094A1 46 inc si ; GOT TO END OF LINKED LIST? (-1) 0 000094A2 742C JZ INSTALL_RET ; yes --> (will overwrite si) 0 000094A4 4E dec si ; undo inc 296 297 ; IF WE HAVE SEVERAL LOGICAL DRIVES USING THE SAME PHYSICAL DRIVE, WE MUST 298 ; SET THE I_AM_MULT FLAG IN EACH OF THE APPROPRIATE BDSS. 0 000094A5 8A4504 MOV AL,BYTE PTR [DI + DRIVENUM] 0 000094A8 26384404 CMP BYTE PTR [ES:SI + DRIVENUM],AL 0 000094AC 7517 JNZ NEXT_BDS 302 MESSAGE FTESTINIT,<"LOGICAL DRIVES",CR,LF> 0 000094AE B310 MOV bl, FI_AM_MULT 0 000094B0 085D23 OR [DI + FLAGS], bl ; SET FLAGS IN BOTH BDSS CONCERNED 0 000094B3 26085C23 OR [ES:SI + FLAGS], bl 0 000094B7 806523DF AND byte [DI + FLAGS], ~ FI_OWN_PHYSICAL 307 ; RESET THAT FLAG FOR 'NEW' BDS 308 ; WE MUST ALSO SET THE FCHANGELINE BIT CORRECTLY. 0 000094BB 268A5C23 MOV bl, [ES:SI + FLAGS] ; DETERMINE IF CHANGELINE AVAILABLE 0 000094BF 80E302 AND BL,FCHANGELINE 0 000094C2 085D23 OR [DI + FLAGS], bl 312 313 NEXT_BDS: 314 ; BEFORE MOVING TO NEXT BDS, PRESERVE POINTER TO CURRENT ONE. THIS IS NEEDED AT 315 ; THE END WHEN THE NEW BDS IS LINKED INTO THE LIST. 0 000094C5 5B POP BX ; DISCARD PREVIOUS POINTER TO BDS 0 000094C6 5B POP BX 0 000094C7 06 PUSH ES 0 000094C8 56 PUSH SI 0 000094C9 26C434 les si, [es:si + LINK] 0 000094CC 8CC3 mov bx, es ; returned bx 0 000094CE EBD1 JMP SHORT LOOP_NEXT_BDS 323 324 INSTALL_RET: 0 000094D0 5E POP SI ; RETRIEVE POINTER TO LAST BDS 0 000094D1 07 POP ES ; IN LINKED LIST. 0 000094D2 8CD8 MOV AX,DS ; returned ax 0 000094D4 26894402 MOV WORD PTR [ES:SI + LINK + 2],AX ; INSTALL BDS 0 000094D8 26893C MOV WORD PTR [ES:SI + LINK],DI 0 000094DB 830DFF or WORD PTR [DI + LINK],-1 ; SET NEXT POINTER TO NULL 0 000094DE C3 RET 332 INSTALL_BDS ENDP 333 334 === Switch to base=002530h -> "SYSINITTRAIL" 335 usesection SYSINITTRAIL ; fix to not run in unrelocated DOSCODE 336 337 ; 338 ; RE_INIT INSTALLS THE INT 2F VECTOR THAT WILL HANDLE COMMUNICATION BETWEEN 339 ; EXTERNAL BLOCK DRIVERS AND THE INTERNAL DRIVER. IT ALSO INSTALLS THE 340 ; RESET_INT_13 INTERFACE. IT IS CALLED BY SYSYINIT 341 ; 342 PUBLIC RE_INIT 343 RE_INIT PROC near 344 MESSAGE FTESTINIT,<"REINIT",CR,LF> 0 00004F60 50 PUSH AX 0 00004F61 1E PUSH DS 0 00004F62 53 PUSH bx 0 00004F63 06 push es 0 00004F64 31DB XOR bx, bx 0 00004F66 8EDB MOV DS, bx 0 00004F68 B3BC MOV bl, 2FH*4 ; POINT IT TO INT 2F VECTOR 352 extern sysinit_get_es_dosentry 0 00004F6A E8[0000] call sysinit_get_es_dosentry 0 00004F6D 8B07 MOV AX,WORD PTR [bx] 0 00004F6F 26A3[0000] MOV WORD PTR [es:INT_2F_NEXT],AX 0 00004F73 8B4702 MOV AX,WORD PTR [bx+2] ; PRESERVE OLD INT 2F VECTOR 0 00004F76 26A3[0200] MOV WORD PTR [es:INT_2F_NEXT+2],AX 358 359 ; INSTALL THE RESET_INT_13 360 ; INTERFACE 361 362 ; 363 ; THE FOLLOWING TWO LINES ARE NOT NEEDED ANYMORE BECAUSE THE LINK HAS BEEN 364 ; HARD-WIRED INTO THE CODE AT NEXT2F_13. - RAJEN. 365 ;------------------------------------------------------------------------------ 366 ; MOV WORD PTR [CS:NEXT2F_13],OFFSET INT2F_DISK ; PRESERVE INT2F_DISK POINTER 367 ; MOV WORD PTR [CS:NEXT2F_13+2],CS 368 ;------------------------------------------------------------------------------ 369 0 00004F7A FA CLI 0 00004F7B C707[A004] MOV WORD PTR [bx], set_i13_i2F + DOSENTRYADJUSTOFFSET 0 00004F7F C74702[0000] MOV WORD PTR [bx+2], DOSENTRY - DOSENTRYADJUSTSEGMENT 373 ; INSTALL NEW VECTORS 0 00004F84 FB STI 0 00004F85 07 pop es 0 00004F86 5B POP bx 0 00004F87 1F POP DS 0 00004F88 58 POP AX 379 0 00004F89 C3 RET 381 382 RE_INIT ENDP 383 384 === Switch to base=008400h -> "BIOCODE" 385 usesection BIOCODE 386 387 ;------------------------------------------------- 388 ; 389 ; ASK TO SWAP THE DISK IN DRIVE A: 390 ; 391 ; INP: ah = prior drive letter 392 ; ds:di -> UPB for target drive, already active 393 ; CHG: ax 394 PUBLIC SWPDSK 395 SWPDSK PROC NEAR 0 000094DF 51 push cx 0 000094E0 52 push dx 0 000094E1 8A4505 MOV AL,BYTE PTR [DI + DRIVELET] ; GET THE DRIVE LETTER 399 ;USING A DIFFERENT DRIVE IN A ONE DRIVE SYSTEM SO REQUEST THE USER CHANGE DISKS 0 000094E4 92 xchg dx, ax ; dh = prior, dl = new 0 000094E5 06 push es 0 000094E6 1E push ds 0 000094E7 07 pop es ; (super undocumented? es:di -> target UPB) 0 000094E8 31C9 xor cx, cx 0 000094EA B8004A mov ax, 4A00h 0 000094ED CD2F int 2Fh ; MS-DOS v5+ drive change notification 0 000094EF 41 inc cx ; was FFFFh ? 0 000094F0 741A jz .skip ; yes, someone handled it --> 0 000094F2 92 xchg ax, dx ; get new drive back to al 0 000094F3 0441 ADD AL,"A" ; make into a letter 0 000094F5 1E PUSH DS ; PRESERVE SEGMENT REGISTER 0 000094F6 E8[0000] call biocode_get_ds_dosentry 0 000094F9 A2[0000] MOV [DRVLET],AL 0 000094FC BE[0000] MOV SI,OFFSET SNGMSG ; DS:SI -> MESSAGE 0 000094FF 53 PUSH BX 0 00009500 E80D00 CALL WRMSG ;PRINT DISK CHANGE MESSAGE 0 00009503 E8[0000] CALL FLUSH 418 ;SB33003*************************************************************** 0 00009506 30E4 xor AH, AH ; set command to read character;SB 0 00009508 CD16 int 16h ; call rom-bios ;SB 421 ;SB33003*************************************************************** 0 0000950A 5B POP BX 0 0000950B 1F POP DS ; RESTORE SEGMENT REGISTER 424 .skip: 0 0000950C 07 pop es 0 0000950D 5A pop dx 0 0000950E 59 pop cx 428 WRMRET: 0 0000950F C3 RET 430 SWPDSK ENDP 431 432 ;---------------------------------------------- 433 ; 434 ; WRITE OUT MESSAGE POINTED TO BY [SI] 435 ; 436 PUBLIC WRMSG 437 WRMSG PROC NEAR 0 00009510 AC LODSB ;GET THE NEXT CHARACTER OF THE MESSAGE 0 00009511 84C0 test AL,AL ;SEE IF END OF MESSAGE 0 00009513 74FA JZ WRMRET 441 ; INT CHROUT 0 00009515 9C PUSHF 0 00009516 0E PUSH CS 0 00009517 E8[0000] CALL OUTCHR 0 0000951A EBF4 JMP SHORT WRMSG 446 WRMSG ENDP 447 448 === Switch to base=000000h -> "DOSENTRY" 449 section DOSENTRY 450 extern SNGMSG 451 extern DRVLET 452 453 === Switch to base=008400h -> "BIOCODE" 454 section BIOCODE 455 456 ; 457 ; END OF SUPPORT FOR MULTIPLE FLOPPIES WITH NO LOGICAL DRIVES 458 ; THIS IS NOT 'SPECIAL' ANY MORE BECAUSE WE NOW HAVE THE CAPABILITY OF 459 ; DEFINING LOGICAL DRIVES IN CONFIG.SYS. WE THEREFORE KEEP THE CODE FOR 460 ; SWAPPING RESIDENT ALL THE TIME. 461 ; 462 463 ;J.K. 10/1/86 ******************************************************* 464 ;Variables for Dynamic Relocatable modules 465 ;These should be stay resident. 466 === Switch to base=000000h -> "DOSENTRY" 467 section DOSENTRY 468 469 align 2, db 0 470 public INT6C_RET_ADDR 0 0000074E ???????? INT6C_RET_ADDR DD ? ; return address from INT 6C for P12 machine 472 473 PATHSTART 001,CLK 205 <1> %IF PATHGEN 206 <1> PUBLIC %2%1S,%2%1E 207 <1> %2%1S LABEL BYTE 208 <1> %ENDIF 474 ; 475 ; DATA STRUCTURES FOR REAL-TIME DATE AND TIME 476 ; 477 public BIN_DATE_TIME 478 public MONTH_TABLE 479 public DAYCNT2 480 public FEB29 481 BIN_DATE_TIME: 0 00000752 00 DB 0 ; CENTURY (19 OR 20) OR HOURS (0-23) 0 00000753 00 DB 0 ; YEAR IN CENTURY (0...99) OR MINUTES (0-59) 0 00000754 00 DB 0 ; MONTH IN YEAR (1...12) OR SECONDS (0-59) 0 00000755 00 DB 0 ; DAY IN MONTH (1...31) 486 MONTH_TABLE: ; 0 00000756 0000 DW 0 ;MJB002 JANUARY 0 00000758 1F00 DW 31 ;MJB002 FEBRUARY 0 0000075A 3B00 DW 59 ;MJB002 0 0000075C 5A00 DW 90 ;MJB002 0 0000075E 7800 DW 120 ;MJB002 0 00000760 9700 DW 151 ;MJB002 0 00000762 B500 DW 181 ;MJB002 0 00000764 D400 DW 212 ;MJB002 0 00000766 F300 DW 243 ;MJB002 0 00000768 1101 DW 273 ;MJB002 0 0000076A 3001 DW 304 ;MJB002 0 0000076C 4E01 DW 334 ;MJB002 DECEMBER 0 0000076E 0000 DAYCNT2 DW 0000 ;MJB002 TEMP FOR COUNT OF DAYS SINCE 1-1-80 0 00000770 00 FEB29 DB 0 ;MJB002 FEBRUARY 29 IN A LEAP YEAR FLAG 501 PATHEND 001,CLK 212 <1> %IF PATHGEN 213 <1> %2%1E LABEL BYTE 214 <1> %ENDIF 502 503 ;******************************************************************** 504 ; 505 506 PUBLIC ENDFLOPPY 507 ENDFLOPPY LABEL BYTE 508 509 PATHSTART 004,BIO 205 <1> %IF PATHGEN 206 <1> PUBLIC %2%1S,%2%1E 207 <1> %2%1S LABEL BYTE 208 <1> %ENDIF 510 511 === Switch to base=002530h -> "SYSINITTRAIL" 512 usesection SYSINITTRAIL 513 514 PUBLIC HNUM 0 00004F8A 00 HNUM DB 0 ;NUMBER OF HARDFILES 516 PUBLIC HARDDRV 0 00004F8B 80 HARDDRV DB 80H ;PHYSICAL DRIVE NUMBER OF FIRST HARDFILE 518 global amountprimary 0 00004F8C 00 amountprimary: db 0 520 521 ;********************************************************************** 522 ; "HDRIVE" IS A HARD DISK WITH 512 BYTE SECTORS 523 ;********************************************************************* 0 00004F8D 00 EVENB 525 526 BDSM_type_size equ BDSM_type_struc_size ; NASM port equate 527 public BDS_harddisk_template 528 BDS_harddisk_template: 529 istruc BDSM_type 530 at mlink 0 00004F8E FFFF dw -1 0 00004F90 FFFF dw -1 ; LINK TO NEXT STRUCTURE 533 at mdriveNum 0 00004F92 80 db 80h ; INT 13 DRIVE NUMBER 535 at mdriveLet 0 00004F93 03 db 3 ; LOGICAL DRIVE LETTER 537 at mBytePerSec 0 00004F94 0002 dw 512 539 at mSecPerClus 0 00004F96 01 db 1 ; SECTORS/ALLOCATION UNIT 541 at mRESSEC 0 00004F97 0100 dw 1 ; RESERVED SECTORS FOR DOS 543 at mcFAT 0 00004F99 02 db 2 ; NO. OF ALLOCATION TABLES 545 at mcDIR 0 00004F9A 1000 dw 16 ; NUMBER OF DIRECTORY ENTRIES 547 at mDRVLIM 0 00004F9C 0000 dw 0 ; NUMBER OF SECTORS (AT 512 BYTES EACH) 549 at mMediad 0 00004F9E F8 db 1111_1000b ; MEDIA DESCRIPTOR 551 at mcSecFat 0 00004F9F 0100 dw 1 ; NUMBER OF FAT SECTORS 553 at mSECLIM 0 00004FA1 0000 dw 0 ; SECTOR LIMIT 555 at mHDLIM 0 00004FA3 0000 dw 0 ; HEAD LIMIT 557 at mHIDSEC_L 0 00004FA5 0000 dw 0 ; HIDDEN SECTOR COUNT(low) 559 at mHidsec_H 0 00004FA7 0000 dw 0 ; Hidden Sector (high) 561 at mDrvlim_L 0 00004FA9 0000 dw 0 ; Number of Sectors (low) 563 at mDrvlim_H 0 00004FAB 0000 dw 0 ; Number of Sectors (high) 565 at mFatSiz 0 00004FAD 00 db 0 ; TRUE => BIGFAT 567 at mOPCNT 0 00004FAE 0000 dw 0 ; OPEN REF. COUNT 569 at mFormFactor 0 00004FB0 03 db 3 ; FORM FACTOR 571 at mFLAGS 0 00004FB1 2000 dw 20h ; VARIOUS FLAGS 573 at mcCyln 0 00004FB3 2800 dw 40 ; NUMBER OF CYLINDERS 575 at mRecBPB 0 00004FB5 00 db 0 ; RECOMMENDED BPB FOR DRIVE 0 00004FB6 00 at mTrack 0 00004FD4 FF db -1 ; LAST TRACK ACCESSED ON THIS DRIVE 579 at IsMini 0 00004FD5 0100 dw 1 581 at Hidden_Trks 0 00004FD7 0000 dw 0 583 at mVOLID 0 00004FD9 4E4F204E414D452020 db "NO NAME " 0 00004FE2 2020 0 00004FE4 00 db 0 ; VOLUME ID FOR THIS DISK 586 at mVol_Serial 0 00004FE5 00000000 dd 0 ; Current volume serial number from Boot record 588 at mFileSys_Id 0 00004FE9 4641543132202020 db "FAT12 " 0 00004FF1 00 db 0 ; Current file system id from Boot record 591 iend 592 === Switch to base=008400h -> "BIOCODE" 593 usesection BIOCODE 594 595 ; 596 ; END OF SECTION FOR TWO HARD DISKS 597 598 PATHEND 004,BIO 212 <1> %IF PATHGEN 213 <1> %2%1E LABEL BYTE 214 <1> %ENDIF 599 600 ; PAGE 601 ;=== Push trace listing source: ms96tpi.nas 602 %include "ms96tpi.nas" ; NASM included file 1 <1> %warning out: MS96TPI.INC... 1 ****************** <1> warning: out: MS96TPI.INC... [-w+user] 2 <1> ;============================================================================== 3 <1> ;REVISION HISTORY: 4 <1> ;AN000 - New for DOS Version 4.00 - J.K. 5 <1> ;AC000 - Changed for DOS Version 4.00 - J.K. 6 <1> ;AN00x - PTM number for DOS Version 4.00 - J.K. 7 <1> ;============================================================================== 8 <1> ;AN001 - p2781 Changeline error behavior incompatibile with DOS 3.3 1/06/88 J.K. 9 <1> ;============================================================================== 10 <1> ; 11 <1> ; DISK OPEN/CLOSE ROUTINES ARR 2.41 12 <1> ; 13 <1> === Switch to base=008400h -> "BIOCODE" 14 <1> section BIOCODE 15 <1> 16 <1> extern ispatched 17 <1> 18 <1> DSK$OPEN: ;ARR 2.41 19 <1> PUBLIC DSK$OPEN 0 0000951C E8[0000] call ispatched 0 0000951F 7206 jc @F 22 <1> MESSAGE FTESTDISK,<"DISK OPEN "> 23 <1> MNUM FTESTDISK,AX 24 <1> MESSAGE FTESTDISK, 25 <1> ; AL IS LOGICAL DRIVE 0 00009521 E8[0000] CALL SETDRIVE ;GET BDS FOR DRIVE 0 00009524 FF4520 INC WORD PTR [DI + OPCNT] 28 <1> @@: 0 00009527 E9[0000] JMP EXIT ;ARR 2.41 30 <1> 31 <1> DSK$CLOSE: ;ARR 2.41 32 <1> PUBLIC DSK$CLOSE 0 0000952A E8[0000] call ispatched 0 0000952D 720C jc @F 35 <1> MESSAGE FTESTDISK,<"DISK CLOSE "> 36 <1> MNUM FTESTDISK,AX 37 <1> MESSAGE FTESTDISK, 38 <1> ; AL IS LOGICAL DRIVE 0 0000952F E8[0000] CALL SETDRIVE ;GET BDS FOR DRIVE 0 00009532 837D2000 CMP WORD PTR [DI + OPCNT],0 0 00009536 7403 JZ EXITJX ; WATCH OUT FOR WRAP ARR 2.41 0 00009538 FF4D20 DEC WORD PTR [DI + OPCNT] 43 <1> EXITJX: 44 <1> @@: 0 0000953B E9[0000] JMP EXIT 46 <1> 47 <1> ; INPUT : DS:DI POINTS TO CURRENT BDS FOR DRIVE. 48 <1> ; RETURN : ZERO SET IF NO OPEN FILES 49 <1> ; ZERO RESET IF OPEN FILES 50 <1> CHKOPCNT: 51 <1> MESSAGE FTEST96,<"CHECK OPEN COUNT "> 52 <1> MNUM FTEST96,AX 53 <1> MESSAGE FTEST96, 0 0000953E 837D2000 CMP WORD PTR [DI + OPCNT],0 0 00009542 C3 RET 56 <1> 57 <1> ; 58 <1> ; AT MEDIA CHECK TIME, WE NEED TO REALLY GET DOWN AND CHECK WHAT THE CHANGE IS. 59 <1> ; THIS IS GUARANTEED TO BE EXPENSIVE. 60 <1> ; 61 <1> PUBLIC MEDIACHECK 62 <1> MEDIACHECK: 0 00009543 E8[0000] CALL CHECKSINGLE ; MAKE SURE CORRECT DISK IS IN PLACE 0 00009546 31F6 XOR SI,SI 0 00009548 E88801 CALL HASCHANGE 0 0000954B 7432 JZ MEDIARET 0 0000954D E87801 CALL CHECKROMCHANGE 0 00009550 752E JNZ MEDIADOVOLID 0 00009552 50 PUSH AX 0 00009553 52 PUSH DX 71 <1> ;SB33001**************************************************************** 72 <1> drivenum equ DRIVENUM ; NASM port equate 0 00009554 8A5504 mov DL, [DI + drivenum] ;SB ; set logical drive number ;3.30* 0 00009557 B416 mov AH, 16h ;SB ; get changeline status ;3.30* 0 00009559 CD13 int 13h ;SB ; call rom diskette routine ;3.30* 76 <1> ;SB33001**************************************************************** 0 0000955B 5A POP DX 0 0000955C 58 POP AX 0 0000955D 7221 JC MEDIADOVOLID 0 0000955F BE0100 MOV SI,1 ; SIGNAL NO CHANGE 81 <1> ; THERE ARE SOME DRIVES WITH CHANGELINE THAT "LOSE" THE CHANGELINE INDICATION 82 <1> ; IF A DIFFERENT DRIVE IS ACCESSED AFTER THE CURRENT ONE. IN ORDER TO AVOID 83 <1> ; MISSING A MEDIA CHANGE, WE RETURN AN "I DON'T KNOW" TO DOS IF THE CHANGELINE 84 <1> ; IS NOT ACTIVE AND WE ARE ACCESSING A DIFFERENT DRIVE FROM THE LAST ONE. 85 <1> ; IF WE ARE ACCESSING THE SAME DRIVE, THEN WE CAN SAFELY RELY ON THE CHANGELINE 86 <1> ; STATUS. 87 <1> PUBLIC LOSECHNG 88 <1> LOSECHNG: 0 00009562 1E push ds 0 00009563 E8[0000] call biocode_get_ds_dosentry 0 00009566 8A1E[0000] MOV BL,[TIM_DRV] ; GET LAST DRIVE ACCESSED 0 0000956A 1F pop ds 0 0000956B 385D04 CMP BYTE PTR [DI + DRIVENUM],BL 0 0000956E 740F JZ MEDIARET 95 <1> ; DO THE 2 SECOND TWIDDLE. IF TIME >= 2 SECONDS, DO A VOLID CHECK. 96 <1> ; OTHERWISE RETURN "I DON'T KNOW" (STRICTLY SPEAKING, WE SHOULD RETURN A 97 <1> ; "NOT CHANGED" HERE SINCE THE 2 SECOND TEST SAID NO CHANGE.) - RS. 0 00009570 505152 SAVEREG 0 00009573 E8[0000] CALL CHECK_TIME_OF_ACCESS 0 00009576 5A5958 RESTOREREG 0 00009579 09F6 OR SI,SI 0 0000957B 7403 JZ MEDIADOVOLID ; CHECK_TIME SAYS ">= 2 SECS PASSED" 0 0000957D 31F6 XOR SI,SI ; RETURN "I DON'T KNOW" 104 <1> PUBLIC MEDIARET 105 <1> MEDIARET: 0 0000957F C3 RET 107 <1> ; 108 <1> ; SOMEHOW THE MEDIA WAS CHANGED. LOOK AT VID TO SEE. WE DO NOT LOOK AT FAT 109 <1> ; BECAUSE THIS MAY BE DIFFERENT SINCE WE ONLY SET MEDBYT WHEN DOING A READ 110 <1> ; OR WRITE. 111 <1> ; 112 <1> MEDIADOVOLID: 0 00009580 E8[0000] CALL GETBP ; BUILD A NEW BPB IN CURRENT BDS 0 00009583 72FA JC MEDIARET 0 00009585 E83400 CALL CHECK_VID 0 00009588 73F5 JNC MEDIARET 0 0000958A E8[0000] CALL MAPERROR ; FIX UP AL FOR RETURN TO DOS 0 0000958D C3 RET 119 <1> ; 120 <1> ; SIMPLE, QUICK CHECK OF LATCHED CHANGE. IF NO INDICATION, THEN RETURN 121 <1> ; OTHERWISE DO EXPENSIVE CHECK. IF THE EXPENSIVE TEST FAILS, POP OFF THE 122 <1> ; RETURN AND SET AL = 15 (FOR INVALID MEDIA CHANGE) WHICH WILL BE RETURNED TO 123 <1> ; DOS. 124 <1> ;J.K. 9/16/86 For DOS 3.3, this will work only for the drive that has 125 <1> ;J.K. 9/16/86 changeline. 126 <1> PUBLIC CHECKLATCHIO 127 <1> CHECKLATCHIO: 128 <1> ; IF RETURNING FAKE BPB THEN ASSUME THE DISK HAS NOT CHANGED 129 <1> ; TEST WORD PTR [DS:DI].FLAGS, RETURN_FAKE_BPB 130 <1> ; JNZ CHECKRET 131 <1> ;J.K. 9/16/86 132 <1> ; call HasChange ;change line supported? 133 <1> ; jz CheckRet ;No. Just return 0 0000958E E8ADFF CALL CHKOPCNT 0 00009591 7501 JNZ CHECKROM 136 <1> CHECKRET: 0 00009593 C3 RET 138 <1> ; 139 <1> ; CHECK FOR PAST ROM INDICATIONS. IF NO ROM CHANGE INDICATED, THEN RETURN OK. 140 <1> ; 141 <1> PUBLIC CHECKROM 142 <1> CHECKROM: 0 00009594 E83101 CALL CHECKROMCHANGE 0 00009597 74FA JZ CHECKRET ; NO CHANGE 145 <1> ; 146 <1> ; WE NOW SEE THAT A CHANGE LINE HAS BEEN SEEN IN THE PAST. LET'S DO THE 147 <1> ; EXPENSIVE VERIFICATION. 148 <1> ; 149 <1> MESSAGE FTEST96,<"CHECKROMCHANGE SAYS YES...",CR,LF> 0 00009599 E8[0000] CALL GETBP ; BUILD BPB IN CURRENT BDS 0 0000959C 720F JC RET_NO_ERROR_MAP ; GETBP HAS ALREADY CALLED MAPERROR 0 0000959E E81B00 CALL CHECK_VID 0 000095A1 7207 JC CHECKLATCHRET ; DISK ERROR TRYING TO READ IN. 0 000095A3 09F6 OR SI,SI ; IS CHANGED FOR SURE? 0 000095A5 79EC JNS CHECKRET 0 000095A7 E88A00 CALL RETURNVID 157 <1> CHECKLATCHRET: 0 000095AA E8[0000] CALL MAPERROR ; FIX UP AL FOR RETURN TO DOS 159 <1> RET_NO_ERROR_MAP: 0 000095AD F9 STC 0 000095AE 5E POP SI ; POP OFF RETURN ADDRESS 0 000095AF C3 RET 163 <1> 164 <1> ; 165 <1> ; CHECK THE FAT AND THE VID. RETURN IN DI -1 OR 0. RETURN WITH CARRY SET 166 <1> ; ONLY IF THERE WAS A DISK ERROR. RETURN THAT ERROR CODE IN AX. 167 <1> ; 168 <1> PUBLIC CHECKFATVID 169 <1> CHECKFATVID: 0 000095B0 06 push es 0 000095B1 E8[0000] call biocode_get_es_dosentry 172 <1> 173 <1> MESSAGE FTEST96,<"CHECK FAT",CR,LF> 0 000095B4 E80902 CALL FAT_CHECK 0 000095B7 09F6 OR SI,SI 0 000095B9 782E JS CHANGED_DRV 177 <1> ; 178 <1> ; THE FAT WAS THE SAME. HOW ABOUT THE VOLUME ID? 179 <1> ; 180 <1> 0 000095BB A8 db __TEST_IMM8 ; skip push 182 <1> CHECK_VID: 0 000095BC 06 push es 0 000095BD E8[0000] call biocode_get_es_dosentry 185 <1> 186 <1> ;J.K. Now with the extended BOOT record, the logic should be enhanced. 187 <1> ;If it is the extended BOOT record, then we check the volume serial 188 <1> ;number instead of volume id. If it is different, then set SI to -1. 189 <1> ;If it is same, then SI= 1 (No change). 190 <1> ;If it is not the extended BOOT record, then just follows the old 191 <1> ;logic. DOS 4.00 will check if the # of FAT in the boot record BPB 192 <1> ;is not 0. If it is 0 then it must be Non_FAT based system and 193 <1> ;should have already covered by extended boot structure checking. 194 <1> ;So, we will return "I don't know" by setting SI to 0. 195 <1> ;This routine assume the newest valid boot record is in [es:DISKSECTOR]. 196 <1> ;(This will be gauranteed by a successful GETBP call right before this 197 <1> ;routine.) 198 <1> MESSAGE FTEST96,<"CHECK VID",CR,LF> 199 <1> ;SB34MS96TPI001********************************************************* 200 <1> ;SB check the EXT_Boot_Sig variable for the Extended boot signature 201 <1> ;SB if it is set then go to do the extended ID check otherwise continue 202 <1> ;SB with code below 203 <1> ;SB 2 LOCS 204 <1> 205 <1> Ext_Boot_Signature equ EXT_BOOT_SIGNATURE ; NASM port equate 0 000095C0 26803E[0000]29 cmp byte [es:Ext_Boot_Sig],Ext_Boot_Signature 207 <1> Do_Ext_Check_Id equ Do_Ext_Check_ID ; NASM port label 0 000095C6 7429 jz Do_Ext_Check_Id 209 <1> ;SB34MS96TPI001********************************************************* 0 000095C8 E80801 call HasChange ;AN000; 211 <1> CheckRet equ CHECKRET ; NASM port label 0 000095CB 74C6 jz CheckRet ;AN000; 213 <1> 0 000095CD 31F6 xor si,si ;AN000; assume I don't know. 215 <1> SECPERCLUSINSECTOR equ SecPerClusInSector ; NASM port label 0 000095CF 26803E[0300]00 cmp byte ptr [es:SECPERCLUSINSECTOR + 3],0 ;AN000; Don't read vol id from 0 000095D5 7410 je CHECKFATRET ;AN000; the directory if not FAT system 218 <1> READ_VOLUME_ID equ read_volume_id ; NASM port label 0 000095D7 E81A01 CALL READ_VOLUME_ID 0 000095DA 720B JC CHECKFATRET 221 <1> CHECK_VOLUME_ID equ check_volume_id ; NASM port label 0 000095DC E8CA01 CALL CHECK_VOLUME_ID 0 000095DF 09F6 OR SI,SI 0 000095E1 7506 JNZ CHANGED_DRV 225 <1> MESSAGE FTEST96,<"VID NOT CHANGED",CR,LF> 226 <1> 227 <1> VID_NO_Changed: 0 000095E3 E8E800 CALL RESETCHANGED 0 000095E6 F8 clc ;AN000; 230 <1> CHECKFATRET: 0 000095E7 07 pop es 0 000095E8 C3 RET 233 <1> CHANGED_DRV: 0 000095E9 26C606[0000]FF MOV byte [es:TIM_DRV],-1 ; ENSURE THAT WE ASK ROM FOR MEDIA 0 000095EF 07 pop es 0 000095F0 C3 RET ; CHECK NEXT TIME ROUND 237 <1> ; 238 <1> ; extended ID check 239 <1> ; 240 <1> Do_Ext_Check_ID: ;AN000; 0 000095F1 50 push ax ;AN000; 242 <1> ;SB34MS96TPI002************************************************************** 243 <1> ;SB The code to check extended ID is basically a check to see if the 244 <1> ;Sb volume serial number is still the same. The volume serial number 245 <1> ;SB previously read is in [es:Boot_Serial_H] and [es:Boot_Serial_L] 246 <1> ;SB high and low words respectively. DS:DI points to the BDS of the 247 <1> ;SB drive under consideration. The BDS has fields containing the 248 <1> ;SB high and low words of the volume serial number of the media in the 249 <1> ;SB drive. Compare these fields to the fields mentioned above. If these 250 <1> ;SB fields do not match the media has changed and so we should jump 251 <1> ;SB to the code starting at Ext_Changed else return "I don't know" status 252 <1> ;SB in the register used for the changeline status and continue executing 253 <1> ;SB the code given below. For temporary storage use the register which 254 <1> ;SB has been saved and restored around this block. 255 <1> ;SB 7 LOCS 256 <1> ;SB BDS fields in inc\msbds.inc 257 <1> 0 000095F2 26A1[0000] mov ax,[es:Boot_Serial_L] 0 000095F6 3B4557 cmp ax,word ptr [di+VOL_SERIAL] 0 000095F9 750E jnz Ext_Changed 0 000095FB 26A1[0000] mov ax,[es:Boot_Serial_H] 0 000095FF 3B4559 cmp ax,word ptr [di+VOL_SERIAL+2] 0 00009602 7505 jnz Ext_Changed 0 00009604 31F6 xor si,si ; don't know 265 <1> 266 <1> ;SB34MS96TPI002************************************************************** 0 00009606 58 pop ax ;AN000; 268 <1> ; jmp CheckFatRet ;AN000; 0 00009607 EBDA jmp VID_NO_Changed ;AN001;Reset the flag 270 <1> Ext_Changed: ;AN000; Serial number is different! 0 00009609 58 pop ax ;AN000; 0 0000960A BEFFFF mov si, -1 ;AN000; disk changed! 0 0000960D F8 clc ;AN000; clear carry. Only SI is meaningful here. 274 <1> Changed_Drv equ CHANGED_DRV ; NASM port label 0 0000960E EBD9 jmp Changed_Drv ;AN000; 276 <1> 277 <1> ; 278 <1> ; AT I/O TIME, WE DETECTED THE ERROR. NOW WE NEED TO DETERMINE WHETHER THE 279 <1> ; MEDIA WAS TRULY CHANGED OR NOT. WE RETURN NORMALLY IF MEDIA CHANGE UNKNOWN. 280 <1> ; AND WE POP OFF THE CALL AND JMP TO HARDERR IF WE SEE AN ERROR. 281 <1> ; 282 <1> PUBLIC CHECKIO 283 <1> CHECKIO: 0 00009610 80FC06 CMP AH,06 0 00009613 7514 JNZ @F 0 00009615 E826FF CALL CHKOPCNT 0 00009618 740F JZ @F ; NO OPEN FILES 288 <1> ; IF RETURNING FAKE BPB THEN IGNORE DISK CHANGES 289 <1> ; TEST WORD PTR [DS:DI].FLAGS, RETURN_FAKE_BPB 290 <1> ; JNZ IGNORECHANGE 0 0000961A E8[0000] CALL GETBP ; BUILD UP A NEW BPB IN CURRENT BDS 0 0000961D 7212 JC NO_ERROR_MAP ; GETBP HAS ALREADY CALLED MAPERROR 0 0000961F E88EFF CALL CHECKFATVID 0 00009622 7209 JC CHECKIORET ; DISK ERROR TRYING TO READ IN. 0 00009624 09F6 OR SI,SI ; IS CHANGED FOR SURE? 0 00009626 7802 JS CHECKIOERR ; YES CHANGED 297 <1> IGNORECHANGE: 0 00009628 45 INC BP ; ALLOW A RETRY 299 <1> @@: 0 00009629 C3 RET 301 <1> CHECKIOERR: 0 0000962A E80700 CALL RETURNVID 303 <1> CHECKIORET: 304 <1> ; POP SI ; POP OFF RETURN 0 0000962D F9 STC ; MAKE SURE CARRY GETS PASSED THROUGH 0 0000962E E9[0000] JMP HARDERR 307 <1> 308 <1> NO_ERROR_MAP: 0 00009631 E9[0000] JMP HARDERR2 310 <1> ; 311 <1> ; RETURN VID SETS UP THE VID FOR A RETURN TO DOS. 312 <1> ; 313 <1> PUBLIC RETURNVID 314 <1> RETURNVID: 315 <1> MESSAGE FTEST96,<"RETURN VID",CR,LF> 0 00009634 1E PUSH DS ; SAVE POINTER TO CURRENT BDS 0 00009635 57 PUSH DI 0 00009636 51 PUSH CX 319 <1> INIT_VID_LOOP equ init_vid_loop ; NASM port label 0 00009637 E89B01 CALL INIT_VID_LOOP ; SETS ES:DI -> VID 0 0000963A E8[0000] call biocode_get_ds_dosentry 0 0000963D C51E[0000] lds bx, [PTRSAV] 0 00009641 897F16 MOV [BX + EXTRA],DI 0 00009644 8C4718 MOV [BX + EXTRA+2],ES 0 00009647 59 POP CX 0 00009648 5F POP DI ; RESTORE CURRENT BDS 0 00009649 1F POP DS 0 0000964A B406 MOV AH,6 ; INVALID MEDIA CHANGE 0 0000964C F9 STC 0 0000964D C3 RET 331 <1> 332 <1> ; 333 <1> ; MUNGE THE TIME OF LAST SUCCESSFUL ACCESS FOR TWEEKED DRIVES 334 <1> ; 335 <1> ; DON'T NEED ANY MORE 336 <1> ; TWEEKCHECK: 337 <1> ; PUSH AX 338 <1> ; MOV AX,WORD PTR [DS:DI].FLAGS 339 <1> ; TEST AL,FCHANGED_BY_FORMAT 340 <1> ; JZ TWEEKDONE 341 <1> ; MOV [CS:TIM_DRV],-1 342 <1> ; TWEEKDONE: 343 <1> ; POP AX 344 <1> ; RET 345 <1> 346 <1> ; 347 <1> ; DRIVE IS THE LOGICAL DRIVE TO USE 348 <1> ; 349 <1> ; FORMAT_MEDIA_CHECK: ;ARR 2.42 350 <1> ; PUSH AX 351 <1> ; MOV AX,WORD PTR [DS:DI].FLAGS 352 <1> ; TEST AL,FCHANGED_BY_FORMAT 353 <1> ; JZ RETF1 ; MEDIA NOT CHANGED VIA FORMAT 354 <1> ; AND AL,NOT FCHANGED_BY_FORMAT 355 <1> ; MOV WORD PTR [DI].FLAGS,AX ; RESET CHANGED_BY_FORMAT BIT 356 <1> ; MOV SI,-1 ; MEDIA CHANGED VIA FORMAT 357 <1> ; RETF1: 358 <1> ; POP AX 359 <1> ; RET 360 <1> 361 <1> ; 362 <1> ; MOVES THE POINTER TO THE VOLID FOR THE DRIVE INTO THE ORIGINAL REQUEST PACKET 363 <1> ; ON ENTRY, DS:BX POINTS TO THE ORIGINAL PACKET. 364 <1> ; NO ATTEMPT IS MADE TO PRESERVE REGISTERS. 365 <1> ; 366 <1> MEDIA_SET_VID: ; ARR 2.42 367 <1> PUBLIC MEDIA_SET_VID 368 <1> 0 0000964E E88401 CALL INIT_VID_LOOP ; SETS ES:DI -> VID 0 00009651 E8[0000] call biocode_get_ds_dosentry 0 00009654 C51E[0000] lds bx, [PTRSAV] ; GET POINTER TO PACKET 0 00009658 897F0F MOV WORD PTR [BX + TRANS+1],DI 0 0000965B 8C4711 MOV WORD PTR [BX + TRANS+3],ES 0 0000965E C3 RET 375 <1> 376 <1> 377 <1> ; 378 <1> ; HIDENSITY - EXAMINE A DRIVE/MEDIA DESCRIPTOR TO SET THE MEDIA TYPE. IF 379 <1> ; THE MEDIA DESCRIPTOR IS NOT F9 (NOT 96TPI OR 3 1/2), WE RETURN AND LET THE 380 <1> ; CALLER DO THE REST. OTHERWISE, WE POP OFF THE RETURN AND JUMP TO THE TAIL 381 <1> ; OF GETBP. FOR 3.5" MEDIA, WE JUST RETURN. 382 <1> ; 383 <1> ; INPUTS: DS:DI POINT TO CORRECT BDS FOR THIS DRIVE 384 <1> ; AH HAS MEDIA BYTE 385 <1> ; 386 <1> ; OUTPUTS: CARRY CLEAR 387 <1> ; NO REGISTERS MODIFIED 388 <1> ; CARRY SET 389 <1> ; AL = SECTORS/FAT 390 <1> ; BH = NUMBER OF ROOT DIRECTORY ENTRIES 391 <1> ; BL = SECTORS PER TRACK 392 <1> ; CX = NUMBER OF SECTORS 393 <1> ; DH = SECTORS PER ALLOCATION UNIT 394 <1> ; DL = NUMBER OF HEADS 395 <1> ; 396 <1> HIDENSITY: 397 <1> PUBLIC HIDENSITY 398 <1> ; 399 <1> ; CHECK FOR CORRECT DRIVE 400 <1> ; 0 0000965F F745230200 TEST WORD PTR [DI + FLAGS],FCHANGELINE ; IS IT SPECIAL? 0 00009664 741C JZ DOFLOPPY ; NO, DO NORMAL FLOPPY TEST 403 <1> ; 404 <1> ; WE HAVE A MEDIA BYTE THAT IS PRETTY COMPLEX. EXAMINE DRIVE INFORMATION 405 <1> ; TABLE TO SEE WHAT KIND IT IS. 406 <1> ; 0 00009666 807D2202 CMP BYTE PTR [DI + FORMFACTOR],FFSMALL; IS IT SINGLE-MEDIA? 0 0000966A 7416 JZ DOFLOPPY ; YES, USE FATID... 409 <1> ; 410 <1> ; 96 TPI DRIVE 411 <1> ; 0 0000966C 80FCF9 CMP AH,0F9H 0 0000966F 7511 JNZ DOFLOPPY 0 00009671 B007 MOV AL,7 ; SEVEN SECTORS / FAT 0 00009673 BB0FE0 MOV BX,224*256+0FH ; 224 ROOT DIR ENTRIES & 0F SECTOR MAX 0 00009676 B96009 MOV CX,80*15*2 ; 80 TRACKS, 15 SECTORS/TRACK, 2 SIDES 0 00009679 BA0201 MOV DX,01*256+2 ; SECTORS/ALLOCATION UNIT & HEAD MAX 418 <1> POPR: 0 0000967C 83C402 ADD SP,2 ; POP OFF RETURN ADDRESS 0 0000967F E9[0000] JMP HAS1 ; RETURN TO TAIL OF GETBP 421 <1> 422 <1> DOFLOPPY: 0 00009682 C3 RET 424 <1> 425 <1> PATHSTART 001,TPI96 205 <2> %IF PATHGEN 206 <2> PUBLIC %2%1S,%2%1E 207 <2> %2%1S LABEL BYTE 208 <2> %ENDIF 426 <1> 427 <1> ; 428 <1> ; CERTAIN BOGUS PROGRAMS AVOID DOS ALTOGETHER AND USE INT 13 DIRECTLY. THESE 429 <1> ; PROGRAMS EVEN RETRY OPERATIONS AND, THUS, WILL IGNORE THE DISK CHANGE LOGIC. 430 <1> ; 431 <1> ; WE HOOK INT 13 AND NOTE ALL ERRORS. 432 <1> ; 433 <1> ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING === Switch to base=000000h -> "DOSENTRY" 434 <1> section DOSENTRY ; in DOSENTRY 435 <1> 0 00000771 00 align 2, db 0 0 00000772 90 nop 438 <1> transfer_real13: 0 00000773 EA db 0EAh 440 <1> PUBLIC REAL13 0 00000774 ???????? REAL13 DD ? 442 <1> 443 <1> PATHEND 001,TPI96 212 <2> %IF PATHGEN 213 <2> %2%1E LABEL BYTE 214 <2> %ENDIF 444 <1> === Switch to base=008400h -> "BIOCODE" 445 <1> section BIOCODE 446 <1> 447 <1> relocated ms96tpi_i13 448 <1> PUBLIC INT13 449 <1> INT13 PROC FAR 450 <1> MESSAGE FTEST13,<"*"> 0 00009683 9C pushf 0 00009684 9A[2500][0000] call DOSENTRY:transfer_real13 0 00009689 7307 jnc transfer_Leave13 454 <1> 455 <1> ERR13: 456 <1> MESSAGE FTEST13,<"INT 13 ERROR "> 457 <1> MNUM FTEST13,AX 458 <1> MESSAGE FTEST13, 0 0000968B 9C PUSHF ; SAVE STATE 0 0000968C 80FC06 CMP AH,06H ; DID I SEE A CHANGE EVENT? 0 0000968F 7404 JZ GOTERR ; YES 0 00009691 9D @@: POPF ; NO, SOME OTHER ERROR, IGNORE IT 463 <1> transfer_Leave13: 0 00009692 E9[0000] jmp Leave13 465 <1> 0 00009695 84D2 GOTERR: test DL,DL ; IS THIS FOR THE HARD DISK? 0 00009697 78F8 JS @B ; YES, IGNORE 0 00009699 53 push bx 0 0000969A BB4000 MOV bx, FCHANGED 0 0000969D E80300 CALL SET_CHANGED_DL 0 000096A0 5B pop bx 0 000096A1 EBEE JMP @B 473 <1> INT13 ENDP 474 <1> 475 <1> extern Leave13 476 <1> 477 <1> ; 478 <1> ; SET_CHANGED_DL - SETS FLAG BITS ACCORDING TO BITS SET IN [FLAGBITS]. 479 <1> ; ESSENTIALLY USED TO INDICATE CHANGELINE, OR FORMAT. 480 <1> ; 481 <1> ; INPUTS: DL CONTAINS PHYSICAL DRIVE NUMBER 482 <1> ; bx CONTAINS BITS TO SET IN THE FLAG FIELD IN THE BDSS 483 <1> ; OUTPUTS: NONE 484 <1> ; REGISTERS MODIFIED: FLAGS, bx 485 <1> ; 486 <1> SET_CHANGED_DL: 487 <1> PUBLIC SET_CHANGED_DL 488 <1> 489 <1> MESSAGE FTEST96,<"SET CHANGED",CR,LF> 0 000096A3 52 PUSH DX 0 000096A4 87DA xchg bx, dx ; bl = int 13h unit, dx = mask 492 <1> ALL_SET: 0 000096A6 30FF XOR BH,BH 494 <1> ; 495 <1> ; IN THE VIRTUAL DRIVE SYSTEM WE *MUST* FLAG THE OTHER DRIVES AS BEING CHANGED 496 <1> ; 497 <1> ; ASSUME FIRST BDS IS IN THIS SEGMENT 0 000096A8 50 PUSH AX 0 000096A9 1E PUSH DS ; SAVE CURRENT BDS 0 000096AA 57 PUSH DI 0 000096AB E8[0000] call biocode_get_ds_dosentry 0 000096AE C53E[0000] lds di, [START_BDS] 503 <1> SCAN_BDS: 0 000096B2 83FFFF CMP DI,-1 0 000096B5 740C je SKIPSET 0 000096B7 385D04 CMP BYTE PTR [DI + DRIVENUM],BL 0 000096BA 7503 JNZ GET_NEXT_BDS 508 <1> ; 509 <1> ; SOMEONE MAY COMPLAIN, BUT THIS *ALWAYS* MUST BE DONE WHEN A DISK CHANGE IS 510 <1> ; NOTED. THERE ARE *NO* OTHER COMPROMISING CIRCUMSTANCES. 511 <1> ; 512 <1> SETCHANGED: 0 000096BC 095523 OR WORD PTR [DI + FLAGS],DX ; SIGNAL CHANGE ON OTHER DRIVE 514 <1> GET_NEXT_BDS: 0 000096BF C53D lds di, [di + LINK] 0 000096C1 EBEF JMP SHORT SCAN_BDS 517 <1> SKIPSET: 0 000096C3 5F POP DI ; RESTORE CURRENT BDS 0 000096C4 1F POP DS 0 000096C5 58 POP AX 0 000096C6 5A POP DX 0 000096C7 C3 RET 523 <1> 524 <1> ; 525 <1> ; CHECKROMCHANGE - SEE IF EXTERNAL PROGRAM HAS DIDDLED ROM CHANGE LINE. 526 <1> ; 527 <1> ; INPUTS: DS:DI POINTS TO CURRENT BDS. 528 <1> ; OUTPUTS: ZERO SET - NO CHANGE 529 <1> ; ZERO RESET - CHANGE 530 <1> ; REGISTERS MODIFIED: NONE 531 <1> 532 <1> CHECKROMCHANGE: 533 <1> MESSAGE FTEST13,<"CHECKROM "> 534 <1> MNUM FTEST13 535 <1> MESSAGE FTEST13, 0 000096C8 F745234000 TEST WORD PTR [DI + FLAGS],FCHANGED 0 000096CD C3 RET 538 <1> 539 <1> ; 540 <1> ; RESETCHANGED - RESTORE VALUE OF CHANGE LINE 541 <1> ; 542 <1> ; INPUTS: DS:DI POINTS TO CURRENT BDS 543 <1> ; OUTPUTS: NONE 544 <1> ; REGISTERS MODIFIED: NONE 545 <1> 546 <1> public ResetChanged 547 <1> RESETCHANGED: 548 <1> MESSAGE FTEST13,<"RESETCHANGED "> 549 <1> MNUM FTEST13 550 <1> MESSAGE FTEST13, 0 000096CE 836523BF AND WORD PTR [DI + FLAGS],~ FCHANGED 0 000096D2 C3 RET 553 <1> 554 <1> ; 555 <1> ; HASCHANGE - SEE IF DRIVE CAN SUPPLY CHANGE LINE 556 <1> ; 557 <1> ; INPUTS: DS:DI POINTS TO CURRENT BDS 558 <1> ; OUTPUTS: ZERO SET - NO CHANGE LINE AVAILABLE 559 <1> ; ZERO RESET - CHANGE LINE AVAILABLE 560 <1> ; REGISTERS MODIFIED: NONE 561 <1> 562 <1> PUBLIC HASCHANGE 563 <1> HASCHANGE: 564 <1> MESSAGE FTEST13,<"HASCHANGE "> 565 <1> MNUM FTEST13 566 <1> MESSAGE FTEST13, 0 000096D3 F745230200 TEST WORD PTR [DI + FLAGS],FCHANGELINE 0 000096D8 C3 RET 569 <1> 570 <1> ASSUME DS:BIOCODE 571 <1> 572 <1> ;=== Push trace listing source: msvolid.nas 573 <1> %include "msvolid.nas" ; NASM included file 1 <2> ;------------------------------------------------------------------------- 2 <2> ; 3 <2> ; File: msvolid.asm 4 <2> ; This file contains the volume_id subroutines and data structures. 5 <2> ; 6 <2> ; Routines in this file are: 7 <2> ; Set_Volume_ID - main routine, calls other routines. 8 <2> ; read_volume_id - read the volume ID and tells if it has 9 <2> ; been changed. 10 <2> ; Transfer_volume_id - copy the volume ID from TMP to special 11 <2> ; drive. 12 <2> ; Check_Volume_ID - compare volume ID in TMP area with one 13 <2> ; expected for drive. 14 <2> ; Fat_Check - see of the fatID has changed in the 15 <2> ; specified drive. 16 <2> ; Init_Vid_loop - set up for VID scan or move 17 <2> ; 18 <2> ; 19 <2> ;------------------------------------------------------------------------- 20 <2> === Switch to base=000000h -> "DOSENTRY" 21 <2> section DOSENTRY 22 <2> 23 <2> ; 24 <2> ; length of the volume id 25 <2> ; 26 <2> 27 <2> vid_size equ 12 28 <2> 29 <2> PATHSTART 001,VOLID ;3.30 205 <3> %IF PATHGEN 206 <3> PUBLIC %2%1S,%2%1E 207 <3> %2%1S LABEL BYTE 208 <3> %ENDIF 30 <2> 31 <2> ; 32 <2> ; null volume id 33 <2> ; 34 <2> 0 00000778 4E4F204E414D452020 nul_vid db "NO NAME ",0 0 00000781 202000 36 <2> 37 <2> ; 38 <2> ; data scratch area used to hold volume ids 39 <2> ; 40 <2> 0 00000784 4E4F204E414D452020 tmp_vid db "NO NAME ",0 0 0000078D 202000 42 <2> 43 <2> PATHEND 001,VOLID ;3.30 212 <3> %IF PATHGEN 213 <3> %2%1E LABEL BYTE 214 <3> %ENDIF 44 <2> 45 <2> ; 46 <2> ; Set_Volume_ID 47 <2> ; If drive has changeline support, read in and set the volume_ID 48 <2> ; and the last FAT_ID byte. If no change line support then do nothing. 49 <2> ; 50 <2> ; On entry: 51 <2> ; DS:DI points to the BDS for this disk. 52 <2> ; AH contains media byte 53 <2> ; 54 <2> ; On Exit: 55 <2> ; Carry clear: 56 <2> ; Successful call 57 <2> ; Carry set 58 <2> ; Error and AX has error code 59 <2> ; 60 <2> === Switch to base=008400h -> "BIOCODE" 61 <2> section BIOCODE 62 <2> 63 <2> Set_Volume_ID: 64 <2> SET_VOLUME_ID equ Set_Volume_ID ; NASM port label 65 <2> PUBLIC SET_VOLUME_ID ;3.30 0 000096D9 52 push dx ; save registers 0 000096DA 50 push ax 68 <2> HasChange equ HASCHANGE ; NASM port label 0 000096DB E8F5FF CALL HasChange ; does drive have changeline support? 0 000096DE 740D jz setvret ; no, get out 0 000096E0 57 push di 72 <2> read_volume_ID equ read_volume_id ; NASM port label 0 000096E1 E81000 call read_volume_ID ; read the volume ID 0 000096E4 5F pop di 0 000096E5 720A jc SetErr ; if error go to error routine 0 000096E7 E8AE00 call transfer_volume_ID ; copy the volume id to special drive 77 <2> ResetChanged equ RESETCHANGED ; NASM port label 0 000096EA E8E1FF call ResetChanged ; restore value of change line 79 <2> 80 <2> setvret: ; SET Volume RETurn 0 000096ED F8 clc ; no error, clear carry flag 0 000096EE 58 pop ax ; restore registers 0 000096EF 5A pop dx 0 000096F0 C3 ret 85 <2> SetErr: 0 000096F1 5A pop dx ; pop stack but don't overwrite AX 0 000096F2 5A pop dx ; restore DX 0 000096F3 C3 ret 89 <2> 90 <2> === Switch to base=000000h -> "DOSENTRY" 91 <2> section DOSENTRY 92 <2> 0 00000790 ???? root_sec DW ? ;Root sector # 94 <2> 95 <2> === Switch to base=008400h -> "BIOCODE" 96 <2> section BIOCODE 97 <2> 98 <2> ; 99 <2> ; read_volume_id read the volume ID and tells if it has been changed. 100 <2> ; 101 <2> ; On entry: 102 <2> ; DS:DI points to current BDS for drive. 103 <2> ; On Exit: 104 <2> ; Carry Clear 105 <2> ; SI = 1 No change 106 <2> ; SI = 0 ? 107 <2> ; SI = -1 Change 108 <2> ; 109 <2> ; Carry Set: 110 <2> ; Error and AX has error code. 111 <2> ; 112 <2> 113 <2> read_volume_id: 0 000096F4 06 push ES ; preserve registers 0 000096F5 52 push DX 0 000096F6 51 push CX 0 000096F7 53 push BX 0 000096F8 50 push AX 0 000096F9 1E push DS ; Preserve Current BDS 0 000096FA 57 push DI 0 000096FB E8[0000] call biocode_get_es_dosentry 0 000096FE 06 push es 0 000096FF 1F pop ds 0 00009700 BF[3600] mov di,offset tmp_vid 0 00009703 BE[2A00] mov si,offset nul_vid 0 00009706 B90C00 mov cx,vid_size 0 00009709 F3A4 rep movsb ; initialize tmp_vid to null vi_id 128 <2> 0 0000970B 5F pop DI ; Restore Current BDS 0 0000970C 1F pop DS 131 <2> cFAT equ CFAT ; NASM port equate 0 0000970D 8A450B mov al,byte ptr [di + cFAT] ; # of fats 133 <2> csecfat equ CSECFAT ; NASM port equate 0 00009710 8B4D11 mov cx,word ptr [di + csecfat] ; sectors / fat 0 00009713 F6E1 mul cl ; size taken by fats 136 <2> ressec equ RESSEC ; NASM port equate 0 00009715 034509 add ax,word ptr [di + ressec] ; add on reserved sectors 138 <2> ; AX is now sector # (0 based) 0 00009718 26A3[4200] mov [es:root_sec],ax ; set initial value 140 <2> cDir equ CDIR ; NASM port equate 0 0000971C 8B450C mov ax,[di + cDir] ; # root dir entries 0 0000971F B104 mov cl,4 ; 16 entries/sector 0 00009721 D3E8 shr ax,cl ; divide by 16 0 00009723 89C1 mov cx,ax ; cx is # of sectors to scan 145 <2> next_sec: 0 00009725 51 push cx ; save outer loop counter 0 00009726 26A1[4200] mov ax,[es:root_sec] ; get sector # 148 <2> seclim equ SECLIM ; NASM port equate 0 0000972A 8B4D13 mov cx,word ptr [di + seclim] ; sectors / track 0 0000972D 31D2 xor DX,DX 0 0000972F F7F1 div cx 152 <2> ; set up registers for call to read_sector 0 00009731 42 inc DX ; dx= sectors into track, ax= track count from 0 0 00009732 88D1 mov cl,dl ; sector to read 0 00009734 31D2 xor DX,DX 156 <2> hdlim equ HDLIM ; NASM port equate 0 00009736 F77515 div word ptr [di + hdlim] ; # heads on this disc 0 00009739 88D6 mov dh,dl ; Head number 0 0000973B 88C5 mov ch,al ; Track # 160 <2> read_sector equ READ_SECTOR ; NASM port label 0 0000973D E8[0000] call read_sector ; get first sector of the root directory, 162 <2> ; ES:BX -> BOOT 163 <2> ; read_sector resets es => DOSENTRY 0 00009740 7252 jc ReadVIDErr ; error on read 0 00009742 B91000 mov cx,16 ; # of dir entries in a block of root 0 00009745 B008 mov al,08h ; volume label bit 167 <2> fvid_loop: 0 00009747 26803F00 cmp byte ptr [es:bx],0 ; End of dir? 0 0000974B 7444 jz no_vid ; yes, no vol id 0 0000974D 26803FE5 cmp byte ptr [es:bx],0E5h ; empty entry? 0 00009751 740D jz ent_loop ; yes, skip 0 00009753 26F6470BD7 test byte [es:bx + 11], ~ 28h ; any bit other than label or archive ? 0 00009758 7506 jnz ent_loop ; yes, may be an LFN, skip it --> 0 0000975A 2684470B test [es:bx+11],al ; is volume label bit set in fcb? 0 0000975E 7511 jnz found_vid ; jmp yes 176 <2> ent_loop: 0 00009760 83C320 ADD BX,32 ;MJB003 ADD LENGTH OF DIRECTORY ENTRY ;3.30 0 00009763 E2E2 loop fvid_loop 0 00009765 59 pop cx ; outer loop 0 00009766 26FF06[4200] inc word [es:root_sec] ; next sector 0 0000976B E2B8 loop next_sec ; continue 182 <2> NotFound: 0 0000976D 31F6 XOR SI,SI 0 0000976F EB19 jmp short fvid_ret 185 <2> 186 <2> found_vid: 0 00009771 59 pop cx ; clean stack of outer loop counter 0 00009772 89DE mov si,bx ; point to volume_id 0 00009774 1E push ds ; preserve currnet BDS 0 00009775 57 push di 0 00009776 06 push es ; es:si points to volume id. 0 00009777 1F pop ds ; source segment 0 00009778 E8[0000] call biocode_get_es_dosentry 0 0000977B BF[3600] mov di,offset tmp_vid ; dest of volume_id 0 0000977E B90B00 mov cx,vid_size -1 ; length of string minus NUL 0 00009781 F3A4 rep movsb ; mov volume label to tmp_vid 0 00009783 30C0 xor al,al 0 00009785 AA stosb ; Null terminate 0 00009786 31F6 XOR SI,SI 0 00009788 5F pop DI ; restore current BDS 0 00009789 1F pop DS 202 <2> fvid_ret: 0 0000978A 58 pop ax 0 0000978B F8 clc 205 <2> RVIDRet: 0 0000978C 5B pop BX ; restore register 0 0000978D 59 pop CX 0 0000978E 5A pop DX 0 0000978F 07 pop ES 0 00009790 C3 ret 211 <2> no_vid: 0 00009791 59 pop cx ; clean stack of outer loop counter 0 00009792 EBD9 jmp NotFound ; not found 214 <2> ReadVIDErr: 0 00009794 5E pop SI 0 00009795 5E pop SI 0 00009796 EBF4 jmp RVIDRet 218 <2> 219 <2> 220 <2> 221 <2> ; 222 <2> ; Transfer_volume_id - copy the volume ID from TMP to special drive 223 <2> ; 224 <2> ; Inputs: DS:DI nas current BDS 225 <2> ; Outputs: BDS for drive has volume ID from TMP 226 <2> ; 227 <2> 228 <2> transfer_volume_ID: 0 00009798 1E push DS ; preserve current BDS 0 00009799 57 push DI 0 0000979A 06 push ES 0 0000979B 56 push SI 0 0000979C 51 push CX 0 0000979D E83500 call init_vid_loop 0 000097A0 FC cld 0 000097A1 F3A4 rep MOVSB ; transfer 0 000097A3 59 pop CX 0 000097A4 5E pop SI 0 000097A5 07 pop ES 0 000097A6 5F pop DI ; restore current BDS 0 000097A7 1F pop DS 0 000097A8 C3 ret 243 <2> 244 <2> 245 <2> ; 246 <2> ; Check_Volume_ID - compare volume ID in TMP area with one expected for 247 <2> ; drive 248 <2> ; 249 <2> ; Inputs: DS:DI has current BDS for drive 250 <2> ; Outputs: SI = 0 if compare succeeds 251 <2> ; SI = -1 if compare fails. 252 <2> 253 <2> check_volume_id: 0 000097A9 1E push DS ; preserve current BDS for drive 0 000097AA 57 push DI 0 000097AB 06 push ES 0 000097AC 51 push CX 0 000097AD E82500 call init_vid_loop 0 000097B0 FC cld 0 000097B1 F3A6 repz cmpsb ; are the 2 volume_ids the same? 0 000097B3 BE0000 mov si,0 ; assume unknown 0 000097B6 7403 jz check_vid_ret ; carry clear if jump taken 0 000097B8 BEFFFF mov si,-1 ; failure 264 <2> check_vid_ret: 0 000097BB 59 pop CX 0 000097BC 07 pop ES 0 000097BD 5F pop DI ; restore current BDS 0 000097BE 1F pop DS 0 000097BF C3 ret 270 <2> 271 <2> ; 272 <2> ; Fat_Check - see of the fatID has changed in the specified drive. 273 <2> ; - uses the FAT ID obtained from the boot sector. 274 <2> ; 275 <2> ; Inputs: MedByt is expected FAT ID 276 <2> ; DS:DI points to current BDS 277 <2> ; Output: Carry Clear 278 <2> ; SI = -1 if fat ID different, 279 <2> ; SI = 0 otherwise 280 <2> ; No other registers changed. 281 <2> 282 <2> FAT_CHECK: 0 000097C0 50 push AX 0 000097C1 31F6 xor SI, SI ; say FAT ID's are same. 0 000097C3 06 push es 0 000097C4 E8[0000] call biocode_get_es_dosentry 287 <2> MedByt equ MEDBYT ; NASM port label 0 000097C7 26A0[0000] mov AL, [es:MedByt] 289 <2> Mediad equ MEDIAD ; NASM port equate 0 000097CB 3A4510 cmp AL, byte ptr [DI + Mediad] ; compare it with the BDS medbyte 291 <2> OKRET1 equ OkRet1 ; NASM port label 0 000097CE 7401 jz OKRET1 ; carry clear 0 000097D0 4E dec SI 0 000097D1 F8 OkRet1: clc 0 000097D2 07 pop es 0 000097D3 58 pop AX 0 000097D4 C3 ret 298 <2> 299 <2> 300 <2> ; 301 <2> ; Init_Vid_loop - set up for VID scan or move 302 <2> ; 303 <2> ; Inputs: DS:DI pionts to BDS for the drive 304 <2> ; Outputs: DS:SI points to tmp_vid 305 <2> ; ES:DI points to vid for drive 306 <2> ; CX has size for VID compare 307 <2> ; 308 <2> 309 <2> init_vid_loop: 0 000097D5 50 push ax 0 000097D6 1E push ds 0 000097D7 07 pop es 0 000097D8 E8[0000] call biocode_get_ds_dosentry 0 000097DB BE[3600] mov si,offset tmp_vid ; source 315 <2> volid equ VOLID ; NASM port equate 0 000097DE 83C74B add di,volid 0 000097E1 B90C00 mov cx,vid_size 0 000097E4 58 pop ax 0 000097E5 C3 ret 320 <2> 574 <1> ;=== Pop trace listing source 575 <1> === Switch to base=000000h -> "DOSENTRY" 576 <1> section DOSENTRY 577 <1> 578 <1> PUBLIC END96TPI 579 <1> END96TPI LABEL BYTE 603 ;=== Pop trace listing source 604 605 ;********************************************************************* 606 ;Memory allocation for BDSM table. - J.K. 2/21/86 607 ;********************************************************************* 608 609 %if 0 610 mlink DW ? ;-1 ;Link to next structure 611 DW ? 612 mdriveNum DB ? ;80 ;Int 13 Drive Number 613 mdriveLet DB ? ;3 ;Logical Drive Number 614 mBytePerSec DW ? ;512 615 mSecPerClus DB ? ;1 ;Sectors/allocation unit 616 mRESSEC DW ? ;1 ;Reserved sectors for DOS 617 mcFAT DB ? ;2 ;No. of allocation tables 618 mcDIR DW ? ;16 ;Number of directory entries 619 mDRVLIM DW ? ;0 ;Number of sectors (at 512 bytes each) 620 mMediad DB ? ;11111000B ;Media descriptor 621 mcSecFat DW ? ;1 ;Number of FAT sectors 622 mSECLIM DW ? ;0 ;Sector limit 623 mHDLIM DW ? ;0 ;Head limit 624 mHIDSEC_L DW ? ;0 ;Hidden sector count 625 mHidsec_H dw ? ;0 ;J.K.87 626 mDrvlim_L dw ? ;0 ;J.K.87 627 mDrvlim_H dw ? ;0 ;J.K.87 628 mFatSiz DB ? ;0 ;TRUE => bigfat 629 mOPCNT DW ? ;0 ;Open Ref. Count 630 mFormFactor DB ? ;3 ;Form Factor 631 mFLAGS DW ? ;0020H ;Various Flags 632 mcCyln dw ? ;40 ;max number of cylinders 633 mRecBPB db 31 dup (?) ;(0) ;Recommended BPB for drive 634 mTrack db ? ;-1 635 IsMini dw ? ;1 ;Overlapping TIM_LOH 636 Hidden_Trks dw ? ;0 ;Overlapping TIM_HIH 637 mVOLID DB 11 dup (?) ;"NO NAME " ;Volume ID for this disk 638 DB ? ;0 ;ASCIZII for "NO NAME " 639 mVol_Serial dd ? ;0 ;Current volume serial number from Boot record 640 mFileSys_Id db 8 dup (?) ;"FAT12 " ;Current file system id from Boot record 641 db ? ;0 642 %endif 643 644 ; 645 ;;3.3 BUG FIX -SP ------------------------------ 646 ;;Migrated into 4.00 -MRW 647 ;Paragraph buffer between the BDSMs and MSHARD 648 ; 649 ;The relocation code for MSHARD needs this. this cannot be used for 650 ;anything. nothing can come before this or after this.....IMPORTANT!!!! 651 ;don't get too smart and using this buffer for anything!!!!!! 652 ; 0 00000792 000000000000000000 db 16 dup(0) 0 0000079B 00000000000000 654 ; 655 ;end of bug fix buffer 656 ;; 657 ;;3.3 BUG FIX -SP------------------------------ 658 END === Trace listing source: mshard.lst 1 ;*** 2 ; Title: Disk 3 ; C: (C) Copyright 1988 by Microsoft corp. 4 ; Date: 1/11/85 5 ; 6 ; There is a bug in some versions of IBM's AT ROM BIOS. 7 ; Interrupts are not disabled during read operations. 8 ; 9 ; Use: This program should be chained in line with the disk 10 ; interupt 13h, it intercepts read calls to the hard disk 11 ; and handles them appropriately. For other functions it 12 ; passes controll to OLD13, which should contain the 13 ; address of the AT ROM disk routine. The entry point for 14 ; this program is IBM_DISK_IO. 15 ; 16 17 18 cpu 286 ;Use 80286 non-protected mode 19 20 BIOSEG equ 040h ;Segment for ROM BIOS Data 21 ROMSEG equ 0F000h ;Segment of ROM 22 23 %idefine ORG absolute ; just address things without segment 24 25 26 BAD_DISK equ 01 27 28 HF_PORT equ 01F0h 29 HF_REG_PORT equ 03F6h 30 31 ;* Offsets into Fixed disk parameter table 32 FDP_PRECOMP equ 5 33 FDP_CONTROL equ 8 34 35 ;section DATA ;ROM BIOS data segment 36 %if 0 37 section DATA ; NASM port directive for fixmem.pl 38 %endif 39 40 ORG 42h 0 00000042 ???????????? CMD_BLOCK DB 6 DUP (?) 42 43 ;* Offsets into CMD_BLOCK for registers 44 PRE_COMP equ 0 ;Write Pre-compensation 45 SEC_CNT equ 1 ;Sector count 46 SEC_NUM equ 2 ;Sector number 47 CYL_LOW equ 3 ;Cylinder number, low part 48 CYL_HIGH equ 4 ;Cylinder number, high part 49 DRV_HEAD equ 5 ;Drive/Head (Bit 7 = ECC mode, Bit 5 = 512 byte sectors, 50 ; Bit 4 = drive number, Bits 3-0 have head number) 51 CMD_REG equ 6 ;Command register 52 53 54 ORG 074h 55 0 00000074 ?? DISK_STATUS1 DB ? 0 00000075 ?? HF_NUM DB ? 0 00000076 ?? CONTROL_BYTE DB ? 59 60 ; (no prior section) ; DATA ENDS 61 62 63 64 ;*** Define where the ROM routines are actually located 65 ;section ROM 66 67 ORG 02E1Eh 68 ROMCOMMAND PROC FAR 69 ROMCOMMAND ENDP 70 71 ORG 02E7Fh 72 ROMWAIT PROC FAR 73 ROMWAIT ENDP 74 75 ORG 02EE2h 76 ROMWAIT_DRQ PROC FAR 77 ROMWAIT_DRQ ENDP 78 79 ORG 02EF8h 80 ROMCHECK_STATUS PROC FAR 81 ROMCHECK_STATUS ENDP 82 83 ORG 02F69h 84 ROMCHECK_DMA PROC FAR 85 ROMCHECK_DMA ENDP 86 87 ORG 02F8Eh 88 ROMGET_VEC PROC FAR 89 ROMGET_VEC ENDP 90 91 ORG 0FF65h 92 ROMFRET PROC FAR ;Far return at F000:FF65 in AT ROM. 93 ROMFRET ENDP 94 95 ; (no prior section) ; ROM ENDS 96 97 === Switch to base=000000h -> "DOSENTRY" 98 section DOSENTRY align=1 PUBLIC class=DOSENTRY 99 100 EXTRN OLD13:DWORD ;Link to AT bios int 13h 101 102 PUBLIC IBM_DISK_IO 103 104 105 ASSUME CS:BIOCODE 106 ASSUME DS:DATA 107 108 109 ;*** IBM_DISK_IO - main routine, fixes AT ROM bug 110 ; 111 ; ENTRY: (AH) = function, 02 or 0A for read. 112 ; (DL) = drive number (80h or 81h). 113 ; (DH) = head number. 114 ; (CH) = cylinder number. 115 ; (CL) = Sector number (high 2 bits has cylinder number). 116 ; (AL) = number of sectors. 117 ; (ES:BX) = address of read buffer. 118 ; For more on register contents see ROM BIOS listing. 119 ; Stack set up for return by an IRET. 120 ; 121 ; EXIT: (AH) = status of current operation. 122 ; (CY) = 1 IF failed, 0 if successful. 123 ; For other register contents see ROM BIOS listing. 124 ; 125 ; USES: 126 ; 127 ; 128 ; WARNING: Uses OLD13 vector for non-read calls. 129 ; Does direct calls to the AT ROM. 130 ; Does segment arithmatic. 131 ; 132 ; EFFECTS: Performs DISK I/O operation. 133 ; 134 IBM_DISK_IO PROC FAR 0 000007A2 80FA80 CMP DL, 80h 0 000007A5 720A JB ATD1 ;Pass through floppy disk calls. 0 000007A7 80FC02 CMP AH, 02 0 000007AA 740A JE ATD2 ;Intercept call 02 (read sectors). 0 000007AC 80FC0A CMP AH, 0Ah 0 000007AF 7405 JE ATD2 ;and call 0Ah (read long). 141 ATD1: 0 000007B1 2EFF2E[0000] JMP far [cs:OLD13] ;Use ROM INT 13h handler. 143 ATD2: 0 000007B6 53 PUSH BX 0 000007B7 51 PUSH CX 0 000007B8 52 PUSH DX 0 000007B9 57 PUSH DI 0 000007BA 1E PUSH DS 0 000007BB 06 PUSH ES 0 000007BC 50 PUSH AX 0 000007BD B84000 MOV AX,BIOSEG ;Establish BIOS segment addressing. 0 000007C0 8ED8 MOV DS,AX 0 000007C2 C606740000 MOV byte [DISK_STATUS1], 0 ;Initially no error code. 0 000007C7 80E27F AND DL, 07fh ;Mask to hard disk number 0 000007CA 3A167500 CMP DL, [HF_NUM] 0 000007CE 7207 JB ATD3 ;Disk number in range 0 000007D0 C606740001 MOV byte [DISK_STATUS1], BAD_DISK 0 000007D5 EB20 JMP SHORT ATD4 ;Disk number out of range error, return 159 160 ATD3: 0 000007D7 53 PUSH BX 0 000007D8 8CC0 MOV AX, ES ;Make ES:BX to Seg:000x form. 0 000007DA C1EB04 SHR BX, 4 0 000007DD 01D8 ADD AX, BX 0 000007DF 8EC0 MOV ES, AX 0 000007E1 5B POP BX 0 000007E2 83E30F AND BX,000Fh 0 000007E5 0E PUSH CS 0 000007E6 E8DE00 CALL CHECK_DMA 0 000007E9 720C JC ATD4 ;Abort if DMA across segment boundary 171 0 000007EB 58 POP AX ;Restore AX register for SETCMD 0 000007EC 50 PUSH AX 0 000007ED E81A00 CALL SETCMD ;Set up command block for disk op 0 000007F0 BAF603 MOV DX, HF_REG_PORT 0 000007F3 EE OUT DX, AL ;Write out command modifier 0 000007F4 E86B00 CALL DOCMD ;Carry out command 178 ATD4: 179 ;; Old code - Carry cleared after set by logical or opearation 180 ;; POP AX 181 ;; MOV AH,DISK_STATUS1 ;On return AH has error code 182 ;; STC 183 ;; OR AH,AH 184 ;; JNZ ATD5 ;Carry set if error 185 ;; CLC 186 ;;--------------------------------------------------- 187 ;; New Code - Let Logical or clear carry and then set carry if ah!=0 188 ;; And save a couple bytes while were at it. 0 000007F7 58 POP AX 0 000007F8 8A267400 MOV AH,[DISK_STATUS1] ;On return AH has error code 0 000007FC 08E4 OR AH,AH 0 000007FE 7401 JZ ATD5 ;Carry set if error 0 00000800 F9 STC 194 195 ATD5: 0 00000801 07 POP ES 0 00000802 1F POP DS 0 00000803 5F POP DI 0 00000804 5A POP DX 0 00000805 59 POP CX 0 00000806 5B POP BX 0 00000807 CA0200 RET 2 ;Far return, dropping flags 203 IBM_DISK_IO ENDP 204 205 206 207 ;*** SETCMD - Set up CMD_BLOCK for the disk operation 208 ; 209 ; ENTRY: (DS) = BIOS Data segment. 210 ; (ES:BX) in seg:000x form. 211 ; Other registers as in INT 13h call 212 ; 213 ; EXIT: CMD_BLOCK set up for disk read call. 214 ; CONTROL_BYTE set up for disk operation. 215 ; (AL) = Control byte modifier 216 ; 217 ; 218 ; Sets the fields of CMD_BLOCK using the register contents 219 ; and the contents of the disk parameter block for the given drive. 220 ; 221 ; WARNING: (AX) destroyed. 222 ; Does direct calls to the AT ROM. 223 ; 224 SETCMD PROC NEAR 0 0000080A A24300 MOV [CMD_BLOCK + SEC_CNT], AL 0 0000080D C606480020 MOV byte [CMD_BLOCK + CMD_REG], 020h ;Assume function 02 0 00000812 80FC02 CMP AH, 2 0 00000815 7405 JE SETC1 ;CMD_REG = 20h if function 02 (read) 0 00000817 C606480022 MOV byte [CMD_BLOCK + CMD_REG], 022h ;CMD_REG = 22h if function 0A (" long) 230 SETC1: ;No longer need value in AX 0 0000081C 88C8 MOV AL, CL 0 0000081E 243F AND AL, 03fh ;Mask to sector number 0 00000820 A24400 MOV [CMD_BLOCK + SEC_NUM], AL 0 00000823 882E4500 MOV [CMD_BLOCK + CYL_LOW], CH 0 00000827 88C8 MOV AL, CL 0 00000829 C0E806 SHR AL, 6 ;Get two high bits of cylender number 0 0000082C A24600 MOV [CMD_BLOCK + CYL_HIGH], AL 0 0000082F 89D0 MOV AX, DX 0 00000831 C0E004 SHL AL, 4 ;Drive number 0 00000834 80E40F AND AH, 0Fh 0 00000837 08E0 OR AL, AH ;Head number 0 00000839 0CA0 OR AL, 0A0h ;Set ECC and 512 bytes per sector 0 0000083B A24700 MOV [CMD_BLOCK + DRV_HEAD], AL 0 0000083E 06 PUSH ES ;GET_VEC destroys ES:BX 0 0000083F 53 PUSH BX 0 00000840 0E PUSH CS 0 00000841 E85B00 CALL GET_VEC 0 00000844 268B4705 MOV AX, [ES:FDP_PRECOMP + BX] ;Write pre-comp from disk parameters 0 00000848 C1E802 SHR AX, 2 0 0000084B A24200 MOV [CMD_BLOCK + PRE_COMP],AL ;Only use low part 0 0000084E 268A4708 MOV AL, [ES:FDP_CONTROL + BX] ;Control byte modifier 0 00000852 5B POP BX 0 00000853 07 POP ES 0 00000854 8A267600 MOV AH, [CONTROL_BYTE] 0 00000858 80E4C0 AND AH, 0C0h ;Keep disable retry bits 0 0000085B 08C4 OR AH, AL 0 0000085D 88267600 MOV [CONTROL_BYTE], AH 0 00000861 C3 RET 259 SETCMD ENDP 260 261 262 263 ;*** DOCMD - Carry out READ operation to AT hard disk 264 ; 265 ; ENTRY: (ES:BX) = address for read in data. 266 ; CMD_BLOCK set up for disk read. 267 ; 268 ; EXIT: Buffer at (ES:BX) contains data read. 269 ; DISK_STATUS1 set to error code (0 if success). 270 ; 271 ; 272 ; 273 ; WARNING: (AX), (BL), (CX), (DX), (DI) destroyed. 274 ; No check is made for DMA boundary overrun. 275 ; 276 ; EFFECTS: Programs disk controller. 277 ; Performs disk input. 278 ; 279 DOCMD PROC NEAR 0 00000862 89DF MOV DI, BX ;(ES:DI) = data buffer addr. 0 00000864 0E PUSH CS 0 00000865 E83F00 CALL COMMAND 0 00000868 7534 JNZ DOC3 284 DOC1: 0 0000086A 0E PUSH CS 0 0000086B E84100 CALL WAITT ;Wait for controller to complete read 0 0000086E 752E JNZ DOC3 0 00000870 B90001 MOV CX, 100h ;256 words per sector 0 00000873 BAF001 MOV DX, HF_PORT 0 00000876 FC CLD ;String op goes up 0 00000877 FA CLI ;Disable interrupts (BUG WAS FORGETTING THIS) 0 00000878 F36D REPZ INSW ;Read in sector 0 0000087A FB STI 0 0000087B F606480002 TEST byte [CMD_BLOCK + CMD_REG], 02 0 00000880 7410 JZ DOC2 ;No ECC bytes to read. 0 00000882 0E PUSH CS 0 00000883 E83100 CALL WAIT_DRQ 0 00000886 7216 JC DOC3 0 00000888 B90400 MOV CX, 4 ;4 bytes of ECC 0 0000088B BAF001 MOV DX, HF_PORT 0 0000088E FA CLI 0 0000088F F36C REPZ INSB ;Read in ECC 0 00000891 FB STI 304 DOC2: 0 00000892 0E PUSH CS 0 00000893 E82900 CALL CHECK_STATUS 0 00000896 7506 JNZ DOC3 ;Operation failed 0 00000898 FE0E4300 DEC byte [CMD_BLOCK + SEC_CNT] 0 0000089C 75CC JNZ DOC1 ;Loop while more sectors to read 310 DOC3: 0 0000089E C3 RET 312 DOCMD ENDP 313 314 315 316 ;*** GET_VEC - Get pointer to hard disk parameters. 317 ; 318 ; ENTRY: (DL) = Low bit has hard disk number (0 or 1). 319 ; 320 ; EXIT: (ES:BX) = address of disk parameters table. 321 ; 322 ; USES: AX for segment computation. 323 ; 324 ; Loads ES:BX from interrupt table in low memory, vector 46h (disk 0) 325 ; or 70h (disk 1). 326 ; 327 ; WARNING: (AX) destroyed. 328 ; This does a direct call to the AT ROM. 329 ; 330 GET_VEC PROC NEAR 0 0000089F 6865FF PUSH OFFSET ROMFRET 0 000008A2 EA8E2F00F0 JMP ROMSEG:ROMGET_VEC 333 GET_VEC ENDP 334 335 336 337 ;*** COMMAND - Send contents of CMD_BLOCK to disk controller. 338 ; 339 ; ENTRY: Control_byte 340 ; CMD_BLOCK - set up with values for hard disk controller. 341 ; 342 ; EXIT: DISK_STATUS1 = Error code. 343 ; NZ if error, ZR for no error. 344 ; 345 ; 346 ; WARNING: (AX), (CX), (DX) destroyed. 347 ; Does a direct call to the AT ROM. 348 ; 349 ; EFFECTS: Programs disk controller. 350 ; 351 COMMAND PROC NEAR 0 000008A7 6865FF PUSH OFFSET ROMFRET 0 000008AA EA1E2E00F0 JMP ROMSEG:ROMCOMMAND 354 COMMAND ENDP 355 356 357 358 ;*** WAITT - Wait for disk interrupt 359 ; 360 ; ENTRY: Nothing. 361 ; 362 ; EXIT: DISK_STATUS1 = Error code. 363 ; NZ if error, ZR if no error. 364 ; 365 ; 366 ; WARNING: (AX), (BL), (CX) destroyed. 367 ; Does a direct call to the AT ROM. 368 ; 369 ; EFFECTS: Calls int 15h, function 9000h. 370 ; 371 WAITT PROC NEAR 0 000008AF 6865FF PUSH OFFSET ROMFRET 0 000008B2 EA7F2E00F0 JMP ROMSEG:ROMWAIT 374 WAITT ENDP 375 376 377 378 ;*** WAIT_DRQ - Wait for data request. 379 ; 380 ; ENTRY: Nothing. 381 ; 382 ; EXIT: DISK_STATUS1 = Error code. 383 ; CY if error, NC if no error. 384 ; 385 ; 386 ; WARNING: (AL), (CX), (DX) destroyed. 387 ; Does a direct call to the AT ROM. 388 ; 389 WAIT_DRQ PROC NEAR 0 000008B7 6865FF PUSH OFFSET ROMFRET 0 000008BA EAE22E00F0 JMP ROMSEG:ROMWAIT_DRQ 392 WAIT_DRQ ENDP 393 394 395 396 ;*** CHECK_STATUS - Check hard disk status. 397 ; 398 ; ENTRY: Nothing. 399 ; 400 ; EXIT: DISK_STATUS1 = Error code. 401 ; NZ if error, ZR if no error. 402 ; 403 ; 404 ; WARNING: (AX), (CX), (DX) destroyed. 405 ; Does a direct call to the AT ROM. 406 ; 407 CHECK_STATUS PROC NEAR 0 000008BF 6865FF PUSH OFFSET ROMFRET 0 000008C2 EAF82E00F0 JMP ROMSEG:ROMCHECK_STATUS 410 CHECK_STATUS ENDP 411 412 413 414 ;*** CHECK_DMA - check for DMA overrun 64k segment. 415 ; 416 ; ENTRY: (ES:BX) = addr. of memory buffer in seg:000x form. 417 ; CMD_BLOCK set up for operation. 418 ; 419 ; EXIT: DISK_STATUS1 - Error code. 420 ; CY if error, NC if no error. 421 ; 422 ; 423 ; WARNING: Does a direct call to the AT ROM. 424 ; 425 CHECK_DMA PROC NEAR 0 000008C7 6865FF PUSH OFFSET ROMFRET 0 000008CA EA692F00F0 JMP ROMSEG:ROMCHECK_DMA 428 CHECK_DMA ENDP 429 430 431 ; (no prior section) ; CODE ENDS 432 END === Trace listing source: msinit.lst 1 ; PAGE ,132 ; 2 %warning out: ...MSINIT.ASM 2 ****************** warning: out: ...MSINIT.ASM [-w+user] 3 ;======================================================= 4 ;REVISION HISTORY: 5 ;AN000; - NEW Version 4.00. J.K. 6 ;AC000; - Modified Line 4.00. J.K. 7 ;ANxxx; - PTMyyy 8 ;============================================================================== 9 ;AN001; P87 Set the value of MOTOR START TIME Variable 6/25/87 J.K. 10 ;AN002; P40 Boot from the system with no floppy diskette drives 6/26/87 J.K. 11 ;AN003; D9 Double Word MOV instruction for 386 based machine 7/1/87 J.K. 12 ;AN004; D64 Extend DOS 3.3 FAT tables to 64 K entries. 7/8/87 J.K. 13 ;AN005; D113 Disable I/O access to unformatted media 9/03/87 J.K. 14 ;AN006; p941 D113 does not implemented properly. 9/11/87 J.K. 15 ;AN007; p969 Should Honor OS2 boot record. 9/11/87 J.K. 16 ;AN008; p985 Allow I/O access to unformtted media 9/14/87 J.K. 17 ;AN009; p1535 Disallow I/O access to unformtted media 10/15/87 J.K. 18 ;AN010; p2349 Cover DOS 3.3 and below FDISK bug 11/10/87 J.K. 19 ;AN011; P2431 OS2 boot record version number is at offset 7 (not 8)11/12/87 J.K. 20 ;AN012; P2900 DOS 4.0 does not recognize 3.0 formatted media 12/18/87 J.K. 21 ;AN013; P3409 Extended keyboard not recognized 02/05/88 J.K. 22 ;AN014; D486 Share installation for big media 02/23/88 J.K. 23 ;AN015; P3929 Boot record buffer overlaps MSBIO code 03/18/88 J.K. 24 ;============================================================================== 25 26 itest equ 0 27 %include "msgroup.mac" ;DEFINE CODE SEGMENT 1 <1> EVBOUND equ 1 ;THIS VALUE BEING 0 DOES NO BOUNDARY ALLIGNMENT, VALUE 1 ;3.30 2 <1> ; ALIGNS TO EVEN ;3.30 3 <1> 4 <1> ; NASM original macros 5 <1> 6 <1> %include "dcodeseg.nas" 1 <2> 2 <2> %ifndef DCODESEGNAS 3 <2> %assign DCODESEGNAS 1 4 <2> === Switch to base=008400h -> "DOSCODETABLE" 5 <2> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <2> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=008400h -> "DOSCODECODE" 7 <2> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <2> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=008400h -> "DOSBIOCODE" 9 <2> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=008400h -> "BIOCODE" 10 <2> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <2> 12 <2> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <2> 14 <2> %endif 7 <1> 8 <1> %if EVBOUND ;;IF EVEN (WORD) ALLIGNMENT IS REQUESTED, ;3.30 9 <1> 10 <1> %imacro EVENB 0.nolist 11 <1> EVEN ;;ADJUST TO EVEN BOUNDARY 12 <1> %endmacro 13 <1> 14 <1> %imacro ODD 0.nolist 15 <1> %if (($ - $$) % 2) == 0 16 <1> db ? 17 <1> %endif 18 <1> %endmacro 19 <1> 20 <1> %else ;;SINCE EVEN ALLIGNMENT IS NOT DESIRED, JUST USE BYTE ALLI;3.30 GNMENT 21 <1> 22 <1> %imacro EVENB 0.nolist 23 <1> ;;REQUEST FOR WORD ALLIGNMENT DOES NOTHING ;3.30 24 <1> %endmacro 25 <1> 26 <1> %imacro ODD 0.nolist 27 <1> ;;REQUEST FOR ODD ALLIGNMENT DOES NOTHING ;3.30 28 <1> %endmacro 29 <1> 30 <1> %endif ;3.30 31 <1> 32 <1> %imacro CODE_SEGMENT 0.nolist === Switch to base=008400h -> "BIOCODE" 33 <1> section BIOCODE 34 <1> %endmacro 35 <1> 36 <1> ; end of NASM original macros 37 <1> 38 <1> CODE_SEGMENT ;3.30 39 <1> ASSUME CS:BIOCODE ;3.30 40 <1> ;3.30 28 %include "lmacros3.mac" 1 <1> [list -] 1 ****************** <1> warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi] 14 <2> [list -] 14 <1> [list -] 29 %include "lstruct.mac" 1 <1> [list -] 13 <1> [list -] 30 === Switch to base=001140h -> "DOSSTART" 31 addsection DOSSTART, align=16 PUBLIC class=DOSSTART 32 ; (no prior section) ; DOSSTART ENDS 33 === Switch to base=002530h -> "AFTERDOSDATA" 34 addsection AFTERDOSDATA, align=16 class=AFTERDOSDATA 35 ; (no prior section) ; AFTERDOSDATA ENDS 36 37 %include "entryseg.nas" 1 <1> === Switch to base=000000h -> "DOSENTRY" 2 <1> section DOSENTRY class=%[DOSENTRY] === Switch to base=000000h -> "DOSENTRY" 3 <1> section DOSENTRY 38 %include "dcodeseg.nas" 1 <1> 2 <1> %ifndef DCODESEGNAS 3 <1> %assign DCODESEGNAS 1 4 <1> === Switch to base=008400h -> "DOSCODETABLE" 5 <1> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <1> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=008400h -> "DOSCODECODE" 7 <1> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <1> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=008400h -> "DOSBIOCODE" 9 <1> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=008400h -> "BIOCODE" 10 <1> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <1> 12 <1> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <1> 14 <1> %endif 39 === Switch to base=008400h -> "BIOCODE" 40 addsection BIOCODE === Switch to base=000000h -> "DOSENTRY" 41 addsection DOSENTRY 42 43 %include "msdskpr.mac" 1 <1> ; The following structure defines the disk parameter table 2 <1> ; pointed to by Interrupt vector 1EH (location 0:78H) 3 <1> 4 <1> DISK_PARMS STRUC 0 000008D0 ?? DISK_SPECIFY_1 DB ? 0 000008D1 ?? DISK_SPECIFY_2 DB ? 0 000008D2 ?? DISK_MOTOR_WAIT DB ? ; Wait till motor off 0 000008D3 ?? DISK_SECTOR_SIZ DB ? ; Bytes/Sector (2 = 512) 0 000008D4 ?? DISK_EOT DB ? ; Sectors per track (MAX) 0 000008D5 ?? DISK_RW_GAP DB ? ; Read Write Gap 0 000008D6 ?? DISK_DTL DB ? 0 000008D7 ?? DISK_FORMT_GAP DB ? ; Format Gap Length 0 000008D8 ?? DISK_FILL DB ? ; Format Fill Byte 0 000008D9 ?? DISK_HEAD_STTL DB ? ; Head Settle Time (MSec) 0 000008DA ?? DISK_MOTOR_STRT DB ? ; Motor start delay 16 <1> DISK_PARMS ENDS 17 <1> 18 <1> ROMStatus equ 1 19 <1> ROMRead equ 2 20 <1> ROMWrite equ 3 21 <1> ROMVerify equ 4 22 <1> ROMFormat equ 5 44 %include "msequ.mac" 1 <1> %warning out: MSEQU.INC... 1 ****************** <1> warning: out: MSEQU.INC... [-w+user] 2 <1> ;============================================================================== 3 <1> 4 <1> FTOOBIG EQU 80H 5 <1> FBIG EQU 40H 6 <1> ROMSTATUS EQU 1 7 <1> ROMREAD EQU 2 8 <1> ROMWRITE EQU 3 9 <1> ROMVERIFY EQU 4 10 <1> ROMFORMAT EQU 5 11 <1> VID_SIZE EQU 12 12 <1> 13 <1> %include "msbds.mac" ; VARIOUS EQUATES FOR BDS 1 <2> 2 <2> %warning out: MSBDS.INC... 2 ****************** <2> warning: out: MSBDS.INC... [-w+user] 3 <2> ; SCCSID = @(#)IBMBDS.ASM 1.9 85/09/16 4 <2> ;============================================================================== 5 <2> ;REVISION HISTORY: 6 <2> ;AN000 - New for DOS Version 4.00 - J.K. 7 <2> ;AC000 - Changed for DOS Version 4.00 - J.K. 8 <2> ;AN00x - PTM number for DOS Version 4.00 - J.K. 9 <2> ;============================================================================== 10 <2> ;AN001; D113 Disable I/O access to unformatted media 9/03/87 J.K. 11 <2> ;============================================================================== 12 <2> 13 <2> ; VALUES FOR VARIOUS FLAGS IN BDS.FLAGS. 14 <2> 15 <2> FNON_REMOVABLE EQU 01H ;FOR NON-REMOVABLE MEDIA 16 <2> FCHANGELINE EQU 02H ;IF CHANGELINE SUPPORTED ON DRIVE 17 <2> RETURN_FAKE_BPB EQU 04H ; WHEN SET, DON'T DO A BUILD BPB 18 <2> ; JUST RETURN THE FAKE ONE 19 <2> GOOD_TRACKLAYOUT EQU 08H ; THE TRACK LAYOUT HAS NO FUNNY SECTORS 20 <2> ; FCHANGED_BY_FORMAT EQU 08H 21 <2> FI_AM_MULT EQU 10H ;IF MORE THAN ONE LOGICAL FOR THIS PHYSICAL 22 <2> FI_OWN_PHYSICAL EQU 20H ;SIGNIFY LOGICAL OWNER OF THIS PHYSICAL 23 <2> FCHANGED EQU 40H ;INDICATES MEDIA CHANGED 24 <2> SET_DASD_TRUE EQU 80H ; SET DASD BEFORE NEXT FORMAT 25 <2> FCHANGED_BY_FORMAT EQU 100H ;MEDIA CHANGED BY FORMAT 26 <2> UNFORMATTED_MEDIA EQU 200H ;AN001; Fixed disk only 27 <2> F_LBA equ 400h ; LBA supported 28 <2> 29 <2> LBAPACKETSTRUC struc 0 000008D0 ???? lpSize dw ? 0 000008D2 ???? lpCount dw ? 0 000008D4 ???????? lpBuffer dd ? 0 000008D8 ???????????????? lpSector dd ?,? 34 <2> LBAPACKETSTRUC ends 35 <2> 36 <2> ; 37 <2> ; VARIOUS FORM FACTORS TO DESCRIBE MEDIA 38 <2> ; 39 <2> FF48TPI EQU 0 40 <2> FF96TPI EQU 1 41 <2> FFSMALL EQU 2 42 <2> FFHARDFILE EQU 5 43 <2> FFOTHER EQU 7 44 <2> 45 <2> BDS_TYPE STRUC 0 000008D0 ???????? LINK DD ? ; LINK TO NEXT BDS 0 000008D4 ?? DRIVENUM DB ? ; INT 13 DRIVE NUMBER 0 000008D5 ?? DRIVELET DB ? ; DOS DRIVE NUMBER 0 000008D6 ???? BYTEPERSEC DW ? ; NUMBER OF BYTES/SEC 0 000008D8 ?? SECPERCLUS DB ? ; SEC PER ALLOCATION UNIT 0 000008D9 ???? RESSEC DW ? ; NUMBER OF RESERVED SECTORS 0 000008DB ?? CFAT DB ? ; NUMBER OF FATS 0 000008DC ???? CDIR DW ? ; NUMBER OF DIRECTORY ENTRIES 0 000008DE ???? DRVLIM DW ? ; NUMBER OF SECTORS ON MEDIUM 0 000008E0 ?? MEDIAD DB ? ; MEDIA DESCRIPTOR BYTE 0 000008E1 ???? CSECFAT DW ? ; NUMBER OF SECTORS/FAT 0 000008E3 ???? SECLIM DW ? ; SECTORS PER TRACK 0 000008E5 ???? HDLIM DW ? ; MAX NUMBER OF HEADS 0 000008E7 ???? HIDSEC_L DW ? ; NUMBER OF HIDDEN SECTORS 0 000008E9 ???? HIDSEC_H dw ? ;0 ;J.K.87 0 000008EB ???? DRVLIM_L dw ? ;0 ;J.K.87 0 000008ED ???? DRVLIM_H dw ? ;0 ;J.K.87 0 000008EF ?? FATSIZ DB ? ; FLAGS... 0 000008F0 ???? OPCNT DW ? ; OPEN REF. COUNT 0 000008F2 ?? FORMFACTOR DB ? ; FORM FACTOR INDEX 0 000008F3 ???? FLAGS DW ? ; VARIOUS FLAGS 0 000008F5 ???? CCYLN DW ? ; MAX NUMBER OF CYLINDERS 0 000008F7 ???? RBYTEPERSEC DW ? ; RECOMMENDED BPB 0 000008F9 ?? RSECPERCLUS DB ? 0 000008FA ???? RRESSEC DW ? 0 000008FC ?? RCFAT DB ? 0 000008FD ???? RCDIR DW ? 0 000008FF ???? RDRVLIM DW ? 0 00000901 ?? RMEDIAD DB ? 0 00000902 ???? RCSECFAT DW ? 0 00000904 ???? RSECLIM DW ? 0 00000906 ???? RHDLIM DW ? 0 00000908 ???? RHIDSEC_L DW ? 0 0000090A ???? RHIDSEC_H DW ? ;0 ;J.K.87 0 0000090C ???? RDRVLIM_L dw ? ;0 ;J.K.87 0 0000090E ???? RDRVLIM_H dw ? ;0 ;J.K.87 0 00000910 ???????????? RESERVE DB 6 DUP (?) ; RESERVED FOR FUTURE 0 00000916 ?? TRACK DB ? ; LAST TRACK ACCESSED ON DRIVE 0 00000917 ???? TIM_LO DW ? ; TIME OF LAST ACCESS. KEEP 0 00000919 ???? TIM_HI DW ? ; THESE CONTIGUOUS. 86 0000004B <2> VOLID DB 12 DUP (?) ; VOLUME ID OF MEDIUM 0 00000927 ???????? VOL_SERIAL dd ? ;0 ;J.K.87 Current volume serial number from Boot record 88 0000005B <2> FILESYS_Id db 9 dup (?) ;(0) ;J.K.87 Current file system id from Boot record 89 <2> BDS_TYPE ENDS 90 <2> 91 <2> BPBSIZE equ TRACK - RBYTEPERSEC ; SIZE IN BYTES OF RECBPB AREA IN THE BDS 92 <2> 93 <2> 94 <2> ;********************************************************************* 95 <2> ; BDS structure for mini disk - J.K. 4/7/86 96 <2> ;********************************************************************* 97 <2> 98 <2> BDSM_type struc 0 000008D0 ???? mlink DW ? ;-1 ;Link to next structure 0 000008D2 ???? DW ? 0 000008D4 ?? mdriveNum DB ? ;80 ;Int 13 Drive Number 0 000008D5 ?? mdriveLet DB ? ;3 ;Logical Drive Number 0 000008D6 ???? mBytePerSec DW ? ;512 0 000008D8 ?? mSecPerClus DB ? ;1 ;Sectors/allocation unit 0 000008D9 ???? mRESSEC DW ? ;1 ;Reserved sectors for DOS 0 000008DB ?? mcFAT DB ? ;2 ;No. of allocation tables 0 000008DC ???? mcDIR DW ? ;16 ;Number of directory entries 0 000008DE ???? mDRVLIM DW ? ;0 ;Number of sectors (at 512 bytes each) 0 000008E0 ?? mMediad DB ? ;11111000B ;Media descriptor 0 000008E1 ???? mcSecFat DW ? ;1 ;Number of FAT sectors 0 000008E3 ???? mSECLIM DW ? ;0 ;Sector limit 0 000008E5 ???? mHDLIM DW ? ;0 ;Head limit 0 000008E7 ???? mHIDSEC_L DW ? ;0 ;Hidden sector count 0 000008E9 ???? mHidsec_H dw ? ;0 ;J.K.87 0 000008EB ???? mDrvlim_L dw ? ;0 ;J.K.87 0 000008ED ???? mDrvlim_H dw ? ;0 ;J.K.87 0 000008EF ?? mFatSiz DB ? ;0 ;TRUE => bigfat 0 000008F0 ???? mOPCNT DW ? ;0 ;Open Ref. Count 0 000008F2 ?? mFormFactor DB ? ;3 ;Form Factor 0 000008F3 ???? mFLAGS DW ? ;0020H ;Various Flags 0 000008F5 ???? mcCyln dw ? ;40 ;max number of cylinders 122 00000027 <2> mRecBPB db 31 dup (?) ;(0) ;Recommended BPB for drive 0 00000916 ?? mTrack db ? ;-1 0 00000917 ???? IsMini dw ? ;1 ;Overlapping TIM_LOH 0 00000919 ???? Hidden_Trks dw ? ;0 ;Overlapping TIM_HIH 126 0000004B <2> mVOLID DB 11 dup (?) ;"NO NAME " ;Volume ID for this disk 0 00000926 ?? DB ? ;0 ;ASCIZII for "NO NAME " 0 00000927 ???????? mVol_Serial dd ? ;0 ;Current volume serial number from Boot record 0 0000092B ???????????????? mFileSys_Id db 8 dup (?) ;"FAT12 " ;Current file system id from Boot record 0 00000933 ?? db ? ;0 131 <2> 132 <2> BDSM_type ENDS 133 <2> ;****************************************************************************** 134 <2> Max_mini_dsk_num equ 23 ;J.K. 4/7/86 - max # of mini disk ibmbio can support 135 <2> ; 136 <2> 14 <1> 15 <1> ;AN000; Extended BPB structure. 16 <1> BPB_TYPE STRUC 0 000008D0 ???? SECSIZE DW ? 0 000008D2 ?? SECALL DB ? 0 000008D3 ???? RESNUM DW ? 0 000008D5 ?? FATNUM DB ? 0 000008D6 ???? DIRNUM DW ? 0 000008D8 ???? SECNUM DW ? 0 000008DA ?? FATID DB ? 0 000008DB ???? FATSIZE DW ? 0 000008DD ???? SLIM DW ? 0 000008DF ???? HLIM DW ? 0 000008E1 ???? HIDDEN_L DW ? 0 000008E3 ???? HIDDEN_H dw ? ;0 ;J.K. 0 000008E5 ???? SECNUM_L dw ? ;0 ;J.K. 0 000008E7 ???? SECNUM_H dw ? ;0 ;J.K. 31 <1> BPB_TYPE ENDS 32 <1> 33 <1> ;;;;;;;;;;; 34 <1> BOOT_SERIAL_SIZE equ 4 ;J.K. 35 <1> BOOT_VOLUME_LABEL_SIZE equ 11 ;J.K. 36 <1> BOOT_SYSTEM_ID_SIZE equ 8 ;J.K. 37 <1> EXT_BOOT_SIGNATURE equ 41 ;J.K. 38 <1> RSINIT equ 0A3H ;RS232 INITIALIZATION 39 <1> ;9600 BAUD:NO PARITY:1 STOP:8 BIT WORD 40 <1> LF equ 10 ;LINE FEED 41 <1> CR equ 13 ;CARRIAGE RETURN 42 <1> BACKSP equ 8 ;BACKSPACE 43 <1> BRKADR equ 1BH * 4 ;006C 1BH BREAK VECTOR ADDRESS 44 <1> TIMADR equ 1CH * 4 ;0070 1CH TIMER INTERRUPT 45 <1> DSKADR equ 1EH * 4 ;ADDRESS OF PTR TO DISK PARAMETERS 46 <1> SEC9 equ 522H ;ADDRESS OF DISK PARAMETERS 47 <1> HEADSETTLE equ SEC9+9 ; ARR 2.20 ADDRESS OF HEAD SETTLE TIME 48 <1> NORMSETTLE equ 15 ; ARR 2.20 NORMAL HEAD SETTLE 49 <1> SPEEDSETTLE equ 0 ; ARR 2.20 SPEED UP SETTLE TIME 50 <1> INITSPOT equ 534H ; ARR IBM WANTS 4 ZEROS HERE 51 <1> AKPORT equ 20H 52 <1> EOI equ 20H 53 <1> CMDLEN equ 0 ;LENGTH OF THIS COMMAND 54 <1> UNIT equ 1 ;SUB UNIT SPECIFIER 55 <1> CMD equ 2 ;COMMAND CODE 56 <1> STATUS equ 3 ;STATUS 57 <1> MEDIA equ 13 ;MEDIA DESCRIPTOR 58 <1> TRANS equ 14 ;TRANSFER ADDRESS 59 <1> COUNT equ 18 ;COUNT OF BLOCKS OR CHARACTERS 60 <1> START equ 20 ;FIRST BLOCK TO TRANSFER 61 <1> EXTRA equ 22 ;USUALLY A POINTER TO VOL ID FOR ERROR 15 62 <1> CHROUT equ 29H 63 <1> MAXERR equ 5 64 <1> LSTDRV equ 504H 65 <1> 66 <1> NOTBUSYSTATUS equ 10000000B ; NOT BUSY 67 <1> ACKSTATUS equ 01000000B ; ACKNOWLEDGE (FOR WHAT?) 68 <1> NOPAPERSTATUS equ 00100000B ; NO MORE PAPER 69 <1> SELECTEDSTATUS equ 00010000B ; THE PRINTER SAID IT WAS SELECTED 70 <1> IOERRSTATUS equ 00001000B ; SOME KINDA ERROR 71 <1> RESERVED equ 00000110B ; NOPS 72 <1> TIMEOUTSTATUS equ 00000001B ; TIME OUT. 73 <1> ERROR_UNKNOWN_MEDIA equ 7 ; FOR USE IN BUILD BPB CALL 74 <1> 75 <1> PATHGEN equ 1 45 %include "msmacro.mac" 1 <1> === Switch to base=008400h -> "BIOCODE" 2 <1> section BIOCODE 3 <1> ; 4 <1> ; This file contains three macros used in debugging the system. If the 5 <1> ; variable "itest" (in msbio.asm) is nonzero code is included in the 6 <1> ; modules to print debugging messages. The level of debugging is controlled 7 <1> ; by the value of the variable fTestBits in msbio.asm. Specific bits in 8 <1> ; the variable determine which messages to print. The equ's below tell 9 <1> ; which bits control which funcitons. For example the fifth bit 10 <1> ; cooresponds to disk activity (see fTestDisk equ below). 11 <1> ; 12 <1> ; The macros in the file are: 13 <1> ; 14 <1> ; message Prints an ascii string on the screen. 15 <1> ; Example usage: 16 <1> ; 17 <1> ; message fTestDisk, <"Start Disk Write", CR, LF> 18 <1> ; message fTestINIT, <"Begin BDS initialization"> 19 <1> ; 20 <1> ; 21 <1> ; MNUM Print the value in a register or memory location on 22 <1> ; the screen. Value is displayed in hex. 23 <1> ; Usage: 24 <1> ; MNUM bitpattern, valueLocation 25 <1> ; 26 <1> ; valueLocation is typically a regester: 27 <1> ; 28 <1> ; mnum fTestCom, AX 29 <1> ; mnum fTestDisk, DX 30 <1> ; 31 <1> ; ValueLocation can also be a memory location: 32 <1> ; 33 <1> ; mnum fTestINIT, Final_Dos_Location 34 <1> ; 35 <1> ; If no valueLocation is given the macro defaults to 36 <1> ; the BX register. 37 <1> ; 38 <1> ; ZWAIT Stops the program until any key is pressed. 39 <1> ; 40 <1> ; 41 <1> ; The three macros preserve all register values. If "test" is zero 42 <1> ; defined during assembly then the marco produce no code. 43 <1> ; 44 <1> 45 <1> %IF itest ;3.30 46 <1> EXTRN MSGOUT:NEAR,MSGNUM:NEAR ;3.30 47 <1> EXTRN NUMBUF:BYTE,DIGITS:BYTE,FTESTBITS:WORD ;3.30 48 <1> EXTRN DUMPBYTES:NEAR,OUTCHAR:NEAR,HEX_TO_ASCII:NEAR ;3.30 49 <1> 50 <1> 51 <1> fTestALL equ 1111111111111111b ; watch everything 52 <1> fTestHARD equ 0000000000000001b ; watch hard disk initialization 53 <1> fTest96 equ 0000000000000010b ; watch 96 tpi activity 54 <1> FTEST13 EQU 0000000000000100B ; WATCH INT 13 ACTIVITY ;3.30 55 <1> FTESTCOM EQU 0000000000001000B ; WATCH PACKET ACTIVITY ;3.30 56 <1> FTESTINIT EQU 0000000000010000B ; WATCH INITIALIZATION MESSAGES ;3.30 57 <1> FTESTDISK EQU 0000000000100000B ; WATCH DISK DEVICE DRIVER CALLS ;3.30 58 <1> FTESTCON EQU 0000000001000000B ; WATCH SYSTEM WAIT ACTIVITY IN CO;3.30 NSOLE 59 <1> FtestClock equ 0000000010000000b ; wathc clock device 5/2/86 ;3.30 60 <1> 61 <1> ; NASM original macros 62 <1> 63 <1> ; 64 <1> ; message macro -- see above for description 65 <1> ; 66 <1> 67 <1> %unimacro stripangles 2+.nolist 68 <1> 69 <1> %imacro stripangles 2+.nolist 70 <1> %defstr %%param %2 71 <1> %rep 16 72 <1> %substr %%opening %%param 1 73 <1> %ifidn %%opening, '<' 74 <1> %substr %%param %%param 2,-1 75 <1> %endif 76 <1> %endrep 77 <1> %rep 16 78 <1> %strlen %%length %%param 79 <1> %substr %%closing %%param %%length 80 <1> %ifidn %%closing, '>' 81 <1> %substr %%param %%param 1,-2 82 <1> %endif 83 <1> %endrep 84 <1> %deftok %%token %%param 85 <1> %1 %%token 86 <1> %endmacro 87 <1> 88 <1> %imacro MESSAGE 2+ 89 <1> jmp short %%b 90 <1> %%a: 91 <1> stripangles db, %2 92 <1> db 0 93 <1> %%b: push SI 94 <1> push AX 95 <1> mov AX, %1 96 <1> mov SI, OFFSET %%a 97 <1> call MSGOUT 98 <1> pop AX 99 <1> pop SI 100 <1> %endmacro 101 <1> 102 <1> 103 <1> ; 104 <1> ; mnum macro -- see above for description 105 <1> ; 106 <1> 107 <1> %imacro MNum 1-2 108 <1> push AX 109 <1> %ifempty %2 110 <1> mov AX,%1 111 <1> call MSGNUM 112 <1> %else 113 <1> push BX 114 <1> mov BX,%2 115 <1> mov AX,%1 116 <1> call MSGNUM 117 <1> pop BX 118 <1> %endif 119 <1> pop AX 120 <1> %endmacro 121 <1> 122 <1> 123 <1> ; 124 <1> ; zwait macro -- see above for description 125 <1> ; 126 <1> 127 <1> %imacro ZWAIT 0 128 <1> Message fTestALL,<"? "> 129 <1> CALL ZWAITrtn 130 <1> %endmacro 131 <1> 132 <1> ZWAITrtn: 133 <1> pushf ; save the flags 134 <1> push AX ; preserve AX 135 <1> xor AH, AH ; set command to get character ;3.30* 136 <1> int 16h ; call rom keyboard routine ;3.30* 137 <1> pop AX ; restore AX 138 <1> popf ; restore the flags 139 <1> ret 140 <1> 141 <1> ;Dump_byte dumps the memory contents in hex. ;3.30 142 <1> ;DUMPOFFLABEL should be a label or a variable defined in DUMPSEG. ;3.30 143 <1> %imacro DUMP_BYTE 3 144 <1> push es ;3.30 145 <1> PUSH DS ;3.30 146 <1> PUSH SI ;3.30 147 <1> PUSH CX ;3.30 148 <1> ;3.30 149 <1> MOV CX, %1 ;3.30 150 <1> MOV DS, CX ;3.30 151 <1> MOV SI, OFFSET %2 ;3.30 152 <1> MOV CX, %3 ;3.30 153 <1> call dumpbytes ;3.30 154 <1> ;3.30 155 <1> POP CX ;3.30 156 <1> POP SI ;3.30 157 <1> POP DS ;3.30 158 <1> pop es ;3.30 159 <1> %endmacro ;3.30 160 <1> ;3.30 161 <1> ;Dump_Byte_Reg dumps the memory contents in hex. - 4/9/86 ;3.30 162 <1> ;DUMPOFFREG should be a register contains the offset value in DUMPSEG. ;3.30 163 <1> %imacro DUMP_BYTE_REG 3 164 <1> DUMP_BYTE_REG MACRO DUMPSEG, DUMPOFFREG, BYTELENGTH ;3.30 165 <1> push es ;3.30 166 <1> PUSH DS ;3.30 167 <1> PUSH SI ;3.30 168 <1> PUSH CX ;3.30 169 <1> ;3.30 170 <1> MOV CX, %1 ;3.30 171 <1> MOV DS, CX ;3.30 172 <1> MOV SI, %2 ;3.30 173 <1> MOV CX, %3 ;3.30 174 <1> call dumpbytes ;3.30 175 <1> ;3.30 176 <1> POP CX ;3.30 177 <1> POP SI ;3.30 178 <1> POP DS ;3.30 179 <1> pop es ;3.30 180 <1> %endmacro ;3.30 181 <1> 182 <1> %else 183 <1> ; if test is not defined then make macro into null statements 184 <1> %imacro Message 0-1+.nolist 185 <1> %endmacro 186 <1> 187 <1> %imacro MNUM 0-1+.nolist 188 <1> %endmacro 189 <1> 190 <1> %imacro ZWAIT 0-1+.nolist 191 <1> %endmacro 192 <1> 193 <1> %imacro DUMP_BYTE 0-1+.nolist 194 <1> %endmacro 195 <1> 196 <1> %imacro DUMP_BYTE_REG 0-1+.nolist 197 <1> %endmacro 198 <1> 199 <1> %endif 200 <1> 201 <1> %unimacro PATHSTART 2 202 <1> %unimacro PATHEND 2 203 <1> 204 <1> %imacro PATHSTART 2 205 <1> %IF PATHGEN ;3.30 206 <1> PUBLIC %2%1S,%2%1E ;3.30 207 <1> %2%1S LABEL BYTE ;3.30 208 <1> %ENDIF ;3.30 209 <1> %endmacro ;3.30 210 <1> ;3.30 211 <1> %imacro PATHEND 2 212 <1> %IF PATHGEN ;3.30 213 <1> %2%1E LABEL BYTE ;3.30 214 <1> %ENDIF ;3.30 215 <1> %endmacro ;3.30 46 %include "msextrn.mac" 1 <1> === Switch to base=008400h -> "BIOCODE" 2 <1> section BIOCODE 3 <1> ; SCCSID = @(#)IBMEXTRN.ASM 1.11 85/11/18 4 <1> ;This is for IBMINIT module. 5 <1> ;======================================================= 6 <1> ;REVISION HISTORY: 7 <1> ;AN000; - NEW Version 4.00. J.K. 8 <1> ;AC000; - Modified Line 4.00. J.K. 9 <1> ;ANxxx; - PTMyyy 10 <1> ;============================================================================== 11 <1> ;AN001; D486 SHARE installation for large media 2/23/88 J.K. 12 <1> ;============================================================================== 13 <1> 14 <1> extern biocode_get_ds_dosentry, biocode_get_es_dosentry 15 <1> extern dosbiocode_get_ds_dosentry, dosbiocode_get_es_dosentry 16 <1> EXTRN ORIG13:DWORD,ORIG19:DWORD 17 <1> EXTRN COM2DEV:WORD,COM1DEV:WORD 18 <1> EXTRN COM4DEV:WORD,COM3DEV:WORD 19 <1> EXTRN LPT3DEV:WORD,LPT2DEV:WORD,LPT1DEV:WORD 20 <1> EXTRN HARDDRV:BYTE,HARDNUM:BYTE,DRVMAX:BYTE,HDSKTAB:WORD 21 <1> EXTRN DSKDRVS:WORD,HNUM:BYTE,EOT:BYTE,FHAVE96:BYTE 22 <1> EXTRN REAL13:DWORD,DAYCNT:WORD,CONHEADER:WORD 23 <1> EXTRN TWOHARD:BYTE,INT_2F_NEXT:DWORD 24 <1> EXTRN BDSH:WORD,BDSX:WORD,START_BDS:WORD 25 <1> EXTRN FHAVEK09:BYTE, NEW_ROM:BYTE 26 <1> EXTRN SINGLE:BYTE 27 <1> EXTRN BDSMs:BYTE ;for Mini Disk -J.K. 4/7/86 28 <1> EXTRN HaveCMOSClock:byte ;set by IBMINIT. Used by IBMCLOCK.ASM 29 <1> EXTRN BinToBCD:word ;set by IBMINIT. Used by IBMCLOCK.ASM 30 <1> EXTRN DaycntToDay:word ;set by IBMINIT. Used by IBMCLOCK.ASM 31 <1> EXTRN OLD13:DWORD 32 <1> extrn Temp_H:word ;J.K. For 32 bit calculation. IBMDISK 33 <1> extrn Start_Sec_H:word ;J.K. IBMDISK. 34 <1> extrn KEYRD_Func:byte ;J.K. For IBMCON. Defined in IBMBDATA. 35 <1> extrn KEYSTS_Func:byte ;J.K. For IBMCON. Defined in IBMBDATA. 36 <1> extrn DiskSector:byte ;J.K. IBMBDATA 37 <1> extrn Bpb_In_Sector:word ;J.K. IBMBDATA 38 <1> extrn SecPerClusInSector:Byte ;J.K. IBMBDATA 39 <1> extrn NumberOfFats:byte ;J.K. IBMBDATA 40 <1> extrn MediaByte:byte ;J.K. IBMBDATA 41 <1> extrn Ext_Boot_Sig:Byte ;J.K. IBMBDATA 42 <1> extrn Boot_Serial_L:Word ;J.K. IBMBDATA 43 <1> extrn Boot_Serial_H:Word ;J.K. IBMBDATA 44 <1> extrn Boot_Volume_Label:Byte ;J.K. IBMBDATA 45 <1> extrn Boot_System_ID:Byte ;J.K. IBMBDATA 46 <1> extrn Fat_12_ID:Byte ;J.K. IBMDISK 47 <1> extrn Fat_16_ID:Byte ;J.K. IBMDISK 48 <1> extrn lbapacket:byte 49 <1> extrn Vol_No_Name:Byte ;J.K. IBMDISK 50 <1> extrn MOTORSTARTUP:Byte ;J.K. IBMBDATA 51 <1> extrn DoubleWordMov:Byte ;J.K. IBMDISK 52 <1> extrn Model_Byte:Byte ;J.K. IBMBIO2 53 <1> extrn Secondary_Model_Byte:Byte ;J.K. IBMBIO2 54 <1> 55 <1> %IF itest 56 <1> EXTRN NUMBUF:BYTE,DIGITS:BYTE,FTESTBITS:WORD 57 <1> %ENDIF 58 <1> 59 <1> EXTRN START$:NEAR,ERROUT:NEAR,BLOCK13:FAR,INT19:FAR 60 <1> EXTRN INTRET:NEAR,HDRIVE:NEAR,DRIVEX:NEAR,INT13:FAR,CBREAK:NEAR,OUTCHR:NEAR 61 <1> EXTRN DISKRD:NEAR,MEDIA_PATCH:NEAR,GETBP1_PATCH:NEAR 62 <1> EXTRN SET_PATCH:NEAR,DISKIO_PATCH:NEAR,DSKERR:NEAR,INIT_PATCH:NEAR 63 <1> extern DSKERR_PATCH 64 <1> EXTRN TABLE_PATCH:NEAR,EXIT:NEAR,CHANGED_PATCH:NEAR 65 <1> EXTRN ERRIN:NEAR,GETBP:NEAR,SWPDSK:NEAR 66 <1> EXTRN OUTCHR:NEAR,WRMSG:NEAR,TIME_TO_TICKS:NEAR 67 <1> EXTRN INT2F_DISK:NEAR,INSTALL_BDS:NEAR,SETDRIVE:NEAR 68 <1> extrn Mov_Media_IDs:Near ;J.K. 69 <1> extrn Clear_IDs:Near ;J.K. 70 <1> %IF itest 71 <1> EXTRN MSGNUM:NEAR,MSGOUT:NEAR,dumpbytes:near,hex_to_ascii:near 72 <1> EXTRN outchar:near 73 <1> %ENDIF 74 <1> extrn lbatochs:near, chstotuple:near 75 <1> extrn lba_packet_setup:near 76 <1> === Switch to base=002530h -> "SYSINITSEG" 77 <1> section SYSINITSEG PUBLIC class=INIT 78 <1> ASSUME CS:SYSINITSEG 79 <1> EXTRN CURRENT_DOS_LOCATION:WORD 80 <1> EXTRN FINAL_DOS_LOCATION:WORD 81 <1> extrn dos_size:word 82 <1> EXTRN DEVICE_LIST:DWORD 83 <1> EXTRN MEMORY_SIZE:WORD 84 <1> EXTRN DEFAULT_DRIVE:BYTE 85 <1> EXTRN BUFFERS:WORD 86 <1> EXTRN SYSINIT:FAR 87 <1> extrn Big_Media_Flag:Byte ;AN001; 88 <1> ; (no prior section) ; SYSINITSEG ENDS === Switch to base=008400h -> "BIOCODE" 89 <1> section BIOCODE 90 <1> 91 <1> ASSUME CS:BIOCODE 92 <1> 93 <1> ; END OF DISK MODULES FOR CONFIGURATION 94 <1> 95 <1> EXTRN END96TPI:BYTE 96 <1> EXTRN ENDTWOHARD:BYTE 97 <1> EXTRN ENDONEHARD:BYTE 98 <1> EXTRN ENDSWAP:BYTE 99 <1> EXTRN ENDFLOPPY:BYTE 100 <1> 101 <1> ; IBM FIXED UP AT ROM 102 <1> 103 <1> EXTRN IBM_DISK_IO:FAR 47 %include "biostruc.mac" 1 <1> %warning out: BIOSTRUC.INC... 1 ****************** <1> warning: out: BIOSTRUC.INC... [-w+user] 2 <1> ; SCCSID = @(#)BIOSTRUC.INC 1.0 86/09/30 3 <1> ; ROM BIOS CALL PACKET STRUCTURES 4 <1> 5 <1> ;******************************* 6 <1> ;System Service call ( Int 15h ) 7 <1> ;******************************* 8 <1> ;Function AH = 0C0h, Return system configuration 9 <1> ;For PC and PCJR on return: 10 <1> ; (AH) = 80h 11 <1> ; (CY) = 1 12 <1> ;For PCXT, PC PORTABLE and PCAT on return: 13 <1> ; (AH) = 86h 14 <1> ; (CY) = 1 15 <1> ;For all others: 16 <1> ; (AH) = 0 17 <1> ; (CY) = 0 18 <1> ; (ES:BX) = pointer to system descriptor vector in ROS 19 <1> ; System descriptor : 20 <1> ; DW xxxx length of descriptor in bytes, 21 <1> ; minimum length = 8 22 <1> ; DB xx model byte 23 <1> ; 0FFh = PC 24 <1> ; 0FEh = PC/XT, Portable 25 <1> ; 0FDh = PC/JR 26 <1> ; 0FCh = PC/AT, 6Mhz PC/AT, 27 <1> ; 6Mhz PC/AT running coprocessor(?), 28 <1> ; PS/2 Model 50, 50 z 29 <1> ; 0FAh = PS/2 Model 25, 30 30 <1> ; 0F9h = PC Convertible 31 <1> ; 0F8h = PS/2 Model 80 32 <1> ; 0F7h = Nova 33 <1> ; 0E0 thru 0EFh = reserved 34 <1> ; 35 <1> ; DB xx secondary model byte 36 <1> ; 000h = PC1 37 <1> ; 000h = PC/XT, Portable 38 <1> ; 000h = PC/JR 39 <1> ; 000h = PC/AT 40 <1> ; 001h = 6Mhz PC/AT 41 <1> ; 003h = 6Mhz PC/AT running coprocessor(?) 42 <1> ; 004h = PS/2 Model 50, 50z 43 <1> ; 001h = PS/2 Model 25 44 <1> ; 000h = PC Convertible 45 <1> ; 000h = PS/2 Model 80 46 <1> ; 000h = Nova 47 <1> ; 48 <1> ; DB xx bios revision level 49 <1> ; 00 for first release, subsequent release 50 <1> ; of code with same model byte and 51 <1> ; secondary model byte require revison level 52 <1> ; to increase by one. 53 <1> ; 54 <1> ; DB xx feature information byte 1 55 <1> ; X0000000 = 1, bios use DMA channel 3 56 <1> ; = 0, DMA channel 3 not used 57 <1> ; 58 <1> ; 0X000000 = 1, 2nd Interrupt chip present 59 <1> ; = 0, 2nd Interrupt chip not present 60 <1> ; 61 <1> ; 00X00000 = 1, Real Time Clock present 62 <1> ; = 0, Real Time Clock not present 63 <1> ; 64 <1> ; 000X0000 = 1, Keyboard escape sequence(INT15h) 65 <1> ; called in keyboard interrupt 66 <1> ; (Int 09h). 67 <1> ; = 0, Keyboard escape sequence not 68 <1> ; called. 69 <1> ; 0000XXXX reserved 70 <1> ; 71 <1> ; DB xx feature information byte 2 - reserved 72 <1> ; 73 <1> ; DB xx feature information byte 2 - reserved 74 <1> ; 75 <1> ; DB xx feature information byte 2 - reserved 76 <1> ; 77 <1> ; DB xx feature information byte 2 - reserved 78 <1> ; 79 <1> 80 <1> BIOS_SYSTEM_DESCRIPTOR struc 0 000097E6 ???? bios_SD_leng dw ? 0 000097E8 ?? bios_SD_modelbyte db ? 0 000097E9 ?? bios_SD_scnd_modelbyte db ? 0 000097EA ?? db ? 0 000097EB ?? bios_SD_featurebyte1 db ? 0 000097EC ???????? db 4 dup (?) 87 <1> BIOS_SYSTEM_DESCRIPTOR ends 88 <1> 89 <1> ;FeatureByte1 bit map equates 90 <1> DMAchannel3 equ 10000000b 91 <1> ScndIntController equ 01000000b 92 <1> RealTimeClock equ 00100000b 93 <1> KeyEscapeSeq equ 00010000b 94 <1> ; 95 <1> ;Model Byte 96 <1> MDL_PC1 EQU 0FFH 97 <1> MDL_XT EQU 0FEH 98 <1> MDL_JR EQU 0FDH 99 <1> MDL_AT EQU 0FCH 100 <1> MDL_CONVERT EQU 0F9H 101 <1> 102 <1> mdl_ps2_30 equ 0fah 103 <1> mdl_ps2_80 equ 0f8h 48 %include "cmosequ.mac" 1 <1> ;;Rev 3.30 Modification 2 <1> ;Equates for CMOS. 3 <1> 4 <1> ;---------------------------------------- 5 <1> ; CMOS EQUATES FOR THIS SYSTEM : 6 <1> ;------------------------------------------------------------------------------- 7 <1> CMOS_PORT EQU 070H ; I/O ADDRESS OF CMOS ADDRESS PORT 8 <1> CMOS_DATA EQU 071H ; I/O ADDRESS OF CMOS DATA PORT 9 <1> NMI EQU 10000000B ; DISABLE NMI INTERRUPTS MASK - 10 <1> ; HIGH BIT OF CMOS LOCATION ADDRESS 11 <1> 12 <1> ;---------- CMOS TABLE LOCATION ADDRESS'S ## ----------------------------------- 13 <1> CMOS_SECONDS EQU 000H ; SECONDS 14 <1> CMOS_SEC_ALARM EQU 001H ; SECONDS ALARM ## NOTE: ALL LOCATIONS 15 <1> CMOS_MINUTES EQU 002H ; MINUTES | IN THE CMOS AREA 16 <1> CMOS_MIN_ALARM EQU 003H ; MINUTES ALARM | ARE IBM USE ONLY 17 <1> CMOS_HOURS EQU 004H ; HOURS | AND SUBJECT TO 18 <1> CMOS_HR_ALARM EQU 005H ; HOURS ALARM | CHANGE. ONLY THE 19 <1> CMOS_DAY_WEEK EQU 006H ; DAY OF THE WEEK | POST & BIOS CODE 20 <1> CMOS_DAY_MONTH EQU 007H ; DAY OF THE MONTH | SHOULD DIRECTLY 21 <1> CMOS_MONTH EQU 008H ; MONTH | ACCESS LOCATIONS 22 <1> CMOS_YEAR EQU 009H ; YEAR (TWO DIGITS) | IN CMOS STORAGE. 23 <1> CMOS_REG_A EQU 00AH ; STATUS REGISTER A '----------------- 24 <1> CMOS_REG_B EQU 00BH ; STATUS REGISTER B ALARM 25 <1> CMOS_REG_C EQU 00CH ; STATUS REGISTER C FLAGS 26 <1> CMOS_REG_D EQU 00DH ; STATUS REGISTER D BATTERY 27 <1> CMOS_DIAG EQU 00EH ; POST DIAGNOSTIC STATUS RESULTS BYTE 28 <1> CMOS_SHUT_DOWN EQU 00FH ; SHUTDOWN STATUS COMMAND BYTE 29 <1> CMOS_DISKETTE EQU 010H ; DISKETTE DRIVE TYPE BYTE ; 30 <1> ; EQU 011H ; - RESERVED ;C 31 <1> CMOS_DISK EQU 012H ; FIXED DISK TYPE BYTE ;H 32 <1> ; EQU 013H ; - RESERVED ;E 33 <1> CMOS_EQUIP EQU 014H ; EQUIPMENT WORD LOW BYTE ;C 34 <1> CMOS_B_M_S_LO EQU 015H ; BASE MEMORY SIZE - LOW BYTE (X1024) ;K 35 <1> CMOS_B_M_S_HI EQU 016H ; BASE MEMORY SIZE - HIGH BYTE ;S 36 <1> CMOS_E_M_S_LO EQU 017H ; EXPANSION MEMORY SIZE - LOW BYTE ;U 37 <1> CMOS_E_M_S_HI EQU 018H ; EXPANSION MEMORY SIZE - HIGH BYTE ;M 38 <1> CMOS_DISK_1 EQU 019H ; FIXED DISK TYPE - DRIVE C EXTENSION ;E 39 <1> CMOS_DISK_2 EQU 01AH ; FIXED DISK TYPE - DRIVE D EXTENSION ;D 40 <1> ; EQU 01BH ; - 1BH THROUGH 2DH - RESERVED ; 41 <1> CMOS_CKSUM_HI EQU 02EH ; CMOS CHECKSUM - HIGH BYTE ;* 42 <1> CMOS_CKSUM_LO EQU 02FH ; CMOS CHECKSUM - LOW BYTE ;* 43 <1> CMOS_U_M_S_LO EQU 030H ; USABLE MEMORY ABOVE 1 MEG - LOW BYTE 44 <1> CMOS_U_M_S_HI EQU 031H ; USABLE MEMORY ABOVE 1 MEG - HIGH BYTE 45 <1> CMOS_CENTURY EQU 032H ; DATE CENTURY BYTE (BCD) 46 <1> CMOS_INFO128 EQU 033H ; 128KB INFORMATION STATUS FLAG BYTE 47 <1> ; EQU 034H ; - 34H THROUGH 3FH - RESERVED 48 <1> ; 49 <1> ;;End of Modification 50 <1> 49 %include "cputype.mac" 1 <1> ; Note: this must be a macro, and not a subroutine in the BIOS since 2 <1> ; it is called from both CODE and SYSINITSEG. 3 <1> ; 4 <1> ;------GET_CPU_TYPE------------------------------------------------------------May, 88 by MW 5 <1> ; Returns: AX = 0 if 8086 or 8088 6 <1> ; = 1 if 80286 7 <1> ; = 2 if 80386 8 <1> ; 9 <1> %macro Get_CPU_Type 0 10 <1> pushf 11 <1> push bx ; preserve bx 12 <1> xor bx, bx ; init bx to zero 13 <1> 14 <1> xor ax,ax ; 0000 into AX 15 <1> push ax ; put it on the stack... 16 <1> popf ; ...then shove it into the flags 17 <1> pushf ; get it back out of the flags... 18 <1> pop ax ; ...and into ax 19 <1> and ax,0F000h ; mask off high four bits 20 <1> cmp ax,0F000h ; was it all 1's? 21 <1> je cpu_8086 ; aye; it's an 8086 or 8088 22 <1> 23 <1> mov ax,0F000h ; now try to set the high four bits.. 24 <1> push ax 25 <1> popf 26 <1> pushf 27 <1> pop ax ; ...and see what happens 28 <1> and ax,0F000h ; any high bits set ? 29 <1> jz cpu_286 ; nay; it's an 80286 30 <1> 31 <1> cpu_386: ; bx starts as zero 32 <1> inc bx ; inc twice if 386 33 <1> cpu_286: ; just inc once if 286 34 <1> inc bx 35 <1> cpu_8086: ; don't inc at all if 086 36 <1> mov ax, bx ; put CPU type value in ax 37 <1> pop bx ; restore original bx 38 <1> popf 39 <1> %endmacro 50 %include "arena.mac" 1 <1> ; SCCSID = @(#)arena.asm 1.1 85/04/09 2 <1> ;BREAK 3 <1> 4 <1> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 5 <1> ; C A V E A T P R O G R A M M E R ; 6 <1> ; ; 7 <1> ; 8 <1> ; arena item 9 <1> ; 10 <1> arena STRUC 0 000097E6 ?? arena_signature DB ? ; 4D for valid item, 5A for last item 0 000097E7 ???? arena_owner DW ? ; owner of arena item 0 000097E9 ???? arena_size DW ? ; size in paragraphs of item 0 000097EB ?????? arena_reserved DB 3 DUP(?) ; reserved 0 000097EE ???????????????? arena_name DB 8 DUP(?) ; owner file name 16 <1> arena ENDS 17 <1> 18 <1> ; 19 <1> ; CAUTION: The routines in ALLOC.ASM rely on the fact that arena_signature 20 <1> ; and arena_owner_system are all equal to zero and are contained in DI. Change 21 <1> ; them and change ALLOC.ASM. 22 <1> 23 <1> arena_owner_system EQU 0 ; free block indication 24 <1> 25 <1> arena_signature_normal EQU 4Dh ; valid signature, not end of arena 26 <1> arena_signature_end EQU 5Ah ; valid signature, last block in arena 27 <1> ; ; 28 <1> ; C A V E A T P R O G R A M M E R ; 29 <1> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 30 <1> 31 <1> 51 === Switch to base=000000h -> "DOSENTRY" 52 usesection DOSENTRY 53 54 ; For lDOS lCFG block 55 LCFG_CheckDebugger equ 20 56 LCFG_DBG_CHECK equ 1 ; flag: check debugger present, run int3 57 LCFG_DBG_ASSUME equ 2 ; flag: default to assume debugger present 58 LCFG_DBG_ONLY_VALID equ 4 59 LCFG_DBG_ONLY_IISP equ 8 60 ; For the FreeDOS kernel the CONFIG block CheckDebugger value is 61 ; as yet used as an ordinal: < 1, == 1, or > 1. However, we use 62 ; ours here as 8 independent flags that can be set individually. 63 64 ; THE FOLLOWING LABEL DEFINES THE END OF THE AT ROM PATCH. THIS IS USED AT 65 ; CONFIGURATION TIME. 66 ;J.K. 10/2/86 Waring!!! This code will be dynamically relocated by MSINIT. 67 68 PUBLIC ENDATROM ;NOT REFERENCES EXTERNALLY, BUT 69 ; JUST TO CAUSE ENTRY IN LINK MAP 70 ENDATROM LABEL BYTE 71 72 ;CMOS Clock setting support routines used by MSCLOCK. 73 ;J.K. 10/2/86 Waring!!! This code will be dynamically relocated by MSINIT. 74 75 EXTRN base_century:byte 76 EXTRN base_year:byte 77 EXTRN month_tab:byte 78 79 public Daycnt_to_day ;J.K. 4/30/86 for real time clock support 80 Daycnt_to_day proc far ;J.K. 4/30/86 for real time clock support 81 ;Entry: [DAYCNT] = number of days since 1-1-80 82 ;Return: CH - centry in BCD, CL - year in BCD, DH - month in BCD, DL - day in BCD 83 84 daycnt equ DAYCNT ; NASM port label 0 000008D0 2EFF36[0000] push word [cs:daycnt] ;save daycnt 0 000008D5 2E813E[0000]891C cmp word [cs:daycnt], (365*20+(20/4)) ;# of days from 1-1-1980 to 1-1-2000 0 000008DC 730F jae century20 0 000008DE 2EC606[0000]13 mov byte [cs:base_century], 19 0 000008E4 2EC606[0000]50 mov byte [cs:base_year], 80 0 000008EA EB14 jmp years 0 000008EC 90 nop ; identicalise 92 century20: ;20th century 0 000008ED 2EC606[0000]14 mov byte [cs:base_century], 20 0 000008F3 2EC606[0000]00 mov byte [cs:base_year], 0 0 000008F9 2E812E[0000]891C sub word [cs:daycnt], (365*20+(20/4)) ;adjust daycnt 96 years: 0 00000900 31D2 xor dx, dx 0 00000902 2EA1[0000] mov ax, [cs:daycnt] 0 00000906 BBB505 mov bx, (366+365*3) ;# of days in a Leap year block 0 00000909 F7F3 div bx ;AX = # of leap block, DX = daycnt 0 0000090B 2E8916[0000] mov [cs:daycnt], dx ;save daycnt left 102 ; or ah, ah ;ax should be less than 256 103 ; jz OK1 104 ; jmp Erroroccur 105 ;OK1: 0 00000910 B304 mov bl,4 0 00000912 F6E3 mul bl ;AX = # of years. Less than 100 years! 0 00000914 2E0006[0000] add [cs:base_year], al ;So, ah = 0. Adjust year accordingly. 0 00000919 2EFF06[0000] inc word [cs:daycnt] ;set daycnt to 1 base 0 0000091E 2E813E[0000]6E01 cmp word [cs:daycnt], 366 ;the daycnt here is the remainder of the leap year block. 0 00000925 7626 jbe Leapyear ;So, it should within 366+355+355+355 days. 0 00000927 2EFE06[0000] inc byte [cs:base_year] ;First if daycnt <= 366, then leap year 0 0000092C 2E812E[0000]6E01 sub word [cs:daycnt], 366 ;else daycnt--, base_year++; 114 ;And the next three years are regular years. 0 00000933 B90300 mov cx, 3 116 Regularyear: 0 00000936 2E813E[0000]6D01 cmp word [cs:daycnt], 365 ;for(i=1; i>3 or daycnt <=365;i++) 118 YearDone equ Yeardone ; NASM port label 0 0000093D 7614 jbe YearDone ;{if (daycnt > 365) 0 0000093F 2EFE06[0000] inc byte [cs:base_year] ; { daycnt -= 365 0 00000944 2E812E[0000]6D01 sub word [cs:daycnt], 365 ; } 122 regularyear equ Regularyear ; NASM port label 0 0000094B E2E9 loop regularyear ;} 124 ; jmp Erroroccur ;cannot come to here 125 Leapyear: 0 0000094D 2EC606[0100]1D mov byte [cs:month_tab+1],29 ;leap year. change the month table. 127 Yeardone: 0 00000953 31DB xor bx,bx 0 00000955 31D2 xor dx,dx 0 00000957 2EA1[0000] mov ax, [cs:daycnt] 0 0000095B BE[0000] mov si, offset month_tab 0 0000095E B90C00 mov cx, 12 133 Months: 0 00000961 FEC3 inc bl ; 0 00000963 8A14 mov dl, byte ptr [si] ;compare daycnt for each month until fits 0 00000965 39D0 cmp ax, dx ;dh=0. 0 00000967 7605 jbe Month_done 0 00000969 46 inc si ;next month 0 0000096A 29D0 sub ax, dx ;adjust daycnt 0 0000096C E2F3 loop Months 141 ; jmp Erroroccur 142 Month_done: 0 0000096E 2EC606[0100]1C mov byte [cs:month_tab+1], 28 ;restore month table value 0 00000974 88DA mov dl, bl 0 00000976 2E8A36[0000] mov dh, [cs:base_year] 0 0000097B 2E8A0E[0000] mov cl, [cs:base_century] ;now, al=day, dl=month,dh=year,cl=century 0 00000980 2EFF1E[0000] call far [cs:BinToBCD] ;Oh my!!! To save 15 bytes, Bin_To_BCD proc 148 ;was relocated seperately from Daycnt_to_Day proc. 149 ; call Bin_to_bcd ;convert "day" to bcd 0 00000985 86D0 xchg dl, al ;dl = bcd day, al = month 0 00000987 2EFF1E[0000] call far [cs:BinToBCD] 152 ; call Bin_to_bcd 0 0000098C 86F0 xchg dh, al ;dh = bcd month, al = year 0 0000098E 2EFF1E[0000] call far [cs:BinToBCD] 155 ; call Bin_to_bcd 0 00000993 86C8 xchg cl, al ;cl = bcd year, al = century 0 00000995 2EFF1E[0000] call far [cs:BinToBCD] 158 ; call Bin_to_bcd 0 0000099A 88C5 mov ch, al ;ch = bcd century 0 0000099C 2E8F06[0000] pop word [cs:daycnt] ;restore original value 0 000009A1 CB ret 162 Daycnt_to_day endp 163 164 public EndDaycntToDay 165 EndDaycntToDay label byte 166 167 public Bin_to_bcd 168 Bin_to_bcd proc far ;J.K. 4/30/86 for real time clock support 169 ;Convert a binary input in AL (less than 63h or 99 decimal) 170 ;into a bcd value in AL. AH destroyed. 0 000009A2 51 push cx 0 000009A3 30E4 xor ah, ah 0 000009A5 B10A mov cl, 10 0 000009A7 F6F1 div cl ;al - high digit for bcd, ah - low digit for bcd 0 000009A9 B104 mov cl, 4 0 000009AB D2E0 shl al, cl ;mov the high digit to high nibble 0 000009AD 08E0 or al, ah 0 000009AF 59 pop cx 0 000009B0 CB ret 180 Bin_to_bcd endp 181 182 Public EndCMOSClockset ;End of supporting routines for CMOS clock setting. 183 EndCMOSClockset label byte 184 ; 185 186 EXTRN INT6C_RET_ADDR:DWORD ; RETURN ADDRESS FROM INT 6C 187 EXTRN BIN_DATE_TIME:BYTE 188 EXTRN MONTH_TABLE:WORD 189 EXTRN DAYCNT2:WORD 190 EXTRN FEB29:BYTE 191 EXTRN TimeToTicks:Word ;indirect intra-segment call address 192 0 000009B1 00 EVENB 194 ; 195 ; THE K09 REQUIRES THE ROUTINES FOR READING THE CLOCK BECAUSE OF THE SUSPEND/ 196 ; RESUME FACILITY. THE SYSTEM CLOCK NEEDS TO BE RESET AFTER RESUME. 197 ; 198 ASSUME ES:NOTHING 199 200 ; THE FOLLOWING ROUTINE IS EXECUTED AT RESUME TIME WHEN THE SYSTEM 201 ; POWERED ON AFTER SUSPENSION. IT READS THE REAL TIME CLOCK AND 202 ; RESETS THE SYSTEM TIME AND DATE, AND THEN IRETS. 203 204 ;J.K. 10/2/86 Warning!!! This code will be dynamically relocated by MSINIT. 205 206 INT6C PROC FAR 0 000009B2 0E PUSH CS 0 000009B3 1F POP DS 209 210 ASSUME DS:BIOCODE 211 0 000009B4 8F06[0000] POP WORD [INT6C_RET_ADDR] ; POP OFF RETURN ADDRESS 0 000009B8 8F06[0200] POP WORD [INT6C_RET_ADDR+2] 0 000009BC 9D POPF 215 READ_REAL_DATE equ read_real_date ; NASM port label 0 000009BD E81300 CALL READ_REAL_DATE ; GET THE DATE FROM THE CLOCK 0 000009C0 FA CLI 0 000009C1 8936[0000] MOV [DAYCNT],SI ; UPDATE DOS COPY OF DATE 0 000009C5 FB STI 220 READ_REAL_TIME equ Read_Real_Time ; NASM port label 0 000009C6 E8CC00 CALL READ_REAL_TIME ; GET THE TIME FROM THE RTC 0 000009C9 FA CLI 223 ;SB33019*************************************************************** 0 000009CA B401 MOV AH, 01h ; COMMAND TO SET THE TIME ;SB;3.30 0 000009CC CD1A INT 1Ah ; CALL ROM-BIOS TIME ROUTINE ;SB;3.30 226 ;SB33019*************************************************************** 0 000009CE FB STI 0 000009CF FF2E[0000] JMP far [INT6C_RET_ADDR] ; LONG JUMP 229 230 INT6C ENDP 231 232 233 ;=== Push trace listing source: readcloc.nas 234 %include "readcloc.nas" ; NASM included file 1 <1> ; SCCSID = @(#)readclock.asm 1.2 85/07/25 2 <1> ;************************************************************************ 3 <1> ; 4 <1> ; read_real_date reads real-time clock for date and returns the number 5 <1> ; of days elapsed since 1-1-80 in si 6 <1> ; 7 <1> read_real_date: ;mjb002 8 <1> assume ds:BIOcode,es:nothing 0 000009D3 50 PUSH AX 0 000009D4 51 PUSH CX 0 000009D5 52 PUSH DX 0 000009D6 30E4 XOR AH,AH ; throw away clock roll over ;3.30* 0 000009D8 CD1A INT 1AH ;3.30* 0 000009DA 5A POP DX 0 000009DB 59 POP CX 0 000009DC 58 POP AX 17 <1> 0 000009DD 50 PUSH AX 0 000009DE 53 PUSH BX 0 000009DF 51 PUSH CX 0 000009E0 52 PUSH DX 0 000009E1 2EC706[0000]0100 MOV word [CS:DAYCNT2],1 ;MJB002 REAL TIME CLOCK ERROR FLAG (+1 DA;3.30Y) 0 000009E8 B404 mov ah,4 ;mjb002 read date function code ;3.30* 0 000009EA CD1A int 1ah ;mjb002 read real-time clock ;3.30* 0 000009EC 7303 jnc read_ok ;mjb002 jmp success 0 000009EE E99300 jmp r_d_ret ;mjb002 jmp error 27 <1> read_ok: ;mjb002 ******* get bcd values in binary ***** 28 <1> bin_date_time equ BIN_DATE_TIME ; NASM port label 0 000009F1 882E[0000] mov byte ptr [bin_date_time+0],ch ;mjb002 store as hex value 0 000009F5 880E[0100] mov byte ptr [bin_date_time+1],cl ;mjb002 ... 0 000009F9 8836[0200] mov byte ptr [bin_date_time+2],dh ;mjb002 ... 0 000009FD 8816[0300] mov byte ptr [bin_date_time+3],dl ;mjb002 ... 0 00000A01 2EC706[0000]0200 MOV word [CS:DAYCNT2],2 ;MJB002 READ OF R-T CLOCK SUCCESSFUL ;3.30 0 00000A08 E85601 call bcd_verify ;mjb002 verify bcd values in range 0 00000A0B 7277 jc r_d_ret ;mjb002 jmp some value out of range 0 00000A0D 2EC706[0000]0300 MOV word [CS:DAYCNT2],3 ;MJB002 READ OF R-T CLOCK SUCCESSFUL ;3.30 0 00000A14 E8F300 call date_verify ;mjb002 verify date values in range 0 00000A17 726B jc r_d_ret ;mjb002 jmp some value out of range 0 00000A19 2EC706[0000]0000 MOV word [CS:DAYCNT2],0 ;MJB002 VERIFY SUCCESSFUL ;3.30;3.30 0 00000A20 E8AC00 call in_bin ;mjb002 convert date to binary 41 <1> ;mjb002 ******* years since 1-1-80 ********* 0 00000A23 A0[0100] mov al,byte ptr [bin_date_time+1] ;mjb002 get years into century 0 00000A26 98 cbw ;mjb002 0 00000A27 803E[0000]14 cmp byte [bin_date_time+0],20 ;mjb002 20th century? 0 00000A2C 7503 jnz century_19 ;mjb002 jmp no 0 00000A2E 83C064 add ax,100 ;mjb002 add in a century 47 <1> century_19: ;mjb002 0 00000A31 83E850 sub ax,80 ;mjb002 subtract off 1-1-80 0 00000A34 B104 mov cl,4 ;mjb002 leap year every 4 0 00000A36 F6F1 div cl ;mjb002 al= # leap year blocks, ah= remainder 0 00000A38 88E3 mov bl,ah ;mjb002 save odd years 0 00000A3A 98 cbw ;mjb002 zero ah 0 00000A3B B9B505 mov cx,366+3*365 ;mjb002 # of days in leap year blocks 0 00000A3E F7E1 mul cx ;mjb002 dx:ax is result 0 00000A40 2EA3[0000] MOV [CS:DAYCNT2],AX ;MJB002 SAVE COUNT OF DAYS ;3.30 0 00000A44 88D8 mov al,bl ;mjb002 get odd years count 0 00000A46 98 cbw ;mjb002 0 00000A47 09C0 or ax,ax ;mjb002 is ax= 0? 0 00000A49 740C jz leap_year ;mjb002 jmp if none 0 00000A4B B96D01 mov cx,365 ;mjb002 days in year 0 00000A4E F7E1 mul cx ;mjb002 dx:ax is result 0 00000A50 2E0106[0000] ADD [CS:DAYCNT2],AX ;MJB002 ADD ON DAYS IN ODD YEARS ;3.30 0 00000A55 EB07 jmp short leap_adjustment ;mjb002 account for leap year 64 <1> leap_year: ;mjb002 possibly account for a leap day 0 00000A57 803E[0200]02 cmp byte [bin_date_time+2],2 ;mjb002 is month february 0 00000A5C 7605 jbe no_leap_adjustment ;mjb002 jan or feb. no leap day yet. 67 <1> leap_adjustment: ;mjb002 account for leap day 0 00000A5E 2EFF06[0000] INC word [CS:DAYCNT2] ;MJB002 ... ;3.30 69 <1> no_leap_adjustment: ;mjb002 ******* get days of month ******* 0 00000A63 8A0E[0300] mov cl,byte ptr [bin_date_time+3] ;mjb002 ... 0 00000A67 30ED xor ch,ch ;mjb002 0 00000A69 49 dec cx ;mjb002 because of offset from day 1, not day 0 0 00000A6A 2E010E[0000] ADD [CS:DAYCNT2],CX ;MJB002 ******* GET DAYS IN MONTHS PRECEE;3.30DING ***** 0 00000A6F 8A0E[0200] mov cl,byte ptr [bin_date_time+2] ;mjb002 get month 0 00000A73 30ED xor ch,ch ;mjb002 0 00000A75 49 dec cx ;mjb002 january starts at offset 0 0 00000A76 D1E1 shl cx,1 ;mjb002 word offset 78 <1> month_table equ MONTH_TABLE ; NASM port label 0 00000A78 BE[0000] mov si,offset month_table ;mjb002 beginning of month_table 0 00000A7B 01CE add si,cx ;mjb002 point into month table 0 00000A7D 8B04 mov ax,word ptr [si];mjb002 get # days in previous months 0 00000A7F 2E0106[0000] ADD [CS:DAYCNT2],AX ;MJB002 ... ;3.30 83 <1> r_d_ret: ;mjb002 0 00000A84 2E8B36[0000] MOV SI,[CS:DAYCNT2] ;MJB002 RESULT IN SI ;3.30 0 00000A89 5A POP DX 0 00000A8A 59 POP CX 0 00000A8B 5B POP BX 0 00000A8C 58 POP AX 0 00000A8D C3 ret ;mjb002 90 <1> 91 <1> r_t_retj: 0 00000A8E 31C9 xor cx,cx 0 00000A90 31D2 xor dx,dx 0 00000A92 EB3A jmp r_t_ret 0 00000A94 90 nop ; identicalise 96 <1> ; 97 <1> ; Read_Real_Time reads the time from the RTC. on exit, it has the number of 98 <1> ; ticks (at 18.2 ticks per sec.) in CX:DX. 99 <1> ; 100 <1> Read_Real_Time: 0 00000A95 B402 mov ah,2 ;3.30* 0 00000A97 CD1A int 1AH ;3.30* 0 00000A99 72F3 jc r_t_retj 104 <1> oktime: 0 00000A9B 882E[0000] mov byte ptr [bin_date_time],ch ; hours 0 00000A9F 880E[0100] mov byte ptr [bin_date_time+1],cl ; minutes 0 00000AA3 8836[0200] mov byte ptr [bin_date_time+2],dh ; seconds 0 00000AA7 C606[0300]00 mov byte [bin_date_time+3],0 ; unused for time 0 00000AAC E8B200 call bcd_verify 0 00000AAF 72DD jc r_t_retj 0 00000AB1 E89400 call time_verify 0 00000AB4 72D8 jc r_t_retj 0 00000AB6 E81600 call in_bin 0 00000AB9 8A2E[0000] MOV ch,byte ptr [bin_date_time] 0 00000ABD 8A0E[0100] MOV cl,byte ptr [bin_date_time+1] 0 00000AC1 8A36[0200] MOV dh,byte PTR [bin_date_time+2] 0 00000AC5 8A16[0300] MOV dl,byte PTR [bin_date_time+3] 118 <1> message ftestinit,<"Read Time "> 119 <1> mnum ftestinit,cx 120 <1> message ftestinit,<" "> 121 <1> mnum ftestinit,dx 122 <1> message ftestinit, 123 <1> ; get time in ticks in CX:DX 0 00000AC9 2EFF1E[0000] CALL far [cs:TimeToTicks] ;3.30 125 <1> message ftestinit,<"Conv Time "> 126 <1> mnum ftestinit,cx 127 <1> message ftestinit,<" "> 128 <1> mnum ftestinit,dx 129 <1> message ftestinit, 130 <1> r_t_ret: 0 00000ACE C3 ret 132 <1> 133 <1> ; 134 <1> ; in_bin converts bin_date_time values from bcd to bin 135 <1> ; 136 <1> in_bin: ;mjb002 137 <1> assume ds:BIOcode,es:nothing 0 00000ACF A0[0000] mov al,byte ptr [bin_date_time+0] ; century or hours 0 00000AD2 E81F00 call bcd_to_bin ; ... 0 00000AD5 A2[0000] mov byte ptr [bin_date_time+0],al ; 0 00000AD8 A0[0100] mov al,byte ptr [bin_date_time+1] ; years or minutes 0 00000ADB E81600 call bcd_to_bin ; ... 0 00000ADE A2[0100] mov byte ptr [bin_date_time+1],al ; 0 00000AE1 A0[0200] mov al,byte ptr [bin_date_time+2] ; months or seconds 0 00000AE4 E80D00 call bcd_to_bin ; ... 0 00000AE7 A2[0200] mov byte ptr [bin_date_time+2],al ; 0 00000AEA A0[0300] mov al,byte ptr [bin_date_time+3] ; days (not used for time) 0 00000AED E80400 call bcd_to_bin ; ... 0 00000AF0 A2[0300] mov byte ptr [bin_date_time+3],al ; 0 00000AF3 C3 ret ; 151 <1> ; 152 <1> ; bcd_to_bin converts two bcd nibbles in al (value <= 99.) to 153 <1> ; a binary representation in al 154 <1> ; ah is destroyed 155 <1> ; 156 <1> bcd_to_bin: ;mjb002 157 <1> assume ds:nothing,es:nothing 0 00000AF4 88C4 mov ah,al ;mjb002 copy bcd number to ah 0 00000AF6 250FF0 and ax,0f00fh ;mjb002 clear unwanted nibbles 0 00000AF9 88C3 mov bl,al ;mjb002 save units place 0 00000AFB 86E0 xchg ah,al ;mjb002 10's place to al 0 00000AFD 30E4 xor ah,ah ;mjb002 ah not wanted 0 00000AFF B104 mov cl,4 ;mjb002 shift count 0 00000B01 D3E8 shr ax,cl ;mjb004 swap nibbles 0 00000B03 B10A mov cl,10 ;mjb002 convert al to ... 0 00000B05 F6E1 mul cl ;mjb002 ... its binary value 0 00000B07 00D8 add al,bl ;mjb002 add in units 0 00000B09 C3 ret ;mjb002 235 ;=== Pop trace listing source 236 ;=== Push trace listing source: clocksub.nas 237 %include "clocksub.nas" ; NASM included file 1 <1> ; 2 <1> ; date_verify loosely checks bcd date values to be in range in bin_date_time 3 <1> ; 4 <1> date_verify: ; 5 <1> assume ds:BIOcode,es:nothing 0 00000B0A 803E[0000]20 cmp byte [bin_date_time+0],20h ; century check 0 00000B0F 7735 ja date_error ; jmp error 0 00000B11 740E jz century_20 ; jmp in 20th century 0 00000B13 803E[0000]19 cmp byte [bin_date_time+0],19h ; century check 0 00000B18 722C jb date_error ; jmp error 0 00000B1A 803E[0100]80 cmp byte [bin_date_time+1],80h ; year check 0 00000B1F 7225 jb date_error ; jmp error 13 <1> century_20: ; 0 00000B21 803E[0100]99 cmp byte [bin_date_time+1],99h ; year check 0 00000B26 771E ja date_error ; jmp error 0 00000B28 803E[0200]12 cmp byte [bin_date_time+2],12h ; month check 0 00000B2D 7717 ja date_error ; jmp error 0 00000B2F 803E[0200]00 cmp byte [bin_date_time+2],00h ; month check 0 00000B34 7610 jbe date_error ; jmp error 0 00000B36 803E[0300]31 cmp byte [bin_date_time+3],31h ; day check 0 00000B3B 7709 ja date_error ; jmp error 0 00000B3D 803E[0300]00 cmp byte [bin_date_time+3],00h ; day check 0 00000B42 7602 jbe date_error ; jmp error 0 00000B44 F8 clc ; set success flag 0 00000B45 C3 ret ; 26 <1> date_error: ; 0 00000B46 F9 stc ; set error flag 0 00000B47 C3 ret ; 29 <1> 30 <1> ; 31 <1> ; time_verify very loosely checks bcd date values to be in range in bin_date_time 32 <1> ; 33 <1> time_verify: 34 <1> assume ds:BIOcode,es:nothing 0 00000B48 803E[0000]24 cmp byte [bin_date_time+0],24H 0 00000B4D 7710 ja time_error 0 00000B4F 803E[0100]59 cmp byte [bin_date_time+1],59H 0 00000B54 7709 ja time_error 0 00000B56 803E[0200]59 cmp byte [bin_date_time+2],59H 0 00000B5B 7702 ja time_error 0 00000B5D F8 clc 0 00000B5E C3 ret 43 <1> time_error: 0 00000B5F F9 stc 0 00000B60 C3 ret 46 <1> 47 <1> ; 48 <1> ; bcd_verify checks values in bin_date_time to be valid 49 <1> ; bcd numerals. carry set if any nibble out of range 50 <1> ; 51 <1> bcd_verify: ; 52 <1> assume ds:BIOcode,es:nothing 0 00000B61 B90400 mov cx,4 ; 4 bytes to check 0 00000B64 BB[0000] mov bx,offset bin_date_time ; 55 <1> bv_loop: ; 0 00000B67 8A07 mov al,[bx] ; get a bcd number (0..99) 0 00000B69 88C4 mov ah,al ; 0 00000B6B 250FF0 and ax,0f00fh ; 10's place in high ah, 1's in al 0 00000B6E 3C0A cmp al,10 ; is 1's place in range? 0 00000B70 7716 ja bv_error ; jmp out of range 0 00000B72 D0EC shr ah,1 ; swap nibbles 0 00000B74 D0EC shr ah,1 ; ... 0 00000B76 D0EC shr ah,1 ; ... 0 00000B78 D0EC shr ah,1 ; ... 0 00000B7A 80E40F and ah,0fh ; get rid of any erroneous bits 0 00000B7D 80FC0A cmp ah,10 ; is 10's place in range 0 00000B80 7706 ja bv_error ; jmp out of range 0 00000B82 43 inc bx ; next byte 0 00000B83 49 dec cx ; 0 00000B84 75E1 jnz bv_loop ; 0 00000B86 F8 clc ; set success flag 0 00000B87 C3 ret ; 73 <1> bv_error: ; 0 00000B88 F9 stc ; set error flag 0 00000B89 C3 ret ; 76 <1> ; 77 <1> ; Dos 3.30 - The real time clock structures were moved to msbio2.asm 78 <1> ; 238 ;=== Pop trace listing source 239 240 PUBLIC ENDK09 ;NOT REFERENCES EXTERNALLY, BUT 241 ; JUST TO CAUSE ENTRY IN LINK MAP 242 ENDK09 LABEL BYTE 243 ASSUME DS:NOTHING,ES:NOTHING 244 245 ;********************************************************* 246 ; SYSTEM INITIALIZATION 247 ; 248 ; THE ENTRY CONDITIONS ARE ESTABLISHED BY THE BOOTSTRAP 249 ; LOADER AND ARE CONSIDERED UNKNOWN. THE FOLLOWING JOBS 250 ; WILL BE PERFORMED BY THIS MODULE: 251 ; 252 ; 1. ALL DEVICE INITIALIZATION IS PERFORMED 253 ; 2. A LOCAL STACK IS SET UP AND DS:SI ARE SET 254 ; TO POINT TO AN INITIALIZATION TABLE. THEN 255 ; AN INTER-SEGMENT CALL IS MADE TO THE FIRST 256 ; BYTE OF THE DOS 257 ; 3. ONCE THE DOS RETURNS FROM THIS CALL THE DS 258 ; REGISTER HAS BEEN SET UP TO POINT TO THE START 259 ; OF FREE MEMORY. THE INITIALIZATION WILL THEN 260 ; LOAD THE COMMAND PROGRAM INTO THIS AREA 261 ; BEGINNING AT 100 HEX AND TRANSFER CONTROL TO 262 ; THIS PROGRAM. 263 ; 264 ;******************************************************** 265 266 ; DRVFAT MUST BE THE FIRST LOCATION OF FREEABLE SPACE! 267 EVENB 0 00000B8A 0000 DRVFAT DW 0000 ;DRIVE AND FAT ID OF DOS 269 ; ldos: no longer used 0 00000B8C 00 checkdebugger: db 0 271 === Switch to base=002530h -> "SYSINITSEG" 272 addsection SYSINITSEG, PUBLIC class=INIT 272 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] === Switch to base=002530h -> "SYSINITTRAIL" 273 addsection SYSINITTRAIL, PUBLIC class=INIT 274 275 group SYSINITGROUP SYSINITSEG SYSINITTRAIL 276 277 align 2, db 0 0 00004FF2 00000000 nextupb: dd 0 279 global Init_BootSeg 0 00004FF6 ???? Init_BootSeg: dw ? ; seg addr of buffer for reading boot record 0 00004FF8 00 FakeFloppyDrv: db 0 ; If 1, then No diskette drives in the system. 0 00004FF9 00 FBIGFAT: db 0 ; FLAGS FOR DRIVE 0 00004FFA 80 ROM_drv_num: db 80h ; rom drv number 284 0 00004FFB 00 evenb 286 BDS_diskette_template: 0 00004FFC FFFFFFFF dw -1, -1 ;LINK TO NEXT STRUCTURE 0 00005000 00 DB 0 ;INT 13 DRIVE NUMBER 0 00005001 00 DB 0 ;LOGICAL DRIVE LETTER 0 00005002 0002 DW 512 ;PHYSICAL SECTOR SIZE IN BYTES 0 00005004 FF DB -1 ;SECTORS/ALLOCATION UNIT 0 00005005 0100 DW 1 ;RESERVED SECTORS FOR DOS 0 00005007 02 DB 2 ;NO. ALLOCATION TABLES 0 00005008 4000 DW 64 ;NUMBER DIRECTORY ENTRIES 0 0000500A 6801 DW 9*40 ;NUMBER SECTORS (AT 512 BYTES EA.) 0 0000500C 00 DB 00000000B ;MEDIA DESCRIPTOR, INITIALLY 00H. 0 0000500D 0200 DW 2 ;NUMBER OF FAT SECTORS 0 0000500F 0900 DW 9 ;SECTOR LIMIT 0 00005011 0100 DW 1 ;HEAD LIMIT 0 00005013 0000 DW 0 ;HIDDEN SECTOR COUNT (low word) 0 00005015 0000 dw 0 ;J.K. Hidden sector (high) 0 00005017 0000 dw 0 ;J.K. Number sectors (low) 0 00005019 0000 dw 0 ;J.K. Number sectors (high) 0 0000501B 00 DB 0 ; TRUE => LARGE FATS 0 0000501C 0000 DW 0 ;OPEN REF. COUNT 306 0 0000501E 03 DB 3 ;FORM FACTOR 0 0000501F 2000 DW 0020H ;VARIOUS FLAGS 309 ; DB 9 DUP (0) ;RESERVED FOR FUTURE USE 0 00005021 2800 DW 40 ; NUMBER OF CYLINDERS 311 ; RECOMMENDED BPB FOR DRIVE. 0 00005023 0002 DW 512 ;BYTES PER SECTOR 0 00005025 01 DB 1 ;SECTORS/ALLOCATION UNIT 0 00005026 0100 DW 1 ;RESERVED SECTORS FOR DOS 0 00005028 02 DB 2 ;NO. ALLOCATION TABLES 0 00005029 E000 DW 0E0H ;NUMBER DIRECTORY ENTRIES 0 0000502B 6801 DW 9*40 ;NUMBER SECTORS (AT 512 BYTES EA.) 0 0000502D F0 DB 0F0H ;MEDIA DESCRIPTOR, INITIALLY F0H. 0 0000502E 0200 DW 2 ;NUMBER OF FAT SECTORS 0 00005030 0900 DW 9 ;SECTOR LIMIT 0 00005032 0200 DW 2 ;HEAD LIMIT 0 00005034 0000 DW 0 ;HIDDEN SECTOR COUNT(low) 0 00005036 0000 dw 0 ;J.K. Hidden sector count (high) 0 00005038 0000 dw 0 ;J.K. Number sectors (low) 0 0000503A 0000 dw 0 ;J.K. Number sectors (high) 0 0000503C ???????????? DB 6 DUP (?) 0 00005042 FF DB -1 ;LAST TRACK ACCESSED ON THIS DRIVE 0 00005043 FFFF DW -1 ;KEEP THESE TWO CONTIGUOUS (?) 0 00005045 FFFF DW -1 0 00005047 4E4F204E414D452020 DB "NO NAME ",0 ;VOLUME ID FOR THIS DISK 0 00005050 202000 0 00005053 00000000 dd 0 ;Current volume serial number from Boot record 0 00005057 464154313220202000 db "FAT12 ",0 ;Current file system id from Boot record 333 334 evenb 335 ; extended_lba_innermost: dd 0 0 00005060 00000000 extended_lba_outermost dd 0 337 ; THE FOLLOWING TWO BYTES ARE USED TO SAVE THE INFO RETURNED BY INT 13, AH = 8 338 ; CALL TO DETERMINE DRIVE PARAMETERS. 0 00005064 0200 NUM_HEADS dw 2 ; NUMBER OF HEADS RETURNED BY ROM 0 00005066 09 SEC_TRK DB 9 ; SEC/TRK RETURNED BY ROM 0 00005067 28 NUM_CYLN DB 40 ; NUMBER OF CYLINDERS RETURNED BY ROM 342 343 344 BOOTBIAS equ 0 345 EXT_BOOT_SIG_OFF equ 11+BPB_TYPE_struc_size ;AN000; 3 byte jmp+8 byte OEM +extended bpb 346 347 348 EVENB 0 00005068 0002000140000000 DISKTABLE DW 512, 0100H, 64, 0 0 00005070 0008010270000000 DW 2048, 0201H, 112, 0 0 00005078 0020020400010000 DW 8192, 0402H, 256, 0 0 00005080 A87F030800020000 DW 32680, 0803H, 512, 0 ;Warning !!! Old values 353 ; DW 20740, 0803H, 512, 0 ;PTM P892 J.K. 12/3/86 DOS 3.3 will use this. 354 ;J.K.3/16/87 P54 Return back to old value for compatibility.!!! 0 00005088 FFFF041000040000 DW 65535, 1004H, 1024, 0 356 357 ;DISKTABLE2 DW 32680, 0803H, 512, 0 ;Warning !!! Old values ;J.K.3/16/87 P54 Return to old value!!! 358 ;DISKTABLE2 DW 20740, 0803H, 512, 0 ;PTM p892 J.K. 12/3/86 DOS 3.3 will use this. 359 ; DW 65535, 0402H, 512, FBIG 360 ;AN000; 361 ;DISKTABLE2 dw 0, 32680, 0803h, 512, 0 ;table with the assumption of the 362 ; dw 2h, 0000h, 0402h, 512, FBIG ;total fat size <= 64KB. 363 ; dw 4h, 0000h, 0803h, 512, FBIG ;-This will cover upto 134 MB 364 ; dw 8h, 0000h, 1004h, 512, FBIG ;-This will cover upto 268 MB 365 ; dw 10h, 0000h, 2005h, 512, FBIG ;-This will cover upto 536 MB 366 367 ;AN004 Default DiskTable under the assumption of Total FAT size <= 128 KB, and 368 ; the maxium size of FAT entry = 16 Bit. 0 00005090 0000A87F0308000200 DiskTable2 dw 0, 32680, 0803h, 512, 0 ;For compatibility. 0 00005099 00 0 0000509A 040000000204000240 dw 4h, 0000h, 0402h, 512, FBIG ;Covers upto 134 MB media. 0 000050A3 00 0 000050A4 080000000308000240 dw 8h, 0000h, 0803h, 512, FBIG ; upto 268 MB 0 000050AD 00 0 000050AE 100000000410000240 dw 10h, 0000h, 1004h, 512, FBIG ; upto 536 MB 0 000050B7 00 0 000050B8 200000000520000240 dw 20h, 0000h, 2005h, 512, FBIG ; upto 1072 MB 0 000050C1 00 0 000050C2 400000000640000240 dw 40h, 0000h, 4006h, 512, FBIG ; upto 2144 MB 0 000050CB 00 0 000050CC 800000000780000240 dw 80h, 0000h, 8007h, 512, FBIG ; upto 4288 MB... 0 000050D5 00 376 377 ;****************************************************************************** 378 ;Variables for Mini disk initialization - J.K. 4/7/86 379 ;****************************************************************************** 0 000050D6 00 numh db 0 ;number of hard files 0 000050D7 00 MiniNum db 0 ;logical drive number for mini disk(s) 0 000050D8 00 num_mini_dsk db 0 ;# of mini disk installed 0 000050D9 80 Rom_Minidsk_num db 80h ;physical mini disk number 384 align 2, db 0 0 000050DA 0000 Mini_HDLIM dw 0 0 000050DC 0000 Mini_SECLIM dw 0 0 000050DE [EE00] Mini_BPB_ptr dw DSKDRVS ;temporary variable used to save the 388 ;Mini Disk BPB pointer address in DskDrvs. 0 000050E0 0000 DSKDRVS times 32 dw 0 390 .end: 0 00005120 0000 dw 0 ; allow overflowing entry 392 393 ;J.K. 4/7/86 End of Mini Disk Init Variables ********************************** 394 395 === Switch to base=000000h -> "DOSENTRY" 396 usesection DOSENTRY 397 0 00000B8D 30312F31302F383400 BIOS_DATE DB '01/10/84',0 ;This is used for checking AT ROM BIOS date. 399 400 === Switch to base=002530h -> "SYSINITTRAIL" 401 usesection SYSINITTRAIL 402 403 ; THE FOLLOWING ARE THE RECOMMENDED BPBS FOR THE MEDIA THAT WE KNOW OF SO 404 ; FAR. 405 406 ; 48 TPI DISKETTES 407 EVENB 0 00005122 0002 BPB48T DW 512 0 00005124 02 DB 2 0 00005125 0100 DW 1 0 00005127 02 DB 2 0 00005128 7000 DW 112 0 0000512A D002 DW 2*9*40 0 0000512C FD DB 0FDH 0 0000512D 0200 DW 2 0 0000512F 0900 DW 9 0 00005131 0200 DW 2 0 00005133 0000 DW 0 0 00005135 0000 dw 0 ;AN000; hidden sector High 0 00005137 00000000 dd 0 ;AN000; extended total sectors 421 422 ; 96TPI DISKETTES 0 0000513B 00 EVENB 0 0000513C 0002 BPB96T DW 512 0 0000513E 01 DB 1 0 0000513F 0100 DW 1 0 00005141 02 DB 2 0 00005142 E000 DW 224 0 00005144 6009 DW 2*15*80 0 00005146 F9 DB 0F9H 0 00005147 0700 DW 7 0 00005149 0F00 DW 15 0 0000514B 0200 DW 2 0 0000514D 0000 DW 0 0 0000514F 0000 dw 0 ;AN000; hidden sector High 0 00005151 00000000 dd 0 ;AN000; extended total sectors 437 438 BPBSIZ equ $-BPB96T 439 440 ; 3 1/2 INCH DISKETTE BPB 441 0 00005155 00 EVENB 0 00005156 0002 BPB35 DW 512 0 00005158 02 DB 2 0 00005159 0100 DW 1 ; DOUBLE SIDED WITH 9 SEC/TRK 0 0000515B 02 DB 2 0 0000515C 7000 DW 70h 0 0000515E A005 DW 2*9*80 0 00005160 F9 DB 0F9H 0 00005161 0300 DW 3 0 00005163 0900 DW 9 0 00005165 0200 DW 2 0 00005167 0000 DW 0 0 00005169 0000 dw 0 ;AN000; hidden sector High 0 0000516B 00000000 dd 0 ;AN000; extended total sectors 456 0 0000516F 00 EVENB 0 00005170 [3001] BPBTABLE DW BPB48T ; 48TPI DRIVES 0 00005172 [4A01] DW BPB96T ; 96TPI DRIVES 0 00005174 [6401] DW BPB35 ; 3.5" DRIVES 461 ;DW BPB48T ; NOT USED - 8" DRIVES 462 ;DW BPB48T ; NOT USED - 8" DRIVES 463 ;DW BPB48T ; NOT USED - HARD FILES 464 ;DW BPB48T ; NOT USED - TAPE DRIVES 465 ;DW BPB48T ; NOT USED - OTHER 466 === Switch to base=000000h -> "DOSENTRY" 467 usesection DOSENTRY 468 469 %if 0 470 align 2, db 0 471 PATCHTABLE LABEL BYTE 472 DW 10,MEDIA_PATCH 473 DW 3,GETBP1_PATCH 474 DW 3,SET_PATCH 475 DW 3,DISKIO_PATCH 476 DW 3,DSKERR_PATCH 477 DW 3,CHANGED_PATCH 478 DW 3,INIT_PATCH 479 DW 0 480 %endif 481 482 ASSUME DS:NOTHING,ES:NOTHING 483 484 ; INP: from drkernpl 485 ; ax => DOS (no longer used) 486 ; si = length of DOS in bytes (para aligned) (no longer used) 487 ; cx:di -> lCFG block passed from drkernpl or inicomp 488 ; dl = load unit 489 ; ds:bp = ss:bp -> load partition boot sector with (E)BPB 490 PUBLIC INIT 491 INIT PROC NEAR 492 MESSAGE FTESTINIT,<"IBMBIO",CR,LF> 0 00000B96 FA CLI 494 495 ; Get lCFG items to use later. 0 00000B97 8EC1 mov es, cx 0 00000B99 268A4514 mov al, byte [es:di + LCFG_CheckDebugger] 0 00000B9D 2EA2[BC02] mov byte [cs:checkdebugger], al 499 500 ; init pointers needed by relocation (i13 etc) 0 00000BA1 31C0 xor ax, ax 0 00000BA3 8ED8 mov ds, ax 0 00000BA5 B8[0000] mov ax, DOSSTART 0 00000BA8 A3C600 mov word [31h * 4 + 2], ax 0 00000BAB 8ED8 mov ds, ax 0 00000BAD C706[0000][0000] mov word [dosdata_to_doscode], DOSCODEGROUP 507 508 extern kernelcommandline 509 510 ; copied from ecm contribution to FreeDOS kernel.asm 511 initialise_command_line_buffer: 0 00000BB3 B8[0000] mov ax, SYSINITSEG 0 00000BB6 8EC0 mov es, ax ; modified to use ax 514 ; (preserve dl = load unit) 515 0 00000BB8 89E0 mov ax, sp ; ax = original sp 0 00000BBA 16 push ss 0 00000BBB 1F pop ds 0 00000BBC 89EE mov si, bp ; ds:si = original ss:bp 520 521 ; Note that the kernel command line buffer in 522 ; the init data segment is pre-initialised to 523 ; hold 0x00 0xFF in the first two bytes. This 524 ; is used to indicate no command line present, 525 ; as opposed to an empty command line which 526 ; will hold 0x00 0x00. 527 ; If any of the branches to .none are taken then 528 ; the buffer is not modified so it retains the 529 ; 0x00 0xFF contents. 0 00000BBE 81FE1401 cmp si, - lsvCommandLine.start ; buffer fits below ss:bp ? 0 00000BC2 7222 jb .none ; no --> 0 00000BC4 817CEC434C cmp word [si + lsvCommandLine.signature], lsvclSignature 533 ; signature passed to us ? 0 00000BC9 751B jne .none ; no --> 0 00000BCB 8DB4ECFE lea si, [si + lsvCommandLine.start] 536 ; -> command line buffer 0 00000BCF 39F0 cmp ax, si ; stack top starts below-or-equal buffer ? 0 00000BD1 7713 ja .none ; no --> 0 00000BD3 BF[0000] mov di, kernelcommandline ; our buffer 0 00000BD6 B9FF00 mov cx, lsvclBufferLength - 1 0 00000BD9 31C0 xor ax, ax 0 00000BDB 57 push di 0 00000BDC F3A4 rep movsb ; copy up to 255 bytes 0 00000BDE AA stosb ; truncate 0 00000BDF 5F pop di 0 00000BE0 B501 mov ch, 1 ; cx = 256 0 00000BE2 F2AE repne scasb ; scan for terminator 0 00000BE4 F3AA rep stosb ; clear remainder of buffer 549 ; (make sure we do not have 0x00 0xFF 550 ; even if the command line given is 551 ; actually the empty string) 552 .none: 553 0 00000BE6 31C0 XOR AX,AX 0 00000BE8 8ED8 MOV DS,AX 0 00000BEA B500 mov ch, 0 557 558 ; 559 ; PRESERVE ORIGINAL INT 13 VECTOR 560 ; WE NEED TO SAVE INT13 IN TWO PLACES IN CASE WE ARE RUNNING ON AN AT. 561 ; ON ATS WE INSTALL THE IBM SUPPLIED ROM_BIOS PATCH DISK.OBJ WHICH HOOKS 562 ; INT13 AHEAD OF ORIG13. SINCE INT19 MUST UNHOOK INT13 TO POINT TO THE 563 ; ROM INT13 ROUTINE, WE MUST HAVE THAT ROM ADDRESS ALSO STORED AWAY. 564 ; 0 00000BEC A14C00 MOV AX,[13H*4] 0 00000BEF 2EA3[0000] MOV WORD PTR [cs:ORIG13],AX 0 00000BF3 A14E00 MOV AX,[13H*4+2] 0 00000BF6 2EA3[0200] MOV WORD PTR [cs:ORIG13+2],AX 569 570 init_irt: 571 extern InterruptRestorationTable 0 00000BFA 0E push cs 0 00000BFB 07 pop es ; => IRT 0 00000BFC FC cld 0 00000BFD BE[0000] mov si, InterruptRestorationTable 576 .: 0 00000C00 31C0 xor ax, ax 0 00000C02 26AC es lodsb 0 00000C04 3CFF cmp al, -1 0 00000C06 740D je .done 0 00000C08 97 xchg di, ax ; di = interrupt number 0 00000C09 01FF add di, di 0 00000C0B 01FF add di, di ; ds:di -> interrupt vector 0 00000C0D 87F7 xchg si, di ; es:di -> IRT, ds:si -> vector 0 00000C0F A5 movsw 0 00000C10 A5 movsw 0 00000C11 87F7 xchg si, di 0 00000C13 EBEB jmp . 589 .done: 590 591 ; 592 ; SET UP INT 13 FOR NEW ACTION 593 ; 594 extern msdisk_i13 0 00000C15 C7064C00[0000] MOV WORD PTR [13H*4],OFFSET msdisk_i13 0 00000C1B 8C0E4E00 MOV [13H*4+2],CS 597 598 ; 599 ; SET UP INT 19 FOR NEW ACTION 600 ; 601 extern i19 0 00000C1F C7066400[0000] MOV WORD PTR [19H*4],OFFSET i19 0 00000C25 8C0E6600 MOV [19H*4+2],CS 0 00000C29 FB STI 0 00000C2A CD11 INT 11H ;GET EQUIPMENT STATUS 606 ;J.K.6/24/87 We have to support a system that does not have any diskette 607 ;drives but only hardfiles. This system will IPL from the hardfile. 608 ;If the equipment flag bit 0 is 1, then the system has diskette drive(s). 609 ;Otherwise, the system only have hardfiles. 610 ;Important thing is that still, for compatibility reason, the drive letter 611 ;for the hardfile start from "C". So, we still need to allocate dummy BDS 612 ;drive A and driver B. In SYSINIT time, we are going to set CDS table entry 613 ;of DPB pointer for these drives to 0, so any user attempt to access this 614 ;drives will get "Invalid drive letter ..." message. We are going to 615 ;establish "FAKEFLOPPYDRV" flag. ***SYSINIT module should call INT 11h to check 616 ;if there are any diskette drivers in the system or not.!!!*** 617 618 ;SB34INIT001************************************************************** 619 ;SB check the register returned by the equipment determination interrupt 620 ;SB we have to handle the case of no diskettes in the system by faking 621 ;SB two dummy drives. 622 ;SB if the register indicates that we do have floppy drives we don't need 623 ;SB to do anything special. 624 ;SB if the register indicates that we don't have any floppy drives then 625 ;SB what we need to do is set the FakeFloppyDrv variable, change the 626 ;SB register to say that we do have floppy drives and then go to execute 627 ;SB the code which starts at NOTSINGLE. This is because we can skip the 628 ;SB code given below which tries to find if there are one or two drives 629 ;SB since we already know about this. 6 LOCS 630 0 00000C2C A801 test al, 1 0 00000C2E 750C jnz DO_FLOPPY 0 00000C30 B8[0000] mov ax, SYSINITSEG 0 00000C33 8ED8 mov ds, ax 0 00000C35 B001 mov al, 1 ; set to indicate 2 floppies 0 00000C37 A2[0600] mov [FakeFloppyDrv], al ; fake floppy 0 00000C3A EB0E jmp short NOTSINGLE 638 639 DO_FLOPPY: 640 641 ;SB34INIT001************************************************************** 642 ; 643 ; Determine if there are one or two diskette drives in system 644 ; 0 00000C3C D0C0 ROL AL,1 ;PUT BITS 6 & 7 INTO BITS 0 & 1 0 00000C3E D0C0 ROL AL,1 0 00000C40 2403 AND al, 3 ;ONLY LOOK AT BITS 0 & 1 0 00000C42 7506 JNZ NOTSINGLE ;ZERO MEANS SINGLE DRIVE SYSTEM 0 00000C44 40 INC AX ;PRETEND IT'S A TWO DRIVE SYSTEM 0 00000C45 2EFE06[0000] INC byte [cs:SINGLE] ;REMEMBER THIS 651 NOTSINGLE: 0 00000C4A 0E push cs 0 00000C4B 1F pop ds 654 0 00000C4C 40 INC AX ;AX HAS NUMBER OF DRIVES, 2-4 656 ;IS ALSO 0 INDEXED BOOT DRIVE IF WE 657 ; BOOTED OFF HARD FILE 0 00000C4D 88C1 MOV CL,AL ;CH IS FAT ID, CL # FLOPPIES 0 00000C4F F6C280 TEST DL,80H ;BOOT FROM FLOPPY ? 0 00000C52 7502 JNZ GOTHRD ;NO. 0 00000C54 31C0 XOR AX,AX ;INDICATE BOOT FROM DRIVE A 662 GOTHRD: 663 ; 664 ; AX = 0-BASED DRIVE WE BOOTED FROM 665 ; CL = NUMBER OF FLOPPIES INCLUDING FAKE ONE 666 ; CH = MEDIA BYTE 667 ; 668 MESSAGE FTESTINIT,<"INIT",CR,LF> 0 00000C56 31D2 XOR DX,DX 0 00000C58 FA CLI 0 00000C59 8ED2 MOV SS,DX 0 00000C5B BC0007 MOV SP,700H ;LOCAL STACK 0 00000C5E FB STI 674 ASSUME SS:NOTHING 675 0 00000C5F 51 PUSH CX ;SAVE NUMBER OF FLOPPIES AND MEDIA BYTE 0 00000C60 88EC MOV AH,CH ;SAVE FAT ID TO AH 0 00000C62 50 PUSH AX ;SAVE BOOT DRIVE NUMBER, AND MEDIA BYTE 679 ;J.K. Let Model_byte, Secondary_Model_Byte be set here!!! 680 ;SB33020****************************************************************** 0 00000C63 F9 stc 0 00000C64 B4C0 mov ah,0c0h ; return system environment ;SB;3.30 0 00000C66 CD15 int 15h ; call ROM-Bios routine ;SB;3.30 684 ;SB33020****************************************************************** 0 00000C68 7214 jc No_Rom_System_Conf ; just use Model_Byte 0 00000C6A 84E4 test ah, ah ; double check 0 00000C6C 7510 jnz No_Rom_System_Conf 0 00000C6E 268A4702 mov al, [ES:BX + bios_SD_modelbyte] ;get the model byte 0 00000C72 A2[0000] mov [Model_Byte], al 0 00000C75 268A4703 mov al, [ES:BX + bios_SD_scnd_modelbyte] ;secondary model byte 0 00000C79 A2[0000] mov [Secondary_Model_Byte], al 0 00000C7C EB0C jmp short Turn_Timer_On 693 No_Rom_System_Conf: 0 00000C7E BEFFFF MOV SI,0FFFFH ;MJB001 0 00000C81 8EC6 MOV ES,SI ;MJB001 0 00000C83 26A00E00 MOV AL,[ES:0EH] ; GET MODEL BYTE ARR 2.41 697 MODEL_BYTE equ Model_Byte ; NASM port label 0 00000C87 A2[0000] MOV [MODEL_BYTE],AL ; SAVE MODEL BYTE ARR 2.41 699 Turn_Timer_On: 0 00000C8A B020 MOV AL,EOI 0 00000C8C E620 OUT AKPORT,AL ;TURN ON THE TIMER 702 703 ; NOP out the double word MOV instruction in MSDISK, if 704 ; this is not a 386 machine... 705 Get_CPU_Type ; macro to determine cpu type 0 00000C8E 9C pushf 0 00000C8F 53 push bx 0 00000C90 31DB xor bx, bx 13 <1> 0 00000C92 31C0 xor ax,ax 0 00000C94 50 push ax 0 00000C95 9D popf 0 00000C96 9C pushf 0 00000C97 58 pop ax 0 00000C98 2500F0 and ax,0F000h 0 00000C9B 3D00F0 cmp ax,0F000h 0 00000C9E 740E je cpu_8086 22 <1> 0 00000CA0 B800F0 mov ax,0F000h 0 00000CA3 50 push ax 0 00000CA4 9D popf 0 00000CA5 9C pushf 0 00000CA6 58 pop ax 0 00000CA7 2500F0 and ax,0F000h 0 00000CAA 7401 jz cpu_286 30 <1> 31 <1> cpu_386: 0 00000CAC 43 inc bx 33 <1> cpu_286: 0 00000CAD 43 inc bx 35 <1> cpu_8086: 0 00000CAE 89D8 mov ax, bx 0 00000CB0 5B pop bx 0 00000CB1 9D popf 0 00000CB2 3C02 cmp al, 2 ; is it a 386? 0 00000CB4 7409 je Skip_Patch_DoubleWordMov; yes: skip the patch 708 709 Patch_DoubleWordMov: 0 00000CB6 B89090 mov ax, 9090h 0 00000CB9 A3[0000] mov word [DoubleWordMov], ax 0 00000CBC A2[0200] mov byte [DoubleWordMov + 2], al; 3 bytes to NOP 713 Skip_Patch_DoubleWordMov: 714 MESSAGE FTESTINIT,<"COM DEVICES",CR,LF> 715 ;SB33IN1********************************************************* 716 0 00000CBF BE[0000] mov si,offset COM4DEV 0 00000CC2 E8B703 call AUX_INIT 0 00000CC5 BE[0000] mov si,offset COM3DEV 0 00000CC8 E8B103 call AUX_INIT 721 ;SB33IN1********************************************************* 0 00000CCB BE[0000] MOV SI,OFFSET COM2DEV 0 00000CCE E8AB03 CALL AUX_INIT ;INIT COM2 0 00000CD1 BE[0000] MOV SI,OFFSET COM1DEV 0 00000CD4 E8A503 CALL AUX_INIT ;INIT COM1 726 727 MESSAGE FTESTINIT,<"LPT DEVICES",CR,LF> 0 00000CD7 BE[0000] MOV SI,OFFSET LPT3DEV 0 00000CDA E89703 CALL PRINT_INIT ;INIT LPT3 0 00000CDD BE[0000] MOV SI,OFFSET LPT2DEV 0 00000CE0 E89103 CALL PRINT_INIT ;INIT LPT2 0 00000CE3 BE[0000] MOV SI,OFFSET LPT1DEV 0 00000CE6 E88B03 CALL PRINT_INIT ;INIT LPT1 734 0 00000CE9 31D2 XOR DX,DX 0 00000CEB 8EDA MOV DS,DX ;TO INITIALIZE PRINT SCREEN VECTOR 0 00000CED 8EC2 MOV ES,DX 738 0 00000CEF 31C0 XOR AX,AX 0 00000CF1 BF3405 MOV DI,INITSPOT 0 00000CF4 AB STOSW ;INIT FOUR BYTES TO 0 0 00000CF5 AB STOSW 743 0 00000CF6 8CC8 MOV AX,CS ;FETCH SEGMENT 745 746 extern i1B 0 00000CF8 C7066C00[0000] MOV WORD [BRKADR], i1B ;BREAK ENTRY POINT 0 00000CFE A36E00 MOV [BRKADR+2],AX ;VECTOR FOR BREAK 749 750 ;*********************************************** ARR 2.15 751 ; SINCE WE'RE FIRST IN SYSTEM, NO NEED TO CHAIN THIS. 752 ; CLI ; ARR 2.15 DON'T GET BLOWN 753 ; MOV DS:WORD PTR TIMADR,OFFSET TIMER ; ARR 2.15 TIMER ENTRY POINT 754 ; MOV DS:TIMADR+2,AX ; ARR 2.15 VECTOR FOR TIMER 755 ; STI 756 ;*********************************************** ARR 2.15 757 758 ; BAS DEBUG 759 extern i29 0 00000D01 C706A400[0000] MOV WORD [CHROUT*4], i29 0 00000D07 A3A600 MOV WORD PTR [CHROUT*4+2],AX 762 763 extern entry_iret 764 MESSAGE FTESTINIT,<"INTERRUPT VECTORS",CR,LF> 0 00000D0A BB[0000] MOV BX, entry_iret ;WILL INITIALIZE REST OF INTERRUPTS 766 0 00000D0D BF1000 mov di, 4 * 4 768 0 00000D10 50 push ax ; preserve segment 0 00000D11 53 push bx ; preserve offset 771 debugger_check: 0 00000D12 2EA0[BC02] mov al, byte [cs:checkdebugger] 0 00000D16 A804 test al, LCFG_DBG_ONLY_VALID 0 00000D18 740E jz @F 775 ; ds => IVT 0 00000D1A 833E0C00FF cmp word [3 * 4], -1 0 00000D1F 7420 je .nocheck 0 00000D21 833E0E0000 cmp word [3 * 4 + 2], 0 0 00000D26 7419 je .nocheck 780 @@: 0 00000D28 A808 test al, LCFG_DBG_ONLY_IISP 0 00000D2A 7411 jz @F 783 ; ds => IVT 0 00000D2C C41E0C00 les bx, [3 * 4] ; es:bx -> int 3 handler 0 00000D30 83FBEE cmp bx, -18 ; valid ? (could tear word access ?) 0 00000D33 770C ja .nocheck ; no, cannot be a valid IISP header --> 0 00000D35 26817F064B42 cmp word [es:bx + 6], "KB" ; signature present ? 0 00000D3B 7504 jne .nocheck ; no --> 789 @@: 0 00000D3D A801 test al, LCFG_DBG_CHECK 0 00000D3F 7508 jnz .check 792 .nocheck: 0 00000D41 2EC606[8004]90 mov byte [cs:.patch], 90h ; do not check 0 00000D47 EB00 jmp @F ; (flush queue for the SMC) 795 @@: 796 .check: 0 00000D49 1E push ds 0 00000D4A 07 pop es 0 00000D4B A802 test al, LCFG_DBG_ASSUME ; (NC) 0 00000D4D 7401 jz .runint3 ; if to assume off --> (NC) 0 00000D4F F9 stc ; assume on (CY) 802 .runint3: 0 00000D50 CC .patch: int3 ; SMC: patched to NOP if not to run int3 0 00000D51 7211 jc debugger_detected 805 806 debugger_disabled: 0 00000D53 BF0400 mov di, 4 * 1 0 00000D56 5B pop bx 0 00000D57 58 pop ax ; = segment 810 0 00000D58 93 XCHG AX,BX 0 00000D59 AB STOSW ;LOCATION 4 0 00000D5A 93 XCHG AX,BX 0 00000D5B AB STOSW ;INT 1 ;LOCATION 6 0 00000D5C 83C704 ADD DI,4 0 00000D5F 93 XCHG AX,BX 0 00000D60 AB STOSW ;LOCATION 12 0 00000D61 93 XCHG AX,BX 0 00000D62 AB STOSW ;INT 3 ;LOCATION 14 820 0 00000D63 A9 db 0A9h ; test ax, imm16 (skip pop, pop) 822 debugger_detected: 0 00000D64 5B pop bx 0 00000D65 58 pop ax 0 00000D66 93 XCHG AX,BX 0 00000D67 AB STOSW ;LOCATION 16 0 00000D68 93 XCHG AX,BX 0 00000D69 AB STOSW ;INT 4 ;LOCATION 18 829 0 00000D6A 89160005 MOV WORD PTR [500H],DX ;SET PRINT SCREEN & BREAK =0 0 00000D6E 89160405 MOV WORD PTR [LSTDRV],DX ;CLEAN OUT LAST DRIVE SPEC 832 833 MESSAGE FTESTINIT,<"DISK PARAMETER TABLE",CR,LF> 834 835 ; lDOS: our sector and initial loader do not relocate 836 ; the DPT so do it here instead. this code used 837 ; to be commented out. 0 00000D72 C5367800 lds si, [DSKADR] ; DS:SI -> CURRENT TABLE ARR 2.41 0 00000D76 BF2205 MOV DI,SEC9 ; ES:DI -> NEW TABLE ARR 2.41 0 00000D79 57 push di 0 00000D7A B90B00 MOV CX,DISK_PARMS_struc_size; ARR 2.41 0 00000D7D F3A4 REP MOVSB ; COPY TABLE ARR 2.41 0 00000D7F 06 PUSH ES ; ARR 2.41 0 00000D80 1F POP DS ; DS = 0 ARR 2.41 845 0 00000D81 8F067800 pop WORD PTR [DSKADR] ; ARR 2.41 0 00000D85 8C1E7A00 MOV WORD PTR [DSKADR+2],DS ; POINT DISK PARM VECTOR TO NEW TABLE 848 ; ARR 2.41 849 ;SB34INIT002****************************************************************** 850 ;SB We need to initalise the cs:MotorStartup variable from the disk 851 ;SB parameter table at SEC9. The offsets in this table are defined in 852 ;SB the DISK_PARMS struc in MSDSKPRM.INC. 2 LOCS 853 0 00000D89 A02C05 mov al,[SEC9 + DISK_MOTOR_STRT] 855 MotorStartup equ MOTORSTARTUP ; NASM port label 0 00000D8C 2EA2[0000] mov [cs:MotorStartup],al 857 ;SB34INIT002****************************************************************** 0 00000D90 2E803E[0000]FD CMP byte [cs:MODEL_BYTE],0FDH ; IS THIS AN OLD ROM? ARR 2.41 0 00000D96 720B JB NO_DIDDLE ; NO ARR 2.41 0 00000D98 C7062B050F02 MOV WORD [(SEC9 + DISK_HEAD_STTL)],0200H+NORMSETTLE 861 ; SET HEAD SETTLE AND MOTOR START 862 ; ON PC-1 PC-2 PC-XT HAL0 ARR 2.41 0 00000D9E C6062205DF MOV byte [(SEC9 + DISK_SPECIFY_1)],0DFH 864 ; SET 1ST SPECIFY BYTE 865 ; ON PC-1 PC-2 PC-XT HAL0 ARR 2.41 866 NO_DIDDLE: ; ARR 2.41 0 00000DA3 CD12 INT 12H ;GET MEMORY SIZE--1K BLOCKS IN AX 0 00000DA5 B106 MOV CL,6 0 00000DA7 D3E0 SHL AX,CL ;CONVERT TO 16-BYTE BLOCKS(SEGMENT NO.) 0 00000DA9 59 POP CX ; RETREIVE BOOT DRIVE NUMBER, AND FAT ID 871 ; cl = boot drive, 0 = A: 0 00000DAA BA[0000] MOV DX,SYSINITSEG 0 00000DAD 8EDA MOV DS,DX 874 875 ASSUME DS:SYSINITSEG 876 0 00000DAF A3[0000] MOV [MEMORY_SIZE],AX 0 00000DB2 41 INC cx 0 00000DB3 880E[0000] MOV [DEFAULT_DRIVE],CL ;SAVE DEFAULT DRIVE SPEC 880 0 00000DB7 31C9 xor cx,cx 882 883 ; IMPORTANT: SOME OLD IBM HARDWARE GENERATES SPURIOUS INT F'S DUE TO BOGUS 884 ; PRINTER CARDS. WE INITIALIZE THIS VALUE TO POINT TO AN IRET ONLY IF 885 886 ; 1) THE ORIGINAL SEGMENT POINTS TO STORAGE INSIDE VALID RAM. 887 888 ; 2) THE ORIGINAL SEGMENT IS 0F000:XXXX 889 890 ; THESES ARE CAPRICIOUS REQUESTS FROM OUR OEM FOR REASONS BEHIND THEM, READ 891 ; THE DCR'S FOR THE IBM DOS 3.2 PROJECT. 892 893 ASSUME ds:SYSINITSEG, es:NOTHING 894 0 00000DB9 8EC1 MOV es,cx ; cx := SEGMENT FOR INT 15 0 00000DBB 26A13E00 MOV AX,WORD PTR [es:(0FH*4+2)] 897 0 00000DBF 3B06[0000] CMP AX,[MEMORY_SIZE] ; CONDITION 1 0 00000DC3 7605 Jbe RESETINTF 900 0 00000DC5 3D00F0 CMP AX,0F000H ; CONDITION 2 0 00000DC8 750C JNE KEEPINTF 903 904 RESETINTF: 0 00000DCA 26C7063C00[0000] MOV WORD PTR [es:0FH*4], entry_iret 0 00000DD1 268C0E3E00 MOV WORD PTR [es:0FH*4+2],CS 907 KEEPINTF: 908 909 ; END IMPORTANT 910 911 ;SB34INIT003**************************************************************** 912 ;SB We will check if the system has IBM extended key board by 913 ;SB looking at a byte at 40:96. If bit 4 is set, then extended key board 914 ;SB is installed, and we are going to set KEYRD_Func to 10h, KEYSTS_Func to 11h 915 ;SB for the extended keyboard function. Use cx as the temporary register. 8 LOCS 916 0 00000DD6 26F606960410 test byte [es:0496h], 0001_0000b ; get keyboard flag 918 0 00000DDC 0E PUSH CS 0 00000DDD 1F POP DS 0 00000DDE 0E PUSH CS 0 00000DDF 07 POP ES 923 924 ASSUME DS:BIOCODE,ES:BIOCODE 925 0 00000DE0 7406 jz ORG_KEY ; orginal keyboard 927 KEYRD_func equ KEYRD_Func ; NASM port label 928 KEYSTS_func equ KEYSTS_Func ; NASM port label 0 00000DE2 C706[0000]1011 mov word [KEYRD_func], 11_10h ; change for extended keyboard functions 930 ; KEYSTS_Func is directly behind KEYRD_Func 931 ORG_KEY: 932 933 ;SB34INIT003**************************************************************** 934 935 ;************************************************************** 936 ; WILL INITIALIZE THE NUMBER OF DRIVES 937 ; AFTER THE EQUIPMENT CALL (INT 11H) BITS 6&7 WILL TELL 938 ; THE INDICATIONS ARE AS FOLLOWS: 939 ; 940 ; BITS 7 6 DRIVES 941 ; 0 0 1 942 ; 0 1 2 943 ; 1 0 3 944 ; 1 1 4 945 ;************************************************************** 946 0 00000DE8 E8A502 call CMOS_Clock_Read ;Before doing anythig else if CMOS clock exists, 948 ;then set the system time according to that. 949 ;Also, reset the cmos clock rate. 950 951 MESSAGE FTESTINIT,<"DISK DEVICES",CR,LF> 952 0 00000DEB 31F6 XOR SI,SI 0 00000DED C704[0000] MOV WORD PTR [SI],OFFSET HARDDRV ;SET UP POINTER TO HDRIVE 955 0 00000DF1 58 POP AX ;NUMBER OF FLOPPIES AND FAT ID 0 00000DF2 30E4 XOR AH,AH ; CHUCK FAT ID BYTE 0 00000DF4 A2[0000] MOV [DRVMAX],AL ;AND SET INITIAL NUMBER OF DRIVES 959 MESSAGE FTESTINIT,<"BEFORE INT 13",CR,LF> 960 961 determine_fhave96: 0 00000DF7 BA[0000] mov dx, SYSINITSEG 0 00000DFA 8EDA mov ds, dx 0 00000DFC 31D2 xor dx, dx ; dl = unit 0 0 00000DFE 803E[0600]01 cmp byte [FakeFloppyDrv],1 0 00000E03 0E push cs 0 00000E04 1F pop ds 0 00000E05 741A je .none 969 970 .LOOP_DRIVE: 0 00000E07 3A16[0000] CMP DL,[DRVMAX] 0 00000E0B 7314 jae .done 973 974 ; CHECK FOR CHANGELINE SUPPORT ON DRIVE 975 ;SB33023******************************************************************** 0 00000E0D B415 mov AH, 15h ;SB ; set command to get DASD type 0 00000E0F F9 stc 0 00000E10 CD13 int 13h ;SB ; call ROM-BIOS 979 ;SB33023******************************************************************** 0 00000E12 7205 JC .NEXTDRIVE 0 00000E14 80FC02 CMP AH,02 ; CHECK FOR PRESENCE OF CHANGELINE 0 00000E17 7403 je .have96 983 984 .NEXTDRIVE: 0 00000E19 42 INC dx 0 00000E1A EBEB JMP .LOOP_DRIVE 987 988 ; WE HAVE A DRIVE WITH CHANGE LINE SUPPORT. 989 ; shortcut to the end of the loop, ignoring any additional units 990 ; that may also have change line support. 991 .have96: 0 00000E1C C606[0000]01 mov byte [FHAVE96], 1 ; REMEMBER THAT WE HAVE 96TPI DISKS 993 994 .DONE_DRIVES: 995 .done: 996 .none: 997 ; proceeds to STATIC_CONFIGURE 998 999 === Switch to base=002530h -> "SYSINITTRAIL" 1000 usesection SYSINITTRAIL 1001 1002 alloc_upb: 0 00005176 50 push ax 0 00005177 53 push bx 0 00005178 51 push cx 0 00005179 2EC43E[0000] les di, [cs:nextupb] 0 0000517E 8CC0 mov ax, es 0 00005180 85C0 test ax, ax 0 00005182 741F jz .alloc 0 00005184 83C764 add di, BDSM_type_struc_size 0 00005187 2E893E[0000] mov word [cs:nextupb], di ; -> next UPB 0 0000518C B104 mov cl, 4 0 0000518E 8D5D73 lea bx, [di + BDSM_type_struc_size + 15] 1014 ; -> behind next UPB, round up 0 00005191 2E3B1E[0000] cmp bx, word [cs:nextupb] 0 00005196 7208 jb mem_err_j 0 00005198 D3EB shr bx, cl ; to paragraphs 0 0000519A B44A mov ah, 4Ah 0 0000519C CD21 int 21h ; resize 0 0000519E 7312 jnc @F 1021 mem_err_j: equ $ 1022 extern MEM_ERR 0 000051A0 E9[0000] jmp MEM_ERR 1024 1025 .alloc: 0 000051A3 B448 mov ah, 48h 0 000051A5 BB0700 mov bx, paras(BDSM_type_struc_size) 0 000051A8 CD21 int 21h 0 000051AA 72F4 jc mem_err_j 0 000051AC 8EC0 mov es, ax 0 000051AE 2EA3[0200] mov word [cs:nextupb + 2], ax 1032 @@: 0 000051B2 59 pop cx 0 000051B3 5B pop bx 0 000051B4 58 pop ax 0 000051B5 C3 retn 1037 1038 1039 global INITUPB 1040 INITUPB: 1041 1042 ;SB33021******************************************************************** 0 000051B6 B280 mov DL, 80h ;SB ; tell rom bios to look at hard drives 0 000051B8 B408 mov AH, 8h ;SB ; set command to get drive parameter 0 000051BA F9 stc 0 000051BB CD13 int 13h ;SB ; call ROM-BIOS to get number of drives 1047 1048 assume es:nothing 1049 ;SB33021******************************************************************** 0 000051BD 7205 JC ENDDRV ;CARRY INDICATES OLD ROM, SO NO HARDFILE 0 000051BF 2E8816[0000] MOV [cs:HNUM],DL 1052 ENDDRV: 1053 MESSAGE FTESTINIT,<"SETTING UP BDSS",CR,LF> 1054 1055 ; 1056 ; SCAN THE LIST OF DRIVES TO DETERMINE THEIR TYPE. WE HAVE THREE FLAVORS OF 1057 ; DISKETTE DRIVES: 1058 ; 1059 ; 48TPI DRIVES WE DO NOTHING SPECIAL FOR THEM 1060 ; 96TPI DRIVES MARK THE FACT THAT THEY HAVE CHANGELINE SUPPORT. 1061 ; 3 1/4 DRIVES MARK CHANGELINE SUPPORT AND SMALL. 1062 ; 1063 ; THE FOLLOWING CODE USES REGISTERS FOR CERTAIN VALUES: 1064 ; DL - PHYSICAL DRIVE 1065 ; DS:DI - POINTS TO CURRENT BDS 1066 ; CX - FLAG BITS FOR BDS 1067 ; DH - FORM FACTOR FOR THE DRIVE (1 - 48TPI, 2 - 96TPI, 3 - 3.5" MEDIUM) 1068 ; 0 000051C4 30D2 XOR DL,DL ; START OUT WITH DRIVE 0. 1070 0 000051C6 E8A002 call sysinit_get_ds_dosentry 0 000051C9 C606[0000]09 MOV byte [EOT],9 1073 ;J.K.6/24/87 Check if the system has no physical diskette drives. 1074 ;J.K. If it is, then we don't have to set BDS tables. But since we 1075 ;J.K. pretend that we have 2 floppies, we are going to reserve two 1076 ;J.K. BDS tables for the fake drive A, and B. and set the end of link 1077 ;J.K. pointer. 1078 1079 ;SB34INIT004********************************************************* 1080 ;SB Check to see if we are faking floppy drives. If not we don't 1081 ;SB do anything special. If we are faking floppy drives we need 1082 ;SB to set aside two BDSs for the two fake floppy drives. We 1083 ;SB don't need to initalise any fields though. So starting at START_BDS 1084 ;SB use the link field in the BDS structure to go to the second BDS 1085 ;SB in the list and initalise it's link field to -1 to set the end of 1086 ;SB the list. Then jump to the routine at DoHard to allocate/initialise 1087 ;SB the BDS for HardDrives. 1088 0 000051CE 2E803E[0600]01 cmp byte [cs:FakeFloppyDrv],1 0 000051D4 7533 jnz LOOP_DRIVE ; system has floppy 1091 link equ LINK ; NASM port equate 0 000051D6 E89DFF call alloc_upb 0 000051D9 0E push cs 0 000051DA 1F pop ds 0 000051DB BE[0A00] mov si, BDS_diskette_template 0 000051DE B96400 mov cx, BDS_TYPE_struc_size 0 000051E1 57 push di 0 000051E2 F3A4 rep movsb 0 000051E4 06 push es 0 000051E5 1F pop ds 0 000051E6 5F pop di 0 000051E7 C6450500 mov byte [di + DRIVELET], 0 0 000051EB E85A08 call Install_BDSM_and_set_bpb 1104 0 000051EE E885FF call alloc_upb 0 000051F1 0E push cs 0 000051F2 1F pop ds 0 000051F3 BE[0A00] mov si, BDS_diskette_template 0 000051F6 B96400 mov cx, BDS_TYPE_struc_size 0 000051F9 57 push di 0 000051FA F3A4 rep movsb 0 000051FC 06 push es 0 000051FD 1F pop ds 0 000051FE 5F pop di 0 000051FF C6450501 mov byte [di + DRIVELET], 1 0 00005203 E84208 call Install_BDSM_and_set_bpb 1117 1118 DoHard equ DOHARD ; NASM port label 0 00005206 E93001 jmp DoHard ; allocate/initialise BDS for HardDrives 1120 ;SB34INIT004********************************************************* 1121 1122 LOOP_DRIVE: 0 00005209 E85D02 call sysinit_get_ds_dosentry 0 0000520C 3A16[0000] CMP DL,[DRVMAX] 0 00005210 7203E92401 jae DONE_DRIVES 1126 0 00005215 E85EFF call alloc_upb 0 00005218 0E push cs 0 00005219 1F pop ds 0 0000521A BE[0A00] mov si, BDS_diskette_template 0 0000521D B96400 mov cx, BDS_TYPE_struc_size 0 00005220 57 push di 0 00005221 F3A4 rep movsb 0 00005223 5F pop di 1135 ; XOR CX,CX ; ZERO ALL FLAGS (cx already zero) 1136 0 00005224 B600 MOV DH,FF48TPI ; SET FORM FACTOR TO 48 TPI 0 00005226 C606[7500]28 MOV byte [NUM_CYLN],40 ; 40 TRACKS PER SIDE 1139 0 0000522B 1E PUSH DS 0 0000522C 57 PUSH DI 0 0000522D 52 PUSH DX 0 0000522E 51 PUSH CX 1144 1145 ;SB33022******************************************************************** 0 0000522F B408 MOV AH, 8h ;GET DRIVE PARAMETERS ;SB;3.30 0 00005231 F9 stc 0 00005232 CD13 INT 13h ;CALL ROM-BIOS ;SB;3.30 1149 ;SB33022******************************************************************** 0 00005234 726F jc NOPARMSFROMROM ; GOT AN OLD ROM 1151 1152 ;J.K. 10/9/86 If CMOS is bad, it gives ES,AX,BX,CX,DH,DI=0. CY=0. 1153 ;In this case, we are going to put bogus informations to BDS table. 1154 ;We are going to set CH=39,CL=9,DH=1 to avoid divide overflow when 1155 ;they are calculated at the later time. This is just for the Diagnostic 1156 ;Diskette which need MSBIO,MSDOS to boot up before it sets CMOS. 1157 ;This should only happen with drive B. 1158 0 00005236 80FD00 CMP CH,0 ; if ch=0, then cl,dh=0 too. 0 00005239 7506 JNE PFR_OK 0 0000523B B527 MOV CH,39 ; ROM gave wrong info. 0 0000523D B109 MOV CL,9 ; Let's default to 360K. 0 0000523F B601 MOV DH,1 1164 PFR_OK: 0 00005241 FEC5 INC CH ; MAKE NUMBER OF CYLINDERS 1-BASED 0 00005243 8836[7200] MOV byte ptr [NUM_HEADS],DH ; SAVE PARMS RETURNED BY ROM 0 00005247 FF06[7200] inc word ptr [NUM_HEADS] ; MAKE NUMBER OF HEADS 1-BASED 0 0000524B 80E13F AND CL,00111111B ; EXTRACT SECTORS/TRACK 0 0000524E 880E[7400] MOV [SEC_TRK],CL 0 00005252 882E[7500] MOV [NUM_CYLN],CH ; ASSUME LESS THAN 256 CYLINDERS!! 1171 0 00005256 E81002 call sysinit_get_ds_dosentry 1173 ; MAKE SURE THAT EOT CONTAINS THE MAX NUMBER OF SEC/TRK IN SYSTEM OF FLOPPIES 0 00005259 3A0E[0000] CMP CL,[EOT] ; MAY SET CARRY 0 0000525D 7604 JBE EOT_OK 0 0000525F 880E[0000] MOV [EOT],CL 1177 EOT_OK: 0 00005263 59 POP CX 0 00005264 5A POP DX 0 00005265 5F POP DI 0 00005266 1F POP DS 1182 1183 ; CHECK FOR CHANGELINE SUPPORT ON DRIVE 1184 ;SB33023******************************************************************** 0 00005267 B415 mov AH, 15h ;SB ; set command to get DASD type 0 00005269 F9 stc 0 0000526A CD13 int 13h ;SB ; call ROM-BIOS 1188 ;SB33023******************************************************************** 0 0000526C 7208 JC CHANGELINE_DONE 0 0000526E 80FC02 CMP AH,02 ; CHECK FOR PRESENCE OF CHANGELINE 0 00005271 7503 JNE CHANGELINE_DONE 1192 ; 1193 ; WE HAVE A DRIVE WITH CHANGE LINE SUPPORT. 1194 ; 1195 MESSAGE FTESTINIT,<"96TPI DEVICES",CR,LF> 1196 0 00005273 80C902 OR CL,FCHANGELINE ; SIGNAL TYPE 1198 ; 1199 ; WE NOW TRY TO SET UP THE FORM FACTOR FOR THE TYPES OF MEDIA THAT WE KNOW 1200 ; AND CAN RECOGNISE. FOR THE REST, WE SET THE FORM FACTOR AS "OTHER". 1201 ; 1202 CHANGELINE_DONE: 0 00005276 0E push cs 0 00005277 1F pop ds 1205 ; 40 CYLINDERS AND 9 OR LESS SEC/TRK, TREAT AS 48 TPI MEDIUM. 0 00005278 803E[7500]28 CMP byte [NUM_CYLN],40 0 0000527D 750B JNZ TRY_80 0 0000527F 803E[7400]09 CMP byte [SEC_TRK],9 0 00005284 761D JBE GOT_FF ; dh = FF48TPI --> 1210 GOTOTHER: 0 00005286 B607 MOV DH,FFOTHER ; WE HAVE A "STRANGE" MEDIUM 0 00005288 EB19 JMP SHORT GOT_FF 1213 1214 ; 1215 ; 80 CYLINDERS AND 9 SECTORS/TRACK => 720 KB DEVICE 1216 ; 80 CYLINDERS AND 15 SEC/TRK => 96 TPI MEDIUM 1217 ; 1218 TRY_80: 0 0000528A B601 MOV DH,FF96TPI ; in case it is 96 TPI 0 0000528C 803E[7500]50 CMP byte [NUM_CYLN],80 0 00005291 75F3 JNZ GOTOTHER ; resets dh 0 00005293 803E[7400]0F CMP byte [SEC_TRK],15 0 00005298 7409 JZ GOT_FF ; (dh = FF96TPI) 0 0000529A 803E[7400]09 CMP byte [SEC_TRK],9 0 0000529F 75E5 JNZ GOTOTHER ; resets dh 0 000052A1 B602 MOV DH,FFSMALL ; reset dh 1227 GOT_FF: 0 000052A3 EB28 JMP SHORT NEXTDRIVE 1229 1230 ; WE HAVE AN OLD ROM, SO WE EITHER HAVE A 48TPI OR 96TPI DRIVE. IF THE DRIVE 1231 ; HAS CHANGELINE, WE ASSUEM IT IS A 96TPI, OTHERWISE WE TREAT IT AS A 48TPI. 1232 1233 NOPARMSFROMROM: 0 000052A5 59 POP CX 0 000052A6 5A POP DX 0 000052A7 5F POP DI 0 000052A8 1F POP DS 1238 1239 ;SB33024**************************************************************** 0 000052A9 B415 MOV AH, 15h ; SET COMMAND TO GET DASD TYPE ;SB;3.30 0 000052AB F9 stc 0 000052AC CD13 INT 13h ; CALL ROM-BIOS ;SB;3.30 1243 ;SB33024**************************************************************** 0 000052AE 721D JC NEXTDRIVE 0 000052B0 80FC02 CMP AH,2 ; IS THERE CHANGELINE? 0 000052B3 7518 JNZ NEXTDRIVE 0 000052B5 80C902 OR CL,FCHANGELINE 0 000052B8 C606[7500]50 MOV byte [NUM_CYLN],80 0 000052BD B601 MOV DH,FF96TPI 0 000052BF B00F MOV AL,15 ; SET EOT IF NECESSARY 1251 0 000052C1 E8A501 call sysinit_get_ds_dosentry 0 000052C4 3A06[0000] CMP AL, [EOT] 0 000052C8 7603 JBE EOT_OK2 0 000052CA A2[0000] MOV [EOT],AL 1256 EOT_OK2: 1257 1258 NEXTDRIVE: 0 000052CD 80C920 OR CL,FI_OWN_PHYSICAL ; SET THIS TRUE FOR ALL DRIVES 0 000052D0 88D7 MOV BH,DL ;SAVE INT13 DRIVE NUMBER 1261 1262 ; WE NEED TO DO SPECIAL THINGS IF WE HAVE A SINGLE DRIVE SYSTEM AND ARE SETTING 1263 ; UP A LOGICAL DRIVE. IT NEEDS TO HAVE THE SAME INT13 DRIVE NUMBER AS ITS 1264 ; COUNTERPART, BUT THE NEXT DRIVE LETTER. ALSO RESET OWNERSHIP FLAG. 1265 ; WE DETECT THE PRESENCE OF THIS SITUATION BY EXAMINING THE FLAG SINGLE FOR THE 1266 ; VALUE 2. 1267 0 000052D2 E89401 call sysinit_get_ds_dosentry 0 000052D5 803E[0000]02 CMP byte [SINGLE],2 0 000052DA 7505 JNZ NOT_SPECIAL 0 000052DC FECF DEC BH ; INT13 DRIVE NUMBER SAME FOR LOGICAL DRIVE 0 000052DE 80F120 XOR CL,FI_OWN_PHYSICAL ; RESET OWNERSHIP FLAG FOR LOGICAL DRIVE 1273 NOT_SPECIAL: 1274 ; THE VALUES THAT WE PUT IN FOR RHDLIM AND RSECLIM WILL ONLY REMAIN IF THE 1275 ; FORM FACTOR IS OF TYPE "FFOTHER". 0 000052E1 2E8E1E[0200] mov ds, word [cs:nextupb + 2] 0 000052E6 2EA1[7200] MOV ax, [cs:NUM_HEADS] 0 000052EA 894536 MOV WORD PTR [DI + RHDLIM],AX 0 000052ED 2EA0[7400] MOV AL,[cs:SEC_TRK] 0 000052F1 894534 MOV WORD PTR [DI + RSECLIM],AX 0 000052F4 894D23 MOV WORD PTR [DI + FLAGS],CX 0 000052F7 887522 MOV BYTE PTR [DI + FORMFACTOR],DH 0 000052FA 885505 MOV BYTE PTR [DI + DRIVELET],DL 0 000052FD 887D04 MOV BYTE PTR [DI + DRIVENUM],BH 0 00005300 2E8A1E[7500] MOV BL,BYTE PTR [cs:NUM_CYLN] 0 00005305 885D25 MOV BYTE PTR [DI + CCYLN],BL ; ONLY THE L.S. BYTE IS SET HERE 0 00005308 E83D07 call Install_BDSM_and_set_bpb 0 0000530B E86401 call sysinit_get_es_dosentry 0 0000530E 26803E[0000]01 CMP byte [es:SINGLE],1 ; SPECIAL CASE FOR SINGLE DRIVE SYSTEM 0 00005314 751F JNZ NO_SINGLE 1291 MESSAGE FTESTINIT,<"SINGLE DRIVE SYSTEM",CR,LF> 0 00005316 26FE06[0000] inc byte [es:SINGLE] ; DON'T LOSE INFO THAT WE HAVE SINGLE SYSTEM 0 0000531B 83C910 OR CX,FI_AM_MULT 0 0000531E 094D23 OR WORD PTR [DI + FLAGS],CX 0 00005321 42 inc dx 1296 0 00005322 E851FE call alloc_upb 0 00005325 0E push cs 0 00005326 1F pop ds 0 00005327 BE[0A00] mov si, BDS_diskette_template 0 0000532A 51 push cx 0 0000532B B96400 mov cx, BDS_TYPE_struc_size 0 0000532E 57 push di 0 0000532F F3A4 rep movsb 0 00005331 5F pop di ; di -> next UPB 0 00005332 59 pop cx 0 00005333 EB98 JMP SHORT NEXTDRIVE ; USE SAME INFO FOR BDS A PREVIOUS 1308 NO_SINGLE: 0 00005335 42 inc dx 0 00005336 E9D0FE JMP LOOP_DRIVE 1311 1312 DONE_DRIVES: 1313 1314 ; SET UP ALL THE HARD DRIVES IN THE SYSTEM 1315 1316 DOHARD: 1317 MNUM FTESTINIT+FTESTHARD,AX 1318 MESSAGE FTESTINIT+FTESTHARD,<" HARD DISK(S) TO INITIALIZE",CR,LF> 1319 MESSAGE FTESTINIT+FTESTHARD,<"HARD DISK 1",CR,LF> 1320 1321 extern amountprimary 1322 0 00005339 B780 mov bh, 80h 0 0000533B 2E8A1E[0000] mov bl, [cs:HARDNUM] 1325 loop_primary: 0 00005340 2E803E[0000]00 cmp byte [cs:HNUM], 0 ; IF (NO_HARD_FILES) 0 00005346 743B jz done_primary ; THEN EXIT TO CONFIGURE 1328 0 00005348 E82BFE call alloc_upb 0 0000534B 0E push cs 0 0000534C 1F pop ds 1332 extern BDS_harddisk_template 0 0000534D BE[0000] mov si, BDS_harddisk_template 0 00005350 51 push cx 0 00005351 B96400 mov cx, BDS_TYPE_struc_size 0 00005354 57 push di 0 00005355 F3A4 rep movsb 0 00005357 5F pop di ; di -> next UPB 0 00005358 06 push es 0 00005359 1F pop ds 0 0000535A 59 pop cx 0 0000535B 88FA mov dl, bh ; dl = hdd unit number 0 0000535D E84E01 CALL SETHARD 0 00005360 FEC7 inc bh ; bh = next hdd unit number 0 00005362 2EFE0E[0000] dec byte [cs:HNUM] ; count down amount hdd units 1346 assume es:nothing 0 00005367 7307 JNC .ok 0 00005369 75D5 jnz loop_primary ; another unit to check 0 0000536B E80E00 call hdd_dealloc 0 0000536E EB13 jmp done_primary 1351 1352 .ok: 0 00005370 2EFE06[0000] inc byte [cs:amountprimary] ; count how many installed 0 00005375 E8D006 call Install_BDSM_and_set_bpb ; INSTALL BDS INTO LINKED LIST 0 00005378 FEC3 inc bl ; bl = next DOS unit number 0 0000537A EBC4 jmp loop_primary 1357 1358 hdd_dealloc: 0 0000537C 2E832E[0000]64 sub word [cs:nextupb], BDS_TYPE_struc_size 0 00005382 C3 retn 1361 1362 done_primary: 0 00005383 2EA0[0000] mov al, [cs:amountprimary] 0 00005387 2E0206[0000] ADD AL,[cs:HARDNUM] 0 0000538C E8DA00 call sysinit_get_ds_dosentry 0 0000538F A2[0000] MOV [DRVMAX],AL 1367 1368 ; End of physical drive initialization. 1369 ; *** Do not change the position of the following statement.-J.K.4/7/86 1370 ; *** DoMini routine will use [DRVMAX] value for the start of the logical 1371 ; *** drive number of Mini disk(s). 1372 0 00005392 E81F05 call DoMini ; For setting up mini disks, if found 1374 1375 assume es:nothing 1376 ; END OF DRIVE INITIALIZATION. 1377 1378 hdd_done: ; (label unused) 1379 ; ADJUST THE NUMBER OF DRIVES TO INCLUDE THE HARD DISKS. 0 00005395 0E push cs 0 00005396 1F pop ds 0 00005397 A0[0000] MOV AL,[HARDNUM] 0 0000539A 0206[0000] add al, [amountprimary] 0 0000539E 0206[E600] add al, [num_mini_dsk] ; J.K. 4/7/86 for mini disks installed 1385 ; if not installed, then num_mini_dsk = 0. 0 000053A2 E8C400 call sysinit_get_ds_dosentry 0 000053A5 A2[0000] MOV [DRVMAX],AL 1388 0 000053A8 E86204 CALL SETDRVPARMS 1390 1391 write_dskdrvs_upb: 0 000053AB 0E push cs 0 000053AC 1F pop ds 0 000053AD C43E[0000] les di, [nextupb] 0 000053B1 8CC0 mov ax, es 0 000053B3 85C0 test ax, ax 0 000053B5 745D jz .done 0 000053B7 83C765 add di, BDSM_type_struc_size + 1; -> behind last UPB 0 000053BA 722C jc .mem_err_j 0 000053BC 83E7FE and di, ~1 ; round to word boundary 0 000053BF BE[EE00] mov si, DSKDRVS 0 000053C2 8B1E[EC00] mov bx, [Mini_BPB_ptr] 0 000053C6 29F3 sub bx, si 0 000053C8 89D9 mov cx, bx 0 000053CA 01FB add bx, di 0 000053CC 721A jc .mem_err_j 0 000053CE 83C30F add bx, 15 ; -> behind wanted list 0 000053D1 7215 jc .mem_err_j 0 000053D3 3B1E[0000] cmp bx, word [nextupb] 0 000053D7 7303E9C4FD jb mem_err_j 0 000053DC 51 push cx 0 000053DD B104 mov cl, 4 0 000053DF D3EB shr bx, cl ; to paragraphs 0 000053E1 59 pop cx 0 000053E2 B44A mov ah, 4Ah 0 000053E4 CD21 int 21h ; resize 0 000053E6 7303 jnc @F 1418 .mem_err_j: 0 000053E8 E9B5FD jmp mem_err_j 1420 @@: 0 000053EB D1E9 shr cx, 1 0 000053ED 57 push di 0 000053EE F3A5 rep movsw 0 000053F0 E87600 call sysinit_get_ds_dosentry 1425 extern dskdrvs_indirect 0 000053F3 8C06[0200] mov word [dskdrvs_indirect + 2], es 0 000053F7 8F06[0000] pop word [dskdrvs_indirect] 1428 0 000053FB 8CC0 mov ax, es 0 000053FD 48 dec ax 0 000053FE 8EC0 mov es, ax 0 00005400 26C70601000800 mov word [es:arena_owner], 8 1433 ; init owner 0 00005407 BF0500 mov di, arena_reserved 0 0000540A 0E push cs 0 0000540B 1F pop ds 0 0000540C BE[3204] mov si, upb_smcb 0 0000540F B90B00 mov cx, 3 + 8 0 00005412 F3A4 rep movsb ; init name and type 1440 1441 .done: 1442 0 00005414 31C9 xor cx, cx 0 00005416 2E870E[0400] xchg cx, word [cs:Init_BootSeg] 0 0000541B E306 jcxz @F 0 0000541D 8EC1 mov es, cx 0 0000541F B449 mov ah, 49h 0 00005421 CD21 int 21h 1449 @@: 0 00005423 C3 retn 1451 1452 upb_smcb: 0 00005424 000000 db 0,0,0 0 00005427 5300 db "S",0 ; name "S" 0 00005429 09 db 9 ; type S_UPB 0 0000542A 00 times 5 db 0 1457 1458 === Switch to base=000000h -> "DOSENTRY" 1459 usesection DOSENTRY 1460 1461 ;J.K. 9/24/86 We now decide, based on the configurations available so far, what 1462 ;code or data we need to keep as a stay resident code. The following table 1463 ;shows the configurations under consideration. They are listed in the order 1464 ;of their current position memory. 1465 ;Configuration will be done in two ways: 1466 ;First, we are going to set "Static configuration". Static configuration will 1467 ;consider from basic configuration to ENDOF96TPI configuration. The result 1468 ;of static configuration will be the address the Dynamic configuration will 1469 ;use to start with. 1470 ;Secondly, "Dynamic cofiguration" will be performed. Dynamic configuration 1471 ;involves possible relocation of CODE or DATA. Dynamic configuration routine 1472 ;will take care of BDSM tables and AT ROM Fix module thru K09 suspend/resume 1473 ;code individually. After these operation, FINAL_DOS_LOCATION will be set. 1474 ;This will be the place SYSINIT routine will relocate MSDOS module for good. 1475 ; 1476 ; 1. BASIC CONFIGURATION FOR IBMBIO (EndFloppy, EndSwap) 1477 ; 2. ENDONEHARD 1478 ; 3. ENDTWOHARD 1479 ; 4. END96TPI ;a system that supports "Change Line Error" 1480 ; 5. End of BDSM ;BDSM tables for mini disks. 1481 ; 6. ENDATROM ;Some of AT ROM fix module. 1482 ; 7. ENDCMOSCLOCKSET;Supporting program for CMOS clock write. 1483 ; 8. ENDK09 ;K09 CMOS Clock module to handle SUSPEND/RESUME operation. 1484 ; 1485 ;J.K. 9/24/86. 1486 1487 STATIC_CONFIGURE: 0 00000E21 B8[0000] mov ax, offset END96TPI ;let's start with the biggest one. 1489 fHave96 equ FHAVE96 ; NASM port label 0 00000E24 803E[0000]00 cmp byte [fHave96], 0 ;Is change line support there? 1491 Config96 equ CONFIG96 ; NASM port label 0 00000E29 7502 jnz Config96 ;Yes. 1493 1494 Basic_Floppy: 1495 ; mov ax, offset ENDFLOPPY 1496 ; ldos: do leave DOSENTRY data up to END96TPI resident 1497 Dynamic_Configure equ DYNAMIC_CONFIGURE ; NASM port label 0 00000E2B EB22 jmp Dynamic_Configure ;static configuration is done! 1499 1500 ; 1501 ; KEEP THE 96TPI CODE 1502 ; 1503 CONFIG96: 1504 ; 1505 ; SAVE OLD INT 13 VECTOR 1506 ; 0 00000E2D 1E push ds 0 00000E2E 07 pop es 1509 0 00000E2F 50 PUSH AX 0 00000E30 1E PUSH DS 0 00000E31 31C0 XOR AX,AX 0 00000E33 8ED8 MOV DS,AX 1514 ASSUME DS:NOTHING 1515 0 00000E35 A14C00 MOV AX,[4 * 13H] 0 00000E38 26A3[0000] MOV WORD PTR [es:REAL13],AX 0 00000E3C A14E00 MOV AX,[4 * 13H+2] 0 00000E3F 26A3[0200] MOV WORD PTR [es:REAL13+2],AX 1520 ; 1521 ; INSERT NEW VECTOR 1522 ; 1523 extern ms96tpi_i13 0 00000E43 C7064C00[0000] MOV WORD PTR [4 * 13H],OFFSET ms96tpi_i13 0 00000E49 8C064E00 MOV [4 * 13H + 2], es 1526 0 00000E4D 1F POP DS 1528 ASSUME DS:BIOCODE 0 00000E4E 58 POP AX 1530 1531 DYNAMIC_CONFIGURE: 0 00000E4F 1E push ds 0 00000E50 07 pop es 1534 assume es:BIOcode 0 00000E51 FC cld ;clear direction 1536 1537 CheckATROM: 0 00000E52 E80B02 call Get_Para_Offset ;For dynamic allocation, we are 1539 ;going to use offset address that 1540 ;is in paragraph boundary. 1541 1542 0 00000E55 803E[0000]FC cmp byte [Model_Byte], 0FCh ;AT ? 0 00000E5A 753D jnz CheckCMOSClock 1545 0 00000E5C 50 push ax 0 00000E5D B280 mov DL, 80h ; tell rom bios to look at hard drives 0 00000E5F B408 mov AH, 8h ; set command to get drive parameter 0 00000E61 F9 stc 0 00000E62 CD13 int 13h ; call ROM-BIOS to get number of drives 0 00000E64 58 pop ax 0 00000E65 7232 jc CheckCMOSClock 0 00000E67 84D2 test dl, dl ; No hard file? 0 00000E69 742E jz CheckCMOSClock 1555 0 00000E6B BE00F0 mov si, 0F000h 0 00000E6E 8EC6 mov es, si ;ES -> BIOS segment 1558 assume es:nothing ; 0 00000E70 BE[BD02] mov si, offset BIOS_DATE ; 0 00000E73 BFF5FF mov di, 0FFF5H ;ROM BIOS string is at F000:FFF5 1561 Cmpbyte: ;Only patch ROM for bios dated 01/10/84 0 00000E76 A6 cmpsb ; 0 00000E77 7520 jnz CheckCMOSClock ; 0 00000E79 807CFF00 cmp byte ptr [si-1],0 ; 0 00000E7D 75F7 jnz Cmpbyte ; 1566 SetRomCode: ;Now we have to install ROM fix 1567 ;AX is the address to move. 0 00000E7F 1E push ds 0 00000E80 07 pop es 1570 assume es:BIOcode 1571 0 00000E81 A3[0000] mov word ptr [ORIG13], ax 0 00000E84 8C1E[0200] mov word ptr [ORIG13+2], ds ;set new ROM bios int 13 vector 0 00000E88 B9[0000] mov cx, offset ENDATROM 0 00000E8B BE[0000] mov si, offset IBM_DISK_IO 0 00000E8E 29F1 sub cx, si ;size of AT ROM FIX module 0 00000E90 89C7 mov di, ax ;destination 0 00000E92 F3A4 rep movsb ;relocate it 0 00000E94 89F8 mov ax, di ;new ending address 0 00000E96 E8C701 call Get_Para_Offset ;in AX 1581 1582 CheckCMOSClock: 0 00000E99 1E push ds 0 00000E9A 07 pop es ;set ES to CODE seg 1585 assume es:BIOcode 0 00000E9B 803E[0000]01 cmp byte [HaveCMOSClock], 1 ;CMOS Clock exists? 0 00000EA0 7528 jne CheckK09 0 00000EA2 A3[0000] mov [DaycntToDay], ax ;set the address for MSCLOCK 0 00000EA5 B9[D200] mov cx, offset EndDaycntToDay 1590 Daycnt_To_Day equ Daycnt_to_day ; NASM port label 0 00000EA8 BE[0000] mov si, offset Daycnt_To_Day 0 00000EAB 29F1 sub cx, si ;size of CMOS clock supporting routine 0 00000EAD 89C7 mov di, ax 0 00000EAF F3A4 rep movsb 0 00000EB1 89F8 mov ax, di 0 00000EB3 E8AA01 call Get_Para_Offset 0 00000EB6 A3[0000] mov [BinToBCD], ax ;set the address for MSCLOCK 1598 EndCMOSClockSet equ EndCMOSClockset ; NASM port label 0 00000EB9 B9[E100] mov cx, offset EndCMOSClockSet 1600 Bin_To_BCD equ Bin_to_bcd ; NASM port label 0 00000EBC BE[D200] mov si, offset Bin_To_BCD 0 00000EBF 29F1 sub cx, si 0 00000EC1 89C7 mov di, ax 0 00000EC3 F3A4 rep movsb 0 00000EC5 89F8 mov ax, di 0 00000EC7 E89601 call Get_Para_Offset 1607 1608 CheckK09: 1609 ;SB33025**************************************************************** 0 00000ECA 50 push ax ;save ax ;SB ;3.30* 0 00000ECB 06 push es 1612 0 00000ECC B4C0 mov ah, 0C0h 0 00000ECE F9 stc 0 00000ECF CD15 int 15h 0 00000ED1 7210 jc .no_k09_if_CY 0 00000ED3 26F6470508 test byte [es:bx + 5], 1 << 3 0 00000ED8 F9 stc 0 00000ED9 7408 jz .no_k09_if_CY 1620 0 00000EDB B80041 mov ax,4100h ;Q: is it a K09 ;SB ;3.30* 0 00000EDE B300 mov bl,0 ; ;SB ;3.30* 0 00000EE0 F9 stc 0 00000EE1 CD15 int 15h ; ;SB ;3.30* 1625 ;SB33025**************************************************************** 1626 .no_k09_if_CY: 0 00000EE3 07 pop es 0 00000EE4 58 pop ax 0 00000EE5 7228 jc CONFIGDONE 1630 0 00000EE7 BE[E200] mov si, offset INT6C 0 00000EEA B9[BA02] mov cx, offset ENDK09 0 00000EED 29F1 sub cx, si ;size of K09 routine 0 00000EEF 89C7 mov di, ax 0 00000EF1 57 push di ;save destination 0 00000EF2 F3A4 rep movsb 0 00000EF4 89F8 mov ax, di ; 0 00000EF6 E86701 call Get_Para_Offset ;AX = new ending address 0 00000EF9 5F pop di 1640 0 00000EFA 50 push ax 0 00000EFB 1E push ds 1643 fHaveK09 equ FHAVEK09 ; NASM port label 0 00000EFC C606[0000]01 mov byte [fHaveK09], 1 ;remember we have a K09 type 0 00000F01 31C0 xor ax,ax 0 00000F03 8ED8 mov ds, ax 1647 assume ds:nothing 1648 0 00000F05 893EB001 mov word ptr [4 * 6Ch], di ;new INT 6Ch handler 0 00000F09 8C06B201 mov [4 * 6Ch +2], es 1651 0 00000F0D 1F pop ds 1653 assume ds:BIOcode 0 00000F0E 58 pop ax ;restore the ending address 1655 1656 ; SET UP CONFIG STUFF FOR SYSINIT 1657 1658 CONFIGDONE: ;AX is final ending address of MSBIO. 0 00000F0F BA[0000] MOV DX,SYSINITSEG 0 00000F12 8EDA MOV DS,DX 1661 ASSUME DS:SYSINITSEG 1662 1663 ; SUB AX,OFFSET START$ ; (zero) 0 00000F14 83C00F ADD AX,15 0 00000F17 D1D8 RCR AX,1 0 00000F19 D1E8 SHR AX, 1 0 00000F1B D1E8 SHR AX, 1 0 00000F1D D1E8 SHR AX, 1 0 00000F1F 05[0000] add ax, DOSENTRY 0 00000F22 A3[0000] MOV [FINAL_DOS_LOCATION], AX 0 00000F25 2EA0[0000] mov al, [cs:DRVMAX] 0 00000F29 A2[0000] mov [HARDNUM], al ; REMEMBER WHICH DRIVE IS HARD DISK 1673 1674 GOINIT: 1675 MESSAGE FTESTINIT,<"FINAL DOS LOCATION IS "> 1676 MNUM FTESTINIT,FINAL_DOS_LOCATION 1677 MESSAGE FTESTINIT, 0 00000F2C 0E PUSH CS 0 00000F2D 1F POP DS 1680 1681 ASSUME DS:BIOCODE,ES:NOTHING 1682 1683 %if 0 1684 CMP BYTE [FHAVE96],0 1685 JNZ READDOS 1686 CALL PURGE_96TPI ;MJB001 ELIMINATE CALLS TO 96TPI HOOHAH 1687 1688 READDOS: 1689 %endif 1690 1691 LOADIT: 1692 MESSAGE FTESTINIT,<"SYSINIT",CR,LF> 1693 ZWAIT 1694 MESSAGE FTESTINIT,<"ON TO SYSINIT...",CR,LF> 1695 1696 extern SYSSIZE, afterdoscodelabel, doscode_start 1697 0 00000F2E B8[0000] MOV AX, SYSSIZE wrt SYSINITSEG 0 00000F31 E85B00 call dosentry_init_ParaRound 0 00000F34 91 xchg cx, ax 0 00000F35 B8[0000] mov ax, afterdoscodelabel wrt DOSCODEGROUP 0 00000F38 E85400 call dosentry_init_ParaRound 0 00000F3B 01C1 add cx, ax 1704 0 00000F3D BB[0000] mov bx, SYSINITSEG 0 00000F40 8EDB mov ds, bx 0 00000F42 8B16[0000] mov dx, [MEMORY_SIZE] 0 00000F46 83EA01 sub dx, 1 ; leave buffer for first UMCB 0 00000F49 7611 jbe .oom 0 00000F4B 29CA sub dx, cx 0 00000F4D 720D jc .oom 1712 0 00000F4F B8[5707] mov ax, end_of_dosentry_init_late 0 00000F52 E83A00 call dosentry_init_ParaRound 0 00000F55 05[0000] add ax, DOSENTRY 0 00000F58 39C2 cmp dx, ax 0 00000F5A 7316 jae @F 1718 1719 .oom: 1720 dosentry_init_oom: 0 00000F5C BE[5707] mov si, dosentry_init_msg.oom 0 00000F5F B40E mov ah, 0Eh 0 00000F61 BB0700 mov bx, 7 0 00000F64 A9 db __TEST_IMM16 ; skip int 1725 .msgloop: 0 00000F65 CD10 int 10h 0 00000F67 2EAC cs lodsb 0 00000F69 84C0 test al, al 0 00000F6B 75F8 jnz .msgloop 1730 .halt: 0 00000F6D CC int3 0 00000F6E FB sti 0 00000F6F F4 hlt 0 00000F70 EBFB jmp .halt 1735 1736 @@: 0 00000F72 B8[0000] mov ax, SYSINITSEG 0 00000F75 E82300 call dosentry_init_movp 1739 1740 ; xor ax, ax 1741 ; mov ds, ax 0 00000F78 B8[0000] mov ax, DOSSTART 1743 ; mov word [31h * 4 + 2], ax ; init => DOSDATA 1744 ; Not needed here, still the same as earlier init. 0 00000F7B 8ED8 mov ds, ax 0 00000F7D B8[0000] mov ax, doscode_start wrt SYSINITGROUP 0 00000F80 B104 mov cl, 4 0 00000F82 D3E8 shr ax, cl ; = how many paragraphs from cs 0 00000F84 01D0 add ax, dx ; => DOSCODE 0 00000F86 A3[0000] mov word [dosdata_to_doscode], ax 1751 0 00000F89 B8[0000] mov ax, SYSINIT 0 00000F8C 52 push dx 0 00000F8D 50 push ax 0 00000F8E CB retf 1756 1757 INIT ENDP 1758 1759 1760 dosentry_init_ParaRound: 0 00000F8F 83C00F ADD AX,15 0 00000F92 D1D8 RCR AX,1 0 00000F94 D1E8 SHR AX,1 0 00000F96 D1E8 SHR AX,1 0 00000F98 D1E8 SHR AX,1 0 00000F9A C3 retn 1767 1768 1769 ; Move paragraphs 1770 ; 1771 ; INP: ax:0-> source 1772 ; dx:0-> destination 1773 ; cx = number of paragraphs 1774 ; CHG: - 1775 ; Note: Doesn't work correctly on HMA; doesn't always wrap to LMA either. 1776 ; Do not provide a wrapped/HMA source or destination! 1777 dosentry_init_movp: 0 00000F9B 51 push cx 0 00000F9C 1E push ds 0 00000F9D 56 push si 0 00000F9E 06 push es 0 00000F9F 57 push di 1783 0 00000FA0 39D0 cmp ax, dx ; source above destination ? 0 00000FA2 770A ja .up ; yes, move up (forwards) --> 0 00000FA4 747B je .return ; same, no need to move --> 0 00000FA6 50 push ax 0 00000FA7 01C8 add ax, cx ; (expected not to carry) 0 00000FA9 39D0 cmp ax, dx ; end of source is above destination ? 0 00000FAB 58 pop ax 0 00000FAC 7730 ja .down ; yes, move from top down --> 1792 ; Here, the end of source is below-or-equal the destination, 1793 ; so they do not overlap. In this case we prefer moving up. 1794 1795 .up: 0 00000FAE 50 push ax 0 00000FAF 52 push dx 1798 .uploop: 0 00000FB0 8ED8 mov ds, ax 0 00000FB2 8EC2 mov es, dx 0 00000FB4 31FF xor di, di 0 00000FB6 31F6 xor si, si ; -> start of segment 0 00000FB8 81E90010 sub cx, 1000h ; 64 KiB left ? 0 00000FBC 7610 jbe .uplast ; no --> 0 00000FBE 51 push cx 0 00000FBF B90080 mov cx, 10000h /2 0 00000FC2 F3A5 rep movsw ; move 64 KiB 0 00000FC4 59 pop cx 0 00000FC5 050010 add ax, 1000h 0 00000FC8 81C20010 add dx, 1000h ; -> next segment 0 00000FCC EBE2 jmp short .uploop ; proceed for more --> 1812 .uplast: 0 00000FCE 81C10010 add cx, 1000h ; restore counter 0 00000FD2 D1E1 shl cx, 1 0 00000FD4 D1E1 shl cx, 1 0 00000FD6 D1E1 shl cx, 1 ; *8, paragraphs to words 0 00000FD8 F3A5 rep movsw ; move last part 0 00000FDA 5A pop dx 0 00000FDB 58 pop ax 0 00000FDC EB43 jmp short .return 1821 1822 .down: 0 00000FDE FD std ; _AMD_ERRATUM_109_WORKAROUND as below 1824 .dnloop: 0 00000FDF 81E90010 sub cx, 1000h ; 64 KiB left ? 0 00000FE3 761A jbe .dnlast ; no --> 0 00000FE5 50 push ax 0 00000FE6 52 push dx 0 00000FE7 01C8 add ax, cx 0 00000FE9 01CA add dx, cx 0 00000FEB 8ED8 mov ds, ax ; -> 64 KiB not yet moved 0 00000FED 8EC2 mov es, dx 0 00000FEF 5A pop dx 0 00000FF0 58 pop ax 0 00000FF1 BFFEFF mov di, -2 0 00000FF4 89FE mov si, di ; moved from last word down 0 00000FF6 51 push cx 0 00000FF7 B90080 mov cx, 10000h /2 0 00000FFA F3A5 rep movsw ; move 64 KiB 0 00000FFC 59 pop cx 0 00000FFD EBE0 jmp short .dnloop ; proceed for more --> 1842 .dnlast: 0 00000FFF 81C10010 add cx, 1000h ; restore counter 0 00001003 D1E1 shl cx, 1 0 00001005 D1E1 shl cx, 1 0 00001007 D1E1 shl cx, 1 ; *8, paragraphs to words 0 00001009 89CF mov di, cx 0 0000100B 4F dec di 0 0000100C D1E7 shl di, 1 ; words to offset, -> last word 0 0000100E 89FE mov si, di 0 00001010 8ED8 mov ds, ax 0 00001012 8EC2 mov es, dx ; first segment correct 1853 1854 1855 numdef AMD_ERRATUM_109_WORKAROUND, 1 1856 %if 0 1857 1858 Jack R. Ellis pointed out this erratum: 1859 1860 Quoting from https://www.amd.com/system/files/TechDocs/25759.pdf page 69: 1861 1862 109 Certain Reverse REP MOVS May Produce Unpredictable Behavior 1863 1864 Description 1865 1866 In certain situations a REP MOVS instruction may lead to 1867 incorrect results. An incorrect address size, data size 1868 or source operand segment may be used or a succeeding 1869 instruction may be skipped. This may occur under the 1870 following conditions: 1871 1872 * EFLAGS.DF=1 (the string is being moved in the reverse direction). 1873 1874 * The number of items being moved (RCX) is between 1 and 20. 1875 1876 * The REP MOVS instruction is preceded by some microcoded instruction 1877 that has not completely retired by the time the REP MOVS begins 1878 execution. The set of such instructions includes BOUND, CLI, LDS, 1879 LES, LFS, LGS, LSS, IDIV, and most microcoded x87 instructions. 1880 1881 Potential Effect on System 1882 1883 Incorrect results may be produced or the system may hang. 1884 1885 Suggested Workaround 1886 1887 Contact your AMD representative for information on a BIOS update. 1888 1889 %endif 1890 1891 %if _AMD_ERRATUM_109_WORKAROUND 0 00001014 E308 jcxz @FF 0 00001016 83F914 cmp cx, 20 0 00001019 7703 ja @FF 1895 @@: 0 0000101B A5 movsw 0 0000101C E2FD loop @B 1898 @@: 1899 %endif 0 0000101E F3A5 rep movsw ; move first part 0 00001020 FC cld 1902 .return: 0 00001021 5F pop di 0 00001022 07 pop es 0 00001023 5E pop si 0 00001024 1F pop ds 0 00001025 59 pop cx 0 00001026 C3 retn 1909 1910 end_of_dosentry_init_late: 1911 1912 dosentry_init_msg: 0 00001027 6C444F53206C6F6164 .oom: asciz "lDOS load error: Out of memory for SYSINIT relocation.",13,10 0 00001030 206572726F723A204F 0 00001039 7574206F66206D656D 0 00001042 6F727920666F722053 0 0000104B 5953494E4954207265 0 00001054 6C6F636174696F6E2E 0 0000105D 0D0A00 1914 1915 1916 ;**************************** 1917 1918 Get_Para_Offset proc near 1919 ;in: AX - offset value 1920 ;out: AX - offset value adjusted for the next paragraph boundary. 0 00001060 83C00F add ax, 15 ;make a paragraph 0 00001063 D1D8 rcr ax, 1 0 00001065 D1E8 shr ax, 1 0 00001067 D1E8 shr ax, 1 0 00001069 D1E8 shr ax, 1 0 0000106B D1E0 shl ax, 1 ;now, make it back to offset value 0 0000106D D1E0 shl ax, 1 0 0000106F D1E0 shl ax, 1 0 00001071 D1E0 shl ax, 1 0 00001073 C3 ret 1931 Get_Para_Offset endp 1932 1933 ;AN004; Don't need this procedure. Get_FAT_Sector replace this. 1934 ; READ A FAT SECTOR INTO FAT LOCATION 1935 ;GETFAT PROC NEAR 1936 ; XOR DI,DI ; OFFSET 1937 ; MOV DX,1 ; RELATIVE SECTOR (1ST SECTOR OF FAT) 1938 ; MOV CX,FATLEN ; READ ENTIRE FAT. 1939 ; MOV AX,FATLOC ; 1940 ; MOV ES,AX ; LOCATION TO READ 1941 ; MOV AX,DRVFAT ; AH FAT ID BYTE, AL DRIVE 1942 ; JMP DISKRD 1943 ;GETFAT ENDP 1944 1945 === Switch to base=002530h -> "SYSINITTRAIL" 1946 usesection SYSINITTRAIL 1947 1948 ; READ A BOOT RECORD INTO 7C0:BOOTBIAS 1949 ;AN015; Read a boot record into Init_BootSeg:BOOTBIAS 1950 1951 GETBOOT PROC NEAR 1952 ;SB33026**************************************************************** 0 0000542F 2E8B0E[0400] mov cx, [cs:Init_BootSeg] 0 00005434 E31C jcxz do_allocate_bootseg 0 00005436 8EC1 mov es, cx 1956 assume es:nothing 1957 BootBias equ BOOTBIAS ; NASM port equate 0 00005438 BB0000 mov BX, BootBias ;SB ; load BX, ES:BX is where sector goes 0 0000543B B80102 mov AX, 0201h ;SB ; command to read & num sec. to 1 0 0000543E 30F6 xor DH, DH ;SB ; head number zero 0 00005440 B90100 mov CX, 0001h ;SB ; cylinder zero and sector one 0 00005443 CD13 int 13h ;SB ; call rom bios 1963 ;SB33026**************************************************************** 0 00005445 7209 JC ERRET 1965 0 00005447 26813EFE0155AA CMP WORD PTR [ES:BOOTBIAS+1FEH],0AA55H ; DAVE L**** MAGIC BYTE? 0 0000544E 7401 JZ NORM_RET 1968 MESSAGE FTESTHARD,<"SIGNATURE AA55 NOT FOUND",CR,LF> 1969 ERRET: 1970 MESSAGE FTESTHARD,<"ERROR IN GETBOOT",CR,LF> 0 00005450 F9 STC 1972 NORM_RET: 0 00005451 C3 RET 1974 GETBOOT ENDP 1975 1976 extern allocate_temporary_block, alloc_init 1977 1978 do_allocate_bootseg: 0 00005452 57 push di 0 00005453 56 push si 0 00005454 1E push ds 0 00005455 52 push dx 0 00005456 B80002 mov ax, 512 0 00005459 BE[0000] mov si, alloc_init 0 0000545C E8[0000] call allocate_temporary_block 0 0000545F 8C06[0400] mov word [Init_BootSeg], es 0 00005463 5A pop dx 0 00005464 1F pop ds 0 00005465 5E pop si 0 00005466 5F pop di 0 00005467 EBC6 jmp GETBOOT 1992 1993 global sysinit_get_ds_dosentry 1994 sysinit_get_ds_dosentry: 0 00005469 2E8E1E[7E04] mov ds, word [cs:.segment] 0 0000546E C3 retn 1997 0 0000546F 00 align 2, db 0 0 00005470 [0000] .segment: dw DOSENTRY 2000 2001 global sysinit_get_es_dosentry 2002 sysinit_get_es_dosentry: 0 00005472 2E8E06[7E04] mov es, word [cs:sysinit_get_ds_dosentry.segment] 0 00005477 C3 retn 2005 2006 extern dosdata_to_doscode 2007 2008 get_ds_biocode: 0 00005478 2E8E1E[9404] mov ds, word [cs:.value] 0 0000547D 8E1EC600 mov ds, word [31h * 4 + 2] 0 00005481 8E1E[0000] mov ds, word [dosdata_to_doscode] 0 00005485 C3 retn 2013 2014 align 2, nop 0 00005486 0000 .value: dw 0 2016 2017 extern biocode_retf 2018 2019 %imacro neartransfer 1.nolist 2020 extern %1 2021 call transfer_sysinitseg_to_biocode 2022 jmp strict short %%skip 2023 dw %1 2024 %%skip: 2025 %endmacro 2026 2027 transfer_sysinitseg_to_biocode: ; near call ip: in_ip_out_cs 0 00005488 50 push ax ; in_ax_out_ip 0 00005489 B8[0000] mov ax, biocode_retf 0 0000548C 50 push ax ; out_retf 0 0000548D 50 push ax ; out_destination + 2 0 0000548E 50 push ax ; out_destination + 0 2033 lframe 0 2034 lpar word, in_ip_out_cs 2035 lpar word, in_ax_out_ip 2036 lpar word, out_retf 2037 lpar dword, out_destination 0 0000548F 5589E5 lenter 0 00005492 1E push ds 0 00005493 56 push si 0 00005494 8CCE mov si, cs ; si = cs 0 00005496 87760A xchg si, word [bp + ?in_ip_out_cs] 2043 ; set cs, get ip 0 00005499 56 push si ; preserve ip for later 0 0000549A AD lodsw ; skip jmp short 0 0000549B 2EAD cs lodsw ; get destination 0 0000549D 894602 mov word [bp + ?out_destination + 0], ax 2048 ; set destination 0 000054A0 E8D5FF call get_ds_biocode ; ds => BIOCODE 0 000054A3 8C5E04 mov word [bp + ?out_destination + 2], ds 2051 ; => BIOCODE 0 000054A6 58 pop ax 0 000054A7 874608 xchg ax, word [bp + ?in_ax_out_ip] 2054 ; ax = original ax, set out ip 0 000054AA 5E pop si 0 000054AB 1F pop ds 0 000054AC 5D lleave 0 000054AD CB retf 2059 2060 2061 ; SETHARD - GENERATE BPB FOR A VARIABLE SIZED HARD FILE. IBM HAS A 2062 ; PARTITIONED HARD FILE; WE MUST READ PHYSICAL SECTOR 0 TO DETERMINE WHERE 2063 ; OUR OWN LOGICAL SECTORS START. WE ALSO READ IN OUR BOOT SECTOR TO 2064 ; DETERMINE VERSION NUMBER 2065 2066 ; INPUTS: DL IS ROM DRIVE NUMBER (80 OR 81) 2067 ; DS:DI POINTS TO BDS 2068 ; OUTPUTS: CARRY CLEAR -> BPB IS FILLED IN 2069 ; CARRY SET -> BPB IS LEFT UNINITIALIZED DUE TO ERROR 2070 2071 SETHARD PROC NEAR 0 000054AE 57 PUSH DI 0 000054AF 53 PUSH BX 0 000054B0 1E PUSH DS 0 000054B1 885D05 MOV BYTE PTR [DI + DRIVELET],BL 0 000054B4 885504 MOV BYTE PTR [DI + DRIVENUM],DL 0 000054B7 B80100 mov ax, FNON_REMOVABLE 0 000054BA 094523 OR WORD PTR [DI + FLAGS],AX 0 000054BD C6452205 MOV BYTE PTR [DI + FORMFACTOR],FFHARDFILE 0 000054C1 2EC606[0700]00 MOV byte [cs:FBIGFAT],0 ; ASSUME 12 BIT FAT 0 000054C7 52 PUSH DX 2082 ;SB33027*************************************************************** 0 000054C8 B408 mov AH, 8 ;SB ; set command to get drive parameters 0 000054CA F9 stc 0 000054CB CD13 int 13h ;SB ; call rom-bios disk routine 2086 ;SB33027*************************************************************** 2087 ; DH IS NUMBER OF HEADS-1 2088 ; DL IS NUMBER OF HARD DISKS ATTACHED 2089 ; LOW 6 BITS OF CL IS SECTORS/TRACK 2090 ; HIGH 2 BITS OF CL WITH CH ARE MAX # OF CYLINDERS 0 000054CD 86F2 xchg dh, dl ; dl = maximum head 0 000054CF B600 mov dh, 0 ; dx = maximum head (preserve CF !) 0 000054D1 42 inc dx ; GET NUMBER OF HEADS (preserve CF !) 0 000054D2 895515 MOV word PTR [DI + HDLIM], dx 0 000054D5 5A POP DX 0 000054D6 7245 JC SETRET ; CARRY HERE MEANS NO HARD DISK 0 000054D8 80E13F AND CL,3FH ; EXTRACT NUMBER OF SECTORS/TRACK 0 000054DB 884D13 MOV BYTE PTR [DI + SECLIM],CL 0 000054DE E84EFF CALL GETBOOT ; IF (GETBOOT ()) 2100 assume es:nothing 0 000054E1 723A JC SETRET ; RETURN -1; 0 000054E3 BBC201 MOV BX,1C2H+BOOTBIAS ; P = &BOOT[0X1C2]; 2103 SET1: 0 000054E6 816523FFFB and word ptr [di + FLAGS], ~ F_LBA 0 000054EB E8BB02 call detectlba 0 000054EE 7205 jc set1_no_lba 0 000054F0 814D230004 or word ptr [di + FLAGS], F_LBA 2108 set1_no_lba: 2109 2110 set1_loop: 0 000054F5 26803F01 CMP BYTE PTR [ES:BX],1 ; WHILE (P->PARTITIONTYPE != 1 && 0 000054F9 7426 JZ SET2 2113 0 000054FB 26803F04 CMP BYTE PTR [ES:BX],4 ; P->PARTITIONTYPE != 4 && 0 000054FF 7420 JZ SET2 2116 2117 ;SB34INIT006****************************************************************** 2118 ;SB we have a new partition type 6 now. add code to support this too. 2119 0 00005501 26803F06 cmp byte ptr [es:bx],6 ; P->PARTITIONTYPE !=6 2121 set2 equ SET2 ; NASM port label 0 00005505 741A jz set2 2123 ;SB34INIT006****************************************************************** 2124 0 00005507 F745230004 test word ptr [di + FLAGS], F_LBA 0 0000550C 7406 jz set1_no_0E 0 0000550E 26803F0E cmp byte ptr [es:bx], 0Eh 0 00005512 740D je set2 2129 set1_no_0E: 2130 0 00005514 83C310 ADD BX,16 ; P += SIZEOF PARTITION; 0 00005517 81FB0202 CMP BX,202H+BOOTBIAS ; IF (P == &BOOT[0X202H]) 0 0000551B 72D8 jb set1_loop ; RETURN -1;} 2134 2135 SETRET: 0 0000551D F9 STC ;AN000; Note: Partitiontype 6 means either 0 0000551E E94202 JMP RET_HARD ;1).the partition has not been formatted yet, or 2138 ;2).(# of sectors before the partition + 2139 ; # of sectors in this partition) > word boundary 2140 ; i.e., needs 32 bit sector calculation, or 2141 ;3).the partition is not a FAT file system. 2142 2143 ;J.K. Until we get the real logical boot record and get the bpb, 2144 ;DRVLIM_H,DRVLIM_L will be used instead of DRVLIM for the convenience of 2145 ;the computation. 2146 ;At the end of this procedure, if a BPB information is gotten from 2147 ;the valid boot record, then we are going to use those BPB information 2148 ;without change. 2149 ;Otherwise, if (hidden sectors + total sectors) <= a word, then 2150 ;we will move DRVLIM_L to DRVLIM and zero out DRVLIM_L entry to make 2151 ;it a conventional BPB format. 2152 2153 SET2: 0 00005521 2E8816[0800] mov [cs:ROM_drv_num], dl ;AN000; save the ROM BIOS drive number we are handling now. 2155 0 00005526 268B4704 mov ax, word ptr [es:bx+4] ; Hidden sectors (based on EPBR) 0 0000552A 014517 add [di + HIDSEC_L],AX ; BPB->HIDSECCT = P->PARTITIONBEGIN; 0 0000552D 268B4706 mov ax, word ptr [es:bx+6] 0 00005531 114519 adc [di + HIDSEC_H],ax ; add to prior value (EPBR base) 2160 0 00005534 268B4708 mov ax, word ptr [es:bx+8] ;# of sectors (Low) 0 00005538 268B570A mov dx, word ptr [es:bx+10] ;AN000; # of sectors (High) 0 0000553C 89551D mov word ptr [di + DRVLIM_H], dx 0 0000553F 89451B mov word ptr [di + DRVLIM_L], ax ; BPB->MAXSEC = P->PARTITIONLENGTH; 0 00005542 85D2 test dx, dx 0 00005544 7505 jnz OKDrive_Cont 0 00005546 83F840 CMP AX,64 ; IF (P->PARTITIONLENGTH < 64) 0 00005549 72D2 JB SETRET ; RETURN -1; 2169 2170 OKDrive_Cont: ;AN000; 2171 0 0000554B 034517 add ax, [di + HIDSEC_L] 0 0000554E 135519 adc dx, [di + HIDSEC_H] ; dx:ax = sector after partition 2174 Okdrive equ OKDRIVE ; NASM port label 0 00005551 7308 jnc Okdrive 0 00005553 7406 jz Okdrive 2177 MESSAGE FTESTHARD,<"PARTITION INVALID",CR,LF> 0 00005555 2E800E[0700]80 OR byte [cs:FBIGFAT],FTOOBIG 2179 OKDRIVE: 2180 0 0000555B F745230004 test word ptr [di + FLAGS], F_LBA 0 00005560 750B jnz okdrive_lba 2183 0 00005562 83E801 sub ax, 1 0 00005565 83DA00 sbb dx, 0 ; dx:ax = last sector of partition 0 00005568 E8[0000] call lbatochs ; convert to CHS 2187 SetRet_brdg equ SetRet_Brdg ; NASM port label 0 0000556B 7255 jc SetRet_brdg ; if CHS overflow --> 2189 2190 okdrive_lba: 0 0000556D 2EA0[0800] mov al, [cs:ROM_drv_num] ;AN000; Set the drive number 0 00005571 884504 mov byte ptr [di + DRIVENUM], al 2193 0 00005574 8B5519 mov dx,[di + HIDSEC_H] 0 00005577 8B4517 mov ax,[di + HIDSEC_L] ; BOOT SECTOR NUMBER - For mini disk,;J.K. 2196 ; XOR DX,DX ; this will be logical and equal to ;AC000; 2197 ; xor bx,bx ;usUally equal to the # of sec/trk. ;J.K. 2198 2199 %if 0 2200 ISMINI equ IsMini ; NASM port equate 2201 cmp word ptr [di + ISMINI], 1 ;check for mini disk -J.K. 4/7/86 2202 jnz OKnotMini ;not mini disk. -J.K. 4/7/86 2203 xchg bx, ax 2204 mov cx, dx ; cx = high word sector number 2205 mov ax, [di + SECLIM] ; ax = number of CHS sectors 2206 mul word ptr [di + HDLIM] ; ax = sectors per cylinder (dx == zero) 2207 mul word ptr [di + Hidden_Trks] ; dx:ax = how many hidden sectors to add 2208 add ax, bx 2209 adc dx, cx 2210 jc SetRet_brdg 2211 OKnotMini: ;J.K. 4/7/86 2212 %endif 2213 2214 ;J.K. For convenience, we are going to read the logical boot sector 2215 ;into cs:DiskSector area. 2216 2217 ;SB34INIT009************************************************************* 2218 ;SB Read in boot sector using BIOS disk interrupt. The buffer where it 2219 ;SB is to be read in is cs:Disksector. 0 0000557A E8F5FE call sysinit_get_es_dosentry 0 0000557D BB[0000] mov bx,offset DiskSector 0 00005580 B90102 mov cx,0201h ; read, one sector 0 00005583 E8EE01 call readsector_flag 0 00005586 723A jc SetRet_brdg ;AN000; Exceeds the limit of Int 13h 2225 ;SB34INIT009************************************************************* 2226 2227 ; cs:Disksec contains THE BOOT SECTOR. IN THEORY, (HA HA) THE BPB IN THIS THING 2228 ; IS CORRECT. WE CAN, THEREFORE, SUCK OUT ALL THE RELEVANT STATISTICS ON THE 2229 ; MEDIA IF WE RECOGNIZE THE VERSION NUMBER. 2230 2231 ; look for a signature for msdos... 0 00005588 26817F034D53 cmp word ptr [es:bx+3], "M" + ("S" << 8) 0 0000558E 750F jne notmssig 0 00005590 26817F05444F cmp word ptr [es:bx+5], "D" + ("O" << 8) 0 00005596 7507 jne notmssig 0 00005598 26807F0753 cmp byte ptr [es:bx+7], "S" 0 0000559D 7420 je sigfound 2238 ; ...or perhaps pcdos... 2239 notmssig: 0 0000559F 26817F034942 CMP WORD PTR [es:bx+3], "I" + ("B" << 8) 0 000055A5 7508 jne notibmsig 0 000055A7 26817F054D20 CMP WORD PTR [es:bx+5], "M" + (" " << 8) 0 000055AD 7410 je sigfound 2244 2245 notibmsig: 0 000055AF 26817F034F53 CMP WORD PTR [es:bx+3], "O" + ("S" << 8) 0 000055B5 7523 jne acceptbpb 0 000055B7 26817F053220 CMP WORD PTR [es:bx+5], "2" + (" " << 8) 0 000055BD 751B jne acceptbpb ; ecm: not MSDOS nor IBM nor OS/2, accept BPB --> 2250 2251 sigfound: ; signature was found, now check version 0 000055BF EB04 jmp check3point0 0 000055C1 90 nop ; identicalise 2254 2255 SetRet_Brdg: 0 000055C2 E958FF jmp SETRET 2257 2258 check3point0: 2259 Cover_Fdisk_Bug equ Cover_FDISK_Bug ; NASM port label 0 000055C5 E80802 call Cover_Fdisk_Bug ;AN010; 2261 ; ecm: only reject "MSDOS3.0" or "IBM 3.0" 0 000055C8 26817F08332E CMP WORD PTR [es:bx+8],"3" + ("." << 8) 0 000055CE 750A jne acceptbpb 0 000055D0 26807F0A30 cmp byte ptr [es:bx+10],"0" ;do not trust 3.0 boot record. But still legal J.K. 4/15/86 0 000055D5 7503 jne acceptbpb ;AN012; if version >= 3.1, then O.K. 0 000055D7 E9B800 jmp unknown3point0 2267 acceptbpb: 2268 COPYBPB: 2269 ; WE HAVE A VALID BOOT SECTOR. USE THE BPB IN IT TO BUILD THE 2270 ; BPB IN BIOS. IT IS ASSUMED THAT ONLY SECPERCLUS, CDIR, AND 2271 ; CSECFAT NEED TO BE SET (ALL OTHER VALUES IN ALREADY). FBIGFAT 2272 ; IS ALSO SET. 2273 2274 ;If it is non FAT based system, then just copy the BPB from the BOOT sector 2275 ;into the BPB in BDS table, and also set the Boot serial number, Volume id, 2276 ;and System ID according to the Boot record. 2277 ;For the non_FAT system, don't need to set the other value. So just 2278 ;do GOODRET.- J.K. 2279 0 000055DA 26803E[0000]29 cmp byte [es:Ext_Boot_Sig], EXT_BOOT_SIGNATURE ;AN000; 0 000055E0 7528 jne COPYBPB_FAT ;AN000; Conventional Fat system 0 000055E2 26803E[0000]00 cmp byte [es:NumberOfFats], 0 ;AN000; If (# of FAT <> 0) then 0 000055E8 7520 jne COPYBPB_FAT ;AN000; a Fat system. 2284 ;J.K. Non Fat based media. 0 000055EA 57 push di ;AN000; Sav Reg. 0 000055EB 1E push ds ;AN000; 0 000055EC 06 push es 2288 0 000055ED 1E push ds ;AN000; 0 000055EE 07 pop es ;AN000; now es:di -> bds 0 000055EF E877FE call sysinit_get_ds_dosentry 2292 0 000055F2 BE[0000] mov si, offset Bpb_In_Sector ;AN000; ds:si -> BPB in Boot 0 000055F5 83C706 add di, BYTEPERSEC ;AN000; es:di -> BPB in BDS 0 000055F8 B91900 mov cx, BPB_TYPE_struc_size ;AN000; 0 000055FB F3A4 rep movsb ;AN000; 2297 0 000055FD 07 pop es 0 000055FE 1F pop ds ;AN000; Restore Reg. 0 000055FF 5F pop di ;AN000; 0 00005600 E885FEEB02[0000] neartransfer Mov_Media_IDs ;AN000; Set Volume id, SystemId, Serial. 2302 GoodRet equ GOODRET ; NASM port label 0 00005607 E93B01 jmp GoodRet 2304 2305 COPYBPB_FAT: ;AN000; Fat system 0 0000560A 31D2 xor dx,dx ;AN000; 0 0000560C BE[0000] mov si, offset Bpb_In_Sector ;AN000; es:bx -> bpb in boot 0 0000560F 268B4408 mov ax, [es:si + SECNUM] ;AN000; total sectors 0 00005613 85C0 test ax, ax ;AN000; double word sector number? 0 00005615 7508 jnz Fat_Big_Small ;AN000; No. Conventional BPB. 0 00005617 268B4415 mov ax, word ptr [es:si + SECNUM_L] ;AN000; Use double word 0 0000561B 268B5417 mov dx, word ptr [es:si + SECNUM_H] ;AN000; 2313 2314 Fat_Big_Small: ;AN000; Determine Fat entry size. 2315 ;At this moment DX;AX = Total sector number 0 0000561F 268B5C03 mov bx, [es:si + RESNUM] 0 00005623 895D09 mov [di + RESSEC], bx 0 00005626 29D8 sub ax,bx ;AN000; Subtract # reserved 0 00005628 83DA00 sbb dx,0 ;AN000; 0 0000562B 268B5C0B mov bx, [es:si + FATSIZE] ;AN000; BX = Sectors/Fat 0 0000562F 895D11 mov [di + CSECFAT],bx ;AN000; Set in BDS BPB 0 00005632 31C9 xor cx, cx 0 00005634 268A4C05 mov cl, [es:si + FATNUM] 0 00005638 884D0B mov [di + CFAT], cl 0 0000563B E307 jcxz .none 2326 .loop: 0 0000563D 29D8 sub ax,bx ;AN000; Subtract # fat sectors 0 0000563F 83DA00 sbb dx,0 ;AN000; 0 00005642 E2F9 loop .loop 2330 .none: 0 00005644 268B5C06 mov bx, [es:si + DIRNUM] ;AN000; # root entries 2332 cDIR equ CDIR ; NASM port equate 0 00005648 895D0C mov [di + cDIR],bx ;AN000; Set in BDS BPB 2334 0 0000564B B104 MOV CL,4 0 0000564D D3EB shr bx,cl ;AN000; Div by 16 ents/sector 0 0000564F 29D8 sub ax,bx ;AN000; sub # dir sectors 0 00005651 83DA00 sbb dx,0 ;AN000; 2339 ;AN000; DX;AX now contains the # of data sectors 0 00005654 268A4C02 MOV CL, [es:si + SECALL] ; SECTORS PER CLUSTER 0 00005658 49 dec cx 0 00005659 B500 mov ch, 0 0 0000565B 41 inc cx ; translate EDR-DOS 0 to 256 0 0000565C 884D08 MOV [DI + SECPERCLUS],CL ; SET IN BIOS BPB (truncated) 2345 ; XOR DX,DX 2346 ; MOV CH,DH 2347 MNUM FTESTHARD,CX 2348 MESSAGE FTESTHARD,<" SECPERCLUS",CR,LF> 2349 ;J.K. 3/16/87 P54 Returning back to old logic for compatibility reason. 2350 ;So, use the old logic again that once had been commented out!!!!!!!!!!!! 2351 ;Old logic to determine FAT Entry Size J.K. 12/3/86 0 0000565F 50 push ax ;AN000; 0 00005660 92 xchg ax, dx ; ax = high word, clobber dx 0 00005661 31D2 xor dx,dx ;AN000; 0 00005663 F7F1 div cx ;AN000; cx = sectors per cluster 0 00005665 26A3[0000] mov [es:Temp_H],ax ;AN000; 0 00005669 58 pop ax ;AN000; 0 0000566A F7F1 DIV CX ;AN000; [Temp_H];AX NOW CONTAINS THE # CLUSTERS. 0 0000566C 26833E[0000]00 cmp word [es:Temp_H],0 ;AN000; 0 00005672 7715 ja TooBig_Ret ;AN000; Too big cluster number 0 00005674 3DF60F CMP AX,4096-10 ; IS THIS 16-BIT FAT? 0 00005677 7206 JB CopyMediaID ; NO, small FAT 0 00005679 2E800E[0700]40 OR byte [cs:FBIGFAT],FBIG ; 16 BIT FAT 2364 ;End of Old logic 2365 CopyMediaID: 0 0000567F E806FEEB02[0000] neartransfer Mov_Media_IDs ;AN000; Copy Filesys_ID, Volume label, 2367 ;and Volume serial to BDS table, if extended 2368 ;boot record. 0 00005686 E99B00 JMP Massage_bpb ;AN000; Now final check for BPB info. and return. 2370 2371 TooBig_Ret: ;AN000; 0 00005689 2E800E[0700]80 OR byte [cs:FBIGFAT],FTOOBIG 0 0000568F E9B300 JMP GOODRET ;AN000; Still drive letter is assigned 2374 ;AN000; But useless. To big for 2375 ;AN000; current PC DOS FAT file system 2376 ; UNKNOWN: 2377 ; or [di].FLAGS, UNFORMATTED_MEDIA ;AN005; Set unformatted media flag. 2378 ; preceeding line commented out 10/88 by MRW-- The boot signature 2379 ; may not be recognizable, but we should TRY and read it anyway. 2380 ;AN006; 2381 ;AN008; For the time being, allow it. 2382 ;AN009; Now implemented again 2383 ; Unknown3_0: ;AN012;Skip setting UNFORMATTED_MEDIA bit 2384 unknown3point0: 2385 MESSAGE FTESTHARD,<"UNKNOWN HARD MEDIA. ASSUMING 3.0.",CR,LF> 0 00005692 8B551D mov dx, [di + DRVLIM_H] ;AN000; 0 00005695 8B451B mov ax, [di + DRVLIM_L] ;AN000; 2388 DISKTABLE2 equ DiskTable2 ; NASM port label 0 00005698 BE[9E00] MOV SI,OFFSET DISKTABLE2 2390 SCAN: 2391 ; CMP AX,[SI] 2392 ; JBE GOTPARM 2393 ; ADD SI,4 * 2 2394 0 0000569B 2E3B14 cmp dx, word ptr [cs:si] ;AN000; 2396 GotParm equ GOTPARM ; NASM port label 0 0000569E 720D jb GotParm ;AN000; 0 000056A0 7706 ja Scan_Next ;AN000; 0 000056A2 2E3B4402 cmp ax, word ptr [cs:si+2] ;AN000; 0 000056A6 7605 jbe GotParm ;AN000; 2401 Scan_Next: ;AN000; 0 000056A8 83C60A add si, 5 * 2 ;AN000; 0 000056AB EBEE JMP SCAN ;AN000; Covers upto 512 MB media 2404 GOTPARM: 2405 ; MOV CL,BYTE PTR [SI+6] 0 000056AD 2E8A4C08 mov cl,byte ptr [cs:si+8] ;AN000; Fat size for FBIGFAT flag 0 000056B1 2E080E[0700] OR [cs:FBIGFAT],CL 2408 ; MOV CX,[SI+2] 2409 ; MOV DX,[SI+4] 0 000056B6 2E8B4C04 mov cx, word ptr [cs:SI+4] ;AN000; 0 000056BA 2E8B5406 mov dx, word ptr [cs:SI+6] ;AN000; 2412 2413 ; DX = NUMBER OF DIR ENTRIES, 2414 ; CH = NUMBER OF SECTORS PER CLUSTER 2415 ; CL = LOG BASE 2 OF CH 2416 2417 ; NOW CALCULATE SIZE OF FAT TABLE 2418 2419 MNUM FTESTHARD,AX 2420 MESSAGE FTESTHARD,<" SECTORS "> 2421 MNUM FTESTHARD,DX 2422 MESSAGE FTESTHARD,<" DIRECTORY ENTRIES "> 2423 MNUM FTESTHARD,CX 2424 MESSAGE FTESTHARD,<" SECPERCLUS|CLUSSHIFT"> 2425 0 000056BE 89550C MOV WORD PTR [CDIR + DI],DX ;SAVE NUMBER OF DIR ENTRIES 2427 2428 ;Now, CX = SecPerClus|Clusshift 2429 ; [DI.CDIR] = number of directory entries. 2430 0 000056C1 8B551D mov dx, [di + DRVLIM_H] ;AN000; 0 000056C4 8B451B mov ax, [di + DRVLIM_L] ;AN000; 0 000056C7 886D08 MOV BYTE PTR [SECPERCLUS + DI],CH ;SAVE SECTORS PER CLUSTER 0 000056CA 2EF606[0700]40 TEST byte [cs:FBIGFAT],FBIG ; IF (FBIGFAT) 0 000056D0 751E JNZ DOBIG ; GOTO DOBIG; 2436 MESSAGE FTESTHARD,<" SMALL FAT",CR,LF> 2437 ;J.K. We don't need to change "small fat" logic since it is gauranteed 2438 ;that double word total sector will not use 12 bit fat (unless 2439 ;it's sectors/cluster >= 16 which will never be in this case.) 2440 ;So in this case we assume DX = 0 !!!. 2441 0 000056D2 31DB XOR BX,BX 0 000056D4 88EB MOV BL,CH 0 000056D6 4B DEC BX 0 000056D7 01C3 ADD BX,AX ;AN000; DX=0 0 000056D9 D3EB SHR BX,CL ; BX = 1+(BPB->MAXSEC+SECPERCLUS-1)/ 0 000056DB 43 INC BX ; SECPERCLUS 0 000056DC 80E3FE AND BL,11111110B ; BX &= ~1; (=NUMBER OF CLUSTERS) 0 000056DF 89DE MOV SI,BX 0 000056E1 D1EB SHR BX,1 0 000056E3 01F3 ADD BX,SI 0 000056E5 81C3FF01 ADD BX,511 ; BX += 511 + BX/2 0 000056E9 D0EF SHR BH,1 ; BH >>= 1; (=BX/512) 0 000056EB 887D11 MOV BYTE PTR [DI + CSECFAT],BH ;SAVE NUMBER OF FAT SECTORS 2455 Massage_BPB equ Massage_bpb ; NASM port label 0 000056EE EB34 JMP SHORT Massage_BPB 2457 DOBIG: 2458 ;J.K. For BIGFAT we do need to extend this logic to 32 bit sector calculation. 2459 MESSAGE FTESTHARD,<" BIG FAT",CR,LF> 0 000056F0 B104 MOV CL,4 ; 16 (2^4) DIRECTORY ENTRIES PER SECTOR 0 000056F2 52 push dx ;AN000; Save total sectors (high) 0 000056F3 8B550C mov dx,[CDIR + DI] ;AN000; 0 000056F6 D3EA SHR DX,CL ; CSECDIR = CDIR / 16; 0 000056F8 29D0 SUB AX,DX ; DX;AX -= CSECDIR; DX;AX -= CSECRESERVED; 0 000056FA 5A pop dx ;AN000; 0 000056FB 83DA00 SBB dx,0 ;AN000; 2467 ; DEC AX ; AX = T - R - D 0 000056FE 83E801 SUB ax,1 ;AN000; DX;AX = T - R - D 0 00005701 83DA00 SBB dx,0 ;AN000; 0 00005704 B302 MOV BL,2 0 00005706 8A7D08 MOV BH,[SECPERCLUS + DI] ; BX = 256 * SECPERCLUS + 2 2472 ; XOR DX,DX 2473 ;J.K. I don't understand why to add BX here!!! 0 00005709 01D8 ADD AX,BX ; AX = T-R-D+256*SPC+2 0 0000570B 83D200 ADC DX,0 0 0000570E 83E801 SUB AX,1 ; AX = T-R-D+256*SPC+1 0 00005711 83DA00 SBB DX,0 2478 ;J.K. Assuming DX in the table will never be bigger than BX. 0 00005714 F7F3 DIV BX ; CSECFAT = CEIL((TOTAL-DIR-RES)/ 2480 ; (256*SECPERCLUS+2)); 0 00005716 894511 MOV WORD PTR [DI + CSECFAT],AX ; NUMBER OF FAT SECTORS 2482 ;J.K. Now, set the default FileSys_ID, Volume label, Serial number 0 00005719 2E8A1E[0700] MOV BL,[cs:FBIGFAT] 0 0000571E 885D1F MOV [DI + FATSIZ],BL ; SET SIZE OF FAT ON MEDIA 0 00005721 E8[0000] call Clear_IDs ;AN000; 2486 2487 ;J.K. At this point, in BPB of BDS table, DRVLIM_H,DRVLIM_L which were 2488 ;set according to the partition information. We are going to 2489 ;see if (hidden sectors + total sectors) > a word. If it is true, 2490 ;then no change. Otherwise, DRVLIM_L will be moved to DRVLIM 2491 ;and DRVLIM_L will be set to 0. 2492 ;We don't do this for the bpb information from the boot record. We 2493 ;are not going to change the BPB information from the boot record. 2494 Massage_bpb: ;AN000; 0 00005724 8B551D mov dx, [di + DRVLIM_H] ;AN000; 0 00005727 8B451B mov ax, [di + DRVLIM_L] ;AN000; 0 0000572A 83FA00 cmp dx,0 ;AN000; Double word total sector? 0 0000572D 7716 ja GOODRET ;AN000; don't have to change it. 0 0000572F 837D1900 cmp word [di + HIDSEC_H], 0 ;AN000; 0 00005733 7710 ja GOODRET ;AN000; don't have to change it. 0 00005735 034517 add ax, [di + HIDSEC_L] ;AN000; 0 00005738 720B jc GOODRET ;AN000; bigger than a word boundary 0 0000573A 8B451B mov ax, [di + DRVLIM_L] ;AN000; 0 0000573D 89450E mov [di + DRVLIM], ax ;AN000; 0 00005740 C7451B0000 mov word [di + DRVLIM_L], 0 ;AN000; 2506 GOODRET: 0 00005745 837D1D00 cmp word [di + DRVLIM_H], 0 ;AN014; Big media? 0 00005749 760F jbe Not_BigMedia ;AN014; No. 0 0000574B 06 push es ;AN014; 0 0000574C 50 push ax ;AN014; 0 0000574D B8[0000] mov ax, SYSINITSEG ;AN014; 0 00005750 8EC0 mov es, ax ;AN014; 0 00005752 26C606[0000]01 mov byte [es:Big_Media_Flag], 1 ;AN014; Set the flag in SYSINITSEG. 0 00005758 58 pop ax ;AN014; 0 00005759 07 pop es ;AN014; 2516 Not_BigMedia: ;AN014; 0 0000575A 2E8A1E[0700] MOV BL,[cs:FBIGFAT] 0 0000575F 885D1F MOV [DI + FATSIZ],BL ; SET SIZE OF FAT ON MEDIA 0 00005762 F8 CLC 2520 RET_HARD: 0 00005763 1F POP DS 0 00005764 5B POP BX 0 00005765 5F POP DI 0 00005766 C3 RET 2525 2526 SETHARD ENDP 2527 2528 2529 readsector_detect: 0 00005767 51 push cx 0 00005768 52 push dx 0 00005769 8A5504 mov dl, byte ptr [di + DRIVENUM] 0 0000576C E83A00 call detectlba 0 0000576F 5A pop dx 0 00005770 59 pop cx 0 00005771 EB09 jmp readsector_NC_LBA 0 00005773 90 nop ; identicalise 2538 2539 readsector_flag: 0 00005774 F745230004 test word ptr [di + FLAGS], F_LBA 0 00005779 7501 jnz readsector_NC_LBA ; --> (NC) 0 0000577B F9 stc 2543 2544 readsector_NC_LBA: 0 0000577C 1E push ds 0 0000577D 56 push si 0 0000577E 720E jc readsector_chs 2548 readsector_lba: 0 00005780 FF7504 push word ptr [di + DRIVENUM] 0 00005783 E802FDEB02[0000] neartransfer lba_packet_setup 0 0000578A 5A pop dx ; dl = unit 0 0000578B EB13 jmp readsector_common 0 0000578D 90 nop ; identicalise 2554 2555 readsector_chs: 0 0000578E 51 push cx 0 0000578F E8F6FCEB02[0000] neartransfer lbatochs 0 00005796 58 pop ax 0 00005797 720C jc readsector_ret_ah 0 00005799 E8ECFCEB02[0000] neartransfer chstotuple 2561 2562 readsector_common: 0 000057A0 CD13 int 13h 2564 readsector_ret: 0 000057A2 5E pop si 0 000057A3 1F pop ds 0 000057A4 C3 ret 2568 2569 readsector_ret_ah: 0 000057A5 B404 mov ah, 04h ; sector not found 0 000057A7 EBF9 jmp readsector_ret 2572 2573 2574 ; INP: dl = unit number 2575 ; OUT: CY no LBA 2576 ; NC LBA 2577 ; CHG: cx 2578 detectlba: 0 000057A9 50 push ax 0 000057AA 53 push bx 0 000057AB 52 push dx 0 000057AC 1E push ds 2583 0 000057AD B84000 mov ax, 40h 0 000057B0 8ED8 mov ds, ax 2586 ; Setting ds = 40h is a Book8088 bugfix, refer to 2587 ; http://www.bttr-software.de/forum/forum_entry.php?id=21061 2588 0 000057B2 B80041 mov ax, 4100h 0 000057B5 BBAA55 mov bx, 55AAh 0 000057B8 31C9 xor cx, cx 0 000057BA 30F6 xor dh, dh 0 000057BC F9 stc 0 000057BD CD13 int 13h 0 000057BF 1F pop ds 0 000057C0 720A jc detectlba_ret ; --> CY 0 000057C2 81FB55AA cmp bx, 0AA55h 0 000057C6 F9 stc ; CY 0 000057C7 7503 jne detectlba_ret 0 000057C9 D1E9 shr cx, 1 ; CY if have LBA access functions 0 000057CB F5 cmc ; NC if have 2602 detectlba_ret: 0 000057CC 5A pop dx 0 000057CD 5B pop bx 0 000057CE 58 pop ax 0 000057CF C3 ret 2607 2608 2609 Cover_FDISK_Bug proc ;AN010; 2610 ;FDISK of PC DOS 3.3 and below, OS2 1.0 has a bug. The maximum number of 2611 ;sector that can be handled by PC DOS 3.3 ibmbio should be 0FFFFh. 2612 ;Instead, sometimes FDISK use 10000h to calculate the maximum number. 2613 ;So, we are going to check that if SECNUM + Hidden sector = 10000h 2614 ;then subtrack 1 from SECNUM. 0 000057D0 50 push ax ;AN010; 0 000057D1 52 push dx ;AN010; 0 000057D2 56 push si ;AN010; 0 000057D3 26803E[0000]29 cmp byte [es:Ext_Boot_Sig], EXT_BOOT_SIGNATURE ;AN010; 0 000057D9 742E je CFB_Retit ;AN010;if extended BPB, then >= PC DOS 4.00 0 000057DB 26817F073130 cmp word ptr [es:bx+7], ("0" << 8) + "1" ;AN011; OS2 1.0 ? = IBM 10.0 0 000057E1 7507 jne CFB_Chk_SECNUM ;AN010; 0 000057E3 26807F0A30 cmp byte ptr [es:bx+10], "0" ;AN010; 0 000057E8 751F jne CFB_Retit ;AN010; 2624 CFB_Chk_SECNUM: ;AN010; 2625 BPB_In_Sector equ Bpb_In_Sector ; NASM port label 0 000057EA BE[0000] mov si, offset BPB_In_Sector ;AN010; 0 000057ED 26837C0800 cmp word [es:si + SECNUM], 0 ;AN010;Just to make sure. 0 000057F2 7415 je CFB_Retit ;AN010; 0 000057F4 268B4408 mov ax, [es:si + SECNUM] ;AN010; 0 000057F8 26034411 add ax, [es:si + HIDDEN_L] ;AN010; 0 000057FC 730B jnc CFB_Retit ;AN010; 0 000057FE 85C0 test ax, ax ;AN010;if carry set and AX=0? 0 00005800 7507 jnz CFB_Retit ;AN010; 0 00005802 26FF4C08 dec word [es:si + SECNUM] ;AN010; then decrease SECNUM by 1. 0 00005806 FF4D1B dec word [di + DRVLIM_L] ;AN010; 2636 CFB_Retit: ;AN010; 0 00005809 5E pop si ;AN010; 0 0000580A 5A pop dx ;AN010; 0 0000580B 58 pop ax ;AN010; 0 0000580C C3 ret ;AN010; 2641 Cover_FDISK_Bug endp ;AN010; 2642 2643 2644 ; SETDRVPARMS SETS UP THE RECOMMENDED BPB IN EACH BDS IN THE SYSTEM BASED ON 2645 ; THE FORM FACTOR. IT IS ASSUMED THAT THE BPBS FOR THE VARIOUS FORM FACTORS 2646 ; ARE PRESENT IN THE BPBTABLE. FOR HARD FILES, THE RECOMMENDED BPB IS THE SAME 2647 ; AS THE BPB ON THE DRIVE. 2648 2649 ; NO ATTEMPT IS MADE TO PRESERVE REGISTERS SINCE WE ARE GOING TO JUMP TO 2650 ; SYSINIT STRAIGHT AFTER THIS ROUTINE. 2651 2652 SETDRVPARMS PROC NEAR 2653 MESSAGE FTESTINIT,<"SETTING DRIVE PARAMETERS",CR,LF> 0 0000580D 31DB XOR BX,BX 0 0000580F E860FC call sysinit_get_es_dosentry 0 00005812 26C43E[0000] LES DI,[es:START_BDS] ; GET FIRST BDS IN LIST 2657 NEXT_BDS: 0 00005817 83FFFF CMP DI,-1 0 0000581A 7501 JNZ DO_SETP 2660 DONE_SETPARMS: 0 0000581C C3 RET 2662 2663 DO_SETP: 0 0000581D 06 PUSH ES 0 0000581E 57 PUSH DI ; PRESERVE POINTER TO BDS 0 0000581F 268A5D22 MOV BL,[ES:DI + FORMFACTOR] 0 00005823 80FB05 CMP BL,FFHARDFILE 0 00005826 7541 JNZ NOTHARDFF 2669 0 00005828 31D2 xor dx,dx ;AN000; 0 0000582A 268B450E MOV AX,[ES:DI + DRVLIM] 0 0000582E 85C0 test ax, ax ;AN000; 0 00005830 7508 jnz GET_cCYL ;AN000; 0 00005832 268B551D mov dx,[es:di + DRVLIM_H] ;AN000; Use Double word sector number 0 00005836 268B451B MOV AX,[ES:DI + DRVLIM_L] ;AN000; 2676 GET_cCYL: 0 0000583A 52 push dx ;AN000; 0 0000583B 50 PUSH AX 0 0000583C 268B4515 MOV AX,WORD PTR [ES:DI + HDLIM] 0 00005840 26F76513 MUL WORD PTR [ES:DI + SECLIM] ;Assume Sectorsp per cyl. < 64K. 0 00005844 89C1 MOV CX,AX ; CX HAS # SECTORS PER CYLINDER 0 00005846 58 POP AX ; 0 00005847 5A pop dx ;AN000; Restore drvlim. 0 00005848 50 push ax ;AN000; 0 00005849 92 xchg ax, dx ; ax = high word, clobber dx 0 0000584A 31D2 xor dx,dx ;AN000; 0 0000584C F7F1 div cx ;AN000; 0 0000584E 1E push ds 0 0000584F E817FC call sysinit_get_ds_dosentry 0 00005852 A3[0000] mov [Temp_H],ax ;AN000; AX be 0 here. 0 00005855 1F pop ds 0 00005856 58 pop ax ;AN000; 0 00005857 F7F1 DIV CX ; DIV #SEC BY SEC/CYL TO GET # CYL. 0 00005859 09D2 OR DX,DX 0 0000585B 7401 JZ NO_CYL_RND ; CAME OUT EVEN 0 0000585D 40 INC AX ; ROUND UP 2697 NO_CYL_RND: 0 0000585E 26894525 MOV [ES:DI + CCYLN],AX 2699 MESSAGE FTESTINIT,<"CCYLN "> 2700 MNUM FTESTINIT,AX 2701 MESSAGE FTESTINIT, 0 00005862 06 PUSH ES 0 00005863 1F POP DS 0 00005864 8D7506 LEA SI,[DI + BYTEPERSEC] ; DS:SI -> BPB FOR HARD FILE 0 00005867 EB3B JMP SHORT SET_RECBPB 2706 2707 NOTHARDFF: 2708 ;J.K. We don't use the extended BPB for a floppy. 2709 ;J.K.6/24/87 2710 2711 ;SB34INIT007****************************************************************** 2712 ;SB If Fake floppy drive variable is set then we don't have to handle this 2713 ;SB BDS. We can just go and deal with the next BDS at label Go_To_Next_BDS. 2714 0 00005869 2E803E[0600]01 cmp byte [cs:FakeFloppyDrv],1 2716 Go_To_Next_BDS equ GO_TO_NEXT_BDS ; NASM port label 0 0000586F 743B jz Go_To_Next_BDS 2718 ;SB34INIT007****************************************************************** 2719 0 00005871 80FB07 CMP BL,FFOTHER ; SPECIAL CASE "OTHER" TYPE OF MEDIUM 0 00005874 7526 JNZ NOT_PROCESS_OTHER 2722 PROCESS_OTHER: 0 00005876 268B4525 MOV AX,[es:DI + CCYLN] 0 0000587A 26F76536 mul word [es:DI + RHDLIM] 0 0000587E 26F76534 mul word [es:DI + RSECLIM] 0 00005882 2689452F MOV [es:DI + RDRVLIM],AX ; HAVE THE TOTAL NUMBER OF SECTORS 0 00005886 48 DEC AX 2728 2729 ;J.K. Old logic was... 2730 ; MOV BX,515 2731 ; DIV BX 2732 ; OR DX,DX 2733 ; JZ NO_ROUND_UP 2734 ; INC AX ; ROUND UP NUMBER OF FAT SECTORS 2735 2736 ;J.K. New logic to get the sectors/fat area. 2737 ;Fat entry is assumed to be 1.5 bytes!!! 0 00005887 BB0300 mov bx, 3 0 0000588A F7E3 mul bx 0 0000588C 4B dec bx ; = 2 0 0000588D F7F3 div bx 0 0000588F 31D2 xor dx, dx 0 00005891 86DF xchg bl, bh ; bh = 2, bl = 0, bx = 512 0 00005893 F7F3 div bx 0 00005895 40 inc ax 2746 2747 NO_ROUND_UP: 0 00005896 26894532 MOV [es:DI + RCSECFAT],AX 0 0000589A EB10 JMP SHORT GO_TO_NEXT_BDS 2750 NOT_PROCESS_OTHER: 0 0000589C D1E3 SHL BX,1 ; BX IS WORD INDEX INTO TABLE OF BPBS 0 0000589E 0E push cs 0 0000589F 1F pop ds 0 000058A0 8BB7[7E01] MOV SI,WORD PTR [BPBTABLE + BX] ; GET ADDRESS OF BPB 2755 SET_RECBPB: 0 000058A4 8D7D27 LEA DI,[DI + RBYTEPERSEC] ; ES:DI -> RECBPB 0 000058A7 B91900 MOV CX,BPBSIZ 0 000058AA F3A4 REP MOVSB ; MOVE BPBSIZ BYTES 2759 GO_TO_NEXT_BDS: 0 000058AC 5F POP DI 0 000058AD 07 POP ES ; RESTORE POINTER TO BDS 0 000058AE 26C43D les di, [ES:DI + LINK] 0 000058B1 E963FF JMP NEXT_BDS 2764 2765 SETDRVPARMS ENDP 2766 2767 === Switch to base=000000h -> "DOSENTRY" 2768 usesection DOSENTRY 2769 2770 ; 2771 ; SI POINTS TO DEVICE HEADER 2772 ; J.K. 4/22/86 - print_init, aux_init is modified to eliminate the self-modifying 2773 ; J.K. code. 2774 2775 PRINT_INIT: 2776 Get_device_number equ GET_DEVICE_NUMBER ; NASM port label 0 00001074 E80F00 call Get_device_number 2778 ;SB33028***************************************************************** 0 00001077 B401 mov ah,1 ;initalize printer port ;SB;3.30 0 00001079 CD17 int 17h ;call ROM-Bios routine ;SB;3.30 2781 ;SB33028***************************************************************** 0 0000107B C3 ret 2783 2784 AUX_INIT: 0 0000107C E80700 call Get_device_number 2786 ;SB33028***************************************************************** 0 0000107F B0A3 mov al,RSINIT ;2400,N,1,8 (MSEQU.INC) ;SB ;3.30* 0 00001081 B400 mov ah,0 ;initalize AUX port ;SB ;3.30* 0 00001083 CD14 int 14h ;call ROM-Bios routine ;SB ;3.30* 2790 ;SB33028***************************************************************** 0 00001085 C3 ret 2792 2793 GET_DEVICE_NUMBER: 2794 ;SI -> device header 0 00001086 2E8A440D MOV AL,[CS:SI+13] ;GET DEVICE NUMBER FROM THE NAME 0 0000108A 2C31 SUB AL,"1" 0 0000108C 98 CBW 0 0000108D 89C2 MOV DX,AX 0 0000108F C3 RET 2800 2801 %if 0 2802 ; 2803 ; PURGE_96TPI NOP'S CALLS TO 96TPI SUPPORT. 2804 ; 2805 PURGE_96TPI PROC NEAR ;MJB001 2806 PUSH DS 2807 PUSH ES 2808 2809 PUSH CS ;MJB001 2810 POP ES ;MJB001 2811 PUSH CS ;MJB001 2812 POP DS ;MJB001 2813 ASSUME DS:BIOCODE,ES:BIOCODE 2814 2815 MOV SI,OFFSET PATCHTABLE 2816 PATCHLOOP: 2817 LODSW 2818 MOV CX,AX 2819 JCXZ PATCHDONE 2820 LODSW 2821 MOV DI,AX 2822 MOV AL,90H 2823 REP STOSB 2824 JMP PATCHLOOP 2825 2826 PATCHDONE: 2827 ;**************NOT NEEDED ANY MORE*********************** 2828 ; MOV DI,OFFSET FORMAT_PATCH ; ARR 2.42 2829 ; MOV AL,CS:INST_FAR_RET 2830 ; STOSB 2831 ;******************************************************** 2832 MOV DI,OFFSET TABLE_PATCH ; ARR 2.42 2833 MOV AX,OFFSET EXIT 2834 STOSW 2835 STOSW 2836 2837 POP ES 2838 POP DS 2839 RET ;MJB001 2840 PURGE_96TPI ENDP 2841 %endif 2842 2843 === Switch to base=002530h -> "SYSINITTRAIL" 2844 usesection SYSINITTRAIL 2845 2846 ;Mini disk initialization routine. Called right after DoHard - J.K. 4/7/86 2847 ; DoMini ********************************************************************** 2848 ; **CS=DS=ES=code 2849 ; **DoMini will search for every extended partition in the system, and 2850 ; initialize it. 2851 ; **BDSM stands for BDS table for Mini disk and located right after the label 2852 ; End96Tpi. End_Of_BDSM will have the offset value of the ending 2853 ; address of BDSM table. 2854 ; **BDSM is the same as usual BDS structure except that TIM_LO, TIM_HI entries 2855 ; are overlapped and used to identify mini disk and the number of Hidden_trks. 2856 ; Right now, they are called as IsMini, Hidden_Trks respectively. 2857 ; **DoMini will use the same routine in SETHARD routine after label SET1 to 2858 ; save coding. 2859 ; **DRVMAX determined in DoHard routine will be used for the next 2860 ; available logical mini disk drive number. 2861 ; 2862 ; Input: DRVMAX, DSKDRVS 2863 ; 2864 ; Output: MiniDisk installed. BDSM table established and installed to BDS. 2865 ; num_mini_dsk - the number of mini disks installed in the system. 2866 ; End_Of_BDSM - ending offset address of BDSM. 2867 ; 2868 ; 2869 ; Called modules: 2870 ; GetBoot, WRMSG, int 13h (AH=8, Rom) 2871 ; FIND_MINI_PARTITION (new), Install_BDSM (new), 2872 ; SetMini (new, it will use SET1 routine) 2873 ; Variables used: End_Of_BDSM, numh, MiniNum, num_mini_dsk, 2874 ; Rom_Minidsk_num, Mini_HDLIM, Mini_SECLIM 2875 ; BDSMs, BDSM_type (struc), Start_BDS 2876 ;****************************************************************************** 2877 ; 2878 2879 DoMini: 2880 Message fTestHard,<"Start of DoMini...",cr,lf> 2881 0 000058B4 E8BFF8 call alloc_upb 0 000058B7 0E push cs 0 000058B8 1F pop ds 0 000058B9 BE[0000] mov si, BDS_harddisk_template 0 000058BC B96400 mov cx, BDS_TYPE_struc_size 0 000058BF 57 push di 0 000058C0 F3A4 rep movsb 0 000058C2 5F pop di ; di -> next UPB 0 000058C3 06 push es 0 000058C4 1F pop ds 2892 2893 ;SB33028******************************************************************** 0 000058C5 B280 mov dl, 80h ;look at first hard drive ;SB ;3.30* 0 000058C7 B408 mov ah, 8h ;get drive parameters ;SB ;3.30* 0 000058C9 CD13 int 13h ;call ROM-Bios ;SB ;3.30* 2897 ;SB33028******************************************************************** 0 000058CB 84D2 test dl, dl 0 000058CD 744D jz DoMiniRet ;no hard file? Then exit. 0 000058CF 2E8816[E400] mov [cs:numh], dl ;save the number of hard files. 0 000058D4 31C0 xor ax,ax 0 000058D6 E899FB call sysinit_get_es_dosentry 2903 drvmax equ DRVMAX ; NASM port label 0 000058D9 26A0[0000] mov al, [es:drvmax] ; ! in DOSENTRY 0 000058DD 2EA2[E500] mov [cs:MiniNum], al ;this will be the logical drive letter 2906 ;for mini disk to start with. 0 000058E1 2EC606[E700]80 mov byte [cs:Rom_Minidsk_num], 80h 2908 DoMiniBegin: 0 000058E7 31C0 xor ax, ax 0 000058E9 88F0 mov al, dh 0 000058EB 40 inc ax ;Get # of heads (convert it to 1 based) 0 000058EC 2EA3[E800] mov [cs:Mini_HDLIM], ax ;save it. 0 000058F0 83E13F and cx, 3Fh ;Get # of sectors/track 0 000058F3 2E890E[EA00] mov [cs:Mini_SECLIM], cx ;and save it. 2915 0 000058F8 2E8A16[E700] mov dl, [cs:Rom_Minidsk_num];drive number
0 000058FD E82FFB call GETBOOT ;read master boot record into 7c0:BootBias 2918 assume es:nothing 0 00005900 7203 jc DoMiniNext 0 00005902 E81A00 call FIND_MINI_PARTITION 2921 DoMiniNext: 0 00005905 2EFE0E[E400] dec byte [cs:numh] 0 0000590A 7410 jz DoMiniRet 2924 Rom_MiniDsk_Num equ Rom_Minidsk_num ; NASM port label 0 0000590C 2EFE06[E700] inc byte [cs:Rom_MiniDsk_Num] ;Next hard file 2926 ;SB33028******************************************************************** 0 00005911 2E8A16[E700] mov dl, [cs:Rom_MiniDsk_Num];look at next hard drive ;SB ;3.30* 0 00005916 B408 mov ah, 8h ;get drive parameters ;SB ;3.30* 0 00005918 CD13 int 13h ;call ROM-Bios ;SB ;3.30* 2930 ;SB33028******************************************************************** 0 0000591A EBCB jmp DoMiniBegin 2932 2933 DoMiniRet: 0 0000591C E95DFA jmp hdd_dealloc 2935 2936 2937 ;Find_Mini_Partition tries to find every Extended partition on a disk. 2938 ;At entry: DI -> BDSM entry 2939 ; ES:BX -> 07c0:BootBias - Master Boot Record 2940 ; Rom_MiniDsk_Num - ROM drive number 2941 ; MiniNum - Logical drive number 2942 ; Mini_HDLIM, Mini_SECLIM 2943 ; 2944 ;Called routine: SETMINI which uses SET1 (in SETHARD routine) 2945 ;Variables & equates used from original BIOS - flags, fNon_Removable, fBigfat 2946 ; 2947 ; 2948 FIND_MINI_PARTITION: 0 0000591F 1E push ds 0 00005920 57 push di ; -> next UPB 0 00005921 0E push cs 0 00005922 1F pop ds 0 00005923 31C0 xor ax, ax 2954 ; mov word ptr [extended_lba_innermost], ax 2955 ; mov word ptr [extended_lba_innermost + 2], ax 0 00005925 A3[6E00] mov word ptr [extended_lba_outermost], ax 0 00005928 A3[7000] mov word ptr [extended_lba_outermost + 2], ax 2958 0 0000592B 81C3C201 add bx, 1C2h ;BX -> system id. 2960 2961 FmpNext: 0 0000592F 0E push cs 0 00005930 1F pop ds 0 00005931 26803F05 cmp byte ptr [ES:BX], 5 ; 5 = extended partition ID. 0 00005935 741B jz FmpGot 0 00005937 8A16[E700] mov dl, [Rom_MiniDsk_Num] 0 0000593B E86BFE call detectlba 0 0000593E 7206 jc fmpnext_no_0F 0 00005940 26803F0F cmp byte ptr [es:bx], 0Fh 0 00005944 740C je FmpGot 2971 2972 fmpnext_no_0F: 0 00005946 83C310 add bx, 16 ; for next entry 0 00005949 81FB0202 cmp bx, 202h+BootBias 0 0000594D 75E0 jnz FmpNext 0 0000594F E9CD00 jmp FmpRet ;not found extended partition 2977 2978 FmpGot: ;found my partition. 0 00005952 5F pop di 0 00005953 1F pop ds ; -> next UPB 0 00005954 1E push ds 0 00005955 57 push di 2983 Message ftestHard,<"Found my partition...",cr,lf> 2984 Flags equ FLAGS ; NASM port equate 2985 fNon_Removable equ FNON_REMOVABLE ; NASM port equate 0 00005956 834D2301 or word ptr [DI + Flags], fNon_Removable 2987 FormFactor equ FORMFACTOR ; NASM port equate 2988 ffHardFile equ FFHARDFILE ; NASM port equate 0 0000595A C6452205 mov byte ptr [DI + FormFactor], ffHardFile 2990 fBigFat equ FBIGFAT ; NASM port label 0 0000595E 2EC606[0700]00 mov byte [cs:fBigFat], 0 ;assume 12 bit Fat. 0 00005964 2EA1[E800] mov ax, [cs:Mini_HDLIM] 0 00005968 894515 mov [DI + HDLIM], ax 0 0000596B 2EA1[EA00] mov ax, [cs:Mini_SECLIM] 0 0000596F 894513 mov [DI + SECLIM], ax 0 00005972 2EA0[E700] mov al, [cs:Rom_MiniDsk_Num] 0 00005976 884504 mov [DI + DRIVENUM], al ;set physical number 0 00005979 2EA0[E500] mov al, [cs:MiniNum] 0 0000597D 884505 mov [DI + DRIVELET], al ;set logical number 3000 0 00005980 26837F0A00 cmp word ptr [es:bx+10], 0 ;AN000; 0 00005985 770A ja FmpGot_Cont ;AN000; 0 00005987 26837F0840 cmp word ptr [ES:BX+8], 64 ;**With current BPB, only lower word 3004 ; is meaningful. 0 0000598C 7303E98E00 jb FmpRet ;should be bigger than 64 sectors at least 3006 FmpGot_Cont: ;AN000; 0 00005991 83EB04 sub bx, 4 ;let BX point to the start of the entry 3008 0 00005994 2EA0[E700] mov al, [cs:Rom_MiniDsk_Num] 0 00005998 884504 mov byte ptr [di + DRIVENUM], al 3011 0 0000599B 268B4708 mov ax, word ptr [es:bx + 8] 0 0000599F 268B570A mov dx, word ptr [es:bx + 8 + 2] 0 000059A3 2E0306[6E00] add ax, word ptr [cs:extended_lba_outermost] 0 000059A8 2E1316[7000] adc dx, word ptr [cs:extended_lba_outermost + 2] 3016 ; mov word ptr [cs:extended_lba_innermost], ax 3017 ; mov word ptr [cs:extended_lba_innermost + 2], dx 3018 0 000059AD 31C9 xor cx, cx 0 000059AF 2E390E[6E00] cmp word ptr [cs:extended_lba_outermost], cx 0 000059B4 7510 jne @F 0 000059B6 2E390E[7000] cmp word ptr [cs:extended_lba_outermost + 2], cx 0 000059BB 7509 jne @F 0 000059BD 2EA3[6E00] mov word ptr [cs:extended_lba_outermost], ax 0 000059C1 2E8916[7000] mov word ptr [cs:extended_lba_outermost + 2], dx 3026 @@: 3027 0 000059C6 894517 mov word ptr [di + HIDSEC_L], ax 0 000059C9 895519 mov word ptr [di + HIDSEC_H], dx 3030 3031 ;** Now, read the volume boot record into BootBias. 3032 ;SB33029****************************************************************** 0 000059CC B90102 mov cx,0201h ;read,1 sector ;SB ;3.30* 0 000059CF BB0000 mov bx,BOOTBIAS ;buffer offset ;SB ;3.30* 0 000059D2 E892FD call readsector_detect 3036 ;SB33029****************************************************************** 0 000059D5 7248 jc FmpRet ;cannot continue. 0 000059D7 BBC201 mov bx, 1c2h+BOOTBIAS 3039 0 000059DA 06 push es ;;DCL/KWC 8/2/87 addressability to 3041 ;; next minidisk 0 000059DB 2E8A16[E700] mov dl, [cs:Rom_MiniDsk_Num] 0 000059E0 E83F00 call SetMini ;install a mini disk. BX value saved. 3044 0 000059E3 07 pop es ;;DCL/KWC 8/2/87 3046 0 000059E4 7236 jc FmpnextChain 3048 0 000059E6 E85600 call have_bpb 0 000059E9 730A jnc @F 0 000059EB 0E PUSH CS 0 000059EC 1F POP DS 3053 extern BADBLOCK 0 000059ED BA[0000] MOV DX,OFFSET BADBLOCK 3055 extern PRINT 0 000059F0 E8[0000] call PRINT 0 000059F3 EB2A jmp FmpRet 3058 @@: 3059 0 000059F5 E85300 call Install_BDSM ;install the BDSM into the BDS table 3061 ; call Show_Installed_Mini ;show the installed message. 3/35/86 - Don't show messages. J.K. 3062 0 000059F8 0E push cs 0 000059F9 1F pop ds 0 000059FA FE06[E500] inc byte [MiniNum] ;increase the logical drive number for next 0 000059FE FE06[E600] inc byte [num_mini_dsk] ;increase the number of mini disk installed. 3067 0 00005A02 E82300 call set_bpb 3069 0 00005A05 06 push es 0 00005A06 E86DF7 call alloc_upb 0 00005A09 0E push cs 0 00005A0A 1F pop ds 0 00005A0B BE[0000] mov si, BDS_harddisk_template 0 00005A0E B96400 mov cx, BDS_TYPE_struc_size 0 00005A11 57 push di 0 00005A12 F3A4 rep movsb 0 00005A14 5F pop di ; di -> next UPB 0 00005A15 06 push es 0 00005A16 1F pop ds 0 00005A17 07 pop es 0 00005A18 5E pop si ; discard di on stack 0 00005A19 5E pop si ; discard ds on stack 0 00005A1A 1E push ds 0 00005A1B 57 push di 0 00005A1C E910FF FmpnextChain: jmp FmpNext ;let's find out if we have any chained partition 3087 FmpRet: 0 00005A1F 5F pop di 0 00005A20 1F pop ds 0 00005A21 C3 ret 3091 3092 SetMini: 0 00005A22 57 push di 0 00005A23 53 push bx 0 00005A24 1E push ds 0 00005A25 E9BEFA jmp SET1 ;will be returned to Find mini partition routine. 3097 ;Some logic has been added to SET1 to 3098 ;deal with Mini disks. 3099 3100 3101 set_bpb: 0 00005A28 56 push si 0 00005A29 53 push bx ; now, set the DskDrvs pointer to BPB info 0 00005A2A 2E8B1E[EC00] mov bx, [cs:Mini_BPB_ptr] 0 00005A2F 8D7506 lea si, [di + BYTEPERSEC] ; points to BPB of BDSM 0 00005A32 2E8937 mov [cs:bx], si 0 00005A35 43 inc bx 0 00005A36 43 inc bx 0 00005A37 2E891E[EC00] mov word [cs:Mini_BPB_ptr], bx ; advance to the next address 0 00005A3C 5B pop bx 0 00005A3D 5E pop si 0 00005A3E C3 retn 3113 3114 have_bpb: 0 00005A3F 2E813E[EC00][2E01] cmp word [cs:Mini_BPB_ptr], DSKDRVS.end 3116 ; CY if valid to append another 0 00005A46 F5 cmc ; NC if valid 0 00005A47 C3 retn 3119 3120 3121 ; 3122 ;Install BDSM installs a BDSM (pointed by DS:DI) into the end of the current 3123 ;linked list of BDS. 3124 ;Also, set the current BDSM pointer segment to DS. 3125 ;At entry: DS:DI -> BDSM 3126 ; 3127 Install_BDSM_and_set_bpb: 0 00005A48 E8DDFF call set_bpb 3129 Install_BDSM: 3130 assume ds:BIOcode,es:nothing 0 00005A4B 50 push ax 0 00005A4C 56 push si 0 00005A4D 06 push es 3134 0 00005A4E B8FFFF mov ax, -1 0 00005A51 894502 mov word ptr [di + LINK + 2], ax 0 00005A54 8905 mov word ptr [di + LINK], ax ; make sure it is a null ptr. 3138 0 00005A56 E819FA call sysinit_get_es_dosentry 3140 Start_BDS equ START_BDS ; NASM port label 0 00005A59 26C436[0000] les si, [es:Start_BDS] ;start of the beginning of list 0 00005A5E 39C6 cmp si, ax 0 00005A60 750F jne I_BDSM_Next 0 00005A62 E80DFA call sysinit_get_es_dosentry 0 00005A65 26893E[0000] mov word [es:Start_BDS], di 0 00005A6A 268C1E[0200] mov word [es:Start_BDS + 2], ds 0 00005A6F EB11 jmp I_BDSM_ret 3148 3149 I_BDSM_Next: 0 00005A71 263904 cmp word ptr [es:si + LINK], ax ;end of the list? 0 00005A74 7405 je I_BDSM_New 0 00005A76 26C434 les si, [es:si + LINK] 0 00005A79 EBF6 jmp short I_BDSM_Next 3154 I_BDSM_New: 0 00005A7B 268C5C02 mov word ptr [es:si + LINK + 2], ds 0 00005A7F 26893C mov word ptr [es:si + LINK], di 3157 3158 I_BDSM_ret: 0 00005A82 07 pop es 0 00005A83 5E pop si 0 00005A84 58 pop ax 0 00005A85 C3 ret 3163 3164 ;***The following code is not needed any more. Don't show any 3165 ;***messages to be compatible with the behavior of IBMBIO.COM. 3166 ;;Show the message "Mini disk installed ..." 3167 ;;This routine uses WRMSG procedure which will call OUTCHR. 3168 ;Show_Installed_Mini: 3169 ; push ax 3170 ; push bx 3171 ; push ds 3172 ; 3173 ; mov al, MiniNum ;logical drive number 3174 ; add al, Drv_Letter_Base ;='A' 3175 ; mov Mini_Drv_Let, al 3176 ; mov si, offset Installed_Mini 3177 ; call WRMSG 3178 ; 3179 ; pop ds 3180 ; pop bx 3181 ; pop ax 3182 ; ret 3183 ;**End of mini disk initialization** ;J.K. 4/7/86 3184 3185 === Switch to base=000000h -> "DOSENTRY" 3186 usesection DOSENTRY 3187 3188 CMOS_Clock_Read proc near 3189 3190 assume ds:BIOcode,es:BIOcode 3191 ; IN ORDER TO DETERMINE IF THERE IS A CLOCK PRESENT IN THE SYSTEM, THE FOLLOWING 3192 ; NEEDS TO BE DONE. 0 00001090 50 PUSH AX 0 00001091 51 PUSH CX 0 00001092 52 PUSH DX 0 00001093 55 PUSH BP 3197 0 00001094 31ED XOR BP,BP 3199 LOOP_CLOCK: 0 00001096 31C9 XOR CX,CX 0 00001098 31D2 XOR DX,DX 3202 ;SB33030******************************************************************** 0 0000109A B402 MOV AH,2 ;READ REAL TIME CLOCK ;SB ;3.30 0 0000109C CD1A INT 1Ah ;CALL ROM-BIOS ROUTINE ;SB ;3.30 3205 ;SB33030******************************************************************** 0 0000109E 83F900 CMP CX,0 0 000010A1 7512 JNZ CLOCK_PRESENT 3208 0 000010A3 83FA00 CMP DX,0 0 000010A6 750D JNZ CLOCK_PRESENT 3211 0 000010A8 83FD01 CMP BP,1 ; READ AGAIN AFTER A SLIGHT DELAY, IN CASE CLOCK 0 000010AB 741C JZ NO_READDATE ; WAS AT ZERO SETTING. 3214 0 000010AD 45 INC BP ; ONLY PERFORM DELAY ONCE. 0 000010AE B90040 MOV CX,4000H 3217 DELAY: 0 000010B1 E2FE LOOP DELAY 0 000010B3 EBE1 JMP LOOP_CLOCK 3220 3221 CLOCK_PRESENT: 0 000010B5 2EC606[0000]01 mov byte [cs:HaveCMOSClock], 1 ;J.K. Set the flag for cmos clock 3223 0 000010BB E81000 call CMOSCK ;J.K. Reset CMOS clock rate that may be 3225 ;possibly destroyed by CP DOS and POST routine did not 3226 ;restore that. 3227 0 000010BE 56 PUSH SI 3229 MESSAGE FTESTINIT,<"CLOCK DEVICE",CR,LF> 0 000010BF E811F9 CALL READ_REAL_DATE ;MJB002 READ REAL-TIME CLOCK FOR DATE 3231 0 000010C2 FA CLI ;MJB002 0 000010C3 8936[0000] MOV [DAYCNT],SI ;MJB002 SET SYSTEM DATE 0 000010C7 FB STI ;MJB002 0 000010C8 5E POP SI ;MJB002 3236 NO_READDATE: 0 000010C9 5D POP BP 0 000010CA 5A POP DX 0 000010CB 59 POP CX 0 000010CC 58 POP AX 0 000010CD C3 RET 3242 3243 CMOS_Clock_Read endp 3244 ; 3245 ;J.K. 10/28/86 3246 ;J.K. THE FOLLOWING CODE IS WRITTEN BY JACK GULLEY IN ENGINEERING GROUP. 3247 ;J.K. CP DOS IS CHANGING CMOS CLOCK RATE FOR ITS OWN PURPOSES AND IF THE 3248 ;J.K. USE COLD BOOT THE SYSTEM TO USE PC DOS WHILE RUNNING CP DOS, THE CMOS 3249 ;J.K. CLOCK RATE ARE STILL SLOW WHICH SLOW DOWN DISK OPERATIONS OF PC DOS 3250 ;J.K. WHICH USES CMOS CLOCK. PC DOS IS PUT THIS CODE IN MSINIT TO FIX THIS 3251 ;J.K. PROBLEM AT THE REQUEST OF CP DOS. 3252 ;J.K. THE PROGRAM IS MODIFIED TO BE RUN ON MSINIT. Equates are defined in CMOSEQU.INC. 3253 ;J.K. This program will be called by CMOS_Clock_Read procedure. 3254 ; 3255 ; The following code CMOSCK is used to insure that the CMOS has not 3256 ; had its rate controls left in an invalid state on older AT's. 3257 ; 3258 ; It checks for an AT model byte "FC" with a submodel type of 3259 ; 00, 01, 02, 03 or 06 and resets the periodic interrupt rate 3260 ; bits incase POST has not done it. This initilization routine 3261 ; is only needed once when DOS loads. It should be ran as soon 3262 ; as possible to prevent slow diskette access. 3263 ; 3264 ; This code exposes one to DOS clearing CMOS setup done by a 3265 ; resident program that hides and re-boots the system. 3266 ; 3267 CMOSCK PROC NEAR ; CHECK AND RESET RTC RATE BITS 3268 assume ds:nothing,es:nothing 3269 3270 ;Model byte and Submodel byte were already determined in MSINIT. 0 000010CE 50 push ax 3272 Model_byte equ Model_Byte ; NASM port label 0 000010CF 2E803E[0000]FC cmp byte [cs:Model_byte], 0FCh ;check for PC-AT model byte 3274 ; EXIT IF NOT "FC" FOR A PC-AT 0 000010D5 7525 JNE CMOSCK9 ; Exit if not an AT model 3276 0 000010D7 2E803E[0000]06 CMP byte [cs:Secondary_Model_Byte],06H ; Is it 06 for the industral AT 0 000010DD 7408 JE CMOSCK4 ; Go reset CMOS periodic rate if 06 0 000010DF 2E803E[0000]04 CMP byte [cs:Secondary_Model_Byte],04H ; Is it 00, 01, 02, or 03 0 000010E5 7315 JNB CMOSCK9 ; EXIT if problem fixed by POST 3281 ;J.K. Also,Secondary_model_byte = 0 when AH=0c0h, int 15h failed. 3282 CMOSCK4: ; RESET THE CMOS PERIODIC RATE 3283 ; Model=FC submodel=00,01,02,03 or 06 3284 ;SB33IN2*********************************************************************** 3285 0 000010E7 B08A mov al,CMOS_REG_A | NMI ;NMI disabled on return 0 000010E9 B426 mov ah,00100110b ;Set divider & rate selection 0 000010EB E83000 call CMOS_WRITE 3289 3290 ;SB33IN2*********************************************************************** 3291 3292 ; CLEAR SET,PIE,AIE,UIE AND SQWE 0 000010EE B08B mov al,CMOS_REG_B | NMI ;NMI disabled on return 0 000010F0 E80B00 call CMOS_READ 0 000010F3 2407 and al,00000111b ;clear SET,PIE,AIE,UIE,SQWE 0 000010F5 88C4 mov ah,al 0 000010F7 B00B mov al,CMOS_REG_B ;NMI enabled on return 0 000010F9 E82200 call CMOS_WRITE 3299 3300 ;SB33IN3*********************************************************************** 3301 3302 CMOSCK9: ; EXIT ROUTINE 0 000010FC 58 pop ax 0 000010FD C3 RET ; RETurn to caller 3305 ; Flags modifyied 3306 CMOSCK ENDP 3307 ;PAGE 3308 ;--- CMOS_READ ----------------------------------------------------------------- 3309 ; READ BYTE FROM CMOS SYSTEM CLOCK CONFIGURATION TABLE : 3310 ; : 3311 ; INPUT: (AL)= CMOS TABLE ADDRESS TO BE READ : 3312 ; BIT 7 = 0 FOR NMI ENABLED AND 1 FOR NMI DISABLED ON EXIT : 3313 ; BITS 6-0 = ADDRESS OF TABLE LOCATION TO READ : 3314 ; : 3315 ; OUTPUT: (AL) VALUE AT LOCATION (AL) MOVED INTO (AL). IF BIT 7 OF (AL) WAS : 3316 ; ON THEN NMI LEFT DISABLED. DURING THE CMOS READ BOTH NMI AND : 3317 ; NORMAL INTERRUPTS ARE DISABLED TO PROTECT CMOS DATA INTEGRITY. : 3318 ; THE CMOS ADDRESS REGISTER IS POINTED TO A DEFAULT VALUE AND : 3319 ; THE INTERRUPT FLAG RESTORED TO THE ENTRY STATE ON RETURN. : 3320 ; ONLY THE (AL) REGISTER AND THE NMI STATE IS CHANGED. : 3321 ;------------------------------------------------------------------------------- 3322 3323 CMOS_READ PROC NEAR ; READ LOCATION (AL) INTO (AL) 3324 assume es:nothing,ds:nothing 0 000010FE 9C PUSHF ; SAVE INTERRUPT ENABLE STATUS AND FLAGS 3326 ;SB33IN4******************************************************************** 3327 0 000010FF FA cli 0 00001100 53 push bx 0 00001101 50 push ax ;save user NMI state 0 00001102 0C80 or al,NMI ;disable NMI for us 0 00001104 E670 out CMOS_PORT,al 0 00001106 90 nop ;undocumented delay needed 0 00001107 E471 in al,CMOS_DATA ;get data value 3335 3336 ;set NMI state to user specified 0 00001109 89C3 mov bx,ax ;save data value 0 0000110B 58 pop ax ;get user NMI 0 0000110C 2480 and al,NMI 0 0000110E 0C0F or al,CMOS_SHUT_DOWN 0 00001110 E670 out CMOS_PORT,al 0 00001112 90 nop 0 00001113 E471 in al,CMOS_DATA 3344 0 00001115 89D8 mov ax,bx ;data value 0 00001117 5B pop bx 3347 3348 ;SB33IN4******************************************************************** 0 00001118 0E PUSH CS ; *PLACE CODE SEGMENT IN STACK AND 0 00001119 E80100 CALL CMOS_POPF ; *HANDLE POPF FOR B- LEVEL 80286 0 0000111C C3 RET ; RETURN WITH FLAGS RESTORED 3352 3353 CMOS_READ ENDP 3354 3355 CMOS_POPF PROC NEAR ; POPF FOR LEVEL B- PARTS 0 0000111D CF IRET ; RETURN FAR AND RESTORE FLAGS 3357 3358 CMOS_POPF ENDP 3359 3360 ;--- CMOS_WRITE ---------------------------------------------------------------- 3361 ; WRITE BYTE TO CMOS SYSTEM CLOCK CONFIGURATION TABLE : 3362 ; : 3363 ; INPUT: (AL)= CMOS TABLE ADDRESS TO BE WRITTEN TO : 3364 ; BIT 7 = 0 FOR NMI ENABLED AND 1 FOR NMI DISABLED ON EXIT : 3365 ; BITS 6-0 = ADDRESS OF TABLE LOCATION TO WRITE : 3366 ; (AH)= NEW VALUE TO BE PLACED IN THE ADDRESSED TABLE LOCATION : 3367 ; : 3368 ; OUTPUT: VALUE IN (AH) PLACED IN LOCATION (AL) WITH NMI LEFT DISABLED : 3369 ; IF BIT 7 OF (AL) IS ON. DURING THE CMOS UPDATE BOTH NMI AND : 3370 ; NORMAL INTERRUPTS ARE DISABLED TO PROTECT CMOS DATA INTEGRITY. : 3371 ; THE CMOS ADDRESS REGISTER IS POINTED TO A DEFAULT VALUE AND : 3372 ; THE INTERRUPT FLAG RESTORED TO THE ENTRY STATE ON RETURN. : 3373 ; ONLY THE CMOS LOCATION AND THE NMI STATE IS CHANGED. : 3374 ;------------------------------------------------------------------------------- 3375 3376 CMOS_WRITE PROC NEAR ; WRITE (AH) TO LOCATION (AL) 3377 assume es:nothing,ds:nothing 0 0000111E 9C PUSHF ; SAVE INTERRUPT ENABLE STATUS AND FLAGS 0 0000111F 50 PUSH AX ; SAVE WORK REGISTER VALUES 3380 0 00001120 FA cli 0 00001121 50 push ax ;save user NMI state 0 00001122 0C80 or al,NMI ;disable NMI for us 0 00001124 E670 out CMOS_PORT,al 0 00001126 90 nop 0 00001127 88E0 mov al,ah 0 00001129 E671 out CMOS_DATA,al ;write data 3388 3389 ;set NMI state to user specified 0 0000112B 58 pop ax ;get user NMI 0 0000112C 2480 and al,NMI 0 0000112E 0C0F or al,CMOS_SHUT_DOWN 0 00001130 E670 out CMOS_PORT,al 0 00001132 90 nop 0 00001133 E471 in al,CMOS_DATA 3396 3397 ;SB33IN5******************************************************************** 0 00001135 58 POP AX ; RESTORE WORK REGISTERS 0 00001136 0E PUSH CS ; *PLACE CODE SEGMENT IN STACK AND 0 00001137 E8E3FF CALL CMOS_POPF ; *HANDLE POPF FOR B- LEVEL 80286 0 0000113A C3 RET 3402 3403 CMOS_WRITE ENDP 3404 ; 3405 3406 3407 END$: 3408 ; (no prior section) ; CODE ENDS 3409 END 3410 3411 === Trace listing source: sysinit1.lst 1 ; PAGE ,132 ; 2 ; SCCSID = @(#)sysinit1.asm 1.7 85/10/24 3 ;TITLE BIOS SYSTEM INITIALIZATION 4 %warning out: ...SYSINIT1 4 ****************** warning: out: ...SYSINIT1 [-w+user] 5 ;============================================================================== 6 ;REVISION HISTORY: 7 ;AN000 - New for DOS Version 4.00 - J.K. 8 ;AC000 - Changed for DOS Version 4.00 - J.K. 9 ;AN00x - PTM number for DOS Version 4.00 - J.K. 10 ;============================================================================== 11 ;AN001; p40 Boot from the system with no floppy diskette drives 6/26/87 J.K. 12 ;AN002; d24 MultiTrack= command added. 6/29/87 J.K. 13 ;AN003; d9 Double word mov for 386 machine 7/15/87 J.K. 14 ;AN004; p447 BUFFERS = 50 /E without EMS installed hangs 8/25/87 J.K. 15 ;AN005; d184 Set DEVMARK for MEM command 8/25/87 J.K. 16 ;AN006; p851 Installable files not recognized corretly. 9/08/87 J.K. 17 ;AN007; p1299 Set the second entry of DEVMARK for MEM command 9/25/87 J.K. 18 ;AN008; p1361 New Extended Attribute 9/28/87 J.K. 19 ;AN009; p1326 Buffers = 50 /e hangs 9/28/87 J.K. 20 ;AN010; New EMS Interface 21 ;AN011; New Message SKL file 10/20/87 J.K. 22 ;AN012; P2211 Setting EA=7 for ANSI.SYS hangs the system 11/02/87 J.K. 23 ;AN013; p2343 Set the name for SYSINIT_BASE for MEM command 11/11/87 J.K. 24 ;AN014; D358 New device driver INIT function package 12/03/87 J.K. 25 ;AN015; For Installed module with no parameter 12/11/87 J.K. 26 ;AN016; D285 Undo the Extended Attribute handling 12/17/87 J.K. 27 ;AN017; P2806 Show "Error in CONFIG.SYS ..." for INSTALL= command 12/17/87 J.K. 28 ;AN018; P2914 Add Extended Memory Size in SYSVAR 01/05/88 J.K. 29 ;AN019; P3111 Take out the order dependency of the INSTALL= 01/25/88 J.K. 30 ;AN020; P3497 Performace fix for new buffer scheme 02/15/88 J.K. 31 ;AN021; D486 SHARE installation for big media 02/23/88 J.K. 32 ;AN022; D493 Undo D358 & do not show error message for device driv02/24/88 J.K. 33 ;AN023; D474 Change BUFFERS= /E option to /X for expanded memory 03/16/88 J.K. 34 ;AN024; D506 Take out the order dependency of the IFS= 03/28/88 J.K. 35 ;AN025; P4086 Memory allocation error when loading SHARE.EXE 03/31/88 J.K. 36 ;AN026; D517 New Balanced Real memory buffer set up scheme 04/18/88 J.K. 37 ;AN027; D528 Install XMAEM.SYS first before everything else 04/29/88 J.K. 38 ;AN028; P4669 SHARE /NC causes an error 05/03/88 J.K. 39 ;AN029; P4759 Install EMS INT2fh, INT 67h handler 05/12/88 J.K. 40 ;AN030; P4934 P4759 INT 2Fh handler number be changed to 1Bh 05/20/88 J.K. 41 ;============================================================================== 42 43 extern BUFFHEAD 44 45 TRUE EQU 0FFFFh 46 FALSE EQU 0 47 CR equ 13 48 LF equ 10 49 TAB equ 9 50 51 IBMVER EQU TRUE 52 IBM EQU IBMVER 53 STACKSW EQU TRUE ;Include Switchable Hardware Stacks 54 IBMJAPVER EQU FALSE ;If TRUE set KANJI true also 55 %iassign MSVER FALSE 56 ALTVECT EQU FALSE ;Switch to build ALTVECT version 57 KANJI EQU FALSE 58 MYCDS_SIZE equ 88 ;J.K. Size of Curdir_List. If it is not 59 ;the same, then will generate compile error. 60 61 ; 62 %IF IBMJAPVER 63 NOEXEC EQU TRUE 64 %ELSE 65 NOEXEC EQU FALSE 66 %ENDIF 67 68 ;DOSSIZE EQU 0A000H 69 ;dossize equ 0C000H ;J.K. for the debugging version of IBMDOS. 70 71 %include "dcodeseg.nas" 1 <1> 2 <1> %ifndef DCODESEGNAS 3 <1> %assign DCODESEGNAS 1 4 <1> === Switch to base=008400h -> "DOSCODETABLE" 5 <1> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <1> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=008400h -> "DOSCODECODE" 7 <1> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <1> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=008400h -> "DOSBIOCODE" 9 <1> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=008400h -> "BIOCODE" 10 <1> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <1> 12 <1> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <1> 14 <1> %endif 72 === Switch to base=011BF0h -> "AFTERDOSCODE" 73 section AFTERDOSCODE class=AFTERDOSCODE align=16 74 global afterdoscodelabel 75 afterdoscodelabel: 76 77 [list -] 77 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 77 ****************** warning: out: BPB.INC... [-w+user] 77 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 77 ****************** warning: out: DEVSYM.INC... [-w+user] 77 ****************** warning: out: IOCTL.INC... [-w+user] 77 ****************** warning: out: BPB.INC... [-w+user] 77 ****************** warning: out: BIOSTRUC.INC... [-w+user] 77 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 77 ****************** warning: out: MSBDS.INC... [-w+user] 77 ****************** warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi] 14 <2> [list -] 14 <1> [list -] 94 [list -] 13 <1> [list -] 96 [list +] 97 98 ;AN000 J.K. If MYCDS_SIZE <> CURDIRLEN, then force a compilatiaon error. 99 %if MYCDS_SIZE != curdirLen 100 %error  !!! SYSINIT1 COMPILATION FAILED. DIFFERENT CDS SIZE !!! 101 %endif 102 103 %IFN IBMJAPVER 104 EXTRN RE_INIT:FAR 105 %ENDIF 106 107 ;--------------------------------------- 108 ;Equates for Main stack and stack Initialization program 109 %IF STACKSW 110 111 EntrySize equ 8 112 113 MinCount equ 8 114 DefaultCount equ 9 115 MaxCount equ 64 116 117 MinSize equ 32 118 DefaultSize equ 128 119 MaxSize equ 512 120 121 labelsize AllocByte, byte, es:bp+0 122 labelsize IntLevel, byte, es:bp+1 123 labelsize SavedSP, word, es:bp+2 124 labelsize SavedSS, word, es:bp+4 125 labelsize NewSP, word, es:bp+6 126 Free equ 0 127 allocated equ 1 128 overflowed equ 2 129 clobbered equ 3 130 131 132 ;External variables in IBMBIO for INT19h handling rouitne. J.K. 10/23/86 133 EXTRN Int19sem:byte 134 135 %macro extrn_irq_handlers 1-* 136 %rep %0 137 EXTRN Int19OLD%1:dword 138 %rotate 1 139 %endrep 140 %endmacro 141 142 extrn_irq_handlers 02,08,09,0A,0B,0C,0D,0E,70,72,73,74,76,77 136 <1> %rep %0 137 <1> EXTRN Int19OLD%1:dword 138 <1> %rotate 1 139 <1> %endrep 137 <2> EXTRN Int19OLD%1:dword 138 <2> %rotate 1 137 <2> EXTRN Int19OLD%1:dword 138 <2> %rotate 1 137 <2> EXTRN Int19OLD%1:dword 138 <2> %rotate 1 137 <2> EXTRN Int19OLD%1:dword 138 <2> %rotate 1 137 <2> EXTRN Int19OLD%1:dword 138 <2> %rotate 1 137 <2> EXTRN Int19OLD%1:dword 138 <2> %rotate 1 137 <2> EXTRN Int19OLD%1:dword 138 <2> %rotate 1 137 <2> EXTRN Int19OLD%1:dword 138 <2> %rotate 1 137 <2> EXTRN Int19OLD%1:dword 138 <2> %rotate 1 137 <2> EXTRN Int19OLD%1:dword 138 <2> %rotate 1 137 <2> EXTRN Int19OLD%1:dword 138 <2> %rotate 1 137 <2> EXTRN Int19OLD%1:dword 138 <2> %rotate 1 137 <2> EXTRN Int19OLD%1:dword 138 <2> %rotate 1 137 <2> EXTRN Int19OLD%1:dword 138 <2> %rotate 1 143 144 ; (no prior section) ; CODE ends 145 %ENDIF 146 ;--------------------------------------- 147 ;J.K. 6/29/87 External variable defined in IBMBIO module for Multi-track 148 MULTRK_ON EQU 10000000B ;User spcified Mutitrack=on, or System turns 149 ; it on after handling CONFIG.SYS file as a 150 ; default value, if MulTrk_flag = MULTRK_OFF1. 151 MULTRK_OFF1 EQU 00000000B ;initial value. No "Multitrack=" command entered. 152 MULTRK_OFF2 EQU 00000001B ;User specified Multitrack=off. 153 === Switch to base=000000h -> "DOSENTRY" 154 section DOSENTRY 155 EXTRN MulTrk_flag:word ;AN002; 156 extrn CONHEADER:byte 157 ; (no prior section) ; CODE ends 158 ;J.K. 6/29/87 End of Multi-track definition. 159 === Switch to base=001140h -> "DOSSTART" 160 addsection DOSSTART, align=16 PUBLIC class=DOSSTART 161 ; (no prior section) ; DOSSTART ENDS 162 === Switch to base=002530h -> "AFTERDOSDATA" 163 addsection AFTERDOSDATA, align=16 class=AFTERDOSDATA 164 ; (no prior section) ; AFTERDOSDATA ENDS 165 global afterdosdatalabel 166 afterdosdatalabel: 167 === Switch to base=002530h -> "SYSINITSEG" 168 section SYSINITSEG PUBLIC class=INIT === Switch to base=002530h -> "SYSINITTRAIL" 169 section SYSINITTRAIL PUBLIC class=INIT 170 171 group SYSINITGROUP SYSINITSEG SYSINITTRAIL 172 === Switch to base=002530h -> "SYSINITSEG" 173 section SYSINITSEG 174 175 ASSUME CS:SYSINITSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING 176 177 EXTRN BADCOM:BYTE 178 EXTRN SYSSIZE:BYTE 179 EXTRN CONDEV:BYTE,AUXDEV:BYTE,PRNDEV:BYTE,COMMND:BYTE 180 extrn DeviceParameters:byte 181 extrn DevMark_Addr:word 182 extrn SetDevMarkFlag:byte 183 extrn PathString:byte ;AN021; 184 extrn LShare:byte ;AN021; 185 extrn ShareWarnMsg:byte ;AN021; 186 187 EXTRN INT24:NEAR,MEM_ERR:NEAR 188 EXTRN DOCONF:NEAR 189 extrn Multi_Pass:NEAR ;AN024; 190 extrn BadLoad:near 191 extrn Error_Line:near 192 extern devicehighflag, shellhighflag 193 194 PUBLIC FINAL_DOS_LOCATION 195 public dos_size 196 PUBLIC DEVICE_LIST 197 SYSI_COUNTRY equ SYSI_Country ; NASM port label 198 PUBLIC SYSI_COUNTRY 199 PUBLIC MEMORY_SIZE 200 PUBLIC DEFAULT_DRIVE 201 PUBLIC BUFFERS 202 PUBLIC FILES 203 PUBLIC NUM_CDS 204 PUBLIC SYSINIT 205 CNTRYFILEHANDLE equ CntryFilehandle ; NASM port label 206 PUBLIC CNTRYFILEHANDLE 207 PUBLIC COMMAND_LINE 208 public Big_Media_Flag ;AN021;Set by IBMINIT 209 210 %IF STACKSW 211 ;Internal Stack Information 212 PUBLIC STACK_COUNT 213 PUBLIC STACK_SIZE 214 PUBLIC STACK_ADDR 215 %ENDIF 216 217 dosinfo equ DOSINFO ; NASM port label 218 entry_point equ ENTRY_POINT ; NASM port label 219 PUBLIC dosinfo,entry_point 220 fcbs equ FCBS ; NASM port label 221 keep equ Keep ; NASM port label 222 PUBLIC fcbs,keep 223 PUBLIC config_block 224 zero equ ZERO ; NASM port label 225 sepchr equ SepChr ; NASM port label 226 PUBLIC zero,sepchr,STALL 227 count equ COUNT ; NASM port equate 228 chrptr equ CHRPTR ; NASM port label 229 org_count equ Org_Count ; NASM port label 230 PUBLIC count,chrptr,org_count 231 bufptr equ BUFPTR ; NASM port label 232 prmblk equ PRMBLK ; NASM port label 233 PUBLIC bufptr,prmblk 234 PUBLIC PACKET,UNITCOUNT 235 drivenumber equ DriveNumber ; NASM port label 236 PUBLIC BREAK_ADDR,BPB_ADDR,drivenumber 237 public Config_Size 238 public Install_Flag 239 public COM_Level 240 public CMMT 241 public CMMT1 242 public CMMT2 243 public Cmd_Indicator 244 public LineCount 245 public ShowCount 246 public Buffer_LineNum 247 public DoNotShowNum 248 public IFS_Flag 249 public IFS_RH 250 public H_Buffers 251 public Buffer_Slash_X ;AN023; 252 public ConfigMsgFlag ;AN014; 253 public Do_Install_Exec ;AN019; 254 public Multi_Pass_Id ;AN024; 255 256 257 ; 258 SYSINIT$: 259 %IF STACKSW 260 ;.SALL 261 ;=== Push trace listing source: msstack.nas 262 %include "msstack.nas" ;Main stack program and data definitions ; NASM included file 1 <1> ; MSStack.inc 2 <1> ; 3 <1> ; Interrupt level 2, 3, 4, 5, 6, 7,(10, 11, 12, 14, 15 - AT level) 4 <1> ; should follow the standard Interrupt Sharing Scheme which has 5 <1> ; a standard header structure. 6 <1> ; Fyi, the following shows the relations between 7 <1> ; the interrupt vector and interrupt level. 8 <1> ; VEC(Hex) 2 8 9 A B C D E 70 72 73 74 76 77 9 <1> ; LVL(Deci) 9 0 1 2 3 4 5 6 8 10 11 12 14 15 10 <1> ; MSSTACK module modifies the following interrupt vectors 11 <1> ; to meet the standard Interrupt Sharing standard; 12 <1> ; A, B, C, D, E, 72, 73, 74, 76, 77. 13 <1> ; Also, for interrupt level 7 and 15, the FirstFlag in a standard header 14 <1> ; should be initialized to indicat whether this interrupt handler is 15 <1> ; the first (= 80h) or not. The FirstFlag entry of INT77h's 16 <1> ; program header is initialized in STKINIT.INC module. 17 <1> ; FirstFlag is only meaningful for interrupt level 7 and 15. 18 <1> ; 19 <1> 20 <1> ; User specifies the number of stack elements - default = 9 21 <1> ; minimum = 8 22 <1> ; maximum = 64 23 <1> ; 24 <1> ; Intercepts Asynchronous Hardware Interrupts only 25 <1> ; 26 <1> ; Picks a stack from pool of stacks and switches to it 27 <1> ; 28 <1> ; Calls the previously saved interrupt vector after pushing flags 29 <1> ; 30 <1> ; On return, returns the stack to the stack pool 31 <1> ; 32 <1> 33 <1> 34 <1> ; This is a modification of STACKS: 35 <1> ; 1. To fix a bug which was causing the program to take up too much space. 36 <1> ; 2. To dispense stack space from hi-mem first rather than low-mem first. 37 <1> ; . Clobbers the stack that got too big instead of innocent stack 38 <1> ; . Allows system to work if the only stack that got too big was the most 39 <1> ; deeply nested one 40 <1> ; 3. Disables NMI interrupts while setting the NMI vector. 41 <1> ; 4. Does not intercept any interupts on a PCjr. 42 <1> ; 5. Double checks that a nested interrupt didn't get the same stack. 43 <1> ; 6. Intercepts Ints 70, 72-77 for PC-ATs and other future products 44 <1> 45 <1> ;The following variables are for MSSTACK.inc 46 <1> EVEN 0 00000000 0000 dw 0 ; SPARE FIELD BUT LEAVE THESE IN ORDER 0 00000002 0000 StackCount dw 0 0 00000004 0000 StackAt dw 0 0 00000006 0000 StackSize dw 0 0 00000008 0000 Stacks dw 0 0 0000000A 0000 dw 0 53 <1> 0 0000000C [0800] FirstEntry dw Stacks 0 0000000E [4800] LastEntry dw Stacks+(DefaultCount*EntrySize)-EntrySize 0 00000010 [4800] NextEntry dw Stacks+(DefaultCount*EntrySize)-EntrySize 57 <1> 58 <1> ;End of variables defined for MSSTACK. 59 <1> 60 <1> ;******************************************************************* 61 <1> ;Macro Interrupt handler for the ordinary interrupt vectors and 62 <1> ;the shared interrupt vectors. 63 <1> ;***************************** 64 <1> %imacro Stack_Main 1-* 65 <1> %rep %0 66 <1> ASSUME DS:NOTHING 67 <1> ASSUME ES:NOTHING 68 <1> ASSUME SS:NOTHING 69 <1> PUBLIC Int%1 70 <1> PUBLIC Old%1 71 <1> ;----------------------------- 72 <1> %ifn IntSharingFlag ;if not IntSharingFlag 73 <1> ;----------------------------- 74 <1> Old%1 DD 0 75 <1> Int%1 PROC FAR 76 <1> ;----------------------------- 77 <1> %else ;for shared interrupt. A Header exists. 78 <1> 79 <1> PUBLIC FirstFlag%1 80 <1> Int%1 PROC FAR 81 <1> jmp short Entry_Int%1_Stk 82 <1> Old%1 dd 0 ;Forward pointer 83 <1> dw 424Bh ;compatible signature for Int. Sharing 84 <1> FirstFlag%1 db 0 ;the firstly hooked. 85 <1> jmp short Intret_%1 ;Reset routine. We don't care this. 86 <1> db 7 dup (0) ;Reserved for future. 87 <1> Entry_Int%1_Stk: 88 <1> ;----------------------------- 89 <1> %endif 90 <1> ;----------------------------- 91 <1> INT%1 equ Int%1 92 <1> OLD%1 equ Old%1 93 <1> 94 <1> ; 95 <1> ; Keyboard interrupt must have a three byte jump, a NOP and a zero byte 96 <1> ; as its first instruction for compatibility reasons 97 <1> %ifidni %1, 09 98 <1> jmp short Keyboard_lbl 99 <1> nop 100 <1> nop 101 <1> db 0 102 <1> Keyboard_lbl label near 103 <1> %endif 104 <1> 105 <1> ; This patches INTERRUPT 75h to be "unhooked". We do this Wierdness, 106 <1> ; rather than never hooking INT 75h, to maintain maximum compat. with IBMs 107 <1> ; post production patch. 108 <1> push ax 109 <1> 110 <1> %ifidni %1, 02 111 <1> 112 <1> ; ********************************************************************* 113 <1> ; 114 <1> ; This is special support for the PC Convertible / NMI handler 115 <1> ; 116 <1> ; On the PC Convertible, there is a situation where an NMI can be 117 <1> ; caused by using the "OUT" instructions to certain ports. When this 118 <1> ; occurs, the PC Convertible hardware *GUARANTEES* that **NOTHING** 119 <1> ; can stop the NMI or interfere with getting to the NMI handler. This 120 <1> ; includes other type of interrupts (hardware and software), and 121 <1> ; also includes other type of NMI's. When any NMI has occured, 122 <1> ; no other interrtupt (hardware, software or NMI) can occur until 123 <1> ; the software takes specific steps to allow further interrupting. 124 <1> ; 125 <1> ; For PC Convertible, the situation where the NMI is generated by the 126 <1> ; "OUT" to a control port requires "fixing-up" and re-attempting. In 127 <1> ; otherwords, it is actually a "restartable exception". In this 128 <1> ; case, the software handler must be able to get to the stack in 129 <1> ; order to figure out what instruction caused the problem, where 130 <1> ; it was "OUT"ing to and what value it was "OUT"ing. Therefore, 131 <1> ; we will not switch stacks in this situation. This situation is 132 <1> ; detected by interrogating port 62h, and checking for a bit value 133 <1> ; of 80h. If set, *****DO NOT SWITCH STACKS*****. 134 <1> ; 135 <1> ; ********************************************************************* 136 <1> 137 <1> push es 138 <1> mov ax,0f000h 139 <1> mov es,ax 140 <1> mdl_convert equ MDL_CONVERT ; NASM port equate 141 <1> cmp byte ptr [es:0fffeh],mdl_convert ;check if convertible 142 <1> pop es 143 <1> jne Normal%1 144 <1> 145 <1> in al,62h 146 <1> test al,80h 147 <1> jz Normal%1 148 <1> 149 <1> Special%1: 150 <1> pop ax 151 <1> jmp far [cs:Old%1] 152 <1> 153 <1> Normal%1: 154 <1> 155 <1> ; ********************************************************************* 156 <1> 157 <1> %endif 158 <1> 159 <1> push bp 160 <1> push es 161 <1> STACKS equ Stacks ; NASM port label 162 <1> mov es, [cs:STACKS+2] ; Get segment of stacks 163 <1> 164 <1> mov bp,[cs:NextEntry] ; get most likely candidate 165 <1> Allocated equ allocated ; NASM port equate 166 <1> mov al,Allocated 167 <1> xchg [AllocByte],al ; grab the entry 168 <1> cmp al,Free ; still avail? 169 <1> jne NotFree%1 170 <1> 171 <1> sub word [cs:NextEntry],EntrySize ; set for next interrupt 172 <1> 173 <1> Found%1: 174 <1> mov [SavedSP],sp ; save sp value 175 <1> mov [SavedSS],ss ; save ss also 176 <1> ; mov IntLevel,%1h ; save the int level 177 <1> 178 <1> mov ax,bp ; temp save of table offset 179 <1> 180 <1> mov bp,[NewSP] ; get new SP value 181 <1> cmp [es:bp],ax ; check for offset into table 182 <1> jne FoundBad%1 183 <1> 184 <1> mov ax,es ; point ss,sp to the new stack 185 <1> mov ss,ax 186 <1> mov sp,bp 187 <1> 188 <1> pushf ; go execute the real interrupt handler 189 <1> call far [cs:Old%1] ; which will iret back to here 190 <1> 191 <1> mov bp,sp ; retrieve the table offset for us 192 <1> mov bp,[es:bp] ; but leave it on the stack 193 <1> mov ss,[SavedSS] ; get old stack back 194 <1> mov sp,[SavedSP] 195 <1> 196 <1> ; cmp AllocByte,Allocated ; If an error occured, 197 <1> ; jne NewError%1 ; do not free us 198 <1> 199 <1> mov byte [AllocByte],Free ; free the entry 200 <1> mov [cs:NextEntry],bp ; setup to use next time 201 <1> 202 <1> NewError%1: 203 <1> pop es 204 <1> pop bp ; saved on entry 205 <1> pop ax ; saved on entry 206 <1> 207 <1> INTRET_%1: ;3.30 208 <1> iret ; done with this interrupt 209 <1> Intret_%1 equ INTRET_%1 210 <1> 211 <1> NotFree%1: 212 <1> cmp al,Allocated ; error flag 213 <1> je FindNext%1 ; no, continue 214 <1> xchg [AllocByte],al ; yes, restore error value 215 <1> 216 <1> FindNext%1: 217 <1> LongPath equ longpath ; NASM port label 218 <1> call LongPath 219 <1> jmp Found%1 220 <1> 221 <1> FoundBad%1: 222 <1> cmp bp,[cs:FirstEntry] 223 <1> jc FindNext%1 224 <1> mov bp,ax ; flag this entry 225 <1> Clobbered equ clobbered ; NASM port equate 226 <1> mov byte [AllocByte],Clobbered 227 <1> ; add bp,EntrySize ; and previous entry 228 <1> ; mov AllocByte,Overflowed 229 <1> ; sub bp,EntrySize 230 <1> jmp FindNext%1 ; keep looking 231 <1> 232 <1> int%1 endp 233 <1> %rotate 1 234 <1> %endrep 235 <1> %endmacro 236 <1> 237 <1> ;***************************** ;3.30 238 <1> ;End of Macro definition ;3.30 239 <1> ;******************************************************************** ;3.30 240 <1> ; THESE ARE THE INDIVIDUAL INTERRUPT HANDLERS ;3.30 241 <1> 242 <1> %iassign IntSharingFlag 0 243 <1> Stack_Main 02,08,09,70 65 <2> %rep %0 66 <2> ASSUME DS:NOTHING 67 <2> ASSUME ES:NOTHING 68 <2> ASSUME SS:NOTHING 69 <2> PUBLIC Int%1 70 <2> PUBLIC Old%1 71 <2> 72 <2> %ifn IntSharingFlag 73 <2> 74 <2> Old%1 DD 0 75 <2> Int%1 PROC FAR 76 <2> 77 <2> %else 78 <2> 79 <2> PUBLIC FirstFlag%1 80 <2> Int%1 PROC FAR 81 <2> jmp short Entry_Int%1_Stk 82 <2> Old%1 dd 0 83 <2> dw 424Bh 84 <2> FirstFlag%1 db 0 85 <2> jmp short Intret_%1 86 <2> db 7 dup (0) 87 <2> Entry_Int%1_Stk: 88 <2> 89 <2> %endif 90 <2> 91 <2> INT%1 equ Int%1 92 <2> OLD%1 equ Old%1 93 <2> 94 <2> 95 <2> 96 <2> 97 <2> %ifidni %1, 09 98 <2> jmp short Keyboard_lbl 99 <2> nop 100 <2> nop 101 <2> db 0 102 <2> Keyboard_lbl label near 103 <2> %endif 104 <2> 105 <2> 106 <2> 107 <2> 108 <2> push ax 109 <2> 110 <2> %ifidni %1, 02 111 <2> 112 <2> 113 <2> 114 <2> 115 <2> 116 <2> 117 <2> 118 <2> 119 <2> 120 <2> 121 <2> 122 <2> 123 <2> 124 <2> 125 <2> 126 <2> 127 <2> 128 <2> 129 <2> 130 <2> 131 <2> 132 <2> 133 <2> 134 <2> 135 <2> 136 <2> 137 <2> push es 138 <2> mov ax,0f000h 139 <2> mov es,ax 140 <2> mdl_convert equ MDL_CONVERT 141 <2> cmp byte ptr [es:0fffeh],mdl_convert 142 <2> pop es 143 <2> jne Normal%1 144 <2> 145 <2> in al,62h 146 <2> test al,80h 147 <2> jz Normal%1 148 <2> 149 <2> Special%1: 150 <2> pop ax 151 <2> jmp far [cs:Old%1] 152 <2> 153 <2> Normal%1: 154 <2> 155 <2> 156 <2> 157 <2> %endif 158 <2> 159 <2> push bp 160 <2> push es 161 <2> STACKS equ Stacks 162 <2> mov es, [cs:STACKS+2] 163 <2> 164 <2> mov bp,[cs:NextEntry] 165 <2> Allocated equ allocated 166 <2> mov al,Allocated 167 <2> xchg [AllocByte],al 168 <2> cmp al,Free 169 <2> jne NotFree%1 170 <2> 171 <2> sub word [cs:NextEntry],EntrySize 172 <2> 173 <2> Found%1: 174 <2> mov [SavedSP],sp 175 <2> mov [SavedSS],ss 176 <2> 177 <2> 178 <2> mov ax,bp 179 <2> 180 <2> mov bp,[NewSP] 181 <2> cmp [es:bp],ax 182 <2> jne FoundBad%1 183 <2> 184 <2> mov ax,es 185 <2> mov ss,ax 186 <2> mov sp,bp 187 <2> 188 <2> pushf 189 <2> call far [cs:Old%1] 190 <2> 191 <2> mov bp,sp 192 <2> mov bp,[es:bp] 193 <2> mov ss,[SavedSS] 194 <2> mov sp,[SavedSP] 195 <2> 196 <2> 197 <2> 198 <2> 199 <2> mov byte [AllocByte],Free 200 <2> mov [cs:NextEntry],bp 201 <2> 202 <2> NewError%1: 203 <2> pop es 204 <2> pop bp 205 <2> pop ax 206 <2> 207 <2> INTRET_%1: 208 <2> iret 209 <2> Intret_%1 equ INTRET_%1 210 <2> 211 <2> NotFree%1: 212 <2> cmp al,Allocated 213 <2> je FindNext%1 214 <2> xchg [AllocByte],al 215 <2> 216 <2> FindNext%1: 217 <2> LongPath equ longpath 218 <2> call LongPath 219 <2> jmp Found%1 220 <2> 221 <2> FoundBad%1: 222 <2> cmp bp,[cs:FirstEntry] 223 <2> jc FindNext%1 224 <2> mov bp,ax 225 <2> Clobbered equ clobbered 226 <2> mov byte [AllocByte],Clobbered 227 <2> 228 <2> 229 <2> 230 <2> jmp FindNext%1 231 <2> 232 <2> int%1 endp 233 <2> %rotate 1 234 <2> %endrep 66 <3> ASSUME DS:NOTHING 67 <3> ASSUME ES:NOTHING 68 <3> ASSUME SS:NOTHING 69 <3> PUBLIC Int%1 70 <3> PUBLIC Old%1 71 <3> 72 <3> %ifn IntSharingFlag 73 <3> 0 00000012 00000000 Old%1 DD 0 75 <3> Int%1 PROC FAR 76 <3> 77 <3> %else 78 <3> 79 <3> PUBLIC FirstFlag%1 80 <3> Int%1 PROC FAR 81 <3> jmp short Entry_Int%1_Stk 82 <3> Old%1 dd 0 83 <3> dw 424Bh 84 <3> FirstFlag%1 db 0 85 <3> jmp short Intret_%1 86 <3> db 7 dup (0) 87 <3> Entry_Int%1_Stk: 88 <3> 89 <3> %endif 90 <3> 91 <3> INT%1 equ Int%1 92 <3> OLD%1 equ Old%1 93 <3> 94 <3> 95 <3> 96 <3> 97 <3> %ifidni %1, 09 98 <3> jmp short Keyboard_lbl 99 <3> nop 100 <3> nop 101 <3> db 0 102 <3> Keyboard_lbl label near 103 <3> %endif 104 <3> 105 <3> 106 <3> 107 <3> 0 00000016 50 push ax 109 <3> 110 <3> %ifidni %1, 02 111 <3> 112 <3> 113 <3> 114 <3> 115 <3> 116 <3> 117 <3> 118 <3> 119 <3> 120 <3> 121 <3> 122 <3> 123 <3> 124 <3> 125 <3> 126 <3> 127 <3> 128 <3> 129 <3> 130 <3> 131 <3> 132 <3> 133 <3> 134 <3> 135 <3> 136 <3> 0 00000017 06 push es 0 00000018 B800F0 mov ax,0f000h 0 0000001B 8EC0 mov es,ax 140 <3> mdl_convert equ MDL_CONVERT 0 0000001D 26803EFEFFF9 cmp byte ptr [es:0fffeh],mdl_convert 0 00000023 07 pop es 0 00000024 750C jne Normal%1 144 <3> 0 00000026 E462 in al,62h 0 00000028 A880 test al,80h 0 0000002A 7406 jz Normal%1 148 <3> 149 <3> Special%1: 0 0000002C 58 pop ax 0 0000002D 2EFF2E[1200] jmp far [cs:Old%1] 152 <3> 153 <3> Normal%1: 154 <3> 155 <3> 156 <3> 157 <3> %endif 158 <3> 0 00000032 55 push bp 0 00000033 06 push es 161 <3> STACKS equ Stacks 0 00000034 2E8E06[0A00] mov es, [cs:STACKS+2] 163 <3> 0 00000039 2E8B2E[1000] mov bp,[cs:NextEntry] 165 <3> Allocated equ allocated 0 0000003E B001 mov al,Allocated 0 00000040 26864600 xchg [AllocByte],al 0 00000044 3C00 cmp al,Free 0 00000046 7542 jne NotFree%1 170 <3> 0 00000048 2E832E[1000]08 sub word [cs:NextEntry],EntrySize 172 <3> 173 <3> Found%1: 0 0000004E 26896602 mov [SavedSP],sp 0 00000052 268C5604 mov [SavedSS],ss 176 <3> 177 <3> 0 00000056 89E8 mov ax,bp 179 <3> 0 00000058 268B6E06 mov bp,[NewSP] 0 0000005C 26394600 cmp [es:bp],ax 0 00000060 7535 jne FoundBad%1 183 <3> 0 00000062 8CC0 mov ax,es 0 00000064 8ED0 mov ss,ax 0 00000066 89EC mov sp,bp 187 <3> 0 00000068 9C pushf 0 00000069 2EFF1E[1200] call far [cs:Old%1] 190 <3> 0 0000006E 89E5 mov bp,sp 0 00000070 268B6E00 mov bp,[es:bp] 0 00000074 268E5604 mov ss,[SavedSS] 0 00000078 268B6602 mov sp,[SavedSP] 195 <3> 196 <3> 197 <3> 198 <3> 0 0000007C 26C6460000 mov byte [AllocByte],Free 0 00000081 2E892E[1000] mov [cs:NextEntry],bp 201 <3> 202 <3> NewError%1: 0 00000086 07 pop es 0 00000087 5D pop bp 0 00000088 58 pop ax 206 <3> 207 <3> INTRET_%1: 0 00000089 CF iret 209 <3> Intret_%1 equ INTRET_%1 210 <3> 211 <3> NotFree%1: 0 0000008A 3C01 cmp al,Allocated 0 0000008C 7404 je FindNext%1 0 0000008E 26864600 xchg [AllocByte],al 215 <3> 216 <3> FindNext%1: 217 <3> LongPath equ longpath 0 00000092 E8D506 call LongPath 0 00000095 EBB7 jmp Found%1 220 <3> 221 <3> FoundBad%1: 0 00000097 2E3B2E[0C00] cmp bp,[cs:FirstEntry] 0 0000009C 72F4 jc FindNext%1 0 0000009E 89C5 mov bp,ax 225 <3> Clobbered equ clobbered 0 000000A0 26C6460003 mov byte [AllocByte],Clobbered 227 <3> 228 <3> 229 <3> 0 000000A5 EBEB jmp FindNext%1 231 <3> 232 <3> int%1 endp 233 <3> %rotate 1 66 <3> ASSUME DS:NOTHING 67 <3> ASSUME ES:NOTHING 68 <3> ASSUME SS:NOTHING 69 <3> PUBLIC Int%1 70 <3> PUBLIC Old%1 71 <3> 72 <3> %ifn IntSharingFlag 73 <3> 0 000000A7 00000000 Old%1 DD 0 75 <3> Int%1 PROC FAR 76 <3> 77 <3> %else 78 <3> 79 <3> PUBLIC FirstFlag%1 80 <3> Int%1 PROC FAR 81 <3> jmp short Entry_Int%1_Stk 82 <3> Old%1 dd 0 83 <3> dw 424Bh 84 <3> FirstFlag%1 db 0 85 <3> jmp short Intret_%1 86 <3> db 7 dup (0) 87 <3> Entry_Int%1_Stk: 88 <3> 89 <3> %endif 90 <3> 91 <3> INT%1 equ Int%1 92 <3> OLD%1 equ Old%1 93 <3> 94 <3> 95 <3> 96 <3> 97 <3> %ifidni %1, 09 98 <3> jmp short Keyboard_lbl 99 <3> nop 100 <3> nop 101 <3> db 0 102 <3> Keyboard_lbl label near 103 <3> %endif 104 <3> 105 <3> 106 <3> 107 <3> 0 000000AB 50 push ax 109 <3> 110 <3> %ifidni %1, 02 111 <3> 112 <3> 113 <3> 114 <3> 115 <3> 116 <3> 117 <3> 118 <3> 119 <3> 120 <3> 121 <3> 122 <3> 123 <3> 124 <3> 125 <3> 126 <3> 127 <3> 128 <3> 129 <3> 130 <3> 131 <3> 132 <3> 133 <3> 134 <3> 135 <3> 136 <3> 137 <3> push es 138 <3> mov ax,0f000h 139 <3> mov es,ax 140 <3> mdl_convert equ MDL_CONVERT 141 <3> cmp byte ptr [es:0fffeh],mdl_convert 142 <3> pop es 143 <3> jne Normal%1 144 <3> 145 <3> in al,62h 146 <3> test al,80h 147 <3> jz Normal%1 148 <3> 149 <3> Special%1: 150 <3> pop ax 151 <3> jmp far [cs:Old%1] 152 <3> 153 <3> Normal%1: 154 <3> 155 <3> 156 <3> 157 <3> %endif 158 <3> 0 000000AC 55 push bp 0 000000AD 06 push es 161 <3> STACKS equ Stacks 0 000000AE 2E8E06[0A00] mov es, [cs:STACKS+2] 163 <3> 0 000000B3 2E8B2E[1000] mov bp,[cs:NextEntry] 165 <3> Allocated equ allocated 0 000000B8 B001 mov al,Allocated 0 000000BA 26864600 xchg [AllocByte],al 0 000000BE 3C00 cmp al,Free 0 000000C0 7542 jne NotFree%1 170 <3> 0 000000C2 2E832E[1000]08 sub word [cs:NextEntry],EntrySize 172 <3> 173 <3> Found%1: 0 000000C8 26896602 mov [SavedSP],sp 0 000000CC 268C5604 mov [SavedSS],ss 176 <3> 177 <3> 0 000000D0 89E8 mov ax,bp 179 <3> 0 000000D2 268B6E06 mov bp,[NewSP] 0 000000D6 26394600 cmp [es:bp],ax 0 000000DA 7535 jne FoundBad%1 183 <3> 0 000000DC 8CC0 mov ax,es 0 000000DE 8ED0 mov ss,ax 0 000000E0 89EC mov sp,bp 187 <3> 0 000000E2 9C pushf 0 000000E3 2EFF1E[A700] call far [cs:Old%1] 190 <3> 0 000000E8 89E5 mov bp,sp 0 000000EA 268B6E00 mov bp,[es:bp] 0 000000EE 268E5604 mov ss,[SavedSS] 0 000000F2 268B6602 mov sp,[SavedSP] 195 <3> 196 <3> 197 <3> 198 <3> 0 000000F6 26C6460000 mov byte [AllocByte],Free 0 000000FB 2E892E[1000] mov [cs:NextEntry],bp 201 <3> 202 <3> NewError%1: 0 00000100 07 pop es 0 00000101 5D pop bp 0 00000102 58 pop ax 206 <3> 207 <3> INTRET_%1: 0 00000103 CF iret 209 <3> Intret_%1 equ INTRET_%1 210 <3> 211 <3> NotFree%1: 0 00000104 3C01 cmp al,Allocated 0 00000106 7404 je FindNext%1 0 00000108 26864600 xchg [AllocByte],al 215 <3> 216 <3> FindNext%1: 217 <3> LongPath equ longpath 0 0000010C E85B06 call LongPath 0 0000010F EBB7 jmp Found%1 220 <3> 221 <3> FoundBad%1: 0 00000111 2E3B2E[0C00] cmp bp,[cs:FirstEntry] 0 00000116 72F4 jc FindNext%1 0 00000118 89C5 mov bp,ax 225 <3> Clobbered equ clobbered 0 0000011A 26C6460003 mov byte [AllocByte],Clobbered 227 <3> 228 <3> 229 <3> 0 0000011F EBEB jmp FindNext%1 231 <3> 232 <3> int%1 endp 233 <3> %rotate 1 66 <3> ASSUME DS:NOTHING 67 <3> ASSUME ES:NOTHING 68 <3> ASSUME SS:NOTHING 69 <3> PUBLIC Int%1 70 <3> PUBLIC Old%1 71 <3> 72 <3> %ifn IntSharingFlag 73 <3> 0 00000121 00000000 Old%1 DD 0 75 <3> Int%1 PROC FAR 76 <3> 77 <3> %else 78 <3> 79 <3> PUBLIC FirstFlag%1 80 <3> Int%1 PROC FAR 81 <3> jmp short Entry_Int%1_Stk 82 <3> Old%1 dd 0 83 <3> dw 424Bh 84 <3> FirstFlag%1 db 0 85 <3> jmp short Intret_%1 86 <3> db 7 dup (0) 87 <3> Entry_Int%1_Stk: 88 <3> 89 <3> %endif 90 <3> 91 <3> INT%1 equ Int%1 92 <3> OLD%1 equ Old%1 93 <3> 94 <3> 95 <3> 96 <3> 97 <3> %ifidni %1, 09 0 00000125 EB03 jmp short Keyboard_lbl 0 00000127 90 nop 0 00000128 90 nop 0 00000129 00 db 0 102 <3> Keyboard_lbl label near 103 <3> %endif 104 <3> 105 <3> 106 <3> 107 <3> 0 0000012A 50 push ax 109 <3> 110 <3> %ifidni %1, 02 111 <3> 112 <3> 113 <3> 114 <3> 115 <3> 116 <3> 117 <3> 118 <3> 119 <3> 120 <3> 121 <3> 122 <3> 123 <3> 124 <3> 125 <3> 126 <3> 127 <3> 128 <3> 129 <3> 130 <3> 131 <3> 132 <3> 133 <3> 134 <3> 135 <3> 136 <3> 137 <3> push es 138 <3> mov ax,0f000h 139 <3> mov es,ax 140 <3> mdl_convert equ MDL_CONVERT 141 <3> cmp byte ptr [es:0fffeh],mdl_convert 142 <3> pop es 143 <3> jne Normal%1 144 <3> 145 <3> in al,62h 146 <3> test al,80h 147 <3> jz Normal%1 148 <3> 149 <3> Special%1: 150 <3> pop ax 151 <3> jmp far [cs:Old%1] 152 <3> 153 <3> Normal%1: 154 <3> 155 <3> 156 <3> 157 <3> %endif 158 <3> 0 0000012B 55 push bp 0 0000012C 06 push es 161 <3> STACKS equ Stacks 0 0000012D 2E8E06[0A00] mov es, [cs:STACKS+2] 163 <3> 0 00000132 2E8B2E[1000] mov bp,[cs:NextEntry] 165 <3> Allocated equ allocated 0 00000137 B001 mov al,Allocated 0 00000139 26864600 xchg [AllocByte],al 0 0000013D 3C00 cmp al,Free 0 0000013F 7542 jne NotFree%1 170 <3> 0 00000141 2E832E[1000]08 sub word [cs:NextEntry],EntrySize 172 <3> 173 <3> Found%1: 0 00000147 26896602 mov [SavedSP],sp 0 0000014B 268C5604 mov [SavedSS],ss 176 <3> 177 <3> 0 0000014F 89E8 mov ax,bp 179 <3> 0 00000151 268B6E06 mov bp,[NewSP] 0 00000155 26394600 cmp [es:bp],ax 0 00000159 7535 jne FoundBad%1 183 <3> 0 0000015B 8CC0 mov ax,es 0 0000015D 8ED0 mov ss,ax 0 0000015F 89EC mov sp,bp 187 <3> 0 00000161 9C pushf 0 00000162 2EFF1E[2101] call far [cs:Old%1] 190 <3> 0 00000167 89E5 mov bp,sp 0 00000169 268B6E00 mov bp,[es:bp] 0 0000016D 268E5604 mov ss,[SavedSS] 0 00000171 268B6602 mov sp,[SavedSP] 195 <3> 196 <3> 197 <3> 198 <3> 0 00000175 26C6460000 mov byte [AllocByte],Free 0 0000017A 2E892E[1000] mov [cs:NextEntry],bp 201 <3> 202 <3> NewError%1: 0 0000017F 07 pop es 0 00000180 5D pop bp 0 00000181 58 pop ax 206 <3> 207 <3> INTRET_%1: 0 00000182 CF iret 209 <3> Intret_%1 equ INTRET_%1 210 <3> 211 <3> NotFree%1: 0 00000183 3C01 cmp al,Allocated 0 00000185 7404 je FindNext%1 0 00000187 26864600 xchg [AllocByte],al 215 <3> 216 <3> FindNext%1: 217 <3> LongPath equ longpath 0 0000018B E8DC05 call LongPath 0 0000018E EBB7 jmp Found%1 220 <3> 221 <3> FoundBad%1: 0 00000190 2E3B2E[0C00] cmp bp,[cs:FirstEntry] 0 00000195 72F4 jc FindNext%1 0 00000197 89C5 mov bp,ax 225 <3> Clobbered equ clobbered 0 00000199 26C6460003 mov byte [AllocByte],Clobbered 227 <3> 228 <3> 229 <3> 0 0000019E EBEB jmp FindNext%1 231 <3> 232 <3> int%1 endp 233 <3> %rotate 1 66 <3> ASSUME DS:NOTHING 67 <3> ASSUME ES:NOTHING 68 <3> ASSUME SS:NOTHING 69 <3> PUBLIC Int%1 70 <3> PUBLIC Old%1 71 <3> 72 <3> %ifn IntSharingFlag 73 <3> 0 000001A0 00000000 Old%1 DD 0 75 <3> Int%1 PROC FAR 76 <3> 77 <3> %else 78 <3> 79 <3> PUBLIC FirstFlag%1 80 <3> Int%1 PROC FAR 81 <3> jmp short Entry_Int%1_Stk 82 <3> Old%1 dd 0 83 <3> dw 424Bh 84 <3> FirstFlag%1 db 0 85 <3> jmp short Intret_%1 86 <3> db 7 dup (0) 87 <3> Entry_Int%1_Stk: 88 <3> 89 <3> %endif 90 <3> 91 <3> INT%1 equ Int%1 92 <3> OLD%1 equ Old%1 93 <3> 94 <3> 95 <3> 96 <3> 97 <3> %ifidni %1, 09 98 <3> jmp short Keyboard_lbl 99 <3> nop 100 <3> nop 101 <3> db 0 102 <3> Keyboard_lbl label near 103 <3> %endif 104 <3> 105 <3> 106 <3> 107 <3> 0 000001A4 50 push ax 109 <3> 110 <3> %ifidni %1, 02 111 <3> 112 <3> 113 <3> 114 <3> 115 <3> 116 <3> 117 <3> 118 <3> 119 <3> 120 <3> 121 <3> 122 <3> 123 <3> 124 <3> 125 <3> 126 <3> 127 <3> 128 <3> 129 <3> 130 <3> 131 <3> 132 <3> 133 <3> 134 <3> 135 <3> 136 <3> 137 <3> push es 138 <3> mov ax,0f000h 139 <3> mov es,ax 140 <3> mdl_convert equ MDL_CONVERT 141 <3> cmp byte ptr [es:0fffeh],mdl_convert 142 <3> pop es 143 <3> jne Normal%1 144 <3> 145 <3> in al,62h 146 <3> test al,80h 147 <3> jz Normal%1 148 <3> 149 <3> Special%1: 150 <3> pop ax 151 <3> jmp far [cs:Old%1] 152 <3> 153 <3> Normal%1: 154 <3> 155 <3> 156 <3> 157 <3> %endif 158 <3> 0 000001A5 55 push bp 0 000001A6 06 push es 161 <3> STACKS equ Stacks 0 000001A7 2E8E06[0A00] mov es, [cs:STACKS+2] 163 <3> 0 000001AC 2E8B2E[1000] mov bp,[cs:NextEntry] 165 <3> Allocated equ allocated 0 000001B1 B001 mov al,Allocated 0 000001B3 26864600 xchg [AllocByte],al 0 000001B7 3C00 cmp al,Free 0 000001B9 7542 jne NotFree%1 170 <3> 0 000001BB 2E832E[1000]08 sub word [cs:NextEntry],EntrySize 172 <3> 173 <3> Found%1: 0 000001C1 26896602 mov [SavedSP],sp 0 000001C5 268C5604 mov [SavedSS],ss 176 <3> 177 <3> 0 000001C9 89E8 mov ax,bp 179 <3> 0 000001CB 268B6E06 mov bp,[NewSP] 0 000001CF 26394600 cmp [es:bp],ax 0 000001D3 7535 jne FoundBad%1 183 <3> 0 000001D5 8CC0 mov ax,es 0 000001D7 8ED0 mov ss,ax 0 000001D9 89EC mov sp,bp 187 <3> 0 000001DB 9C pushf 0 000001DC 2EFF1E[A001] call far [cs:Old%1] 190 <3> 0 000001E1 89E5 mov bp,sp 0 000001E3 268B6E00 mov bp,[es:bp] 0 000001E7 268E5604 mov ss,[SavedSS] 0 000001EB 268B6602 mov sp,[SavedSP] 195 <3> 196 <3> 197 <3> 198 <3> 0 000001EF 26C6460000 mov byte [AllocByte],Free 0 000001F4 2E892E[1000] mov [cs:NextEntry],bp 201 <3> 202 <3> NewError%1: 0 000001F9 07 pop es 0 000001FA 5D pop bp 0 000001FB 58 pop ax 206 <3> 207 <3> INTRET_%1: 0 000001FC CF iret 209 <3> Intret_%1 equ INTRET_%1 210 <3> 211 <3> NotFree%1: 0 000001FD 3C01 cmp al,Allocated 0 000001FF 7404 je FindNext%1 0 00000201 26864600 xchg [AllocByte],al 215 <3> 216 <3> FindNext%1: 217 <3> LongPath equ longpath 0 00000205 E86205 call LongPath 0 00000208 EBB7 jmp Found%1 220 <3> 221 <3> FoundBad%1: 0 0000020A 2E3B2E[0C00] cmp bp,[cs:FirstEntry] 0 0000020F 72F4 jc FindNext%1 0 00000211 89C5 mov bp,ax 225 <3> Clobbered equ clobbered 0 00000213 26C6460003 mov byte [AllocByte],Clobbered 227 <3> 228 <3> 229 <3> 0 00000218 EBEB jmp FindNext%1 231 <3> 232 <3> int%1 endp 233 <3> %rotate 1 244 <1> 245 <1> %iassign IntSharingFlag 1 246 <1> Stack_Main 0A,0B,0C,0D,0E,72,73,74,76,77 65 <2> %rep %0 66 <2> ASSUME DS:NOTHING 67 <2> ASSUME ES:NOTHING 68 <2> ASSUME SS:NOTHING 69 <2> PUBLIC Int%1 70 <2> PUBLIC Old%1 71 <2> 72 <2> %ifn IntSharingFlag 73 <2> 74 <2> Old%1 DD 0 75 <2> Int%1 PROC FAR 76 <2> 77 <2> %else 78 <2> 79 <2> PUBLIC FirstFlag%1 80 <2> Int%1 PROC FAR 81 <2> jmp short Entry_Int%1_Stk 82 <2> Old%1 dd 0 83 <2> dw 424Bh 84 <2> FirstFlag%1 db 0 85 <2> jmp short Intret_%1 86 <2> db 7 dup (0) 87 <2> Entry_Int%1_Stk: 88 <2> 89 <2> %endif 90 <2> 91 <2> INT%1 equ Int%1 92 <2> OLD%1 equ Old%1 93 <2> 94 <2> 95 <2> 96 <2> 97 <2> %ifidni %1, 09 98 <2> jmp short Keyboard_lbl 99 <2> nop 100 <2> nop 101 <2> db 0 102 <2> Keyboard_lbl label near 103 <2> %endif 104 <2> 105 <2> 106 <2> 107 <2> 108 <2> push ax 109 <2> 110 <2> %ifidni %1, 02 111 <2> 112 <2> 113 <2> 114 <2> 115 <2> 116 <2> 117 <2> 118 <2> 119 <2> 120 <2> 121 <2> 122 <2> 123 <2> 124 <2> 125 <2> 126 <2> 127 <2> 128 <2> 129 <2> 130 <2> 131 <2> 132 <2> 133 <2> 134 <2> 135 <2> 136 <2> 137 <2> push es 138 <2> mov ax,0f000h 139 <2> mov es,ax 140 <2> mdl_convert equ MDL_CONVERT 141 <2> cmp byte ptr [es:0fffeh],mdl_convert 142 <2> pop es 143 <2> jne Normal%1 144 <2> 145 <2> in al,62h 146 <2> test al,80h 147 <2> jz Normal%1 148 <2> 149 <2> Special%1: 150 <2> pop ax 151 <2> jmp far [cs:Old%1] 152 <2> 153 <2> Normal%1: 154 <2> 155 <2> 156 <2> 157 <2> %endif 158 <2> 159 <2> push bp 160 <2> push es 161 <2> STACKS equ Stacks 162 <2> mov es, [cs:STACKS+2] 163 <2> 164 <2> mov bp,[cs:NextEntry] 165 <2> Allocated equ allocated 166 <2> mov al,Allocated 167 <2> xchg [AllocByte],al 168 <2> cmp al,Free 169 <2> jne NotFree%1 170 <2> 171 <2> sub word [cs:NextEntry],EntrySize 172 <2> 173 <2> Found%1: 174 <2> mov [SavedSP],sp 175 <2> mov [SavedSS],ss 176 <2> 177 <2> 178 <2> mov ax,bp 179 <2> 180 <2> mov bp,[NewSP] 181 <2> cmp [es:bp],ax 182 <2> jne FoundBad%1 183 <2> 184 <2> mov ax,es 185 <2> mov ss,ax 186 <2> mov sp,bp 187 <2> 188 <2> pushf 189 <2> call far [cs:Old%1] 190 <2> 191 <2> mov bp,sp 192 <2> mov bp,[es:bp] 193 <2> mov ss,[SavedSS] 194 <2> mov sp,[SavedSP] 195 <2> 196 <2> 197 <2> 198 <2> 199 <2> mov byte [AllocByte],Free 200 <2> mov [cs:NextEntry],bp 201 <2> 202 <2> NewError%1: 203 <2> pop es 204 <2> pop bp 205 <2> pop ax 206 <2> 207 <2> INTRET_%1: 208 <2> iret 209 <2> Intret_%1 equ INTRET_%1 210 <2> 211 <2> NotFree%1: 212 <2> cmp al,Allocated 213 <2> je FindNext%1 214 <2> xchg [AllocByte],al 215 <2> 216 <2> FindNext%1: 217 <2> LongPath equ longpath 218 <2> call LongPath 219 <2> jmp Found%1 220 <2> 221 <2> FoundBad%1: 222 <2> cmp bp,[cs:FirstEntry] 223 <2> jc FindNext%1 224 <2> mov bp,ax 225 <2> Clobbered equ clobbered 226 <2> mov byte [AllocByte],Clobbered 227 <2> 228 <2> 229 <2> 230 <2> jmp FindNext%1 231 <2> 232 <2> int%1 endp 233 <2> %rotate 1 234 <2> %endrep 66 <3> ASSUME DS:NOTHING 67 <3> ASSUME ES:NOTHING 68 <3> ASSUME SS:NOTHING 69 <3> PUBLIC Int%1 70 <3> PUBLIC Old%1 71 <3> 72 <3> %ifn IntSharingFlag 73 <3> 74 <3> Old%1 DD 0 75 <3> Int%1 PROC FAR 76 <3> 77 <3> %else 78 <3> 79 <3> PUBLIC FirstFlag%1 80 <3> Int%1 PROC FAR 0 0000021A EB10 jmp short Entry_Int%1_Stk 0 0000021C 00000000 Old%1 dd 0 0 00000220 4B42 dw 424Bh 0 00000222 00 FirstFlag%1 db 0 0 00000223 EB5F jmp short Intret_%1 0 00000225 00000000000000 db 7 dup (0) 87 <3> Entry_Int%1_Stk: 88 <3> 89 <3> %endif 90 <3> 91 <3> INT%1 equ Int%1 92 <3> OLD%1 equ Old%1 93 <3> 94 <3> 95 <3> 96 <3> 97 <3> %ifidni %1, 09 98 <3> jmp short Keyboard_lbl 99 <3> nop 100 <3> nop 101 <3> db 0 102 <3> Keyboard_lbl label near 103 <3> %endif 104 <3> 105 <3> 106 <3> 107 <3> 0 0000022C 50 push ax 109 <3> 110 <3> %ifidni %1, 02 111 <3> 112 <3> 113 <3> 114 <3> 115 <3> 116 <3> 117 <3> 118 <3> 119 <3> 120 <3> 121 <3> 122 <3> 123 <3> 124 <3> 125 <3> 126 <3> 127 <3> 128 <3> 129 <3> 130 <3> 131 <3> 132 <3> 133 <3> 134 <3> 135 <3> 136 <3> 137 <3> push es 138 <3> mov ax,0f000h 139 <3> mov es,ax 140 <3> mdl_convert equ MDL_CONVERT 141 <3> cmp byte ptr [es:0fffeh],mdl_convert 142 <3> pop es 143 <3> jne Normal%1 144 <3> 145 <3> in al,62h 146 <3> test al,80h 147 <3> jz Normal%1 148 <3> 149 <3> Special%1: 150 <3> pop ax 151 <3> jmp far [cs:Old%1] 152 <3> 153 <3> Normal%1: 154 <3> 155 <3> 156 <3> 157 <3> %endif 158 <3> 0 0000022D 55 push bp 0 0000022E 06 push es 161 <3> STACKS equ Stacks 0 0000022F 2E8E06[0A00] mov es, [cs:STACKS+2] 163 <3> 0 00000234 2E8B2E[1000] mov bp,[cs:NextEntry] 165 <3> Allocated equ allocated 0 00000239 B001 mov al,Allocated 0 0000023B 26864600 xchg [AllocByte],al 0 0000023F 3C00 cmp al,Free 0 00000241 7542 jne NotFree%1 170 <3> 0 00000243 2E832E[1000]08 sub word [cs:NextEntry],EntrySize 172 <3> 173 <3> Found%1: 0 00000249 26896602 mov [SavedSP],sp 0 0000024D 268C5604 mov [SavedSS],ss 176 <3> 177 <3> 0 00000251 89E8 mov ax,bp 179 <3> 0 00000253 268B6E06 mov bp,[NewSP] 0 00000257 26394600 cmp [es:bp],ax 0 0000025B 7535 jne FoundBad%1 183 <3> 0 0000025D 8CC0 mov ax,es 0 0000025F 8ED0 mov ss,ax 0 00000261 89EC mov sp,bp 187 <3> 0 00000263 9C pushf 0 00000264 2EFF1E[1C02] call far [cs:Old%1] 190 <3> 0 00000269 89E5 mov bp,sp 0 0000026B 268B6E00 mov bp,[es:bp] 0 0000026F 268E5604 mov ss,[SavedSS] 0 00000273 268B6602 mov sp,[SavedSP] 195 <3> 196 <3> 197 <3> 198 <3> 0 00000277 26C6460000 mov byte [AllocByte],Free 0 0000027C 2E892E[1000] mov [cs:NextEntry],bp 201 <3> 202 <3> NewError%1: 0 00000281 07 pop es 0 00000282 5D pop bp 0 00000283 58 pop ax 206 <3> 207 <3> INTRET_%1: 0 00000284 CF iret 209 <3> Intret_%1 equ INTRET_%1 210 <3> 211 <3> NotFree%1: 0 00000285 3C01 cmp al,Allocated 0 00000287 7404 je FindNext%1 0 00000289 26864600 xchg [AllocByte],al 215 <3> 216 <3> FindNext%1: 217 <3> LongPath equ longpath 0 0000028D E8DA04 call LongPath 0 00000290 EBB7 jmp Found%1 220 <3> 221 <3> FoundBad%1: 0 00000292 2E3B2E[0C00] cmp bp,[cs:FirstEntry] 0 00000297 72F4 jc FindNext%1 0 00000299 89C5 mov bp,ax 225 <3> Clobbered equ clobbered 0 0000029B 26C6460003 mov byte [AllocByte],Clobbered 227 <3> 228 <3> 229 <3> 0 000002A0 EBEB jmp FindNext%1 231 <3> 232 <3> int%1 endp 233 <3> %rotate 1 66 <3> ASSUME DS:NOTHING 67 <3> ASSUME ES:NOTHING 68 <3> ASSUME SS:NOTHING 69 <3> PUBLIC Int%1 70 <3> PUBLIC Old%1 71 <3> 72 <3> %ifn IntSharingFlag 73 <3> 74 <3> Old%1 DD 0 75 <3> Int%1 PROC FAR 76 <3> 77 <3> %else 78 <3> 79 <3> PUBLIC FirstFlag%1 80 <3> Int%1 PROC FAR 0 000002A2 EB10 jmp short Entry_Int%1_Stk 0 000002A4 00000000 Old%1 dd 0 0 000002A8 4B42 dw 424Bh 0 000002AA 00 FirstFlag%1 db 0 0 000002AB EB5F jmp short Intret_%1 0 000002AD 00000000000000 db 7 dup (0) 87 <3> Entry_Int%1_Stk: 88 <3> 89 <3> %endif 90 <3> 91 <3> INT%1 equ Int%1 92 <3> OLD%1 equ Old%1 93 <3> 94 <3> 95 <3> 96 <3> 97 <3> %ifidni %1, 09 98 <3> jmp short Keyboard_lbl 99 <3> nop 100 <3> nop 101 <3> db 0 102 <3> Keyboard_lbl label near 103 <3> %endif 104 <3> 105 <3> 106 <3> 107 <3> 0 000002B4 50 push ax 109 <3> 110 <3> %ifidni %1, 02 111 <3> 112 <3> 113 <3> 114 <3> 115 <3> 116 <3> 117 <3> 118 <3> 119 <3> 120 <3> 121 <3> 122 <3> 123 <3> 124 <3> 125 <3> 126 <3> 127 <3> 128 <3> 129 <3> 130 <3> 131 <3> 132 <3> 133 <3> 134 <3> 135 <3> 136 <3> 137 <3> push es 138 <3> mov ax,0f000h 139 <3> mov es,ax 140 <3> mdl_convert equ MDL_CONVERT 141 <3> cmp byte ptr [es:0fffeh],mdl_convert 142 <3> pop es 143 <3> jne Normal%1 144 <3> 145 <3> in al,62h 146 <3> test al,80h 147 <3> jz Normal%1 148 <3> 149 <3> Special%1: 150 <3> pop ax 151 <3> jmp far [cs:Old%1] 152 <3> 153 <3> Normal%1: 154 <3> 155 <3> 156 <3> 157 <3> %endif 158 <3> 0 000002B5 55 push bp 0 000002B6 06 push es 161 <3> STACKS equ Stacks 0 000002B7 2E8E06[0A00] mov es, [cs:STACKS+2] 163 <3> 0 000002BC 2E8B2E[1000] mov bp,[cs:NextEntry] 165 <3> Allocated equ allocated 0 000002C1 B001 mov al,Allocated 0 000002C3 26864600 xchg [AllocByte],al 0 000002C7 3C00 cmp al,Free 0 000002C9 7542 jne NotFree%1 170 <3> 0 000002CB 2E832E[1000]08 sub word [cs:NextEntry],EntrySize 172 <3> 173 <3> Found%1: 0 000002D1 26896602 mov [SavedSP],sp 0 000002D5 268C5604 mov [SavedSS],ss 176 <3> 177 <3> 0 000002D9 89E8 mov ax,bp 179 <3> 0 000002DB 268B6E06 mov bp,[NewSP] 0 000002DF 26394600 cmp [es:bp],ax 0 000002E3 7535 jne FoundBad%1 183 <3> 0 000002E5 8CC0 mov ax,es 0 000002E7 8ED0 mov ss,ax 0 000002E9 89EC mov sp,bp 187 <3> 0 000002EB 9C pushf 0 000002EC 2EFF1E[A402] call far [cs:Old%1] 190 <3> 0 000002F1 89E5 mov bp,sp 0 000002F3 268B6E00 mov bp,[es:bp] 0 000002F7 268E5604 mov ss,[SavedSS] 0 000002FB 268B6602 mov sp,[SavedSP] 195 <3> 196 <3> 197 <3> 198 <3> 0 000002FF 26C6460000 mov byte [AllocByte],Free 0 00000304 2E892E[1000] mov [cs:NextEntry],bp 201 <3> 202 <3> NewError%1: 0 00000309 07 pop es 0 0000030A 5D pop bp 0 0000030B 58 pop ax 206 <3> 207 <3> INTRET_%1: 0 0000030C CF iret 209 <3> Intret_%1 equ INTRET_%1 210 <3> 211 <3> NotFree%1: 0 0000030D 3C01 cmp al,Allocated 0 0000030F 7404 je FindNext%1 0 00000311 26864600 xchg [AllocByte],al 215 <3> 216 <3> FindNext%1: 217 <3> LongPath equ longpath 0 00000315 E85204 call LongPath 0 00000318 EBB7 jmp Found%1 220 <3> 221 <3> FoundBad%1: 0 0000031A 2E3B2E[0C00] cmp bp,[cs:FirstEntry] 0 0000031F 72F4 jc FindNext%1 0 00000321 89C5 mov bp,ax 225 <3> Clobbered equ clobbered 0 00000323 26C6460003 mov byte [AllocByte],Clobbered 227 <3> 228 <3> 229 <3> 0 00000328 EBEB jmp FindNext%1 231 <3> 232 <3> int%1 endp 233 <3> %rotate 1 66 <3> ASSUME DS:NOTHING 67 <3> ASSUME ES:NOTHING 68 <3> ASSUME SS:NOTHING 69 <3> PUBLIC Int%1 70 <3> PUBLIC Old%1 71 <3> 72 <3> %ifn IntSharingFlag 73 <3> 74 <3> Old%1 DD 0 75 <3> Int%1 PROC FAR 76 <3> 77 <3> %else 78 <3> 79 <3> PUBLIC FirstFlag%1 80 <3> Int%1 PROC FAR 0 0000032A EB10 jmp short Entry_Int%1_Stk 0 0000032C 00000000 Old%1 dd 0 0 00000330 4B42 dw 424Bh 0 00000332 00 FirstFlag%1 db 0 0 00000333 EB5F jmp short Intret_%1 0 00000335 00000000000000 db 7 dup (0) 87 <3> Entry_Int%1_Stk: 88 <3> 89 <3> %endif 90 <3> 91 <3> INT%1 equ Int%1 92 <3> OLD%1 equ Old%1 93 <3> 94 <3> 95 <3> 96 <3> 97 <3> %ifidni %1, 09 98 <3> jmp short Keyboard_lbl 99 <3> nop 100 <3> nop 101 <3> db 0 102 <3> Keyboard_lbl label near 103 <3> %endif 104 <3> 105 <3> 106 <3> 107 <3> 0 0000033C 50 push ax 109 <3> 110 <3> %ifidni %1, 02 111 <3> 112 <3> 113 <3> 114 <3> 115 <3> 116 <3> 117 <3> 118 <3> 119 <3> 120 <3> 121 <3> 122 <3> 123 <3> 124 <3> 125 <3> 126 <3> 127 <3> 128 <3> 129 <3> 130 <3> 131 <3> 132 <3> 133 <3> 134 <3> 135 <3> 136 <3> 137 <3> push es 138 <3> mov ax,0f000h 139 <3> mov es,ax 140 <3> mdl_convert equ MDL_CONVERT 141 <3> cmp byte ptr [es:0fffeh],mdl_convert 142 <3> pop es 143 <3> jne Normal%1 144 <3> 145 <3> in al,62h 146 <3> test al,80h 147 <3> jz Normal%1 148 <3> 149 <3> Special%1: 150 <3> pop ax 151 <3> jmp far [cs:Old%1] 152 <3> 153 <3> Normal%1: 154 <3> 155 <3> 156 <3> 157 <3> %endif 158 <3> 0 0000033D 55 push bp 0 0000033E 06 push es 161 <3> STACKS equ Stacks 0 0000033F 2E8E06[0A00] mov es, [cs:STACKS+2] 163 <3> 0 00000344 2E8B2E[1000] mov bp,[cs:NextEntry] 165 <3> Allocated equ allocated 0 00000349 B001 mov al,Allocated 0 0000034B 26864600 xchg [AllocByte],al 0 0000034F 3C00 cmp al,Free 0 00000351 7542 jne NotFree%1 170 <3> 0 00000353 2E832E[1000]08 sub word [cs:NextEntry],EntrySize 172 <3> 173 <3> Found%1: 0 00000359 26896602 mov [SavedSP],sp 0 0000035D 268C5604 mov [SavedSS],ss 176 <3> 177 <3> 0 00000361 89E8 mov ax,bp 179 <3> 0 00000363 268B6E06 mov bp,[NewSP] 0 00000367 26394600 cmp [es:bp],ax 0 0000036B 7535 jne FoundBad%1 183 <3> 0 0000036D 8CC0 mov ax,es 0 0000036F 8ED0 mov ss,ax 0 00000371 89EC mov sp,bp 187 <3> 0 00000373 9C pushf 0 00000374 2EFF1E[2C03] call far [cs:Old%1] 190 <3> 0 00000379 89E5 mov bp,sp 0 0000037B 268B6E00 mov bp,[es:bp] 0 0000037F 268E5604 mov ss,[SavedSS] 0 00000383 268B6602 mov sp,[SavedSP] 195 <3> 196 <3> 197 <3> 198 <3> 0 00000387 26C6460000 mov byte [AllocByte],Free 0 0000038C 2E892E[1000] mov [cs:NextEntry],bp 201 <3> 202 <3> NewError%1: 0 00000391 07 pop es 0 00000392 5D pop bp 0 00000393 58 pop ax 206 <3> 207 <3> INTRET_%1: 0 00000394 CF iret 209 <3> Intret_%1 equ INTRET_%1 210 <3> 211 <3> NotFree%1: 0 00000395 3C01 cmp al,Allocated 0 00000397 7404 je FindNext%1 0 00000399 26864600 xchg [AllocByte],al 215 <3> 216 <3> FindNext%1: 217 <3> LongPath equ longpath 0 0000039D E8CA03 call LongPath 0 000003A0 EBB7 jmp Found%1 220 <3> 221 <3> FoundBad%1: 0 000003A2 2E3B2E[0C00] cmp bp,[cs:FirstEntry] 0 000003A7 72F4 jc FindNext%1 0 000003A9 89C5 mov bp,ax 225 <3> Clobbered equ clobbered 0 000003AB 26C6460003 mov byte [AllocByte],Clobbered 227 <3> 228 <3> 229 <3> 0 000003B0 EBEB jmp FindNext%1 231 <3> 232 <3> int%1 endp 233 <3> %rotate 1 66 <3> ASSUME DS:NOTHING 67 <3> ASSUME ES:NOTHING 68 <3> ASSUME SS:NOTHING 69 <3> PUBLIC Int%1 70 <3> PUBLIC Old%1 71 <3> 72 <3> %ifn IntSharingFlag 73 <3> 74 <3> Old%1 DD 0 75 <3> Int%1 PROC FAR 76 <3> 77 <3> %else 78 <3> 79 <3> PUBLIC FirstFlag%1 80 <3> Int%1 PROC FAR 0 000003B2 EB10 jmp short Entry_Int%1_Stk 0 000003B4 00000000 Old%1 dd 0 0 000003B8 4B42 dw 424Bh 0 000003BA 00 FirstFlag%1 db 0 0 000003BB EB5F jmp short Intret_%1 0 000003BD 00000000000000 db 7 dup (0) 87 <3> Entry_Int%1_Stk: 88 <3> 89 <3> %endif 90 <3> 91 <3> INT%1 equ Int%1 92 <3> OLD%1 equ Old%1 93 <3> 94 <3> 95 <3> 96 <3> 97 <3> %ifidni %1, 09 98 <3> jmp short Keyboard_lbl 99 <3> nop 100 <3> nop 101 <3> db 0 102 <3> Keyboard_lbl label near 103 <3> %endif 104 <3> 105 <3> 106 <3> 107 <3> 0 000003C4 50 push ax 109 <3> 110 <3> %ifidni %1, 02 111 <3> 112 <3> 113 <3> 114 <3> 115 <3> 116 <3> 117 <3> 118 <3> 119 <3> 120 <3> 121 <3> 122 <3> 123 <3> 124 <3> 125 <3> 126 <3> 127 <3> 128 <3> 129 <3> 130 <3> 131 <3> 132 <3> 133 <3> 134 <3> 135 <3> 136 <3> 137 <3> push es 138 <3> mov ax,0f000h 139 <3> mov es,ax 140 <3> mdl_convert equ MDL_CONVERT 141 <3> cmp byte ptr [es:0fffeh],mdl_convert 142 <3> pop es 143 <3> jne Normal%1 144 <3> 145 <3> in al,62h 146 <3> test al,80h 147 <3> jz Normal%1 148 <3> 149 <3> Special%1: 150 <3> pop ax 151 <3> jmp far [cs:Old%1] 152 <3> 153 <3> Normal%1: 154 <3> 155 <3> 156 <3> 157 <3> %endif 158 <3> 0 000003C5 55 push bp 0 000003C6 06 push es 161 <3> STACKS equ Stacks 0 000003C7 2E8E06[0A00] mov es, [cs:STACKS+2] 163 <3> 0 000003CC 2E8B2E[1000] mov bp,[cs:NextEntry] 165 <3> Allocated equ allocated 0 000003D1 B001 mov al,Allocated 0 000003D3 26864600 xchg [AllocByte],al 0 000003D7 3C00 cmp al,Free 0 000003D9 7542 jne NotFree%1 170 <3> 0 000003DB 2E832E[1000]08 sub word [cs:NextEntry],EntrySize 172 <3> 173 <3> Found%1: 0 000003E1 26896602 mov [SavedSP],sp 0 000003E5 268C5604 mov [SavedSS],ss 176 <3> 177 <3> 0 000003E9 89E8 mov ax,bp 179 <3> 0 000003EB 268B6E06 mov bp,[NewSP] 0 000003EF 26394600 cmp [es:bp],ax 0 000003F3 7535 jne FoundBad%1 183 <3> 0 000003F5 8CC0 mov ax,es 0 000003F7 8ED0 mov ss,ax 0 000003F9 89EC mov sp,bp 187 <3> 0 000003FB 9C pushf 0 000003FC 2EFF1E[B403] call far [cs:Old%1] 190 <3> 0 00000401 89E5 mov bp,sp 0 00000403 268B6E00 mov bp,[es:bp] 0 00000407 268E5604 mov ss,[SavedSS] 0 0000040B 268B6602 mov sp,[SavedSP] 195 <3> 196 <3> 197 <3> 198 <3> 0 0000040F 26C6460000 mov byte [AllocByte],Free 0 00000414 2E892E[1000] mov [cs:NextEntry],bp 201 <3> 202 <3> NewError%1: 0 00000419 07 pop es 0 0000041A 5D pop bp 0 0000041B 58 pop ax 206 <3> 207 <3> INTRET_%1: 0 0000041C CF iret 209 <3> Intret_%1 equ INTRET_%1 210 <3> 211 <3> NotFree%1: 0 0000041D 3C01 cmp al,Allocated 0 0000041F 7404 je FindNext%1 0 00000421 26864600 xchg [AllocByte],al 215 <3> 216 <3> FindNext%1: 217 <3> LongPath equ longpath 0 00000425 E84203 call LongPath 0 00000428 EBB7 jmp Found%1 220 <3> 221 <3> FoundBad%1: 0 0000042A 2E3B2E[0C00] cmp bp,[cs:FirstEntry] 0 0000042F 72F4 jc FindNext%1 0 00000431 89C5 mov bp,ax 225 <3> Clobbered equ clobbered 0 00000433 26C6460003 mov byte [AllocByte],Clobbered 227 <3> 228 <3> 229 <3> 0 00000438 EBEB jmp FindNext%1 231 <3> 232 <3> int%1 endp 233 <3> %rotate 1 66 <3> ASSUME DS:NOTHING 67 <3> ASSUME ES:NOTHING 68 <3> ASSUME SS:NOTHING 69 <3> PUBLIC Int%1 70 <3> PUBLIC Old%1 71 <3> 72 <3> %ifn IntSharingFlag 73 <3> 74 <3> Old%1 DD 0 75 <3> Int%1 PROC FAR 76 <3> 77 <3> %else 78 <3> 79 <3> PUBLIC FirstFlag%1 80 <3> Int%1 PROC FAR 0 0000043A EB10 jmp short Entry_Int%1_Stk 0 0000043C 00000000 Old%1 dd 0 0 00000440 4B42 dw 424Bh 0 00000442 00 FirstFlag%1 db 0 0 00000443 EB5F jmp short Intret_%1 0 00000445 00000000000000 db 7 dup (0) 87 <3> Entry_Int%1_Stk: 88 <3> 89 <3> %endif 90 <3> 91 <3> INT%1 equ Int%1 92 <3> OLD%1 equ Old%1 93 <3> 94 <3> 95 <3> 96 <3> 97 <3> %ifidni %1, 09 98 <3> jmp short Keyboard_lbl 99 <3> nop 100 <3> nop 101 <3> db 0 102 <3> Keyboard_lbl label near 103 <3> %endif 104 <3> 105 <3> 106 <3> 107 <3> 0 0000044C 50 push ax 109 <3> 110 <3> %ifidni %1, 02 111 <3> 112 <3> 113 <3> 114 <3> 115 <3> 116 <3> 117 <3> 118 <3> 119 <3> 120 <3> 121 <3> 122 <3> 123 <3> 124 <3> 125 <3> 126 <3> 127 <3> 128 <3> 129 <3> 130 <3> 131 <3> 132 <3> 133 <3> 134 <3> 135 <3> 136 <3> 137 <3> push es 138 <3> mov ax,0f000h 139 <3> mov es,ax 140 <3> mdl_convert equ MDL_CONVERT 141 <3> cmp byte ptr [es:0fffeh],mdl_convert 142 <3> pop es 143 <3> jne Normal%1 144 <3> 145 <3> in al,62h 146 <3> test al,80h 147 <3> jz Normal%1 148 <3> 149 <3> Special%1: 150 <3> pop ax 151 <3> jmp far [cs:Old%1] 152 <3> 153 <3> Normal%1: 154 <3> 155 <3> 156 <3> 157 <3> %endif 158 <3> 0 0000044D 55 push bp 0 0000044E 06 push es 161 <3> STACKS equ Stacks 0 0000044F 2E8E06[0A00] mov es, [cs:STACKS+2] 163 <3> 0 00000454 2E8B2E[1000] mov bp,[cs:NextEntry] 165 <3> Allocated equ allocated 0 00000459 B001 mov al,Allocated 0 0000045B 26864600 xchg [AllocByte],al 0 0000045F 3C00 cmp al,Free 0 00000461 7542 jne NotFree%1 170 <3> 0 00000463 2E832E[1000]08 sub word [cs:NextEntry],EntrySize 172 <3> 173 <3> Found%1: 0 00000469 26896602 mov [SavedSP],sp 0 0000046D 268C5604 mov [SavedSS],ss 176 <3> 177 <3> 0 00000471 89E8 mov ax,bp 179 <3> 0 00000473 268B6E06 mov bp,[NewSP] 0 00000477 26394600 cmp [es:bp],ax 0 0000047B 7535 jne FoundBad%1 183 <3> 0 0000047D 8CC0 mov ax,es 0 0000047F 8ED0 mov ss,ax 0 00000481 89EC mov sp,bp 187 <3> 0 00000483 9C pushf 0 00000484 2EFF1E[3C04] call far [cs:Old%1] 190 <3> 0 00000489 89E5 mov bp,sp 0 0000048B 268B6E00 mov bp,[es:bp] 0 0000048F 268E5604 mov ss,[SavedSS] 0 00000493 268B6602 mov sp,[SavedSP] 195 <3> 196 <3> 197 <3> 198 <3> 0 00000497 26C6460000 mov byte [AllocByte],Free 0 0000049C 2E892E[1000] mov [cs:NextEntry],bp 201 <3> 202 <3> NewError%1: 0 000004A1 07 pop es 0 000004A2 5D pop bp 0 000004A3 58 pop ax 206 <3> 207 <3> INTRET_%1: 0 000004A4 CF iret 209 <3> Intret_%1 equ INTRET_%1 210 <3> 211 <3> NotFree%1: 0 000004A5 3C01 cmp al,Allocated 0 000004A7 7404 je FindNext%1 0 000004A9 26864600 xchg [AllocByte],al 215 <3> 216 <3> FindNext%1: 217 <3> LongPath equ longpath 0 000004AD E8BA02 call LongPath 0 000004B0 EBB7 jmp Found%1 220 <3> 221 <3> FoundBad%1: 0 000004B2 2E3B2E[0C00] cmp bp,[cs:FirstEntry] 0 000004B7 72F4 jc FindNext%1 0 000004B9 89C5 mov bp,ax 225 <3> Clobbered equ clobbered 0 000004BB 26C6460003 mov byte [AllocByte],Clobbered 227 <3> 228 <3> 229 <3> 0 000004C0 EBEB jmp FindNext%1 231 <3> 232 <3> int%1 endp 233 <3> %rotate 1 66 <3> ASSUME DS:NOTHING 67 <3> ASSUME ES:NOTHING 68 <3> ASSUME SS:NOTHING 69 <3> PUBLIC Int%1 70 <3> PUBLIC Old%1 71 <3> 72 <3> %ifn IntSharingFlag 73 <3> 74 <3> Old%1 DD 0 75 <3> Int%1 PROC FAR 76 <3> 77 <3> %else 78 <3> 79 <3> PUBLIC FirstFlag%1 80 <3> Int%1 PROC FAR 0 000004C2 EB10 jmp short Entry_Int%1_Stk 0 000004C4 00000000 Old%1 dd 0 0 000004C8 4B42 dw 424Bh 0 000004CA 00 FirstFlag%1 db 0 0 000004CB EB5F jmp short Intret_%1 0 000004CD 00000000000000 db 7 dup (0) 87 <3> Entry_Int%1_Stk: 88 <3> 89 <3> %endif 90 <3> 91 <3> INT%1 equ Int%1 92 <3> OLD%1 equ Old%1 93 <3> 94 <3> 95 <3> 96 <3> 97 <3> %ifidni %1, 09 98 <3> jmp short Keyboard_lbl 99 <3> nop 100 <3> nop 101 <3> db 0 102 <3> Keyboard_lbl label near 103 <3> %endif 104 <3> 105 <3> 106 <3> 107 <3> 0 000004D4 50 push ax 109 <3> 110 <3> %ifidni %1, 02 111 <3> 112 <3> 113 <3> 114 <3> 115 <3> 116 <3> 117 <3> 118 <3> 119 <3> 120 <3> 121 <3> 122 <3> 123 <3> 124 <3> 125 <3> 126 <3> 127 <3> 128 <3> 129 <3> 130 <3> 131 <3> 132 <3> 133 <3> 134 <3> 135 <3> 136 <3> 137 <3> push es 138 <3> mov ax,0f000h 139 <3> mov es,ax 140 <3> mdl_convert equ MDL_CONVERT 141 <3> cmp byte ptr [es:0fffeh],mdl_convert 142 <3> pop es 143 <3> jne Normal%1 144 <3> 145 <3> in al,62h 146 <3> test al,80h 147 <3> jz Normal%1 148 <3> 149 <3> Special%1: 150 <3> pop ax 151 <3> jmp far [cs:Old%1] 152 <3> 153 <3> Normal%1: 154 <3> 155 <3> 156 <3> 157 <3> %endif 158 <3> 0 000004D5 55 push bp 0 000004D6 06 push es 161 <3> STACKS equ Stacks 0 000004D7 2E8E06[0A00] mov es, [cs:STACKS+2] 163 <3> 0 000004DC 2E8B2E[1000] mov bp,[cs:NextEntry] 165 <3> Allocated equ allocated 0 000004E1 B001 mov al,Allocated 0 000004E3 26864600 xchg [AllocByte],al 0 000004E7 3C00 cmp al,Free 0 000004E9 7542 jne NotFree%1 170 <3> 0 000004EB 2E832E[1000]08 sub word [cs:NextEntry],EntrySize 172 <3> 173 <3> Found%1: 0 000004F1 26896602 mov [SavedSP],sp 0 000004F5 268C5604 mov [SavedSS],ss 176 <3> 177 <3> 0 000004F9 89E8 mov ax,bp 179 <3> 0 000004FB 268B6E06 mov bp,[NewSP] 0 000004FF 26394600 cmp [es:bp],ax 0 00000503 7535 jne FoundBad%1 183 <3> 0 00000505 8CC0 mov ax,es 0 00000507 8ED0 mov ss,ax 0 00000509 89EC mov sp,bp 187 <3> 0 0000050B 9C pushf 0 0000050C 2EFF1E[C404] call far [cs:Old%1] 190 <3> 0 00000511 89E5 mov bp,sp 0 00000513 268B6E00 mov bp,[es:bp] 0 00000517 268E5604 mov ss,[SavedSS] 0 0000051B 268B6602 mov sp,[SavedSP] 195 <3> 196 <3> 197 <3> 198 <3> 0 0000051F 26C6460000 mov byte [AllocByte],Free 0 00000524 2E892E[1000] mov [cs:NextEntry],bp 201 <3> 202 <3> NewError%1: 0 00000529 07 pop es 0 0000052A 5D pop bp 0 0000052B 58 pop ax 206 <3> 207 <3> INTRET_%1: 0 0000052C CF iret 209 <3> Intret_%1 equ INTRET_%1 210 <3> 211 <3> NotFree%1: 0 0000052D 3C01 cmp al,Allocated 0 0000052F 7404 je FindNext%1 0 00000531 26864600 xchg [AllocByte],al 215 <3> 216 <3> FindNext%1: 217 <3> LongPath equ longpath 0 00000535 E83202 call LongPath 0 00000538 EBB7 jmp Found%1 220 <3> 221 <3> FoundBad%1: 0 0000053A 2E3B2E[0C00] cmp bp,[cs:FirstEntry] 0 0000053F 72F4 jc FindNext%1 0 00000541 89C5 mov bp,ax 225 <3> Clobbered equ clobbered 0 00000543 26C6460003 mov byte [AllocByte],Clobbered 227 <3> 228 <3> 229 <3> 0 00000548 EBEB jmp FindNext%1 231 <3> 232 <3> int%1 endp 233 <3> %rotate 1 66 <3> ASSUME DS:NOTHING 67 <3> ASSUME ES:NOTHING 68 <3> ASSUME SS:NOTHING 69 <3> PUBLIC Int%1 70 <3> PUBLIC Old%1 71 <3> 72 <3> %ifn IntSharingFlag 73 <3> 74 <3> Old%1 DD 0 75 <3> Int%1 PROC FAR 76 <3> 77 <3> %else 78 <3> 79 <3> PUBLIC FirstFlag%1 80 <3> Int%1 PROC FAR 0 0000054A EB10 jmp short Entry_Int%1_Stk 0 0000054C 00000000 Old%1 dd 0 0 00000550 4B42 dw 424Bh 0 00000552 00 FirstFlag%1 db 0 0 00000553 EB5F jmp short Intret_%1 0 00000555 00000000000000 db 7 dup (0) 87 <3> Entry_Int%1_Stk: 88 <3> 89 <3> %endif 90 <3> 91 <3> INT%1 equ Int%1 92 <3> OLD%1 equ Old%1 93 <3> 94 <3> 95 <3> 96 <3> 97 <3> %ifidni %1, 09 98 <3> jmp short Keyboard_lbl 99 <3> nop 100 <3> nop 101 <3> db 0 102 <3> Keyboard_lbl label near 103 <3> %endif 104 <3> 105 <3> 106 <3> 107 <3> 0 0000055C 50 push ax 109 <3> 110 <3> %ifidni %1, 02 111 <3> 112 <3> 113 <3> 114 <3> 115 <3> 116 <3> 117 <3> 118 <3> 119 <3> 120 <3> 121 <3> 122 <3> 123 <3> 124 <3> 125 <3> 126 <3> 127 <3> 128 <3> 129 <3> 130 <3> 131 <3> 132 <3> 133 <3> 134 <3> 135 <3> 136 <3> 137 <3> push es 138 <3> mov ax,0f000h 139 <3> mov es,ax 140 <3> mdl_convert equ MDL_CONVERT 141 <3> cmp byte ptr [es:0fffeh],mdl_convert 142 <3> pop es 143 <3> jne Normal%1 144 <3> 145 <3> in al,62h 146 <3> test al,80h 147 <3> jz Normal%1 148 <3> 149 <3> Special%1: 150 <3> pop ax 151 <3> jmp far [cs:Old%1] 152 <3> 153 <3> Normal%1: 154 <3> 155 <3> 156 <3> 157 <3> %endif 158 <3> 0 0000055D 55 push bp 0 0000055E 06 push es 161 <3> STACKS equ Stacks 0 0000055F 2E8E06[0A00] mov es, [cs:STACKS+2] 163 <3> 0 00000564 2E8B2E[1000] mov bp,[cs:NextEntry] 165 <3> Allocated equ allocated 0 00000569 B001 mov al,Allocated 0 0000056B 26864600 xchg [AllocByte],al 0 0000056F 3C00 cmp al,Free 0 00000571 7542 jne NotFree%1 170 <3> 0 00000573 2E832E[1000]08 sub word [cs:NextEntry],EntrySize 172 <3> 173 <3> Found%1: 0 00000579 26896602 mov [SavedSP],sp 0 0000057D 268C5604 mov [SavedSS],ss 176 <3> 177 <3> 0 00000581 89E8 mov ax,bp 179 <3> 0 00000583 268B6E06 mov bp,[NewSP] 0 00000587 26394600 cmp [es:bp],ax 0 0000058B 7535 jne FoundBad%1 183 <3> 0 0000058D 8CC0 mov ax,es 0 0000058F 8ED0 mov ss,ax 0 00000591 89EC mov sp,bp 187 <3> 0 00000593 9C pushf 0 00000594 2EFF1E[4C05] call far [cs:Old%1] 190 <3> 0 00000599 89E5 mov bp,sp 0 0000059B 268B6E00 mov bp,[es:bp] 0 0000059F 268E5604 mov ss,[SavedSS] 0 000005A3 268B6602 mov sp,[SavedSP] 195 <3> 196 <3> 197 <3> 198 <3> 0 000005A7 26C6460000 mov byte [AllocByte],Free 0 000005AC 2E892E[1000] mov [cs:NextEntry],bp 201 <3> 202 <3> NewError%1: 0 000005B1 07 pop es 0 000005B2 5D pop bp 0 000005B3 58 pop ax 206 <3> 207 <3> INTRET_%1: 0 000005B4 CF iret 209 <3> Intret_%1 equ INTRET_%1 210 <3> 211 <3> NotFree%1: 0 000005B5 3C01 cmp al,Allocated 0 000005B7 7404 je FindNext%1 0 000005B9 26864600 xchg [AllocByte],al 215 <3> 216 <3> FindNext%1: 217 <3> LongPath equ longpath 0 000005BD E8AA01 call LongPath 0 000005C0 EBB7 jmp Found%1 220 <3> 221 <3> FoundBad%1: 0 000005C2 2E3B2E[0C00] cmp bp,[cs:FirstEntry] 0 000005C7 72F4 jc FindNext%1 0 000005C9 89C5 mov bp,ax 225 <3> Clobbered equ clobbered 0 000005CB 26C6460003 mov byte [AllocByte],Clobbered 227 <3> 228 <3> 229 <3> 0 000005D0 EBEB jmp FindNext%1 231 <3> 232 <3> int%1 endp 233 <3> %rotate 1 66 <3> ASSUME DS:NOTHING 67 <3> ASSUME ES:NOTHING 68 <3> ASSUME SS:NOTHING 69 <3> PUBLIC Int%1 70 <3> PUBLIC Old%1 71 <3> 72 <3> %ifn IntSharingFlag 73 <3> 74 <3> Old%1 DD 0 75 <3> Int%1 PROC FAR 76 <3> 77 <3> %else 78 <3> 79 <3> PUBLIC FirstFlag%1 80 <3> Int%1 PROC FAR 0 000005D2 EB10 jmp short Entry_Int%1_Stk 0 000005D4 00000000 Old%1 dd 0 0 000005D8 4B42 dw 424Bh 0 000005DA 00 FirstFlag%1 db 0 0 000005DB EB5F jmp short Intret_%1 0 000005DD 00000000000000 db 7 dup (0) 87 <3> Entry_Int%1_Stk: 88 <3> 89 <3> %endif 90 <3> 91 <3> INT%1 equ Int%1 92 <3> OLD%1 equ Old%1 93 <3> 94 <3> 95 <3> 96 <3> 97 <3> %ifidni %1, 09 98 <3> jmp short Keyboard_lbl 99 <3> nop 100 <3> nop 101 <3> db 0 102 <3> Keyboard_lbl label near 103 <3> %endif 104 <3> 105 <3> 106 <3> 107 <3> 0 000005E4 50 push ax 109 <3> 110 <3> %ifidni %1, 02 111 <3> 112 <3> 113 <3> 114 <3> 115 <3> 116 <3> 117 <3> 118 <3> 119 <3> 120 <3> 121 <3> 122 <3> 123 <3> 124 <3> 125 <3> 126 <3> 127 <3> 128 <3> 129 <3> 130 <3> 131 <3> 132 <3> 133 <3> 134 <3> 135 <3> 136 <3> 137 <3> push es 138 <3> mov ax,0f000h 139 <3> mov es,ax 140 <3> mdl_convert equ MDL_CONVERT 141 <3> cmp byte ptr [es:0fffeh],mdl_convert 142 <3> pop es 143 <3> jne Normal%1 144 <3> 145 <3> in al,62h 146 <3> test al,80h 147 <3> jz Normal%1 148 <3> 149 <3> Special%1: 150 <3> pop ax 151 <3> jmp far [cs:Old%1] 152 <3> 153 <3> Normal%1: 154 <3> 155 <3> 156 <3> 157 <3> %endif 158 <3> 0 000005E5 55 push bp 0 000005E6 06 push es 161 <3> STACKS equ Stacks 0 000005E7 2E8E06[0A00] mov es, [cs:STACKS+2] 163 <3> 0 000005EC 2E8B2E[1000] mov bp,[cs:NextEntry] 165 <3> Allocated equ allocated 0 000005F1 B001 mov al,Allocated 0 000005F3 26864600 xchg [AllocByte],al 0 000005F7 3C00 cmp al,Free 0 000005F9 7542 jne NotFree%1 170 <3> 0 000005FB 2E832E[1000]08 sub word [cs:NextEntry],EntrySize 172 <3> 173 <3> Found%1: 0 00000601 26896602 mov [SavedSP],sp 0 00000605 268C5604 mov [SavedSS],ss 176 <3> 177 <3> 0 00000609 89E8 mov ax,bp 179 <3> 0 0000060B 268B6E06 mov bp,[NewSP] 0 0000060F 26394600 cmp [es:bp],ax 0 00000613 7535 jne FoundBad%1 183 <3> 0 00000615 8CC0 mov ax,es 0 00000617 8ED0 mov ss,ax 0 00000619 89EC mov sp,bp 187 <3> 0 0000061B 9C pushf 0 0000061C 2EFF1E[D405] call far [cs:Old%1] 190 <3> 0 00000621 89E5 mov bp,sp 0 00000623 268B6E00 mov bp,[es:bp] 0 00000627 268E5604 mov ss,[SavedSS] 0 0000062B 268B6602 mov sp,[SavedSP] 195 <3> 196 <3> 197 <3> 198 <3> 0 0000062F 26C6460000 mov byte [AllocByte],Free 0 00000634 2E892E[1000] mov [cs:NextEntry],bp 201 <3> 202 <3> NewError%1: 0 00000639 07 pop es 0 0000063A 5D pop bp 0 0000063B 58 pop ax 206 <3> 207 <3> INTRET_%1: 0 0000063C CF iret 209 <3> Intret_%1 equ INTRET_%1 210 <3> 211 <3> NotFree%1: 0 0000063D 3C01 cmp al,Allocated 0 0000063F 7404 je FindNext%1 0 00000641 26864600 xchg [AllocByte],al 215 <3> 216 <3> FindNext%1: 217 <3> LongPath equ longpath 0 00000645 E82201 call LongPath 0 00000648 EBB7 jmp Found%1 220 <3> 221 <3> FoundBad%1: 0 0000064A 2E3B2E[0C00] cmp bp,[cs:FirstEntry] 0 0000064F 72F4 jc FindNext%1 0 00000651 89C5 mov bp,ax 225 <3> Clobbered equ clobbered 0 00000653 26C6460003 mov byte [AllocByte],Clobbered 227 <3> 228 <3> 229 <3> 0 00000658 EBEB jmp FindNext%1 231 <3> 232 <3> int%1 endp 233 <3> %rotate 1 66 <3> ASSUME DS:NOTHING 67 <3> ASSUME ES:NOTHING 68 <3> ASSUME SS:NOTHING 69 <3> PUBLIC Int%1 70 <3> PUBLIC Old%1 71 <3> 72 <3> %ifn IntSharingFlag 73 <3> 74 <3> Old%1 DD 0 75 <3> Int%1 PROC FAR 76 <3> 77 <3> %else 78 <3> 79 <3> PUBLIC FirstFlag%1 80 <3> Int%1 PROC FAR 0 0000065A EB10 jmp short Entry_Int%1_Stk 0 0000065C 00000000 Old%1 dd 0 0 00000660 4B42 dw 424Bh 0 00000662 00 FirstFlag%1 db 0 0 00000663 EB5F jmp short Intret_%1 0 00000665 00000000000000 db 7 dup (0) 87 <3> Entry_Int%1_Stk: 88 <3> 89 <3> %endif 90 <3> 91 <3> INT%1 equ Int%1 92 <3> OLD%1 equ Old%1 93 <3> 94 <3> 95 <3> 96 <3> 97 <3> %ifidni %1, 09 98 <3> jmp short Keyboard_lbl 99 <3> nop 100 <3> nop 101 <3> db 0 102 <3> Keyboard_lbl label near 103 <3> %endif 104 <3> 105 <3> 106 <3> 107 <3> 0 0000066C 50 push ax 109 <3> 110 <3> %ifidni %1, 02 111 <3> 112 <3> 113 <3> 114 <3> 115 <3> 116 <3> 117 <3> 118 <3> 119 <3> 120 <3> 121 <3> 122 <3> 123 <3> 124 <3> 125 <3> 126 <3> 127 <3> 128 <3> 129 <3> 130 <3> 131 <3> 132 <3> 133 <3> 134 <3> 135 <3> 136 <3> 137 <3> push es 138 <3> mov ax,0f000h 139 <3> mov es,ax 140 <3> mdl_convert equ MDL_CONVERT 141 <3> cmp byte ptr [es:0fffeh],mdl_convert 142 <3> pop es 143 <3> jne Normal%1 144 <3> 145 <3> in al,62h 146 <3> test al,80h 147 <3> jz Normal%1 148 <3> 149 <3> Special%1: 150 <3> pop ax 151 <3> jmp far [cs:Old%1] 152 <3> 153 <3> Normal%1: 154 <3> 155 <3> 156 <3> 157 <3> %endif 158 <3> 0 0000066D 55 push bp 0 0000066E 06 push es 161 <3> STACKS equ Stacks 0 0000066F 2E8E06[0A00] mov es, [cs:STACKS+2] 163 <3> 0 00000674 2E8B2E[1000] mov bp,[cs:NextEntry] 165 <3> Allocated equ allocated 0 00000679 B001 mov al,Allocated 0 0000067B 26864600 xchg [AllocByte],al 0 0000067F 3C00 cmp al,Free 0 00000681 7542 jne NotFree%1 170 <3> 0 00000683 2E832E[1000]08 sub word [cs:NextEntry],EntrySize 172 <3> 173 <3> Found%1: 0 00000689 26896602 mov [SavedSP],sp 0 0000068D 268C5604 mov [SavedSS],ss 176 <3> 177 <3> 0 00000691 89E8 mov ax,bp 179 <3> 0 00000693 268B6E06 mov bp,[NewSP] 0 00000697 26394600 cmp [es:bp],ax 0 0000069B 7535 jne FoundBad%1 183 <3> 0 0000069D 8CC0 mov ax,es 0 0000069F 8ED0 mov ss,ax 0 000006A1 89EC mov sp,bp 187 <3> 0 000006A3 9C pushf 0 000006A4 2EFF1E[5C06] call far [cs:Old%1] 190 <3> 0 000006A9 89E5 mov bp,sp 0 000006AB 268B6E00 mov bp,[es:bp] 0 000006AF 268E5604 mov ss,[SavedSS] 0 000006B3 268B6602 mov sp,[SavedSP] 195 <3> 196 <3> 197 <3> 198 <3> 0 000006B7 26C6460000 mov byte [AllocByte],Free 0 000006BC 2E892E[1000] mov [cs:NextEntry],bp 201 <3> 202 <3> NewError%1: 0 000006C1 07 pop es 0 000006C2 5D pop bp 0 000006C3 58 pop ax 206 <3> 207 <3> INTRET_%1: 0 000006C4 CF iret 209 <3> Intret_%1 equ INTRET_%1 210 <3> 211 <3> NotFree%1: 0 000006C5 3C01 cmp al,Allocated 0 000006C7 7404 je FindNext%1 0 000006C9 26864600 xchg [AllocByte],al 215 <3> 216 <3> FindNext%1: 217 <3> LongPath equ longpath 0 000006CD E89A00 call LongPath 0 000006D0 EBB7 jmp Found%1 220 <3> 221 <3> FoundBad%1: 0 000006D2 2E3B2E[0C00] cmp bp,[cs:FirstEntry] 0 000006D7 72F4 jc FindNext%1 0 000006D9 89C5 mov bp,ax 225 <3> Clobbered equ clobbered 0 000006DB 26C6460003 mov byte [AllocByte],Clobbered 227 <3> 228 <3> 229 <3> 0 000006E0 EBEB jmp FindNext%1 231 <3> 232 <3> int%1 endp 233 <3> %rotate 1 66 <3> ASSUME DS:NOTHING 67 <3> ASSUME ES:NOTHING 68 <3> ASSUME SS:NOTHING 69 <3> PUBLIC Int%1 70 <3> PUBLIC Old%1 71 <3> 72 <3> %ifn IntSharingFlag 73 <3> 74 <3> Old%1 DD 0 75 <3> Int%1 PROC FAR 76 <3> 77 <3> %else 78 <3> 79 <3> PUBLIC FirstFlag%1 80 <3> Int%1 PROC FAR 0 000006E2 EB10 jmp short Entry_Int%1_Stk 0 000006E4 00000000 Old%1 dd 0 0 000006E8 4B42 dw 424Bh 0 000006EA 00 FirstFlag%1 db 0 0 000006EB EB5F jmp short Intret_%1 0 000006ED 00000000000000 db 7 dup (0) 87 <3> Entry_Int%1_Stk: 88 <3> 89 <3> %endif 90 <3> 91 <3> INT%1 equ Int%1 92 <3> OLD%1 equ Old%1 93 <3> 94 <3> 95 <3> 96 <3> 97 <3> %ifidni %1, 09 98 <3> jmp short Keyboard_lbl 99 <3> nop 100 <3> nop 101 <3> db 0 102 <3> Keyboard_lbl label near 103 <3> %endif 104 <3> 105 <3> 106 <3> 107 <3> 0 000006F4 50 push ax 109 <3> 110 <3> %ifidni %1, 02 111 <3> 112 <3> 113 <3> 114 <3> 115 <3> 116 <3> 117 <3> 118 <3> 119 <3> 120 <3> 121 <3> 122 <3> 123 <3> 124 <3> 125 <3> 126 <3> 127 <3> 128 <3> 129 <3> 130 <3> 131 <3> 132 <3> 133 <3> 134 <3> 135 <3> 136 <3> 137 <3> push es 138 <3> mov ax,0f000h 139 <3> mov es,ax 140 <3> mdl_convert equ MDL_CONVERT 141 <3> cmp byte ptr [es:0fffeh],mdl_convert 142 <3> pop es 143 <3> jne Normal%1 144 <3> 145 <3> in al,62h 146 <3> test al,80h 147 <3> jz Normal%1 148 <3> 149 <3> Special%1: 150 <3> pop ax 151 <3> jmp far [cs:Old%1] 152 <3> 153 <3> Normal%1: 154 <3> 155 <3> 156 <3> 157 <3> %endif 158 <3> 0 000006F5 55 push bp 0 000006F6 06 push es 161 <3> STACKS equ Stacks 0 000006F7 2E8E06[0A00] mov es, [cs:STACKS+2] 163 <3> 0 000006FC 2E8B2E[1000] mov bp,[cs:NextEntry] 165 <3> Allocated equ allocated 0 00000701 B001 mov al,Allocated 0 00000703 26864600 xchg [AllocByte],al 0 00000707 3C00 cmp al,Free 0 00000709 7542 jne NotFree%1 170 <3> 0 0000070B 2E832E[1000]08 sub word [cs:NextEntry],EntrySize 172 <3> 173 <3> Found%1: 0 00000711 26896602 mov [SavedSP],sp 0 00000715 268C5604 mov [SavedSS],ss 176 <3> 177 <3> 0 00000719 89E8 mov ax,bp 179 <3> 0 0000071B 268B6E06 mov bp,[NewSP] 0 0000071F 26394600 cmp [es:bp],ax 0 00000723 7535 jne FoundBad%1 183 <3> 0 00000725 8CC0 mov ax,es 0 00000727 8ED0 mov ss,ax 0 00000729 89EC mov sp,bp 187 <3> 0 0000072B 9C pushf 0 0000072C 2EFF1E[E406] call far [cs:Old%1] 190 <3> 0 00000731 89E5 mov bp,sp 0 00000733 268B6E00 mov bp,[es:bp] 0 00000737 268E5604 mov ss,[SavedSS] 0 0000073B 268B6602 mov sp,[SavedSP] 195 <3> 196 <3> 197 <3> 198 <3> 0 0000073F 26C6460000 mov byte [AllocByte],Free 0 00000744 2E892E[1000] mov [cs:NextEntry],bp 201 <3> 202 <3> NewError%1: 0 00000749 07 pop es 0 0000074A 5D pop bp 0 0000074B 58 pop ax 206 <3> 207 <3> INTRET_%1: 0 0000074C CF iret 209 <3> Intret_%1 equ INTRET_%1 210 <3> 211 <3> NotFree%1: 0 0000074D 3C01 cmp al,Allocated 0 0000074F 7404 je FindNext%1 0 00000751 26864600 xchg [AllocByte],al 215 <3> 216 <3> FindNext%1: 217 <3> LongPath equ longpath 0 00000755 E81200 call LongPath 0 00000758 EBB7 jmp Found%1 220 <3> 221 <3> FoundBad%1: 0 0000075A 2E3B2E[0C00] cmp bp,[cs:FirstEntry] 0 0000075F 72F4 jc FindNext%1 0 00000761 89C5 mov bp,ax 225 <3> Clobbered equ clobbered 0 00000763 26C6460003 mov byte [AllocByte],Clobbered 227 <3> 228 <3> 229 <3> 0 00000768 EBEB jmp FindNext%1 231 <3> 232 <3> int%1 endp 233 <3> %rotate 1 247 <1> 248 <1> ;******************************************************************** ;3.30 249 <1> ;Common routines ;3.30 250 <1> 251 <1> longpath: 0 0000076A 2E8B2E[0E00] mov bp,[cs:LastEntry] ; start with last entry in table 253 <1> 254 <1> LPLOOPP: ;3.30 0 0000076F 26807E0000 cmp byte [AllocByte],Free ; is entry free? 0 00000774 7512 jne inuse ; no, try next one 257 <1> 0 00000776 B001 mov al,Allocated 0 00000778 26864600 xchg [AllocByte],al ; allocate entry 0 0000077C 3C00 cmp al,Free ; is it still free? 0 0000077E 7414 je found ; yes, go use it 262 <1> 0 00000780 3C01 cmp al,Allocated ; is it other than Allocated or Free? 0 00000782 7404 je inuse ; no, check the next one 265 <1> 0 00000784 26884600 mov [AllocByte],al ; yes, put back the error state 267 <1> 268 <1> inuse: 0 00000788 2E3B2E[0C00] cmp bp,[cs:FirstEntry] 270 <1> Fatal equ fatal ; NASM port label 0 0000078D 7406 je Fatal 0 0000078F 83ED08 sub bp,EntrySize 0 00000792 EBDB JMP LPLOOPP ;3.30 274 <1> 275 <1> found: 0 00000794 C3 ret 277 <1> 278 <1> ; page 279 <1> 280 <1> fatal proc near 0 00000795 1E push ds ;3.30 0 00000796 B800F0 mov ax, 0f000h ;loook at the model byte ;3.30 0 00000799 8ED8 mov ds, ax ;3.30 0 0000079B 803EFEFFF9 cmp byte ptr [0fffeh], mdl_convert ;convertible? ;3.30 0 000007A0 1F pop ds ;3.30 0 000007A1 7504 jne Skip_NMIS ;3.30 287 <1> ;3.30 0 000007A3 B007 mov al,07h ; disable PC Convertible NMIs 0 000007A5 E672 out 72h,al 290 <1> 291 <1> Skip_NMIS: ;3.30 0 000007A7 FA cli ; disable and mask 0 000007A8 B0FF mov al,0ffh ; all other ints 0 000007AA E621 out 021h,al 0 000007AC E6A1 out 0a1h,al 296 <1> 0 000007AE 8CCE mov si,cs 0 000007B0 8EDE mov ds,si 299 <1> fatal_msg equ FATAL_MSG ; NASM port label 0 000007B2 BE[C407] mov si,offset fatal_msg 301 <1> 302 <1> fatal_loop: 0 000007B5 AC lodsb 0 000007B6 3C24 cmp al,'$' 0 000007B8 7408 je fatal_done 306 <1> 0 000007BA B307 mov bl,7 ;3.30* 0 000007BC B40E mov ah,14 ;3.30* 0 000007BE CD10 int 010h ; whoops, this enables ints ;3.30* 0 000007C0 EBF3 jmp fatal_loop 311 <1> 312 <1> fatal_done: 0 000007C2 EBFE jmp fatal_done 314 <1> fatal endp 263 ;=== Pop trace listing source 264 ; include STKMES.INC ;Fatal stack error message 265 ;=== Push trace listing source: msbio.cl5 266 %include "msbio.cl5" ;Fatal stack error message ; NASM included file 1 <1> ; msbio.cl5 2 <1> 3 <1> 4 <1> ;_______________________ 5 <1> 0 000007C4 0D0A070D0A496E7465 FATAL_MSG DB 0DH,0AH,7,0DH,0AH, "Internal stack overflow",0DH,0AH 0 000007CD 726E616C2073746163 0 000007D6 6B206F766572666C6F 0 000007DF 770D0A 0 000007E2 53797374656D206861 DB "System halted",0DH,0AH,"$" 0 000007EB 6C7465640D0A24 267 ;=== Pop trace listing source 268 ;.XALL 269 public Endstackcode 270 Endstackcode label byte 271 %ENDIF 272 273 ; 274 SYSINIT: 0 000007F2 E95F03 JMP GOINIT 0 000007F5 90 nop ; identicalise 277 278 even 279 DOSINFO LABEL DWORD 0 000007F6 00000000 DW 0,0 281 282 MSDOS LABEL DWORD 283 ENTRY_POINT LABEL DWORD 0 000007FA 0000 DW 0000 0 000007FC 0000 FINAL_DOS_LOCATION DW 0000 0 000007FE [0000] dos_size dw afterdosdatalabel wrt DOSSTART 0 00000800 [0000][0000] DEVICE_LIST dw CONHEADER, seg CONHEADER 288 289 SYSI_Country LABEL DWORD ;J.K. 5/29/86 Pointer to 0 00000804 0000 DW 0000 ;country table in DOS 0 00000806 0000 DW 0000 292 0 00000808 00 Fake_Floppy_Drv db 0 ;AN001;Set to 1 if this machine 294 ;does not have any floppies!!! 0 00000809 00 Big_Media_Flag db 0 ;AN021;Set by IBMINIT if > 32 MB fixed media exist. 296 ; 297 ;Variables for Stack Initialization Program. 298 %IF STACKSW 0 0000080A 0900 STACK_COUNT DW DefaultCount 0 0000080C 8000 STACK_SIZE DW DefaultSize 0 0000080E 00000000 STACK_ADDR DD 00000000 302 %ENDIF 303 ; various default values 304 0 00000812 0100 MEMORY_SIZE DW 0001 0 00000814 00 DEFAULT_DRIVE DB 00 ;initialized by IBMINIT. 0 00000815 FFFF BUFFERS DW -1 ; initialized during buffer allocation 0 00000817 0000 H_Buffers dw 0 ;AN000; # of the Heuristic buffers. Initially 0. 309 %ifndef BUF2 310 Buffer_Pages dw 0 ;AN000; # of extended memory pages for the buffer. 311 BufferBuckets dw 0 ;AN000; 312 Buffer_odds dw 0 ;AN000; 313 %endif 0 00000819 ???? SingleBufferSize dw ? ;AN000; Maximum sector size + buffer header 315 %ifndef BUF2 316 MaxNumBuf1 db 15 ;AN026;Num of buffers in a bucket group 1. 317 MaxNumBuf2 db 15 ;AN026;Num of buffers in a possible bucket group 2. 318 NthBuck db 0 ;AN026; 1st bucket group = 1st bucket through Nth Bucket. The rest = second group 319 320 %IF BUFFERFLAG 321 322 FIRST_PAGE DW 0, 0 323 LAST_PAGE DW 0, 0 324 NPA640 DW 0 325 EMS_SAVE_BUF DB 0,0,0,0,0,0,0,0,0,0,0,0 326 327 %ENDIF 328 %endif 329 0 0000081B 08 FILES DB 8 ; enough files for pipe 0 0000081C 04 FCBS DB 4 ; performance for recycling 0 0000081D 00 Keep DB 0 ; keep original set 0 0000081E 05 NUM_CDS DB 5 ; 5 net drives 0 0000081F ???? config_block DW ? 0 00000821 0000 buffer_block: dw 0 0 00000823 413A FOOSTRNG DB "A:" 0 00000825 020050 COMMAND_LINE DB 2,0,"P" ;Default Command.com Args 0 00000828 000000000000000000 DB 29 DUP (0) 0 00000831 000000000000000000 0 0000083A 000000000000000000 0 00000843 0000 0 00000845 00 ZERO DB 0 0 00000846 00 SepChr DB 0 0 00000847 0000 LineCount dw 0 ;AN000; Line count in config.sys 0 00000849 20202020200D0A24 ShowCount db ' ',CR,LF,'$' ;AN000; Used to convert Linecount to ASCII. 0 00000851 0000 Buffer_LineNum dw 0 ;AN000; Line count for "BUFFERS=" command if entered. 344 0 00000853 FF Sys_Model_Byte db 0FFh ;model byte used in SYSINIT 0 00000854 00 Sys_Scnd_Model_Byte db 0 ;secondary model byte used in SYSINIT 347 ; 0 00000855 00 Buffer_Slash_X db 0 ;AN000;AN023; BUFFERS= ... /X option entered. 349 %ifndef BUF2 350 Real_IBM_Page_Id dw 0 ;AN029; 351 IBM_Frame_Seg dw 0 ;AN000; segment value for physical IBM page frame. 352 Frame_Info_Buffer dw (MAX_NUM_PAGEFRAME * 4) dup (0) ;AN010; For EMS. as per spec. 2 words per entry 353 EMSHandleName db 'BUFFERS ' ;AN010; 8 char. EMS handle name 354 EMS_Ctrl_Tab dd 0 ;AN010; 355 EMS_State_Buf dd 0 ;AN010; 356 BUF_PREV_OFF dw 0 ;AN020; 357 EMS_Buf_First dw 0 ;AN020; 358 %endif 359 360 %IFN NOEXEC 361 align 2, db 0 362 COMEXE: ; NASM structure instance 363 Exec0_size equ Exec0_struc_size ; NASM port equate 364 istruc Exec0 365 at Exec0_environ 0 00000856 0000 dw 0 367 at Exec0_com_line 0 00000858 [2508][0000] dw COMMAND_LINE, seg COMMAND_LINE 369 at Exec0_5C_FCB 0 0000085C [1408][0000] dw DEFAULT_DRIVE, seg DEFAULT_DRIVE 371 at Exec0_6C_FCB 0 00000860 [4508][0000] dw ZERO, seg ZERO 373 iend 374 %ENDIF 375 376 ;------------------------------------------------------------------ 377 ;J.K. 2/23/87 ;variables for INSTALL= command. 378 0 00000864 00 Multi_Pass_Id db 0 ;AN024;AN027; 380 0 00000865 00 align 2, db 0 0 00000866 0000 Install_Flag dw 0 ;AN000; 383 HAVE_INSTALL_CMD equ 00000001b ;AN019; CONFIG.SYS has INSTALL= commands 384 HAS_INSTALLED equ 00000010b ;AN019; SYSINIT_BASE installed. 385 SHARE_INSTALL equ 00000100b ;AN021; Used to install SHARE.EXE 386 0 00000868 0000 Config_Size dw 0 ;AN000; size of config.sys file. Set by SYSCONF.ASM 0 0000086A 0000 CheckSum dw 0 ;AN000; Used by Sum_up 389 0 0000086C 202020202020202020 Ldexec_FCB db 20 dup (' ') ;AN000;big enough 0 00000875 202020202020202020 0 0000087E 2020 0 00000880 00 Ldexec_Line db 0 ;AN000;# of parm characters 0 00000881 20 Ldexec_start db ' ' ;AN000; 0 00000882 000000000000000000 Ldexec_parm db 80 dup (0) ;AN000; 0 0000088B 000000000000000000 0 00000894 000000000000000000 0 0000089D 000000000000000000 0 000008A6 000000000000000000 0 000008AF 000000000000000000 0 000008B8 000000000000000000 0 000008C1 000000000000000000 0 000008CA 0000000000000000 394 395 align 2, db 0 396 INSTEXE: ; NASM structure instance 397 istruc Exec0 398 at Exec0_environ 0 000008D2 0000 dw 0 400 at Exec0_com_line 0 000008D4 [8008][0000] dw Ldexec_Line, seg Ldexec_Line 402 at Exec0_5C_FCB 0 000008D8 [6C08][0000] dw Ldexec_FCB, seg Ldexec_FCB 404 at Exec0_6C_FCB 0 000008DC [6C08][0000] dw Ldexec_FCB, seg Ldexec_FCB 406 iend 407 408 ;AN016; Undo the extended attribute handling 409 ;EA_QueryList label byte 410 ; dw 1 ;AN008; I need just one EA info. 411 ; db 02h ;AN008; Type is BINARY 412 ; dw 8000h ;AN008; Flag is SYSTEM DEFINED. 413 ; db 8 ;AN008; Length of name is 8 bytes 414 ; db 'FILETYPE' ;AN008; Name is FILETYPE 415 ;Ext_Attr_List dw 1 ;AN008; Just 1 Extended attribute List 416 ; db 2 ;AN008;EA_TYPE 417 ; dw 8000h ;AN008;FLAG 418 ; db 0 ;AN008;Failure reason 419 ; db 8 ;AN008;Length of NAME 420 ; dw 1 ;AN008;Length of VALUE 421 ; db 'FILETYPE' ;AN008;Name 422 ;Ext_Attr_Value db 0 ;AN008;Value 423 ;SIZE_EXT_ATTR_LIST equ $-Ext_Attr_List ;AN008; 424 ; 425 ;;Extended attribute value 426 ;EA_INSTALLABLE equ 4 ;AN008;Value for Installable file 427 428 ;------------------------------------------------------------------ 429 ;J.K. 5/15/87 ;Request header, variables for IFS= command. 430 0 000008E0 0000 IFS_Flag dw 0 ;AN000; Set to 1 if it is an IFS. 432 IS_IFS equ 00000001b ;IFS command? 433 NOT_IFS equ 11111110b 434 435 IFS_RH: ; NASM structure instance 436 IFSRH_size equ IFSRH_struc_size ; NASM port equate 437 istruc IFSRH 438 at IFSR_LENGTH 0 000008E2 1C00 dw LENGTH_INIT 440 at IFSR_FUNCTION 0 000008E4 01 db IFSINIT 0 000008E5 00 iend 443 444 ;------------------------------------------------------------------ 445 ;Variables for Comment= 0 0000091E 00 COM_Level db 0 ;AN000;level of " " in command line 0 0000091F 00 CMMT db 0 ;AN000;length of COMMENT string token 0 00000920 00 CMMT1 db 0 ;AN000;token 0 00000921 00 CMMT2 db 0 ;AN000;token 0 00000922 ?? Cmd_Indicator db ? ;AN000; 0 00000923 00 DoNotShowNum db 0 ;AN000; 452 453 ;------------------------------------------------------------------ 0 00000924 0000 COUNT DW 0000 0 00000926 0000 Org_Count dw 0000 ;AN019; 0 00000928 0000 CHRPTR DW 0000 0 0000092A 0000 CntryFilehandle DW 0000 458 ;------------------------------------------------------------------ 459 BucketPTR LABEL dword ;AN000; 460 BUFPTR LABEL DWORD ;LEAVE THIS STUFF IN ORDER! 0 0000092C 0000 DW 0 0 0000092E 0000 DW 0 463 PRMBLK LABEL WORD 0 00000930 0000 dw 0 0 00000932 0000 dw 0 466 0 00000934 18 PACKET DB 24 ;AN014; Was 22 0 00000935 00 DB 0 0 00000936 00 DB 0 ;INITIALIZE CODE 0 00000937 0000 DW 0 0 00000939 ???????????????? DB 8 DUP (?) 0 00000941 00 UNITCOUNT DB 0 0 00000942 00000000 BREAK_ADDR DD 0 0 00000946 00000000 BPB_ADDR DD 0 0 0000094A 00 DriveNumber DB 0 0 0000094B 0000 ConfigMsgFlag dw 0 ;AN014;AN022; Used to control "Error in CONFIG.SYS line #" message 477 478 0000094D TempStack DB 80h DUP (?) 479 0 000009CD 00 align 16, db 0 481 initpspmcb: 482 istruc arena 0 000009D0 4D at arena_signature, db 'M' 484 at arena_owner 0 000009D1 000E00 at arena_size, dw 10h - 2 486 at arena_reserved 0 000009D5 00494E4954 at arena_name, db "INIT",0 0 000009DC 00 0 000009DD 00 at arena_struc_size 489 ; iend ; cannot use arena_size as it clashes with the field named the same 490 %pop 491 492 align 2, db 0 493 sysinitmcb: 494 istruc MCB 0 000009E0 5A at mcbSignature, db 'Z' 0 000009E1 0800 at mcbOwner, dw 8 0 000009E3 005300 at smcbName, db "S",0 0 000009EA 1F at smcbType, db S_INIT 0 000009EB 00 iend 500 0 000009F0 0000 tempcds_block: dw 0 502 503 global kernelcommandline 504 global kernelcommandline.end 505 506 align 2, db 0 0 000009F2 00FF00 kernelcommandline: fill 256, 0, {db 0, -1} 0 00000AF2 0000 .end: dw 0 509 510 extern OLDCONFIG_name 511 global CONFIG_pointers 512 513 commandnames: 514 ; these are just to validate the names. 515 ; their contents aren't used here. 0 00000AF4 0000[380B] dw 0, namedot 0 00000AF8 0000[290B] dw 0, nameprepend 0 00000AFC 0000[310B] dw 0, nameappend 519 520 CONFIG_pointers: 0 00000B00 0000[0E0B] .config: dw 0, .nameconfig 0 00000B04 [3A0B][150B] .altconfig: dw ALTCONFIG_name, .namealtconfig 0 00000B08 [0000][1F0B] .oldconfig: dw OLDCONFIG_name, .nameoldconfig 0 00000B0C FFFF dw -1 525 0 00000B0E 434F4E46494700 .nameconfig: asciz "CONFIG" 0 00000B15 414C54434F4E464947 .namealtconfig: asciz "ALTCONFIG" 0 00000B1E 00 0 00000B1F 4F4C44434F4E464947 .nameoldconfig: asciz "OLDCONFIG" 0 00000B28 00 529 530 global nameprepend, nameappend 0 00000B29 50524550454E4400 nameprepend: asciz "PREPEND" 0 00000B31 415050454E4400 nameappend: asciz "APPEND" 0 00000B38 2E00 namedot: asciz "." 534 0 00000B3A 6C646F732E696E6900 ALTCONFIG_name: asciz "ldos.ini" 536 537 msg_startingsmall: 0 00000B43 5374617274696E6720 .: db "Starting small " 0 00000B4C 736D616C6C20 539 .length equ $ - . 540 msg_linebreak: 0 00000B52 0D0A .: db 13,10 542 .length equ $ - . 543 544 GOINIT: 545 ;J.K. before doing anything else, let's set the model byte 546 ;SB33043***************************************************************** 0 00000B54 B4C0 mov ah,0c0h ;get system configuration ;SB ;3.30* 0 00000B56 CD15 int 15h ; * ;SB ;3.30* 549 ;SB33043***************************************************************** 0 00000B58 7217 jc No_ROM_Config 0 00000B5A 80FC00 cmp ah, 0 ; double check 0 00000B5D 7512 jne No_ROM_Config 0 00000B5F 268A4702 mov al, [ES:BX + bios_SD_modelbyte] 0 00000B63 2EA2[5308] mov [cs:Sys_Model_Byte], al 0 00000B67 268A4703 mov al, [ES:BX + bios_SD_scnd_modelbyte] 0 00000B6B 2EA2[5408] mov [cs:Sys_Scnd_Model_Byte], al 0 00000B6F EB0C jmp @F 558 No_ROM_Config: ; Old ROM 0 00000B71 B800F0 mov ax, 0f000h 0 00000B74 8ED8 mov ds, ax 0 00000B76 A0FEFF mov al, byte ptr [0fffeh] 0 00000B79 2EA2[5308] mov [cs:Sys_Model_Byte], al ;set the model byte. 563 @@: 564 565 ;J.K.6/24/87 Set Fake_Floppy_Drv if there is no diskette drives in this machine. 566 ;SB34SYSINIT1001******************************************************** 567 ;SB execute the equipment determination interrupt and then 568 ;SB check the returned value to see if we have any floppy drives 569 ;SB if we have no floppy drive we set cs:Fake_Floppy_Drv to 1 570 ;SB See the AT Tech Ref BIOS listings for help on the equipment 571 ;SB flag interrupt (11h) 572 0 00000B7D CD11 int 11h 0 00000B7F A801 test al, 1 ; has floppy ? 0 00000B81 7506 jnz Move_Myself 0 00000B83 2EC606[0808]01 mov byte [cs:Fake_Floppy_Drv],1 ; no floppy, fake. 577 578 ;SB34SYSINIT1001******************************************************** 579 Move_Myself: 0 00000B89 FC CLD ; Set up move 0 00000B8A 31F6 XOR SI,SI 0 00000B8C 89F7 MOV DI,SI 583 584 %if 0 585 %IF MSVER 586 MOV CX,[cs:MEMORY_SIZE] 587 CMP CX,1 ; 1 means do scan 588 JNZ NOSCAN 589 MOV CX,2048 ;START SCANNING AT 32K BOUNDARY 590 XOR BX,BX 591 592 MEMSCAN:INC CX 593 JZ SETEND 594 MOV DS,CX 595 MOV AL,[BX] 596 NOT AL 597 MOV [BX],AL 598 CMP AL,[BX] 599 NOT AL 600 MOV [BX],AL 601 JZ MEMSCAN 602 SETEND: 603 MOV [cs:MEMORY_SIZE],CX 604 %ENDIF 605 606 %IF IBMVER | IBMJAPVER 607 MOV CX,[cs:MEMORY_SIZE] 608 %ENDIF 609 %endif 610 NOSCAN: ; CX is mem size in para 0 00000B8E 0E push cs 0 00000B8F 1F pop ds ; ds => SYSINITSEG (unrelocated) 613 ASSUME DS:SYSINITSEG 614 615 ; 616 ; MOVE THE DOS TO ITS PROPER LOCATION 617 ; 618 SYSIN: 0 00000B90 0E push cs 0 00000B91 07 pop es 0 00000B92 0E push cs 0 00000B93 1F pop ds 0 00000B94 BF[F209] mov di, kernelcommandline 0 00000B97 89FE mov si, di 0 00000B99 B90001 mov cx, 256 0 00000B9C 31C0 xor ax, ax 0 00000B9E F2AE repne scasb 0 00000BA0 4F dec di 0 00000BA1 893E[F20A] mov word [kernelcommandline.end], di 0 00000BA5 89F7 mov di, si ; -> start 0 00000BA7 56 push si 632 @@: 0 00000BA8 3B36[F20A] cmp si, word [kernelcommandline.end] 0 00000BAC 7314 jae @F 0 00000BAE AC lodsb ; get text 0 00000BAF AA stosb ; store text 0 00000BB0 3C3B cmp al, ';' ; was semicolon ? 0 00000BB2 75F4 jne @B ; no, loop --> 0 00000BB4 803C3B cmp byte [si], ';' ; escaped ? 0 00000BB7 7406 je .escapesemicolon ; yes --> 0 00000BB9 C645FF00 mov byte [di - 1], 0 ; no, treat as terminator 0 00000BBD EBE9 jmp @B 643 644 .escapesemicolon: 0 00000BBF 46 inc si ; -> past next semicolon 0 00000BC0 EBE6 jmp @B 647 648 @@: 0 00000BC2 A4 movsb ; copy the NUL 0 00000BC3 4F dec di ; -> at the NUL 0 00000BC4 893E[F20A] mov word [kernelcommandline.end], di 652 ; update the end offset (<= before) 0 00000BC8 5E pop si 654 655 parse_config: 656 .loopcommand: 0 00000BC9 A8 db __TEST_IMM8 ; skip inc 658 @@: 0 00000BCA 46 inc si 0 00000BCB 803C20 cmp byte [si], 32 0 00000BCE 74FA je @B 0 00000BD0 803C09 cmp byte [si], 9 0 00000BD3 74F5 je @B 664 0 00000BD5 803C00 cmp byte [si], 0 ; empty ? 0 00000BD8 7503E99000 je .donename ; yes --> 667 0 00000BDD BF[F40A] mov di, commandnames 669 .loopname: 0 00000BE0 B8FFFF mov ax, -1 0 00000BE3 AF scasw ; skip content field, and compaere to -1 0 00000BE4 7431 je .unknownname 0 00000BE6 56 push si 0 00000BE7 57 push di 0 00000BE8 8B3D mov di, [di] 676 .comparename: 0 00000BEA AC lodsb 0 00000BEB 3C00 cmp al, 0 0 00000BED 7423 je .next 0 00000BEF 3C61 cmp al, 'a' 0 00000BF1 7206 jb @F 0 00000BF3 3C7A cmp al, 'z' 0 00000BF5 7702 ja @F 0 00000BF7 2C20 sub al, 20h 685 @@: 0 00000BF9 AE scasb 0 00000BFA 7516 jne .next 0 00000BFC 803D00 cmp byte [di], 0 0 00000BFF 75E9 jne .comparename 0 00000C01 AC lodsb 0 00000C02 3C00 cmp al, 0 0 00000C04 744C je .found 0 00000C06 3C20 cmp al, 32 0 00000C08 7448 je .found 0 00000C0A 3C09 cmp al, 9 0 00000C0C 7444 je .found 0 00000C0E 3C3D cmp al, '=' 0 00000C10 7440 je .found 699 .next: 0 00000C12 5F pop di 0 00000C13 5E pop si 0 00000C14 AF scasw ; skip name field 0 00000C15 EBC9 jmp .loopname 704 705 .unknownname: 0 00000C17 56 push si 707 708 extern unknown_command 0 00000C18 BE[0000] mov si, unknown_command 0 00000C1B BB0700 mov bx, 7 0 00000C1E A9 db __TEST_IMM16 ; skip int 712 @@: 0 00000C1F CD10 int 10h 0 00000C21 AC lodsb 0 00000C22 B40E mov ah, 0Eh 0 00000C24 84C0 test al, al 0 00000C26 75F7 jnz @B 0 00000C28 5E pop si 0 00000C29 56 push si 720 @@: 0 00000C2A CD10 int 10h 0 00000C2C AC lodsb 0 00000C2D B40E mov ah, 0Eh 0 00000C2F 84C0 test al, al 0 00000C31 740C jz @F 0 00000C33 3C20 cmp al, 32 0 00000C35 7204 jb .ctrl 0 00000C37 3C7F cmp al, 127 0 00000C39 72EF jb @B 730 .ctrl: 0 00000C3B B02E mov al, '.' 0 00000C3D EBEB jmp @B 733 @@: 0 00000C3F 5E pop si 0 00000C40 B8220E mov ax, 0E00h + '"' 0 00000C43 CD10 int 10h 0 00000C45 B80D0E mov ax, 0E00h + 13 0 00000C48 CD10 int 10h 0 00000C4A B80A0E mov ax, 0E00h + 10 0 00000C4D CD10 int 10h 0 00000C4F EB1C jmp .donename 742 743 @@: 0 00000C51 AC lodsb 745 .found: 0 00000C52 3C20 cmp al, 32 0 00000C54 74FB je @B 0 00000C56 3C09 cmp al, 9 0 00000C58 74F7 je @B 0 00000C5A 3C3D cmp al, '=' 0 00000C5C 7501 jne @FF 752 @@: 0 00000C5E AC lodsb 754 @@: 0 00000C5F 3C20 cmp al, 32 0 00000C61 74FB je @BB 0 00000C63 3C09 cmp al, 9 0 00000C65 74F7 je @BB 759 0 00000C67 4E dec si ; -> content 0 00000C68 5F pop di 0 00000C69 8975FE mov word [di - 2], si 0 00000C6C 5E pop si 764 .donename: 765 @@: 0 00000C6D AC lodsb 0 00000C6E 3C00 cmp al, 0 0 00000C70 75FB jne @B 0 00000C72 3B36[F20A] cmp si, word [kernelcommandline.end] 0 00000C76 7703E94EFF jbe .loopcommand ; (ZR means an empty command at end) 771 0 00000C7B 31C0 xor ax, ax 0 00000C7D 8ED8 mov ds, ax 774 ASSUME DS:NOTHING,ES:SYSINITSEG,SS:NOTHING 0 00000C7F 2EA1[FC07] MOV ax, [cs:FINAL_DOS_LOCATION] ; Where it is going (set by BIOS) 0 00000C83 A3C600 mov word [31h * 4 + 2], ax 0 00000C86 8EC0 mov es, ax 778 ASSUME ES:NOTHING 0 00000C88 31FF xor di, di 0 00000C8A BB[0000] mov bx, DOSSTART 0 00000C8D B9[0000] mov cx, afterdosdatalabel wrt DOSSTART ; = early DOS data length 0 00000C90 8EDB mov ds, bx ; => early DOS data location 0 00000C92 31F6 xor si, si 0 00000C94 39C3 cmp bx, ax 785 ; cmp ds, es 0 00000C96 7306 jae load_dos_to_lower 787 load_dos_to_higher: 0 00000C98 89CE mov si, cx ; -> behind source 0 00000C9A 89F7 mov di, si ; -> behind dest 0 00000C9C FD std ; set DOWN 0 00000C9D A7 cmpsw ; -> at last words 792 load_dos_to_lower: 0 00000C9E D1E9 shr cx, 1 0 00000CA0 F3A5 rep movsw 0 00000CA2 FC cld 796 0 00000CA3 BB6000 mov bx, 60h ; => place for MCB / PSP 0 00000CA6 8EC3 mov es, bx 0 00000CA8 43 inc bx ; => place for PSP 0 00000CA9 31FF xor di, di ; es:di -> MCB 0 00000CAB 0E push cs 0 00000CAC 1F pop ds 0 00000CAD BE[D009] mov si, initpspmcb ; ds:si -> template 0 00000CB0 895C01 mov word [si + arena_owner], bx 0 00000CB3 B108 mov cl, 8 0 00000CB5 F3A5 rep movsw 807 0 00000CB7 8CC8 mov ax, cs 0 00000CB9 48 dec ax 0 00000CBA 8EC0 mov es, ax 0 00000CBC 31FF xor di, di 0 00000CBE BE[E009] mov si, sysinitmcb 0 00000CC1 B108 mov cl, 8 0 00000CC3 8B16[1208] MOV DX,[MEMORY_SIZE] ; Set for call to DOSINIT 0 00000CC7 40 inc ax 0 00000CC8 40 inc ax 0 00000CC9 F7D8 neg ax 0 00000CCB 01D0 add ax, dx 0 00000CCD 894403 mov word [si + mcbSize], ax 0 00000CD0 F3A5 rep movsw 0 00000CD2 8CC1 mov cx, es 822 0 00000CD4 C536[0008] LDS SI,[DEVICE_LIST] ; Set for call to DOSINIT 824 0 00000CD8 FA CLI 826 0 00000CD9 90 align 2, nop 828 LOCSTACK LABEL BYTE 0 00000CDA 8CC8 MOV AX,CS 0 00000CDC 8ED0 MOV SS,AX 0 00000CDE BC[DA0C] MOV SP,OFFSET LOCSTACK ; Set stack 832 833 ASSUME SS:SYSINITSEG 834 835 %IFN ALTVECT 0 00000CE1 FB STI ; Leave INTs disabled for ALTVECT 837 %ENDIF 838 839 extern doscode_start 840 0 00000CE2 368E06[FC07] mov es, word [ss:FINAL_DOS_LOCATION] 842 ; => DOSDATA 0 00000CE7 B8[0000] mov ax, doscode_start wrt SYSINITGROUP 0 00000CEA 51 push cx 0 00000CEB B104 mov cl, 4 0 00000CED D3E8 shr ax, cl ; = how many paragraphs from cs 0 00000CEF 8CC9 mov cx, cs 0 00000CF1 01C8 add ax, cx ; => DOSCODE 0 00000CF3 26A3[0000] mov word [es:dosdata_to_doscode], ax 0 00000CF7 1E push ds 0 00000CF8 31C9 xor cx, cx 0 00000CFA 8ED9 mov ds, cx 0 00000CFC 8C06C600 mov word [31h * 4 + 2], es 0 00000D00 1F pop ds 0 00000D01 59 pop cx ; preserve => SYSINIT S MCB 856 857 extern NEARDOSINIT 0 00000D02 E8[0000] call NEARDOSINIT 859 ;ES:DI -> SysInitVars_Ext 0 00000D05 268B05 mov ax, word ptr [es:di + SYSI_InitVars] ;J.K. 5/29/86 0 00000D08 36A3[F607] mov word ptr [ss:dosinfo], ax 0 00000D0C 268B4502 mov ax, word ptr [es:di + SYSI_InitVars+2] 0 00000D10 36A3[F807] mov word ptr [ss:dosinfo+2],ax ;set the sysvar pointer 864 0 00000D14 268B4504 mov ax, word ptr [es:di + SYSI_Country_Tab] 0 00000D18 36A3[0408] mov word ptr [ss:SYSI_Country],ax 0 00000D1C 268B4506 mov ax, word ptr [es:di + SYSI_Country_Tab+2] 0 00000D20 36A3[0608] mov word ptr [ss:SYSI_Country+2],ax ;set the SYSI_Country pointer J.K. 869 0 00000D24 B440 mov ah, 40h 0 00000D26 BB0100 mov bx, 1 0 00000D29 0E push cs 0 00000D2A 1F pop ds 0 00000D2B BA[430B] mov dx, msg_startingsmall 0 00000D2E B90F00 mov cx, msg_startingsmall.length 0 00000D31 CD21 int 21h 0 00000D33 B8FF33 mov ax, 33FFh 0 00000D36 CD21 int 21h 0 00000D38 92 xchg dx, ax ; dx -> message, ax => segment 0 00000D39 89D7 mov di, dx 0 00000D3B 8EC0 mov es, ax 0 00000D3D 8ED8 mov ds, ax 0 00000D3F B000 mov al, 0 0 00000D41 B9FFFF mov cx, -1 0 00000D44 F2AE repne scasb 0 00000D46 F7D1 not cx 0 00000D48 49 dec cx 0 00000D49 B440 mov ah, 40h 0 00000D4B CD21 int 21h 0 00000D4D B440 mov ah, 40h 0 00000D4F BB0100 mov bx, 1 0 00000D52 0E push cs 0 00000D53 1F pop ds 0 00000D54 BA[520B] mov dx, msg_linebreak 0 00000D57 B90200 mov cx, msg_linebreak.length 0 00000D5A CD21 int 21h 897 898 extern INITUPB 0 00000D5C E8[0000] call INITUPB 900 901 extern INITDPB 0 00000D5F E8[0000] call INITDPB 903 904 relocate_upb_early: 905 extern sysinit_get_ds_dosentry, dskdrvs_indirect, START_BDS, DRVMAX 906 0 00000D62 E8[0000] call sysinit_get_ds_dosentry 0 00000D65 31F6 xor si, si 0 00000D67 8A2E[0000] mov ch, [DRVMAX] ; ch = how many UPBs 0 00000D6B C43E[0000] les di, [START_BDS] ; es:di -> first UPB 0 00000D6F C516[0000] lds dx, [dskdrvs_indirect] ; ds:dx -> dskdrvs array (used by INITDPB) 0 00000D73 83FFFF cmp di, -1 ; none ? 0 00000D76 7503E90701 je .warn ; then skip --> 0 00000D7B 84ED test ch, ch 0 00000D7D 7503E90001 jz .warn 916 ; Harden: Expect UPBs at start of memory block. 0 00000D82 85FF test di, di 0 00000D84 7403E9F900 jnz .warn 0 00000D89 8CC0 mov ax, es 0 00000D8B 8CDB mov bx, ds 0 00000D8D 39D8 cmp ax, bx ; UPB segment == dskdrvs segment ? 0 00000D8F 7403E9EE00 jne .warn 0 00000D94 48 dec ax 0 00000D95 8ED8 mov ds, ax 0 00000D97 837C0108 cmp word [si + mcbOwner], 8 ; an S MCB ? 0 00000D9B 7403E9E200 jne .warn 0 00000DA0 837C0853 cmp word [si + mcbName], "S" ; S MCB ? 0 00000DA4 7403E9D900 jne .warn 0 00000DA9 807C0A09 cmp byte [si + smcbType], S_UPB ; correct type ? 0 00000DAD 7403E9D000 jne .warn 0 00000DB2 8B4403 mov ax, [si + mcbSize] 0 00000DB5 B104 mov cl, 4 0 00000DB7 D3E0 shl ax, cl ; = size in bytes 0 00000DB9 89C3 mov bx, ax 0 00000DBB D3E8 shr ax, cl ; compute paragraphs again 0 00000DBD 394403 cmp word [si + mcbSize], ax ; match ? 0 00000DC0 7403E9BD00 jne .warn 0 00000DC5 39D3 cmp bx, dx ; dskdrvs array fits in block ? 0 00000DC7 7703E9B600 jbe .warn ; certainly no --> 0 00000DCC 31C0 xor ax, ax 0 00000DCE 88E8 mov al, ch ; ax = how many UPBs 0 00000DD0 01C0 add ax, ax ; how large dskdrvs array should be 0 00000DD2 01D0 add ax, dx ; -> behind array 0 00000DD4 83C00F add ax, 15 ; round up 0 00000DD7 24F0 and al, ~ 15 ; get to paragraph boundary 0 00000DD9 39C3 cmp bx, ax ; match ? 0 00000DDB 7403E9A200 jne .warn 0 00000DE0 B064 mov al, BDS_TYPE_struc_size 0 00000DE2 F6E5 mul ch ; ax = how many bytes needed for UPBs 0 00000DE4 39C2 cmp dx, ax ; last UPB fits below dskdrvs ? 0 00000DE6 7303E99700 jb .warn ; no --> 0 00000DEB 89C3 mov bx, ax 0 00000DED 40 inc ax 0 00000DEE 24FE and al, ~ 1 0 00000DF0 39C2 cmp dx, ax 0 00000DF2 7403E98B00 jne .warn 957 0 00000DF7 88E9 mov cl, ch 0 00000DF9 84C9 test cl, cl 0 00000DFB 7503E98200 jz .warn 0 00000E00 06 push es 0 00000E01 57 push di 963 .loop: 0 00000E02 80F901 cmp cl, 1 0 00000E05 7416 je .last 0 00000E07 8CC3 mov bx, es 0 00000E09 26395D02 cmp word [es:di + LINK + 2], bx 0 00000E0D 7571 jne .warn_pop_pop 0 00000E0F 8D5D64 lea bx, [di + BDS_TYPE_struc_size] 0 00000E12 26391D cmp word [es:di + LINK], bx 0 00000E15 7569 jne .warn_pop_pop 0 00000E17 49 dec cx ; count down 0 00000E18 26C43D les di, [es:di + LINK] 0 00000E1B EBE5 jmp .loop 975 976 .last: 0 00000E1D 26833DFF cmp word [es:di + LINK], -1 0 00000E21 755D jne .warn_pop_pop 979 0 00000E23 BE[E427] mov si, alloc_upb_temporary 0 00000E26 51 push cx 0 00000E27 50 push ax 0 00000E28 E8F61A call allocate_temporary_block 0 00000E2B 59 pop cx ; = size of initialised UPBs 0 00000E2C 5B pop bx ; bh = number of UPBs 0 00000E2D 5E pop si 0 00000E2E 1F pop ds ; -> first UPB source 0 00000E2F 89FA mov dx, di ; es:dx -> destination 0 00000E31 F3A4 rep movsb ; copy them over 0 00000E33 89D7 mov di, dx ; es:di -> copied UPBs 0 00000E35 88F9 mov cl, bh 0 00000E37 B500 mov ch, 0 ; cx = amount UPBs 0 00000E39 8CDB mov bx, ds 994 995 .newloop: 0 00000E3B 49 dec cx 0 00000E3C 7417 jz .newlast 0 00000E3E 26395D02 cmp word [es:di + LINK + 2], bx 0 00000E42 7537 jne .warn_free 0 00000E44 8D4564 lea ax, [di + BDS_TYPE_struc_size] 0 00000E47 263905 cmp word [es:di + LINK], ax 0 00000E4A 752F jne .warn_free 0 00000E4C 268C4502 mov word [es:di + LINK + 2], es ; relocate next link 0 00000E50 26C43D les di, [es:di + LINK] 0 00000E53 EBE6 jmp .newloop 1006 1007 .newlast: 0 00000E55 26833DFF cmp word [es:di + LINK], -1 0 00000E59 7520 jne .warn_free 1010 0 00000E5B E8[0000] call sysinit_get_ds_dosentry 0 00000E5E FA cli 0 00000E5F B8FFFF mov ax, -1 0 00000E62 A3[0000] mov word [dskdrvs_indirect], ax 0 00000E65 A3[0200] mov word [dskdrvs_indirect + 2], ax 1016 ; invalidate the dskdrvs pointer 0 00000E68 8CC0 mov ax, es 0 00000E6A 8916[0000] mov word [START_BDS], dx 0 00000E6E 8706[0200] xchg word [START_BDS + 2], ax ; relocate the UPBs 0 00000E72 FB sti 0 00000E73 8EC0 mov es, ax 0 00000E75 B449 mov ah, 49h 0 00000E77 CD21 int 21h ; free the original allocation 0 00000E79 EB16 jmp .done 1025 1026 .warn_free: 0 00000E7B B449 mov ah, 49h 0 00000E7D CD21 int 21h ; free new allocation 0 00000E7F A9 db __TEST_IMM16 ; skip twice pop 1030 .warn_pop_pop: 0 00000E80 58 pop ax 0 00000E81 58 pop ax 1033 .warn: 0 00000E82 0E push cs 0 00000E83 1F pop ds 0 00000E84 BA[CE29] mov dx, sysinit_msg.warn_upb 0 00000E87 B92800 mov cx, sysinit_msg.warn_upb.size 0 00000E8A BB0100 mov bx, 1 0 00000E8D B440 mov ah, 40h 0 00000E8F CD21 int 21h 1041 .done: 1042 1043 1044 ; ! Note that at this point no SFTs, CDSes, buffers 1045 ; hold references to our early DOS-internal DPBs. 1046 relocate_dpb_early: 1047 extern NUMIO, DPBHEAD, sysinit_getdosdata 1048 0 00000E91 E8[0000] call sysinit_getdosdata 0 00000E94 8ED8 mov ds, ax 0 00000E96 31F6 xor si, si 0 00000E98 8A2E[0000] mov ch, [NUMIO] ; ch = how many DPBs (at this point) 0 00000E9C C43E[0000] les di, [DPBHEAD] ; es:di -> first DPB 0 00000EA0 83FFFF cmp di, -1 ; none ? 0 00000EA3 7503E9E500 je .warn ; then skip --> 0 00000EA8 84ED test ch, ch 0 00000EAA 7503E9DE00 jz .warn 1058 ; Harden: Expect DPBs at start of memory block. 0 00000EAF 85FF test di, di 0 00000EB1 7403E9D700 jnz .warn 0 00000EB6 8CC0 mov ax, es 0 00000EB8 48 dec ax 0 00000EB9 8ED8 mov ds, ax 0 00000EBB 837C0108 cmp word [si + mcbOwner], 8 ; an S MCB ? 0 00000EBF 7403E9C900 jne .warn 0 00000EC4 837C0853 cmp word [si + mcbName], "S" ; S MCB ? 0 00000EC8 7403E9C000 jne .warn 0 00000ECD 807C0A08 cmp byte [si + smcbType], S_DPB ; correct type ? 0 00000ED1 7403E9B700 jne .warn 0 00000ED6 8B4403 mov ax, [si + mcbSize] 0 00000ED9 B104 mov cl, 4 0 00000EDB D3E0 shl ax, cl ; = size in bytes 0 00000EDD 89C3 mov bx, ax 0 00000EDF D3E8 shr ax, cl ; compute paragraphs again 0 00000EE1 394403 cmp word [si + mcbSize], ax ; match ? 0 00000EE4 7403E9A400 jne .warn 0 00000EE9 B021 mov al, dpb_struc_size 0 00000EEB F6E5 mul ch ; ax = how many bytes needed for DPBs 0 00000EED 39C3 cmp bx, ax ; last DPB fits in block ? 0 00000EEF 7303E99900 jb .warn ; no --> 0 00000EF4 89C2 mov dx, ax 0 00000EF6 83C20F add dx, 15 0 00000EF9 80E2F0 and dl, ~ 15 0 00000EFC 39D3 cmp bx, dx 0 00000EFE 7403E98A00 jne .warn 1086 0 00000F03 88E9 mov cl, ch 0 00000F05 84C9 test cl, cl 0 00000F07 7503E98100 jz .warn 0 00000F0C 06 push es 0 00000F0D 57 push di 1092 .loop: 0 00000F0E 80F901 cmp cl, 1 0 00000F11 7418 je .last 0 00000F13 8CC3 mov bx, es 0 00000F15 26395D1B cmp word [es:di + dpb_next_dpb + 2], bx 0 00000F19 7570 jne .warn_pop_pop 0 00000F1B 8D5D21 lea bx, [di + dpb_struc_size] 0 00000F1E 26395D19 cmp word [es:di + dpb_next_dpb], bx 0 00000F22 7567 jne .warn_pop_pop 0 00000F24 49 dec cx ; count down 0 00000F25 26C47D19 les di, [es:di + dpb_next_dpb] 0 00000F29 EBE3 jmp .loop 1104 1105 .last: 0 00000F2B 26837D19FF cmp word [es:di + dpb_next_dpb], -1 0 00000F30 7559 jne .warn_pop_pop 1108 0 00000F32 BE[F827] mov si, alloc_dpb_temporary 0 00000F35 51 push cx 0 00000F36 50 push ax 0 00000F37 E8E719 call allocate_temporary_block 0 00000F3A 59 pop cx ; = size of initialised DPBs 0 00000F3B 5B pop bx ; bh = number of DPBs 0 00000F3C 5E pop si 0 00000F3D 1F pop ds ; -> first DPB source 0 00000F3E 89FA mov dx, di ; es:dx -> destination 0 00000F40 F3A4 rep movsb ; copy them over 0 00000F42 89D7 mov di, dx ; es:di -> copied DPBs 0 00000F44 88F9 mov cl, bh 0 00000F46 B500 mov ch, 0 ; cx = amount DPBs 0 00000F48 8CDB mov bx, ds 1123 1124 .newloop: 0 00000F4A 49 dec cx 0 00000F4B 7419 jz .newlast 0 00000F4D 26395D1B cmp word [es:di + dpb_next_dpb + 2], bx 0 00000F51 7533 jne .warn_free 0 00000F53 8D4521 lea ax, [di + dpb_struc_size] 0 00000F56 26394519 cmp word [es:di + dpb_next_dpb], ax 0 00000F5A 752A jne .warn_free 0 00000F5C 268C451B mov word [es:di + dpb_next_dpb + 2], es ; relocate next link 0 00000F60 26C47D19 les di, [es:di + dpb_next_dpb] 0 00000F64 EBE4 jmp .newloop 1135 1136 .newlast: 0 00000F66 26837D19FF cmp word [es:di + dpb_next_dpb], -1 0 00000F6B 7519 jne .warn_free 1139 0 00000F6D E8[0000] call sysinit_getdosdata 0 00000F70 8ED8 mov ds, ax 0 00000F72 FA cli 0 00000F73 8CC0 mov ax, es 0 00000F75 8916[0000] mov word [DPBHEAD], dx 0 00000F79 8706[0200] xchg word [DPBHEAD + 2], ax ; relocate the DPBs 0 00000F7D FB sti 0 00000F7E 8EC0 mov es, ax 0 00000F80 B449 mov ah, 49h 0 00000F82 CD21 int 21h ; free the original allocation 0 00000F84 EB16 jmp .done 1151 1152 .warn_free: 0 00000F86 B449 mov ah, 49h 0 00000F88 CD21 int 21h ; free new allocation 0 00000F8A A9 db __TEST_IMM16 ; skip twice pop 1156 .warn_pop_pop: 0 00000F8B 58 pop ax 0 00000F8C 58 pop ax 1159 .warn: 0 00000F8D 0E push cs 0 00000F8E 1F pop ds 0 00000F8F BA[F629] mov dx, sysinit_msg.warn_dpb 0 00000F92 B92800 mov cx, sysinit_msg.warn_dpb.size 0 00000F95 BB0100 mov bx, 1 0 00000F98 B440 mov ah, 40h 0 00000F9A CD21 int 21h 1167 .done: 1168 0 00000F9C 36C43E[F607] les di, [ss:dosinfo] ;es:di -> dosinfo 1170 0 00000FA1 F8 clc ;AN018;Get the extended memory size 1172 ;SB34SYSINIT1002************************************************************** 1173 ;SB execute the get extended memory size subfunction in the BIOS INT 15h 1174 ;SB if the function reports an error do nothing else store the extended 1175 ;SB memory size reported at the appropriate location in the dosinfo buffer 1176 ;SB currently pointed to by es:di. Use the offsets specified in the 1177 ;SB definition of the sysinitvars struct in inc\sysvar.inc 1178 ;SB 5 LOCS 1179 0 00000FA2 B488 mov ah,88h 0 00000FA4 CD15 int 15h ;check extended memory size 0 00000FA6 7204 jc No_Ext_Memory 0 00000FA8 26894545 mov [es:di + SYSI_EXT_MEM],ax ;save extended memory size 1184 No_Ext_Memory: 1185 1186 ;SB34SYSINIT1002************************************************************** 0 00000FAC 26C7453BFFFF mov word ptr [es:di + SYSI_IFS], -1 ;AN000; Initialize SYSI_IFS chain. 0 00000FB2 26C7453DFFFF mov word ptr [es:di + SYSI_IFS+2], -1 ;AN000; 1189 0 00000FB8 268B4510 mov ax, [es:di + SYSI_MAXSEC] ;AN020; Get the sector size 0 00000FBC 83C010 add ax, BUFINSIZ ;AN020; size of buffer header 0 00000FBF 36A3[1908] mov [ss:SingleBufferSize], ax ;AN020; total size for a buffer 1193 1194 Default_Drive equ DEFAULT_DRIVE ; NASM port label 0 00000FC3 36A0[1408] mov al, [ss:Default_Drive] ;AN000;Get the 1 based boot drive number set by IBMINIT 0 00000FC7 26884543 mov [es:di + SYSI_BOOT_DRIVE], al ;AN000; set SYSI_BOOT_DRIVE 1197 1198 ; Determine if 386 system... 1199 Get_CPU_Type ; macro to determine cpu type 0 00000FCB 9C pushf 0 00000FCC 53 push bx 0 00000FCD 31DB xor bx, bx 13 <1> 0 00000FCF 31C0 xor ax,ax 0 00000FD1 50 push ax 0 00000FD2 9D popf 0 00000FD3 9C pushf 0 00000FD4 58 pop ax 0 00000FD5 2500F0 and ax,0F000h 0 00000FD8 3D00F0 cmp ax,0F000h 0 00000FDB 740E je cpu_8086 22 <1> 0 00000FDD B800F0 mov ax,0F000h 0 00000FE0 50 push ax 0 00000FE1 9D popf 0 00000FE2 9C pushf 0 00000FE3 58 pop ax 0 00000FE4 2500F0 and ax,0F000h 0 00000FE7 7401 jz cpu_286 30 <1> 31 <1> cpu_386: 0 00000FE9 43 inc bx 33 <1> cpu_286: 0 00000FEA 43 inc bx 35 <1> cpu_8086: 0 00000FEB 89D8 mov ax, bx 0 00000FED 5B pop bx 0 00000FEE 9D popf 0 00000FEF 83F802 cmp ax, 2 ; is it a 386? 0 00000FF2 7505 jne Not_386_System ; no: don't mess with flag 0 00000FF4 26C6454401 mov byte [es:di + SYSI_DWMOVE], 1 ;AN003; 1203 Not_386_System: ;AN003; 0 00000FF9 268A4520 MOV AL,[ES:DI + SYSI_NUMIO] 0 00000FFD 36A2[4A09] MOV [ss:DriveNumber],AL ; Save start of installable block drvs 1206 0 00001001 06 push es ;AN020; 0 00001002 57 push di ;AN020; 1209 0 00001003 06 push es 0 00001004 36A1[1908] mov ax, [ss:SingleBufferSize] ;AN020;Temporary Single buffer area 0 00001008 BE[C627] mov si, alloc_init 0 0000100B E81319 call allocate_temporary_block 0 0000100E 8CC0 mov ax, es ; ax => buffer 0 00001010 07 pop es ; es => DOSDATA 1216 0 00001011 36A3[2108] mov word [ss:buffer_block], ax 1218 %ifdef BUF2 0 00001015 26A3[0200] mov word [es:BUFFHEAD + 2], ax 0 00001019 268326[0000]00 and word [es:BUFFHEAD], 0 0 0000101F 8EC0 mov es, ax 0 00001021 31FF xor di, di 0 00001023 26834D02FF or word [es:di + NEXTBUF + 2], -1 0 00001028 26830DFF or word [es:di + NEXTBUF], -1 0 0000102C 26C74504FF00 mov word [es:di + BUFDRV], 00FFh 1226 %else 1227 les di, [es:di + SYSI_BUF] ;AN020;get the buffer hash entry pointer 1228 HASH_PTR equ Hash_ptr ; NASM port equate 1229 les di, [es:di + HASH_PTR] ;AN020; 1230 mov word ptr [es:di + BUFFER_BUCKET],0 ;AN020; 1231 mov word ptr [es:di + BUFFER_BUCKET+2], ax ;AN020; 1232 mov es, ax ;AN020; 1233 xor ax, ax ;AN020; 1234 mov di, ax ;AN020;es:di -> Single buffer 1235 BUF_NEXT equ buf_next ; NASM port equate 1236 mov [es:di + BUF_NEXT], ax ;AN020;points to itself 1237 BUF_PREV equ buf_prev ; NASM port equate 1238 mov [es:di + BUF_PREV], ax ;AN020;points to itself 1239 BUF_ID equ buf_ID ; NASM port equate 1240 mov word ptr [es:di + BUF_ID],00FFh ;AN020;free buffer, clear flag 1241 BUF_SECTOR equ buf_sector ; NASM port equate 1242 mov word ptr [es:di + BUF_SECTOR], ax ;AN020; 1243 mov word ptr [es:di + BUF_SECTOR+2], ax ;AN020; 1244 %endif 0 00001032 5F pop di ;AN020; 0 00001033 07 pop es ;AN020; 1247 0 00001034 1E PUSH DS ; Save as input to RE_INIT 0 00001035 0E PUSH CS 0 00001036 1F POP DS 1251 ASSUME DS:SYSINITSEG 0 00001037 E82904 CALL TEMPCDS ; Set up CDSs so RE_INIT and SYSINIT 1253 ; can make DISK system calls 1254 0 0000103A 1F POP DS ; Recover DS input to RE_INIT 1256 ASSUME DS:NOTHING 1257 1258 %IFN IBMJAPVER 0 0000103B E8[0000] CALL RE_INIT ; Re-call the BIOS 1260 %ENDIF 1261 0 0000103E FB STI ; INTs OK 0 0000103F FC CLD ; MAKE SURE 1264 1265 %if 0 1266 ; DOSINIT has set up a default "process" (PHP) at DS:0. We will move it out 1267 ; of the way by putting it just below SYSINIT at end of memory. 1268 MOV BX,CS 1269 SUB BX,10H 1270 MOV ES,BX 1271 XOR SI,SI 1272 MOV DI,SI 1273 MOV CX,80H 1274 REP MOVSW 1275 MOV WORD PTR [ES:PDB_JFN_Pointer + 2],ES ; Relocate 1276 SET_CURRENT_PDB equ Set_Current_PDB ; NASM port equate 1277 MOV AH,SET_CURRENT_PDB 1278 INT 21H ; Tell DOS we moved it 1279 %endif 1280 0 00001040 0E PUSH CS 0 00001041 1F POP DS 1283 ASSUME DS:SYSINITSEG 0 00001042 BA[0000] MOV DX,OFFSET INT24 ;SET UP INT 24 HANDLER 1285 SET_INTERRUPT_VECTOR equ Set_Interrupt_Vector ; NASM port equate 0 00001045 B82425 MOV AX,(SET_INTERRUPT_VECTOR << 8) | 24H 0 00001048 CD21 INT 21H 1288 1289 %if 0 1290 MOV BX,0FFFFH 1291 ALLOC equ Alloc ; NASM port equate 1292 MOV AH,ALLOC 1293 INT 21H ;FIRST TIME FAILS 1294 MOV AH,ALLOC 1295 INT 21H ;SECOND TIME GETS IT 1296 MOV [AREA],AX 1297 MOV [MEMHI],AX ; MEMHI:MEMLO now points to 1298 ; start of free memory 1299 %endif 1300 %IF ALTVECT 1301 MOV DX,OFFSET BOOTMES 1302 invoke PRINT ;Print message DOSINIT couldn't 1303 %ENDIF 1304 1305 ASSUME DS:NOTHING 1306 0 0000104A 368A16[1408] MOV DL,[ss:DEFAULT_DRIVE] 0 0000104F 08D2 OR DL,DL 0 00001051 7406 JZ NODRVSET ; BIOS didn't say 0 00001053 FECA DEC DL ;A = 0 1311 SET_DEFAULT_DRIVE equ Set_Default_Drive ; NASM port equate 0 00001055 B40E MOV AH,SET_DEFAULT_DRIVE 0 00001057 CD21 INT 21H ;SELECT THE DISK 1314 ;J.K. 2/23/87 Modified to handle INSTALL= command. 1315 NODRVSET: 0 00001059 E8[0000] CALL DOCONF ;DO THE CONFIG STUFF 0 0000105C 2EFE06[6408] inc byte [cs:Multi_Pass_Id] ;AN027; 0 00001061 E8[0000] call Multi_Pass ;AN027; 0 00001064 2EFE06[6408] inc byte [cs:Multi_Pass_Id] ;AN024; 0 00001069 E8[0000] call Multi_Pass ;AN024; 1321 EndFile equ ENDFILE ; NASM port label 0 0000106C E88004 call EndFile 0 0000106F 36F706[6608]0100 test word [ss:Install_Flag], HAVE_INSTALL_CMD ;AN019; 0 00001076 7408 jz DoLast ;AN019; 0 00001078 2EFE06[6408] inc byte [cs:Multi_Pass_Id] ;AN024; 0 0000107D E8[0000] call Multi_Pass ;AN019;AN024; Execute INSTALL= commands 1327 1328 ;J.K. [AREA] has the segment address for the allocated memory of SYSINIT,CONFBOT. 1329 ;Free the CONFBOT area used for CONFIG.SYS and SYSINIT itself. 1330 DoLast: 1331 0 00001080 31C9 xor cx, cx 0 00001082 2E870E[1F08] xchg cx, word [cs:config_block] 0 00001087 E306 jcxz @F 0 00001089 8EC1 mov es, cx 0 0000108B B449 mov ah, 49h 0 0000108D CD21 int 21h 1338 @@: 1339 0 0000108F B8FFFF mov ax, -1 0 00001092 E88610 call init2_relocate_device 0 00001095 B8FFFF mov ax, -1 0 00001098 E83B16 call init2_relocate_end 1344 1345 extern dosdata_to_doscode 1346 1347 1348 relocate_upb_late: 0 0000109B E8[0000] call sysinit_get_ds_dosentry 0 0000109E 31F6 xor si, si 0 000010A0 8A2E[0000] mov ch, [DRVMAX] ; ch = how many UPBs 0 000010A4 C43E[0000] les di, [START_BDS] ; es:di -> first UPB 0 000010A8 83FFFF cmp di, -1 ; none ? 0 000010AB 7503E90C01 je .warn ; then skip --> 0 000010B0 84ED test ch, ch 0 000010B2 7503E90501 jz .warn 1357 ; Harden: Expect UPBs at start of memory block. 0 000010B7 85FF test di, di 0 000010B9 7403E9FE00 jnz .warn 0 000010BE 8CC0 mov ax, es 0 000010C0 48 dec ax 0 000010C1 8ED8 mov ds, ax 0 000010C3 837C0108 cmp word [si + mcbOwner], 8 ; an S MCB ? 0 000010C7 7403E9F000 jne .warn 0 000010CC 837C0853 cmp word [si + mcbName], "S" ; S MCB ? 0 000010D0 7403E9E700 jne .warn 0 000010D5 807C0A09 cmp byte [si + smcbType], S_UPB ; correct type ? 0 000010D9 7403E9DE00 jne .warn 0 000010DE 8B4403 mov ax, [si + mcbSize] 0 000010E1 B104 mov cl, 4 0 000010E3 D3E0 shl ax, cl ; = size in bytes 0 000010E5 89C3 mov bx, ax 0 000010E7 D3E8 shr ax, cl ; compute paragraphs again 0 000010E9 394403 cmp word [si + mcbSize], ax ; match ? 0 000010EC 7403E9CB00 jne .warn 0 000010F1 B064 mov al, BDS_TYPE_struc_size 0 000010F3 F6E5 mul ch ; ax = how many bytes needed for UPBs 0 000010F5 39C3 cmp bx, ax ; last UPB fits below size ? 0 000010F7 7303E9C000 jb .warn ; no --> 0 000010FC 89C2 mov dx, ax 0 000010FE 83C20F add dx, 15 0 00001101 80E2F0 and dl, ~ 15 0 00001104 39D3 cmp bx, dx 0 00001106 7403E9B100 jne .warn 1385 0 0000110B 88E9 mov cl, ch 0 0000110D 84C9 test cl, cl 0 0000110F 7503E9A800 jz .warn 0 00001114 06 push es 0 00001115 57 push di 1391 .loop: 0 00001116 80F901 cmp cl, 1 0 00001119 741C je .last 0 0000111B 8CC3 mov bx, es 0 0000111D 26395D02 cmp word [es:di + LINK + 2], bx 0 00001121 7403E99400 jne .warn_pop_pop 0 00001126 8D5D64 lea bx, [di + BDS_TYPE_struc_size] 0 00001129 26391D cmp word [es:di + LINK], bx 0 0000112C 7403E98900 jne .warn_pop_pop 0 00001131 49 dec cx ; count down 0 00001132 26C43D les di, [es:di + LINK] 0 00001135 EBDF jmp .loop 1403 1404 .last: 0 00001137 26833DFF cmp word [es:di + LINK], -1 0 0000113B 7408 je @F 0 0000113D 8CC3 mov bx, es 0 0000113F 26395D02 cmp word [es:di + LINK + 2], bx 0 00001143 7477 je .warn 1410 @@: 1411 0 00001145 BE[EE27] mov si, alloc_upb 0 00001148 51 push cx 0 00001149 50 push ax 0 0000114A E8D516 call allocate_relocate_block 0 0000114D 59 pop cx ; = size of initialised UPBs 0 0000114E 5B pop bx ; bh = number of UPBs 0 0000114F 5E pop si 0 00001150 1F pop ds ; -> first UPB source 0 00001151 56 push si 0 00001152 89FA mov dx, di ; es:dx -> destination 0 00001154 F3A4 rep movsb ; copy them over 0 00001156 89D7 mov di, dx ; es:di -> copied UPBs 0 00001158 89D6 mov si, dx ; es:si -> first UPB in new allocation 0 0000115A 31C9 xor cx, cx 0 0000115C 08F9 or cl, bh ; cx = amount UPBs 0 0000115E 5B pop bx ; ds:bx -> source 0 0000115F 8CDA mov dx, ds 0 00001161 7438 jz .warn_free 1430 .newloop: 0 00001163 49 dec cx 0 00001164 741E jz .newlast 0 00001166 26395502 cmp word [es:di + LINK + 2], dx 0 0000116A 752F jne .warn_free 0 0000116C 8D4764 lea ax, [bx + BDS_TYPE_struc_size] 1436 ; ds:ax -> next expected source UPB 0 0000116F 263905 cmp word [es:di + LINK], ax 0 00001172 7527 jne .warn_free 0 00001174 93 xchg bx, ax ; ds:bx -> next source UPB 1440 ; ! in HMA allocstion the offset is changed 0 00001175 8D4564 lea ax, [di + BDS_TYPE_struc_size] 1442 ; es:di -> next destination 0 00001178 268C4502 mov word [es:di + LINK + 2], es ; relocate next link segment 0 0000117C 268905 mov word [es:di + LINK], ax ; relocate next link offset 0 0000117F 26C43D les di, [es:di + LINK] 0 00001182 EBDF jmp .newloop 1447 1448 .newlast: 1449 ; ! last relocated UPB's next link pointer is left alone 1450 0 00001184 E8[0000] call sysinit_get_ds_dosentry 0 00001187 FA cli 0 00001188 8CC0 mov ax, es 0 0000118A 8936[0000] mov word [START_BDS], si 0 0000118E 8706[0200] xchg word [START_BDS + 2], ax ; relocate the UPBs 0 00001192 FB sti 0 00001193 8EC0 mov es, ax 0 00001195 B449 mov ah, 49h 0 00001197 CD21 int 21h ; free the original allocation 0 00001199 EB30 jmp .done 1461 1462 .warn_free: 0 0000119B 8CC3 mov bx, es 0 0000119D 83FBFE cmp bx, -2 ; HMA ? 0 000011A0 7213 jb @F ; no --> 0 000011A2 7706 ja .warn_free_hma_essi ; it is es == 0FFFFh --> 1467 ; it is es == 0FFFEh 0 000011A4 43 inc bx ; = 0FFFFh 0 000011A5 8EC3 mov es, bx ; es = 0FFFFh 0 000011A7 83EE10 sub si, 16 ; es:si -> HMA allocation 1471 .warn_free_hma_essi: 0 000011AA 89F7 mov di, si 0 000011AC B8034A mov ax, 4A03h 0 000011AF B202 mov dl, 2 0 000011B1 CD2F int 2Fh ; free new HMA allocation 0 000011B3 EB07 jmp .warn 1477 1478 @@: 0 000011B5 B449 mov ah, 49h 0 000011B7 CD21 int 21h ; free new LMA/UMA allocation 0 000011B9 A9 db __TEST_IMM16 ; skip twice pop 1482 .warn_pop_pop: 0 000011BA 58 pop ax 0 000011BB 58 pop ax 1485 .warn: 0 000011BC 0E push cs 0 000011BD 1F pop ds 0 000011BE BA[CE29] mov dx, sysinit_msg.warn_upb 0 000011C1 B92800 mov cx, sysinit_msg.warn_upb.size 0 000011C4 BB0100 mov bx, 1 0 000011C7 B440 mov ah, 40h 0 000011C9 CD21 int 21h 1493 .done: 1494 1495 1496 relocate_dpb_late: 0 000011CB E8[0000] call sysinit_getdosdata 0 000011CE 8ED8 mov ds, ax 0 000011D0 31F6 xor si, si 0 000011D2 8A2E[0000] mov ch, [NUMIO] ; ch = how many DPBs at most 0 000011D6 C43E[0000] les di, [DPBHEAD] ; es:di -> first DPB 0 000011DA 83FFFF cmp di, -1 ; none ? 0 000011DD 7503E98401 je .warn ; then skip --> 0 000011E2 84ED test ch, ch 0 000011E4 7503E97D01 jz .warn 1506 ; Harden: Expect DPBs at start of memory block. 0 000011E9 85FF test di, di 0 000011EB 7403E97601 jnz .warn 0 000011F0 8CC0 mov ax, es 0 000011F2 48 dec ax 0 000011F3 8ED8 mov ds, ax 1512 ; We expect at least two DOS-internal DPBs. 1513 ; Although we do somewhat work if none are 1514 ; used, we can warn here anyway. 0 000011F5 837C0108 cmp word [si + mcbOwner], 8 ; an S MCB ? 0 000011F9 7403E96801 jne .warn 0 000011FE 837C0853 cmp word [si + mcbName], "S" ; S MCB ? 0 00001202 7403E95F01 jne .warn 0 00001207 807C0A08 cmp byte [si + smcbType], S_DPB ; correct type ? 0 0000120B 7403E95601 jne .warn 0 00001210 8B4403 mov ax, [si + mcbSize] 0 00001213 89C2 mov dx, ax 0 00001215 B104 mov cl, 4 0 00001217 D3E0 shl ax, cl ; = size in bytes 0 00001219 D3E8 shr ax, cl ; compute paragraphs again 0 0000121B 394403 cmp word [si + mcbSize], ax ; match ? 0 0000121E 7403E94301 jne .warn 1528 0 00001223 88E9 mov cl, ch 0 00001225 84C9 test cl, cl 0 00001227 7503E93A01 jz .warn 0 0000122C B500 mov ch, 0 0 0000122E 06 push es 0 0000122F 57 push di 1535 .loop: 0 00001230 FEC5 inc ch 0 00001232 80F901 cmp cl, 1 0 00001235 7418 je .last 0 00001237 8CC3 mov bx, es 0 00001239 26395D1B cmp word [es:di + dpb_next_dpb + 2], bx 0 0000123D 7522 jne .havelast_pop_pop 0 0000123F 8D5D21 lea bx, [di + dpb_struc_size] 0 00001242 26395D19 cmp word [es:di + dpb_next_dpb], bx 0 00001246 7519 jne .havelast_pop_pop 0 00001248 49 dec cx ; count down 0 00001249 26C47D19 les di, [es:di + dpb_next_dpb] 0 0000124D EBE1 jmp .loop 1548 1549 .last: 0 0000124F 26837D19FF cmp word [es:di + dpb_next_dpb], -1 0 00001254 740B je @F 0 00001256 8CC3 mov bx, es 0 00001258 26395D19 cmp word [es:di + dpb_next_dpb], bx 0 0000125C 7503E90301 je .warn_pop_pop 1555 @@: 1556 .havelast_pop_pop: 0 00001261 8D4521 lea ax, [di + dpb_struc_size] 0 00001264 50 push ax 0 00001265 E81206 call ParaRound 0 00001268 39D0 cmp ax, dx ; MCB size matches ? 0 0000126A 58 pop ax 0 0000126B 7403E9F400 jne .warn_pop_pop 1563 0 00001270 BE[0228] mov si, alloc_dpb 0 00001273 51 push cx 0 00001274 50 push ax 0 00001275 E8AA15 call allocate_relocate_block 0 00001278 59 pop cx ; = size of relocateable DPBs 0 00001279 5B pop bx ; bh = number of relocateable DPBs 0 0000127A 5E pop si 0 0000127B 1F pop ds ; -> first DPB source 0 0000127C 56 push si 0 0000127D 89FA mov dx, di ; es:dx -> destination 0 0000127F F3A4 rep movsb ; copy them over 0 00001281 89D7 mov di, dx ; es:di -> copied DPBs 0 00001283 89D6 mov si, dx ; es:si -> first DPB in new allocation 0 00001285 31C9 xor cx, cx 0 00001287 08F9 or cl, bh ; cl = amount relocated DPBs 0 00001289 5B pop bx ; ds:bx -> source 0 0000128A 89DD mov bp, bx ; dx:bp -> first source DPB 0 0000128C 88CD mov ch, cl ; ch = amount relocated DPBs 0 0000128E 8CDA mov dx, ds 0 00001290 7503E9B000 jz .warn_free 1584 .newloop: 0 00001295 FEC9 dec cl 0 00001297 7427 jz .newlast 0 00001299 2639551B cmp word [es:di + dpb_next_dpb + 2], dx 0 0000129D 7403E9A300 jne .warn_free 0 000012A2 8D4721 lea ax, [bx + dpb_struc_size] 1590 ; ds:ax -> next expected source UPB 0 000012A5 26394519 cmp word [es:di + dpb_next_dpb], ax 0 000012A9 7403E99700 jne .warn_free 0 000012AE 93 xchg bx, ax ; ds:bx -> next source UPB 1594 ; ! in HMA allocstion the offset is changed 0 000012AF 8D4521 lea ax, [di + dpb_struc_size] 1596 ; es:di -> next destination 0 000012B2 268C451B mov word [es:di + dpb_next_dpb + 2], es ; relocate next link segment 0 000012B6 26894519 mov word [es:di + dpb_next_dpb], ax ; relocate next link offset 0 000012BA 26C47D19 les di, [es:di + dpb_next_dpb] 0 000012BE EBD5 jmp .newloop 1601 1602 .newlast: 1603 ; ! last relocated DPB's next link pointer is left alone 1604 1605 ; now we have to relocate all references to the DPBs. 1606 ; there's buffers, CDSes, SFTs, and FCB SFTs. 1607 ; INP: dx:bp -> first relocated DPB source 1608 ; ch = amount 1609 ; es:si -> first destination DPB 0 000012C0 06 push es 0 000012C1 56 push si 0 000012C2 88E9 mov cl, ch 0 000012C4 B500 mov ch, 0 1614 1615 extern BUFFHEAD, CDSADDR, CDSCOUNT, sft_addr, sftFCB 1616 1617 .relocloop: 0 000012C6 51 push cx 1619 1620 %ifndef BUF2 1621 %fatal DPB reloc not done for non-BUF2 1622 %endif 1623 0 000012C7 E8[0000] call sysinit_getdosdata 0 000012CA 8ED8 mov ds, ax 0 000012CC C53E[0000] lds di, [BUFFHEAD] 1627 @@: 0 000012D0 83FFFF cmp di, -1 0 000012D3 7410 je @FF 0 000012D5 807D04FF cmp byte [di + BUFDRV], -1 0 000012D9 7406 je @F 0 000012DB BB0C00 mov bx, BUFDRVDP 0 000012DE E83201 call relocate_dibx_dpb_from_dxbp_to_essi 1634 @@: 0 000012E1 C53D lds di, [di + NEXTBUF] 0 000012E3 EBEB jmp @BB 1637 1638 @@: 1639 0 000012E5 E8[0000] call sysinit_getdosdata 0 000012E8 8ED8 mov ds, ax 0 000012EA 8A0E[0000] mov cl, byte [CDSCOUNT] ; ch already 0 0 000012EE C53E[0000] lds di, [CDSADDR] 1644 @@: 0 000012F2 F6454480 testopt [di + curdir_flags], curdir_isnet 1646 ; net or IFS ? 0 000012F6 7506 jnz @F ; yes, don't check --> 0 000012F8 BB4500 mov bx, curdir_devptr 0 000012FB E81501 call relocate_dibx_dpb_from_dxbp_to_essi 1650 @@: 0 000012FE 83C758 add di, curdir_list_struc_size 0 00001301 E2EF loop @BB 1653 0 00001303 E8[0000] call sysinit_getdosdata 0 00001306 8ED8 mov ds, ax 0 00001308 C53E[0000] lds di, [sft_addr] 0 0000130C E81501 call reloc_dpb_in_sftc 1658 0 0000130F E8[0000] call sysinit_getdosdata 0 00001312 8ED8 mov ds, ax 0 00001314 C53E[0000] lds di, [sftFCB] 0 00001318 E80901 call reloc_dpb_in_sftc 1663 1664 .relocnext: 0 0000131B 59 pop cx 0 0000131C 26C47419 les si, [es:si + dpb_next_dpb] 0 00001320 8EDA mov ds, dx 0 00001322 3EC56E19 lds bp, [ds:bp + dpb_next_dpb] 0 00001326 8CDA mov dx, ds 0 00001328 E29C loop .relocloop 1671 0 0000132A 5E pop si 0 0000132B 07 pop es 1674 0 0000132C E8[0000] call sysinit_getdosdata 0 0000132F 8ED8 mov ds, ax 0 00001331 FA cli 0 00001332 8CC0 mov ax, es 0 00001334 8936[0000] mov word [DPBHEAD], si 0 00001338 8706[0200] xchg word [DPBHEAD + 2], ax ; relocate the DPBs 0 0000133C FB sti 0 0000133D 8EC0 mov es, ax 0 0000133F B449 mov ah, 49h 0 00001341 CD21 int 21h ; free the original allocation 0 00001343 EB30 jmp .done 1686 1687 .warn_free: 0 00001345 8CC3 mov bx, es 0 00001347 83FBFE cmp bx, -2 ; HMA ? 0 0000134A 7213 jb @F ; no --> 0 0000134C 7706 ja .warn_free_hma_essi ; it is es == 0FFFFh --> 1692 ; it is es == 0FFFEh 0 0000134E 43 inc bx ; = 0FFFFh 0 0000134F 8EC3 mov es, bx ; es = 0FFFFh 0 00001351 83EE10 sub si, 16 ; es:si -> HMA allocation 1696 .warn_free_hma_essi: 0 00001354 89F7 mov di, si 0 00001356 B8034A mov ax, 4A03h 0 00001359 B202 mov dl, 2 0 0000135B CD2F int 2Fh ; free new HMA allocation 0 0000135D EB07 jmp .warn 1702 1703 @@: 0 0000135F B449 mov ah, 49h 0 00001361 CD21 int 21h ; free new LMA/UMA allocation 0 00001363 A9 db __TEST_IMM16 ; skip twice pop 1707 .warn_pop_pop: 0 00001364 58 pop ax 0 00001365 58 pop ax 1710 .warn: 0 00001366 0E push cs 0 00001367 1F pop ds 0 00001368 BA[F629] mov dx, sysinit_msg.warn_dpb 0 0000136B B92800 mov cx, sysinit_msg.warn_dpb.size 0 0000136E BB0100 mov bx, 1 0 00001371 B440 mov ah, 40h 0 00001373 CD21 int 21h 1718 .done: 1719 1720 0 00001375 0E push cs 0 00001376 1F pop ds 0 00001377 0E push cs 0 00001378 07 pop es 1725 0 00001379 E83609 call LoadShare ;AN021; Try to load share.exe, if needed. 0 0000137C 2EC606[2309]01 mov byte [cs:DoNotShowNum], 1 ;AN000; Done with CONFIG.SYS. Do not show line number message. 1728 %if 0 1729 mov cx, [ss:area] ;AN000; 1730 mov es, cx ;AN000; 1731 mov ah, 49h ;AN000; Free allocated memory for command.com 1732 int 21h ;AN000; 1733 1734 Install_flag equ Install_Flag ; NASM port label 1735 test word [cs:Install_flag], HAS_INSTALLED ;AN013; SYSINIT_BASE installed? 1736 jz Skip_Free_SYSINITBASE ;AN013; No. 1737 ;Set Block from the Old_Area with Impossible_Owner_size. 1738 ;This will free the unnecessary SYSINIT_BASE that had been put in memory to 1739 ;handle INSTALL= command. 1740 push es ;AN013; 1741 push bx ;AN013; 1742 mov ax, [cs:Old_Area] ;AN013; 1743 mov es, ax ;AN013; 1744 mov bx, [cs:Impossible_Owner_Size] ;AN013; 1745 SETBLOCK equ Setblock ; NASM port equate 1746 mov ah, SETBLOCK ;AN013; 1747 int 21h ;AN013; 1748 MOV AX,ES ;AN013; 1749 DEC AX ;AN013; 1750 MOV ES,AX ;Point to arena 1751 MOV word [ES:arena_owner],8 ;Set impossible owner 1752 mov word ptr [es:arena_name], "SD" ; set SD name ; NASM port swapped text literals 1753 and word ptr [es:arena_name + 2], 0 ; NUL 1754 pop bx ;AN013; 1755 pop es ;AN013; 1756 Skip_Free_SYSINITBASE: ;AN013; 1757 %endif 1758 %IF NOEXEC 1759 MOV BP,DS ;SAVE COMMAND.COM SEGMENT 1760 PUSH DS 1761 POP ES 1762 MOV BX,CS 1763 SUB BX,10H ; Point to current PHP 1764 MOV DS,BX 1765 XOR SI,SI 1766 MOV DI,SI 1767 MOV CX,80H 1768 REP MOVSW ; Copy it to new location for shell 1769 MOV WORD PTR [ES:PDB_JFN_Pointer + 2],ES ; Relocate 1770 MOV BX,ES 1771 MOV AH,SET_CURRENT_PDB 1772 INT 21H ; Tell DOS we moved it 1773 PDB_PARENT_PID equ PDB_Parent_PID ; NASM port equate 1774 MOV [ES:PDB_PARENT_PID],ES ;WE ARE THE ROOT 1775 %ENDIF 1776 0 00001382 0E PUSH CS 0 00001383 1F POP DS 1779 ASSUME DS:SYSINITSEG 1780 ; 1781 ; SET UP THE PARAMETERS FOR COMMAND 1782 ; 1783 0 00001384 BE[2608] MOV SI,OFFSET COMMAND_LINE+1 1785 1786 %IF NOEXEC 1787 MOV DI,81H 1788 %ELSE 0 00001387 1E PUSH DS 0 00001388 07 POP ES 0 00001389 89F7 MOV DI,SI 1792 %ENDIF 1793 0 0000138B B1FF MOV CL,-1 1795 COMTRANLP: ;FIND LENGTH OF COMMAND LINE 0 0000138D FEC1 INC CL 0 0000138F AC LODSB 0 00001390 AA STOSB ;COPY COMMAND LINE IN 0 00001391 08C0 OR AL,AL 0 00001393 75F8 JNZ COMTRANLP 0 00001395 4F DEC DI 0 00001396 B00D MOV AL,CR ; CR terminate 0 00001398 AA STOSB 1804 1805 %IF NOEXEC 1806 MOV [ES:80H],CL ; Set up header 1807 MOV AL,[DEFAULT_DRIVE] 1808 MOV [ES:5CH],AL 1809 %ELSE 0 00001399 880E[2508] MOV [COMMAND_LINE],CL ;Count 1811 %ENDIF 1812 0 0000139D BA[0000] MOV DX,OFFSET COMMND ;NOW POINTING TO FILE DESCRIPTION 1814 1815 %IF NOEXEC 1816 MOV ES,BP ;SET LOAD ADDRESS 1817 MOV BX,100H 1818 CALL LDFIL ;READ IN COMMAND 1819 JC COMERR 1820 MOV DS,BP 1821 MOV DX,80H 1822 SET_DMA equ Set_DMA ; NASM port equate 1823 MOV AH,SET_DMA ;SET DISK TRANFER ADDRESS 1824 INT 21H 1825 CLI 1826 MOV SS,BP 1827 MOV SP,DX 1828 STI 1829 XOR AX,AX ;PUSH A WORD OF ZEROS 1830 PUSH AX 1831 PUSH BP ;SET HIGH PART OF JUMP ADDRESS 1832 MOV AX,100H 1833 PUSH AX ;SET LOW PART OF JUMP ADDRESS 1834 CCC PROC FAR 1835 RET ;CRANK UP COMMAND! 1836 CCC ENDP 1837 1838 %ELSE 1839 ; We are going to open the command interpreter and size it as is done in 1840 ; LDFIL. The reason we must do this is that SYSINIT is in free memory. If 1841 ; there is not enough room for the command interpreter, EXEC will probably 1842 ; overlay our stack and code so when it returns with an error SYSINIT won't be 1843 ; here to catch it. This code is not perfect (for instance .EXE command 1844 ; interpreters are possible) because it does its sizing based on the 1845 ; assumption that the file being loaded is a .COM file. It is close enough to 1846 ; correctness to be usable. 1847 0 000013A0 52 PUSH DX ; Save pointer to name 1849 1850 %if 0 1851 ; First, find out where the command interpreter is going to go. 1852 MOV BX,0FFFFH 1853 MOV AH,ALLOC 1854 INT 21H ;Get biggest piece 1855 MOV AH,ALLOC 1856 INT 21H ;SECOND TIME GETS IT 1857 JC MEMERRJX ; Oooops 1858 MOV ES,AX 1859 DEALLOC equ Dealloc ; NASM port equate 1860 MOV AH,DEALLOC 1861 INT 21H ; Give it right back 1862 MOV BP,BX 1863 ; ES:0 points to Block, and BP is the size of the block 1864 ; in para. 1865 1866 ; We will now adjust the size in BP DOWN by the size of SYSINIT. We 1867 ; need to do this because EXEC might get upset if some of the EXEC 1868 ; data in SYSINIT is overlayed during the EXEC. 1869 MOV BX,[MEMORY_SIZE] 1870 MOV AX,CS 1871 SUB BX,AX ; BX is size of SYSINIT in Para 1872 inc bx ; for SYSINIT S MCB 1873 SUB BP,BX ; BAIS down 1874 JC MEMERRJX ; No Way. 1875 1876 MOV AX,(OPEN << 8) ;OPEN THE FILE being EXECED 1877 STC ;IN CASE OF INT 24 1878 INT 21H 1879 JC COMERR ; Ooops 1880 MOV BX,AX ;Handle in BX 1881 XOR CX,CX 1882 XOR DX,DX 1883 MOV AX,(LSEEK << 8) | 2 1884 STC ;IN CASE OF INT 24 1885 INT 21H ; Get file size in DX:AX 1886 JC COMERR 1887 ; Convert size in DX:AX to para in AX 1888 ADD AX,15 ; Round up size for conversion to para 1889 ADC DX,0 1890 MOV CL,4 1891 SHR AX,CL 1892 MOV CL,12 1893 SHL DX,CL ; Low nibble of DX to high nibble 1894 OR AX,DX ; AX is now # of para for file 1895 ADD AX,10H ; 100H byte PHP 1896 CMP AX,BP ; Will it fit? 1897 JB OKLD ; Jump if yes. 1898 %else 0 000013A1 EB03 jmp OKLD 1900 %endif 1901 1902 MEMERRJX: 0 000013A3 E9[0000] JMP MEM_ERR 1904 1905 OKLD: 1906 %if 0 1907 MOV AH,CLOSE 1908 INT 21H ; Close file 1909 %endif 1910 OPEN equ Open ; NASM port equate 1911 LSEEK equ LSeek ; NASM port equate 1912 CLOSE equ Close ; NASM port equate 0 000013A6 5A POP DX ; Recover pointer to name 1914 1915 extern backdoor_free_mcb_exec 0 000013A7 BB[D009] mov bx, initpspmcb 0 000013AA 2EC6075A mov byte [cs:bx + mcbSignature], 'Z' 1918 ; pretend we are a valid process MCB 0 000013AE B104 mov cl, 4 0 000013B0 D3EB shr bx, cl ; segment displacement 0 000013B2 43 inc bx ; pretend PSP 0 000013B3 E8[0000] call sysinit_getdosdata 0 000013B6 8EC0 mov es, ax 0 000013B8 8CC8 mov ax, cs 0 000013BA 01D8 add ax, bx ; => our pseudo INIT PSP 0 000013BC 26A3[0000] mov word [es:backdoor_free_mcb_exec], ax 1927 ; enter owner for the backdoor free 0 000013C0 8CCB mov bx, cs 0 000013C2 4B dec bx 0 000013C3 8EC3 mov es, bx 0 000013C5 26A30100 mov word [es:mcbOwner], ax ; owned by backdoor owner 1932 1933 INITSTACKSIZE equ fromparas(paras(160)) 0 000013C9 1E push ds 0 000013CA 52 push dx 0 000013CB B8A000 mov ax, INITSTACKSIZE 0 000013CE BE[0C28] mov si, alloc_initstack 0 000013D1 E84E14 call allocate_relocate_block 0 000013D4 81C7A000 add di, INITSTACKSIZE 0 000013D8 5A pop dx 0 000013D9 1F pop ds 0 000013DA 8CC0 mov ax, es ; use this as a stack if exec returns 0 000013DC FA cli 0 000013DD 8ED0 mov ss, ax 0 000013DF 89FC mov sp, di ; -> stack 0 000013E1 FB sti 1947 0 000013E2 0E PUSH CS 0 000013E3 07 POP ES 1950 ASSUME ES:SYSINITSEG 0 000013E4 BB[5608] MOV BX,OFFSET COMEXE ; Point to EXEC block 0 000013E7 2E8326000000 and word [cs:0], 0 1953 ;AN000; Make a null environment segment 1954 ;AN000; by overlap JMP instruction of SYSINITSEG. 0 000013ED 8C0F mov [bx + EXEC0_ENVIRON],cs ;AN000; Set the environment seg. 1956 EXEC0_COM_LINE equ Exec0_com_line ; NASM port equate 0 000013EF 8C4F04 MOV WORD PTR [BX + EXEC0_COM_LINE+2],CS ; Set segments 1958 EXEC0_5C_FCB equ Exec0_5C_FCB ; NASM port equate 0 000013F2 8C4F08 MOV WORD PTR [BX + EXEC0_5C_FCB+2],CS 1960 EXEC0_6C_FCB equ Exec0_6C_FCB ; NASM port equate 0 000013F5 8C4F0C MOV WORD PTR [BX + EXEC0_6C_FCB+2],CS 1962 EXEC equ Exec ; NASM port equate 0 000013F8 B8004B mov ax, EXEC << 8 ; Load and go 0 000013FB 2ED006[0000] rol byte [cs:shellhighflag], 1 0 00001400 D0D8 rcr al, 1 ; al = 80h if shellhigh= 0 00001402 F9 STC ;IN CASE OF INT 24 0 00001403 EA[A004][0000] jmp DOSENTRY - DOSENTRYADJUSTSEGMENT : run_int21_shell + DOSENTRYADJUSTOFFSET 1969 extern run_int21_shell ;GO START UP COMMAND 1970 %ENDIF 1971 ; NOTE FALL THROUGH IF EXEC RETURNS (an error) 1972 1973 COMERR: 0 00001408 BA[0000] MOV DX,OFFSET BADCOM ;WANT TO PRINT COMMAND ERROR 0 0000140B E8[0000] INVOKE BADFIL 1976 STALL: 0 0000140E CC int3 0 0000140F FB sti 0 00001410 F4 hlt 0 00001411 EBFB JMP STALL 1981 1982 1983 relocate_dibx_dpb_from_dxbp_to_essi: 0 00001413 3929 cmp word [di + bx], bp 0 00001415 750C jne .ret 0 00001417 395102 cmp word [di + bx + 2], dx 0 0000141A 7507 jne .ret ; match ? 0 0000141C FA cli 0 0000141D 8931 mov word [di + bx], si 0 0000141F 8C4102 mov word [di + bx + 2], es 0 00001422 FB sti ; yes, relocate 1992 .ret: 0 00001423 C3 retn 1994 1995 1996 reloc_dpb_in_sftc: 1997 .loop_sftc: 0 00001424 83FFFF cmp di, -1 0 00001427 7425 je .done 0 00001429 57 push di 0 0000142A 8B4D04 mov cx, [di + SFCount] 0 0000142D E31A jcxz .next_sftc 0 0000142F 83C706 add di, SFTable 2004 .loop_entry: 0 00001432 833D00 cmp word [di + sf_ref_count], 0 0 00001435 740D je @F 0 00001437 F745058080 testopt [di + sf_flags], sf_isnet | devid_device 2007 ****************** warning: Macro generated word access [-w+user] 2008 ; net or device ? 0 0000143C 7506 jnz @F ; yes, don't check --> 0 0000143E BB0700 mov bx, sf_devptr 0 00001441 E8CFFF call relocate_dibx_dpb_from_dxbp_to_essi 2012 @@: 0 00001444 83C73B add di, sf_entry_struc_size 0 00001447 E2E9 loop .loop_entry 2015 .next_sftc: 0 00001449 5F pop di 0 0000144A C53D lds di, [di + SFLink] 0 0000144C EBD6 jmp .loop_sftc 2019 2020 .done: 0 0000144E C3 retn 2022 2023 2024 free_temp_cds: 0 0000144F 31C0 xor ax, ax 0 00001451 2E8706[F009] xchg ax, word [cs:tempcds_block] 0 00001456 85C0 test ax, ax 0 00001458 7408 jz @F 0 0000145A 06 push es 0 0000145B 8EC0 mov es, ax 0 0000145D B449 mov ah, 49h 0 0000145F CD21 int 21h 0 00001461 07 pop es 2034 @@: 0 00001462 C3 retn 2036 2037 2038 PUBLIC TEMPCDS 2039 TEMPCDS: 2040 ASSUME DS:SYSINITSEG 0 00001463 E8E9FF call free_temp_cds 2042 0 00001466 C43E[F607] LES DI,[DOSINFO] 2044 0 0000146A 268A4D20 MOV CL,BYTE PTR [ES:DI + SYSI_NUMIO] 0 0000146E 30ED XOR CH,CH 0 00001470 26884D21 MOV [ES:DI + SYSI_NCDS],CL 0 00001474 B058 mov al, curdir_list_struc_size 0 00001476 F6E1 mul cl 2050 0 00001478 51 push cx 0 00001479 06 push es 0 0000147A 57 push di 0 0000147B BE[D027] mov si, alloc_initcds 0 0000147E E8A014 call allocate_temporary_block 0 00001481 2E8C06[F009] mov word [cs:tempcds_block], es ; => temp CDS 0 00001486 5E pop si 0 00001487 1F pop ds ; -> DOSINFO 0 00001488 59 pop cx 2060 0 00001489 8C4418 MOV WORD PTR [si + SYSI_CDS + 2], es 0 0000148C 217C16 and WORD PTR [si + SYSI_CDS], di 2063 ; -> temp CDS 0 0000148F C534 LDS SI,[si + SYSI_DPB] ; -> first DPB 2065 ASSUME DS:NOTHING 2066 2067 FOOSET: ; Init CDSs 0 00001491 36A1[2308] MOV AX,WORD PTR [ss:FOOSTRNG] 0 00001495 AB STOSW 0 00001496 B85C00 MOV AX, "\" ; constant 0 00001499 AB STOSW 0 0000149A 36FE06[2308] INC BYTE PTR [ss:FOOSTRNG] 0 0000149F 31C0 XOR AX,AX 0 000014A1 51 PUSH CX 0 000014A2 B93F00 MOV CX,curdir_flags - 4 0 000014A5 F3AA REP STOSB 0 000014A7 83FEFF CMP SI,-1 2078 ; JNZ NORMCDS 2079 ;J.K. 6/24/87 Should handle the system that does not have any floppies. 2080 ;J.K. In this case, we are going to pretended there are two dummy floppies 2081 ;J.K. in the system. Still they have DPB and CDS, but we are going to 2082 ;J.K. 0 out Curdir_Flags, Curdir_devptr of CDS so IBMDOS can issue 2083 ;J.K. "Invalid drive specification" message when the user try to 2084 ;J.K. access them. 0 000014AA 7410 je Fooset_Zero ;AN001;Don't have any physical drive. 2086 ;SB34SYSINIT1003************************************************************* 2087 ;SB Check to see if we are faking floppy drives. If not go to NORMCDS. 2088 ;SB If we are faking floppy drives then see if this CDS being initialised 2089 ;SB is for drive a: or b: by checking the appropriate field in the DPB 2090 ;SB pointed to by ds:si. If not for a: or b: then go to NORMCDS. If 2091 ;Sb for a: or b: then execute the code given below starting at Fooset_Zero. 2092 ;SB For dpb offsets look at inc\dpb.inc. 2093 ;SB 5 LOCS 2094 0 000014AC 2E803E[0808]01 cmp byte [cs:Fake_Floppy_Drv],1 ;fake drive ? 0 000014B2 750F jnz NORMCDS 0 000014B4 803C02 cmp byte [si + dpb_drive],02 ;check for a: or b: 0 000014B7 730A jae NORMCDS 0 000014B9 C57419 LDS SI,[SI + dpb_next_dpb] 2100 2101 ;SB34SYSINIT1003************************************************************* 2102 Fooset_Zero: ;AN001; 2103 ; ax still zero 0 000014BC B103 MOV CL,3 0 000014BE F3AB REP STOSW 0 000014C0 59 POP CX 0 000014C1 EB13 JMP SHORT FINCDS 2108 NORMCDS: 0 000014C3 59 POP CX 2110 ;J.K. If a non-fat based media is detected (by DPB.NumberOfFat == 0), then 2111 ; set curdir_flags to 0. This is for signaling IBMDOS and IFSfunc that 2112 ; this media is a non-fat based one. 0 000014C4 807C0800 cmp byte [SI + dpb_FAT_count], 0 ;AN000; Non fat system? 0 000014C8 7402 je SetNormCDS ;AN000; Yes. Set curdir_Flags to 0. AX = 0 now. 2115 CURDIR_INUSE equ curdir_inuse ; NASM port equate 0 000014CA B440 MOV ah, CURDIR_INUSE >> 8 ;AN000; else, FAT system. set the flag to CURDIR_INUSE. 2117 SetNormCDS: ;AN000; 0 000014CC AB STOSW ; curdir_flags 0 000014CD 89F0 MOV AX,SI 0 000014CF AB STOSW ; curdir_devptr 0 000014D0 8CD8 MOV AX,DS 0 000014D2 AB STOSW 0 000014D3 C57419 LDS SI,[SI + dpb_next_dpb] 2124 FINCDS: 0 000014D6 B8FFFF MOV AX,-1 0 000014D9 AB STOSW ; curdir_ID 0 000014DA AB STOSW ; curdir_ID 0 000014DB AB STOSW ; curdir_user_word 0 000014DC B80200 mov ax,2 0 000014DF AB stosw ; curdir_end 0 000014E0 31C0 xor ax, ax ;AN000;Clear out 7 bytes (curdir_type, 0 000014E2 AB stosw ;AN000; curdir_ifs_hdr, curdir_fsda) 0 000014E3 AB stosw ;AN000; 0 000014E4 AB stosw ;AN000; 0 000014E5 AA stosb ;AN000; 0 000014E6 E2A9 LOOP FOOSET 0 000014E8 36C606[2308]41 MOV BYTE PTR [ss:FOOSTRNG],"A" 0 000014EE C3 return 2139 2140 ;------------------------------------------------------------------------------ 2141 ; Allocate FILEs 2142 ;------------------------------------------------------------------------------ 2143 ENDFILE: 2144 ; WE ARE NOW SETTING UP FINAL CDSs, BUFFERS, FILES, FCSs STRINGs etc. We no 2145 ; longer need the space taken by The TEMP stuff below CONFBOT, so set ALLOCLIM 2146 ; to CONFBOT. 2147 2148 ;J.K. 2/23/87 If this procedure has been called to take care of INSTALL= command, 2149 ;then we have to save ES,SI registers. 2150 2151 ; test [Install_Flag],IS_INSTALL ;AN000; Called to handle INSTALL=? 2152 ; jz ENDFILE_Cont ;AN000; 2153 ; push es ;AN000; Save es,si for CONFIG.SYS 2154 ; push si ;AN000; 2155 ; test [Install_Flag],HAS_INSTALLED ;AN000; Sysinit_base already installed? 2156 ; jz ENDFILE_Cont ;AN000; No. Install it. 2157 ; jmp DO_Install_EXEC ;AN000; Just handle "INSTALL=" cmd only. 2158 ;ENDFILE_Cont: ;AN000; 2159 0 000014EF 1E push ds ;AN002; 0 000014F0 B8[0000] mov ax, DOSENTRY ;AN002; 0 000014F3 8ED8 mov ds, ax ;AN002; 2163 assume ds:DOSENTRY 0 000014F5 833E[0000]00 cmp word [MulTrk_flag], MULTRK_OFF1 ;AN002;=0, MULTRACK= command entered? 0 000014FA 7506 jne MulTrk_Flag_Done ;AN002; 0 000014FC 810E[0000]8000 or word [MulTrk_flag], MULTRK_ON ;AN002; Default will be ON. 2167 MulTrk_Flag_Done: ;AN002; 0 00001502 1F pop ds ;AN002; 2169 assume ds:nothing 2170 2171 do_sft: 0 00001503 31C0 xor ax, ax 0 00001505 36A0[1B08] MOV AL,[ss:FILES] 0 00001509 2C05 SUB AL,5 0 0000150B 7623 JBE DOFCBS 0 0000150D 50 push ax 2177 SF_ENTRY_struc_size equ sf_entry_struc_size ; NASM port equate 0 0000150E B33B MOV BL,SF_ENTRY_struc_size 0 00001510 F6E3 MUL BL ;AX = NUMBER OF BYTES TO CLEAR 0 00001512 83C006 add ax, 6 0 00001515 BE[9427] mov si, alloc_sft 0 00001518 E80713 call allocate_relocate_block 2183 0 0000151B 36C536[F607] LDS si, [ss:DOSINFO] 0 00001520 C57404 LDS si, [si + SYSI_SFT] 2186 SFLINK equ SFLink ; NASM port equate 0 00001523 893C MOV WORD PTR [si + SFLINK], di 0 00001525 8C4402 MOV WORD PTR [si + SFLINK+2], es ; SET POINTER TO NEW SFT 0 00001528 26830DFF or WORD PTR [ES:DI + SFLINK], -1 2190 SFCOUNT equ SFCount ; NASM port equate 0 0000152C 268F4504 pop word [ES:DI + SFCOUNT] 2192 2193 ;------------------------------------------------------------------------------ 2194 ; Allocate FCBs 2195 ;------------------------------------------------------------------------------ 2196 DOFCBS: 0 00001530 31C0 xor ax, ax 0 00001532 36A0[1C08] MOV AL,[ss:FCBS] 0 00001536 50 push ax 0 00001537 B33B MOV BL,SF_ENTRY_struc_size 0 00001539 F6E3 MUL BL ;AX = NUMBER OF BYTES TO CLEAR 0 0000153B 83C006 add ax, 6 0 0000153E BE[9E27] mov si, alloc_fcb 0 00001541 E8DE12 call allocate_relocate_block 2205 0 00001544 36C536[F607] LDS si, [ss:DOSINFO] 2207 0 00001549 897C1A MOV WORD PTR [si + SYSI_FCB], di 0 0000154C 8C441C MOV WORD PTR [si + SYSI_FCB+2], es ; SET POINTER TO NEW Table 0 0000154F 31DB xor bx, bx 0 00001551 2E8A1E[1D08] MOV BL,[CS:Keep] 2212 SYSI_keep equ SYSI_Keep ; NASM port equate 0 00001556 895C1E MOV [si + SYSI_keep],BX 0 00001559 0E PUSH CS 0 0000155A 1F POP DS 2216 ASSUME DS:SYSINITSEG 0 0000155B 26830DFF or WORD PTR [ES:DI + SFLINK], -1 0 0000155F 59 pop cx 0 00001560 26894D04 mov word [ES:DI + SFCOUNT], cx 2220 2221 sf_struc_size equ SF_struc_size ; NASM port equate 0 00001564 83C706 add di, sf_struc_size-2 ; es:di -> SFT entries 2223 0 00001567 B041 MOV AL,"A" 2225 FillLoop: 0 00001569 51 PUSH CX ; save count 0 0000156A B93B00 MOV CX,sf_entry_struc_size ; number of bytes to fill 0 0000156D FC cld 0 0000156E F3AA REP STOSB ; filled 0 00001570 26894DC5 MOV WORD PTR [ES:DI-(sf_entry_struc_size)+sf_ref_count], cx 0 00001574 26894DDA MOV WORD PTR [ES:DI-(sf_entry_struc_size)+sf_position], cx 0 00001578 26894DDC MOV WORD PTR [ES:DI-(sf_entry_struc_size)+sf_position+2], cx 0 0000157C 59 POP CX 0 0000157D E2EA LOOP FillLoop 2235 2236 ;------------------------------------------------------------------------------ 2237 ; Allocate Buffers 2238 ;------------------------------------------------------------------------------ 2239 2240 ; Search through the list of media supported and allocate 3 buffers if the 2241 ; capacity of the drive is > 360KB 2242 0 0000157F 833E[1508]FF CMP word [BUFFERS], -1 ; Has buffers been already set? 0 00001584 7403 je DoDefaultBuff 2245 %ifndef BUF2 2246 cmp byte [Buffer_Slash_X], 1 ;AN000; 2247 jne DO_Buffer ;AN000; 2248 call DoEMS ;AN000; Carry set if (enough) EMS is not available 2249 jc DoDefaultBuff ;AN000; Error. Just use default buffer. 2250 %endif 2251 DO_Buffer: 0 00001586 E99800 jmp DOBUFF ; the user entered the buffers=. 2253 2254 DoDefaultBuff: 0 00001589 C706[1708]0000 mov word [H_Buffers], 0 ;AN000; Default is no heuristic buffers. 0 0000158F C706[1508]0200 MOV word [BUFFERS], 2 ; Default to 2 buffers 0 00001595 50 PUSH AX 0 00001596 1E PUSH DS 0 00001597 2EC42E[F607] LES BP,[CS:DOSINFO] ; Search through the DPB's 0 0000159C 26C46E00 LES BP,[ES:BP + SYSI_DPB] ; Get first DPB 2261 2262 ASSUME DS:SYSINITSEG 0 000015A0 0E PUSH CS 0 000015A1 1F POP DS 2265 2266 NEXTDPB: 2267 ; Test if the drive supports removeable media 2268 DPB_DRIVE equ dpb_drive ; NASM port equate 0 000015A2 268A5E00 MOV BL, BYTE PTR [ES:BP + DPB_DRIVE] 0 000015A6 FEC3 INC BL 2271 IOCTL equ IOCtl ; NASM port equate 0 000015A8 B80844 MOV AX, (IOCTL << 8) | 8 0 000015AB CD21 INT 21H 2274 2275 ; Ignore fixed disks 0 000015AD 09C0 OR AX, AX ; AX is nonzero if disk is nonremoveable 0 000015AF 7537 JNZ NOSETBUF 2278 2279 ; Get parameters of drive 0 000015B1 31DB XOR BX, BX 0 000015B3 268A5E00 MOV BL, BYTE PTR [ES:BP + DPB_DRIVE] 0 000015B7 FEC3 INC BL 0 000015B9 BA[0000] MOV DX, OFFSET DeviceParameters 0 000015BC B80D44 MOV AX, (IOCTL << 8) | GENERIC_IOCTL 0 000015BF B96008 MOV CX, (RAWIO << 8) | GET_DEVICE_PARAMETERS 0 000015C2 CD21 INT 21H 0 000015C4 7222 JC NOSETBUF ; Get next DPB if driver doesn't support 2288 ; Generic IOCTL 2289 2290 ; Determine capacity of drive 2291 ; Media Capacity = #Sectors * Bytes/Sector 2292 BPB_TotalSectors equ BPB_TOTALSECTORS ; NASM port equate 0 000015C6 8B1E[0F00] MOV BX, WORD PTR [DeviceParameters + DP_BPB + BPB_TotalSectors] 2294 2295 ; To keep the magnitude of the media capacity within a word, 2296 ; scale the sector size 2297 ; (ie. 1 -> 512 bytes, 2 -> 1024 bytes, ...) 2298 BPB_BytesPerSector equ BPB_BYTESPERSECTOR ; NASM port equate 0 000015CA A1[0700] MOV AX, WORD PTR [DeviceParameters + DP_BPB + BPB_BytesPerSector] 0 000015CD 31D2 XOR DX, DX 0 000015CF B90002 MOV CX, 512 0 000015D2 F7F1 DIV CX ; Scale sector size in factor of 2303 ; 512 bytes 2304 0 000015D4 F7E3 MUL BX ; AX = #sectors * size factor 0 000015D6 09D2 OR DX, DX ; Just in case of LARGE floppies 0 000015D8 7505 JNZ SETBUF 0 000015DA 3DD002 CMP AX, 720 ; 720 Sectors * size factor of 1 0 000015DD 7609 JBE NOSETBUF 2310 SETBUF: 0 000015DF C706[1508]0300 MOV word [BUFFERS], 3 0 000015E5 EB0E jmp Chk_Memsize_for_Buffers ; Now check the memory size for default buffer count 0 000015E7 90 nop ; identicalise 2314 ; JMP BUFSET ; Jump out of search loop 2315 NOSETBUF: 2316 DPB_NEXT_DPB equ dpb_next_dpb ; NASM port equate 0 000015E8 26837E19FF CMP WORD PTR [ES:BP + DPB_NEXT_DPB],-1 0 000015ED 7406 jz Chk_Memsize_for_Buffers 2319 ; JZ BUFSET 0 000015EF 26C46E19 LES BP,[ES:BP + DPB_NEXT_DPB] 0 000015F3 EBAD JMP NEXTDPB 2322 2323 ;J.K. 10/15/86 DCR00014. 2324 ;From DOS 3.3, the default number of buffers will be changed according to the 2325 ;memory size too. 2326 ; Default buffers = 2 2327 ; If diskette Media > 360 kb, then default buffers = 3 2328 ; If memory size > 128 kb (2000H para), then default buffers = 5 2329 ; If memory size > 256 kb (4000H para), then default buffers = 10 2330 ; If memory size > 512 kb (8000H para), then default buffers = 15. 2331 2332 Chk_Memsize_for_Buffers: 2333 memory_size equ MEMORY_SIZE ; NASM port label 0 000015F5 813E[1208]0020 cmp word [memory_size], 2000h 2335 BufSet equ BUFSET ; NASM port label 0 000015FB 7622 jbe BufSet 2337 buffers equ BUFFERS ; NASM port label 0 000015FD C706[1508]0500 mov word [buffers], 5 0 00001603 813E[1208]0040 cmp word [memory_size], 4000h 0 00001609 7614 jbe BufSet 0 0000160B C706[1508]0A00 mov word [buffers], 10 0 00001611 813E[1208]0080 cmp word [memory_size], 8000h 0 00001617 7606 jbe BufSet 0 00001619 C706[1508]0F00 mov word [buffers], 15 2345 2346 BUFSET: 2347 ASSUME DS:NOTHING 0 0000161F 1F POP DS 0 00001620 58 POP AX 2350 2351 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2352 ;J.K. Here we should put extended stuff and new allocation scheme!!! 2353 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2354 ;******************************************************************************* 2355 ; * 2356 ; Function: Actually allocate BUFFERS into the (extended) memory and initialize* 2357 ; it. * 2358 ; If it is installed in real memory, the number of buffers in each * 2359 ; bucket will be balanced out as far as possible for perfermance. * 2360 ; Also, if the user specified the secondary buffer cache, it will * 2361 ; be installed in the real memory. * 2362 ; * 2363 ; Input : * 2364 ; BuffINFO.EMS_MODE - 0=IBM mode, -1 = do not use extended memory. * 2365 ; BuffINFO.Frame_Page - Page frame 0 segment address * 2366 ; MEMHI:MEMLO - Start of the next available memory * 2367 ; Buffer_Pages = Number of extended memory pages for buffer * 2368 ; BUFFERS = Number of buffers * 2369 ; H_Buffers = Number of secondary buffers * 2370 ; * 2371 ; Output: * 2372 ; BuffINFO.Cache_Count - # of caches to be installed. * 2373 ; Hash table set. * 2374 ; BuffINFO set. * 2375 ; BufferBuckets set. * 2376 ; MaxNumBuf1, MaxNumBuf2, and NthBuck set. * 2377 ; * 2378 ; Subroutines to be called: * 2379 ; * 2380 ; Logic: * 2381 ; { * 2382 ; IF (BuffINFO.EMS_MODE == -1) THEN * 2383 ; { * 2384 ; IF BUFFERS < 30 THEN * 2385 ; {# of Bucket = 1; MaxNumBuf1 = BUFFERS; NthBuck = 1} * 2386 ; ELSE { * 2387 ; # of Bucket = BUFFERS/15; * 2388 ; r = BUFFERS mod 15; * 2389 ; IF r == 0 THEN NthBuck = # of Bucket * 2390 ; ELSE * 2391 ; { * 2392 ; AddBuff = r / # of Bucket; * 2393 ; NthBuck = r mod # of Bucket; * 2394 ; MaxNumBuf1 = 15 + AddBuff; /* 1st Bucket - Nth Bucket* 2395 ; MaxNumBuf2 = 15 + AddBuff +1;/*(N+1)th Bucket to last* 2396 ; } * 2397 ; } * 2398 ; } * 2399 ; ELSE * 2400 ; { * 2401 ; # of Bucket = Buffer_Pages * 2; /* 2 buckets per page * 2402 ; }; * 2403 ; * 2404 ; /*Now allocate memory for Hash table */ * 2405 ; Hash Table Size = (size Buffer_Hash_Entry) * # of Bucket; * 2406 ; Set BuffINFO.Hash_ptr to MEMHI:MEMLO; * 2407 ; Adjust MEMHI:MEMLO according to Hash table size; * 2408 ; * 2409 ; /*Set buffers*/ * 2410 ; IF (EMS_MODE <> -1) THEN * 2411 ; Set_EMS_Buffer * 2412 ; ELSE /*Do not use the extended memory */ * 2413 ; Set_Buffer; * 2414 ;/*Now set the caches if specified.*/ * 2415 ; IF (BuffINFO.Cache_count > 0) THEN * 2416 ; {Set BuffINFO.Cache_ptr to MEMHI:MEMLO; * 2417 ; MEMHI:MEMLO = MEMHI:MEMLO + 512 * BuffINFO.Cache_count; * 2418 ; }; * 2419 ; }; * 2420 ; * 2421 ;******************************************************************************* 2422 DOBUFF: ;AN000; 2423 %ifndef BUF2 2424 DosInfo equ DOSINFO ; NASM port label 2425 lds bx, [cs:DosInfo] ;AN000; ds:bx -> SYSINITVAR 2426 2427 Buffers equ BUFFERS ; NASM port label 2428 mov ax, [ss:Buffers] ;AN000;Set SYSI_BUFFERS 2429 mov word ptr [bx + SYSI_BUFFERS], ax ;AN000; 2430 mov ax, [ss:H_Buffers] ;AN000; 2431 mov word ptr [bx + SYSI_BUFFERS+2], ax ;AN000; 2432 2433 lds bx, [bx + SYSI_BUF] ;AN000; now, ds:bx -> BuffInfo 2434 EMS_MODE equ EMS_mode ; NASM port equate 2435 cmp byte [bx + EMS_MODE], -1 ;AN000; 2436 ; $IF E, LONG ;AN000; 2437 JE DD_XL1 2438 JMP DD_IF1 2439 nop ; identicalise 2440 DD_XL1: 2441 xor dx, dx ;AN000; 2442 mov ax, [ss:Buffers] ;AN000; < 99 2443 cmp al, 30 ;AN026; if less than 30, 2444 ; $IF B ;AN026; 2445 JNB DD_IF2 2446 mov word [ss:BufferBuckets], 1 ;AN026; then put every buffer 2447 HASH_COUNT equ Hash_count ; NASM port equate 2448 mov word [bx + HASH_COUNT], 1 ;AN026; into one bucket 2449 mov [ss:MaxNumBuf1], al ;AN026; 2450 mov byte [ss:NthBuck], 1 ;AN026; 2451 ; $ELSE ;AN026; else... 2452 JMP SHORT DD_EN2 2453 DD_IF2: 2454 mov cl, 15 ;AN026; Magic number 15. 2455 div cl ;AN026; al=# of buckets, ah=remainders 2456 push ax ;AN026; save the result 2457 xor ah, ah ;AN026; 2458 mov [ss:BufferBuckets], ax ;AN026; 2459 mov [bx + HASH_COUNT], ax ;AN026; 2460 pop ax ;AN026; 2461 or ah, ah ;AN026; 2462 ; $IF Z ;AN026;if no remainders 2463 JNZ DD_IF4 2464 mov [ss:NthBuck], al ;AN026;then set NthBuck=# of bucket for Set_Buffer proc. 2465 ; $ELSE ;AN026;else 2466 JMP SHORT DD_EN4 2467 DD_IF4: 2468 mov cl, al ;AN026; 2469 mov al, ah ;AN026;remainder/# of buckets 2470 xor ah, ah ;AN026; = 2471 div cl ;AN026;al=additional num of buffers 2472 or ah, ah ;AN026;ah=Nth bucket 2473 ; $IF Z ;AN026; 2474 JNZ DD_IF6 2475 add [ss:MaxNumBuf1], al ;AN026; 2476 mov ax, [ss:BufferBuckets] ;AN026; 2477 mov [ss:NthBuck], al ;AN026; 2478 ; $ELSE ;AN026; 2479 JMP SHORT DD_EN6 2480 DD_IF6: 2481 mov [ss:NthBuck], ah ;AN026; 2482 add [ss:MaxNumBuf1], al ;AN026;MaxNumNuf are initially set to 15. 2483 add [ss:MaxNumBuf2], al ;AN026; 2484 inc byte [ss:MaxNumBuf1] ;AN026;Additional 1 more buffer for group 1 buckets. 2485 ; $ENDIF ;AN026; 2486 DD_EN6: 2487 ; $ENDIF ;AN026; 2488 DD_EN4: 2489 ; $ENDIF ;AN026; 2490 DD_EN2: 2491 ; $ELSE ;AN000; Use the extended memory. 2492 JMP SHORT DD_EN1 2493 DD_IF1: 2494 mov ax, [ss:Buffer_Pages] ;AN000; 2495 MAXBUCKETINPAGE equ MaxBucketinPage ; NASM port equate 2496 mov cx, MAXBUCKETINPAGE ;AN000; 2497 mul cx ;AN000; gauranteed to be word boundary. 2498 mov [ss:BufferBuckets], ax ;AN000; 2499 mov [bx + HASH_COUNT], ax ;AN000; 2500 ; $ENDIF ;AN000; 2501 DD_EN1: 2502 invoke Round ;AN000; get [MEMHI]:[MEMLO] 2503 mov al, DEVMARK_BUF ;AN005; ='B' 2504 call SetDevMark ;AN005; 2505 ;Now, allocate Hash table at [memhi]:[memlo]. AX = Hash_Count. 2506 mov ax, [ss:BufferBuckets] ;AN026; # of buckets==Hash_Count 2507 mov cx, BUFFER_HASH_ENTRY_struc_size ;AN000; 2508 mul cx ;AN000; now AX = Size of hash table. 2509 les di, [bx + HASH_PTR] ;AN000; save Single buffer address. 2510 MemLo equ MEMLO ; NASM port label 2511 mov cx, [ss:MemLo] ;AN000; 2512 mov word ptr [bx + HASH_PTR], cx ;AN000; set BuffINFO.HASH_PTR 2513 MemHi equ MEMHI ; NASM port label 2514 mov cx, [ss:MemHi] ;AN000; 2515 mov word ptr [bx + HASH_PTR+2], cx ;AN000; 2516 Memlo equ MEMLO ; NASM port label 2517 mov [ss:Memlo], ax ;AN000; 2518 or byte [ss:SetDevMarkFlag], FOR_DEVMARK ;AN005; 2519 call Round ;AN000; get new [memhi]:[memlo] 2520 ;Allocate buffers 2521 push ds ;AN000; Save Buffer info. ptr. 2522 push bx ;AN000; 2523 cmp byte [bx + EMS_MODE], -1 ;AN000; 2524 ; $IF NE ;AN000; 2525 JE DD_IF13 2526 call Set_EMS_Buffer ;AN000; 2527 ; $ELSE ;AN000; 2528 JMP SHORT DD_EN13 2529 DD_IF13: 2530 call Set_Buffer ;AN000; 2531 ; $ENDIF ;AN000; 2532 DD_EN13: 2533 pop bx ;AN000; 2534 pop ds ;AN000; 2535 ;Now set the secondary buffer if specified. 2536 cmp word [ss:H_Buffers], 0 ;AN000; 2537 ; $IF NE ;AN000; 2538 JE DD_IF16 2539 call Round ;AN000; 2540 mov cx, [ss:MemLo] ;AN000; 2541 CACHE_PTR equ Cache_ptr ; NASM port equate 2542 mov word ptr [bx + CACHE_PTR], cx ;AN000; 2543 mov cx, [ss:MemHi] ;AN000; 2544 mov word ptr [bx + CACHE_PTR+2], cx ;AN000; 2545 mov cx, [ss:H_Buffers] ;AN000; 2546 CACHE_COUNT equ Cache_count ; NASM port equate 2547 mov [bx + CACHE_COUNT], cx ;AN000; 2548 mov ax, 512 ;AN000; 512 byte 2549 mul cx ;AN000; 2550 mov [ss:Memlo], ax ;AN000; 2551 or byte [ss:SetDevMarkFlag], FOR_DEVMARK ;AN005; 2552 call Round ;AN000; 2553 ; $ENDIF ;AN000; 2554 DD_IF16: 2555 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2556 ;J.K. END OF NEW BUFFER SCHEME. 2557 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2558 %else 2559 ;DOBUFF: 2560 0 00001621 36C51E[F607] LDS BX,[ss:DOSINFO] ; -> list of lists 0 00001626 8B4710 mov ax, [bx + SYSI_MAXSEC] 0 00001629 83C010 add ax, BUFINSIZE 0 0000162C 50 push ax ; ax = buffer size 0 0000162D 36F726[1508] mul word [ss:BUFFERS] ; dx:ax = required amount bytes 0 00001632 BE[A827] mov si, alloc_buffers 0 00001635 1E push ds 0 00001636 E8EB11 call allocate_relocate_block.large 2569 ; es:di -> first buffer 0 00001639 1F pop ds 0 0000163A 59 pop cx ; = buffer size 0 0000163B 1E push ds 0 0000163C 51 push cx 0 0000163D C536[0000] lds si, [BUFFHEAD] ; -> initial sysinit buffer 0 00001641 57 push di 0 00001642 F3A4 rep movsb ; copy the initial buffer 0 00001644 5F pop di 0 00001645 26830DFF or word [es:di + NEXTBUF], -1 0 00001649 26834D02FF or word [es:di + NEXTBUF + 2], -1 ; set pointer 0 0000164E 59 pop cx 0 0000164F 1F pop ds 0 00001650 8C06[0200] mov word [BUFFHEAD + 2], es 0 00001654 893E[0000] mov word [BUFFHEAD], di ; -> first buffer 2584 2585 .loop: 0 00001658 01CF add di, cx ; -> next buffer 0 0000165A 724B jc j_mem_err 0 0000165C 8CC0 mov ax, es 0 0000165E 83F8FF cmp ax, -1 ; are we in HMA ? 0 00001661 741A je .unnormalised ; yes, do not normalise --> 0 00001663 89F8 mov ax, di ; ax = offset 0 00001665 3D00C0 cmp ax, 48 * 1024 0 00001668 7613 jbe .unnormalised 0 0000166A D1E8 shr ax, 1 0 0000166C D1E8 shr ax, 1 0 0000166E D1E8 shr ax, 1 0 00001670 D1E8 shr ax, 1 ; ax = how many paragraphs to advance 0 00001672 8CC3 mov bx, es 0 00001674 01C3 add bx, ax 0 00001676 722F jc j_mem_err ; harden 0 00001678 8EC3 mov es, bx ; es => next buffer 0 0000167A 83E70F and di, 15 ; di = offset of next buffer, normalised 2603 .unnormalised: 0 0000167D 57 push di 0 0000167E 01CF add di, cx 0 00001680 5F pop di 0 00001681 7224 jc j_mem_err 2608 0 00001683 36FF0E[1508] DEC word [ss:BUFFERS] ; FIRST DEC acounts for buffer already 2610 ; in system. 0 00001688 7420 JZ BUF1 ; All done 0 0000168A 26C74504FF00 MOV WORD PTR [ES:DI + BUFDRV],00FFH ;NEW BUFFER FREE 2613 0 00001690 A1[0000] MOV AX,WORD PTR [BUFFHEAD] ; Link in new buffer 0 00001693 268905 MOV WORD PTR [ES:DI + NEXTBUF],AX 0 00001696 A1[0200] MOV AX,WORD PTR [BUFFHEAD+2] 0 00001699 26894502 MOV WORD PTR [ES:DI + NEXTBUF +2],AX 0 0000169D 893E[0000] MOV WORD PTR [BUFFHEAD],DI 0 000016A1 8C06[0200] MOV WORD PTR [BUFFHEAD+2],ES 0 000016A5 EBB1 JMP .loop 2621 2622 j_mem_err: 0 000016A7 E9[0000] jmp MEM_ERR 2624 %endif 2625 2626 ;------------------------------------------------------------------------------ 2627 ; Allocate CDSs 2628 ;------------------------------------------------------------------------------ 2629 BUF1: 0 000016AA 31C9 xor cx, cx 0 000016AC 36870E[2108] xchg cx, word [ss:buffer_block] 0 000016B1 E306 jcxz @F 0 000016B3 8EC1 mov es, cx 0 000016B5 B449 mov ah, 49h 0 000016B7 CD21 int 21h 2636 @@: 2637 0 000016B9 36C43E[F607] LES DI,[ss:DOSINFO] 0 000016BE 268A4D20 MOV CL,BYTE PTR [ES:DI + SYSI_NUMIO] 0 000016C2 363A0E[1E08] CMP CL,[ss:NUM_CDS] 0 000016C7 7305 JAE GOTNCDS ; User setting must be at least NUMIO 0 000016C9 368A0E[1E08] MOV CL,[ss:NUM_CDS] 2643 GOTNCDS: 0 000016CE 30ED XOR CH,CH 0 000016D0 26884D21 MOV [ES:DI + SYSI_NCDS],CL 0 000016D4 B058 mov al, curdir_list_struc_size 0 000016D6 F6E1 mul cl 0 000016D8 51 push cx 0 000016D9 06 push es 0 000016DA 57 push di 0 000016DB BE[B227] mov si, alloc_cds 0 000016DE E84111 call allocate_relocate_block 0 000016E1 5E pop si 0 000016E2 1F pop ds 0 000016E3 59 pop cx 0 000016E4 8C4418 MOV WORD PTR [si + SYSI_CDS + 2], es 0 000016E7 897C16 MOV WORD PTR [si + SYSI_CDS], di 0 000016EA C534 LDS SI,[si + SYSI_DPB] 2659 ASSUME DS:NOTHING 0 000016EC E860FD call free_temp_cds 2661 0 000016EF E89FFD CALL FOOSET 2663 2664 ;------------------------------------------------------------------------------ 2665 ; Allocate Space for Internal Stack 2666 ;------------------------------------------------------------------------------ 2667 2668 %IF STACKSW 2669 0 000016F2 0E PUSH CS 0 000016F3 1F POP DS 2672 ASSUME DS:SYSINITSEG 2673 2674 %IF IBM 2675 ;Don't install the system stack on the PCjr. Ignore STACKS=command too. 0 000016F4 803E[5308]FD CMP byte [Sys_Model_Byte], 0FDh ; PCjr = 0FDh 2677 SkipStack_brdg equ SkipStack_Brdg ; NASM port label 0 000016F9 741C JE SkipStack_brdg 2679 %ENDIF 2680 2681 ;J.K. 10/15/86 DCR00013 2682 ;If the use does not entered STACKS= command, as a default, do not install 2683 ;sytem stacks for PC1, PC XT, PC Portable cases. 2684 ;Otherwise, install it to the user specified value or to the default 2685 ;value of 9, 128 for the rest of the system. 2686 2687 stack_addr equ STACK_ADDR ; NASM port label 0 000016FB 833E[0E08]FF cmp word ptr [stack_addr], -1 ;Has the user entered "stacks=" command? 0 00001700 7418 je DoInstallStack ;Then install as specified by the user 0 00001702 803E[5408]00 cmp byte [Sys_Scnd_Model_Byte], 0 ;PC1, XT has the secondary model byte = 0 0 00001707 7511 jne DoInstallStack ;Other model should have default stack of 9, 128 0 00001709 803E[5308]FF cmp byte [Sys_Model_Byte], 0FFh ;PC1 ? 0 0000170E 7407 je SkipStack_brdg 0 00001710 803E[5308]FE cmp byte [Sys_Model_Byte], 0FEh ;PC/XT or PC Portable ? 0 00001715 7503 jne DoInstallStack 2696 SkipStack_Brdg: 0 00001717 EB38 jmp SkipStack 0 00001719 90 nop ; identicalise 2699 DoInstallStack: 2700 stack_count equ STACK_COUNT ; NASM port label 0 0000171A A1[0A08] mov ax, [stack_count] ;J.K. Stack_count = 0? 0 0000171D 83F800 cmp ax, 0 ;then, stack size must be 0 too. 0 00001720 74F5 jz SkipStack_brdg ;Don't install stack. 2704 2705 ; Space for Internal Stack area = STACK_COUNT(ENTRYSIZE + STACK_SIZE) 0 00001722 B80800 MOV AX, EntrySize 0 00001725 0306[0C08] ADD AX, [STACK_SIZE] 0 00001729 8B0E[0A08] MOV CX, [STACK_COUNT] 0 0000172D F7E1 MUL CX 0 0000172F 05[F207] add ax, offset Endstackcode 0 00001732 83D200 adc dx, 0 0 00001735 BE[BC27] mov si, alloc_stack 0 00001738 E8E710 call allocate_relocate_block 2714 2715 assume es:nothing 0 0000173B 0E push cs 0 0000173C 1F pop ds 0 0000173D 31F6 xor si,si 2719 ;!!We know that Stack code is at the beginning of SYSINIT. 0 0000173F 31FF xor di,di 0 00001741 B9[F207] mov cx, offset Endstackcode 0 00001744 F3A4 rep movsb 2723 0 00001746 893E[0E08] mov word ptr [stack_addr], di 0 0000174A 8C06[1008] mov word ptr [stack_addr+2], es 2726 ; set for stack area initialization 2727 ; This will be used by Stack_Init routine. 2728 0 0000174E E8B101 CALL StackInit 2730 ; Initialize hardware stack. 2731 ; CS=DS=sysinitseg, ES=Relocated stack code & data 2732 2733 SkipStack: 2734 %ENDIF 2735 0 00001751 0E PUSH CS 0 00001752 1F POP DS 2738 ASSUME DS:SYSINITSEG 2739 0 00001753 A0[1B08] MOV AL,[FILES] 0 00001756 30E4 XOR AH,AH ; DO NOT USE CBW INSTRUCTION!!!!! 2742 ; IT DOES SIGN EXTEND. 0 00001758 89C1 MOV CX,AX 0 0000175A 31DB XOR BX,BX ;Close standard input 0 0000175C B43E MOV AH,CLOSE 0 0000175E CD21 INT 21H 0 00001760 BB0200 MOV BX,2 2748 RCCLLOOP: ;Close everybody but standard output 0 00001763 B43E MOV AH,CLOSE ; Need output so we can print message 0 00001765 CD21 INT 21H ; in case we can't get new one open. 0 00001767 43 INC BX 0 00001768 E2F9 LOOP RCCLLOOP 2753 0 0000176A BA[0000] MOV DX,OFFSET CONDEV 0 0000176D B002 MOV AL,2 0 0000176F B43D MOV AH,OPEN ;OPEN CON FOR READ/WRITE 0 00001771 F9 STC ; Set for possible INT 24 0 00001772 CD21 INT 21H 0 00001774 7305 JNC GOAUX 0 00001776 E8[0000] INVOKE BADFIL 0 00001779 EB13 JMP SHORT GOAUX2 2762 0 0000177B 50 GOAUX: PUSH AX 0 0000177C BB0100 MOV BX,1 ;close standard output 0 0000177F B43E MOV AH,CLOSE 0 00001781 CD21 INT 21H 0 00001783 58 POP AX 2768 0 00001784 89C3 MOV BX,AX ;New device handle 2770 XDUP equ XDup ; NASM port equate 0 00001786 B445 MOV AH,XDUP 0 00001788 CD21 INT 21H ;Dup to 1, STDOUT 0 0000178A B445 MOV AH,XDUP 0 0000178C CD21 INT 21H ;Dup to 2, STDERR 2775 0 0000178E BA[0000] GOAUX2: MOV DX,OFFSET AUXDEV 0 00001791 B002 MOV AL,2 ;READ/WRITE ACCESS 0 00001793 E8[0000] INVOKE OPEN_DEV 2779 0 00001796 BA[0000] MOV DX,OFFSET PRNDEV 0 00001799 B001 MOV AL,1 ;WRITE ONLY 0 0000179B E8[0000] INVOKE OPEN_DEV 2783 2784 ;J.K.9/29/86 ******************* 2785 ;Global Rearm command for Shared Interrupt devices attached in the system; 2786 ;Shared interrupt attachment has some problem when it issues interrupt 2787 ;during a warm reboot. Once the interrupt is presented by the attachment, 2788 ;no further interrupts on that level will be presented until a global rearm 2789 ;is issued. By the request of the system architecture group, IBMBIO will 2790 ;issue a global rearm after every device driver is loaded. 2791 ;To issue a global rearm: ;For PC1, XT, Palace 2792 ; OUT 02F2h, XX ; Interrupt level 2 2793 ; OUT 02F3h, XX ; Interrupt level 3 2794 ; OUT 02F4h, XX ; Interrupt level 4 2795 ; OUT 02F5h, XX ; Interrupt level 5 2796 ; OUT 02F6h, XX ; Interrupt level 6 2797 ; OUT 02F7h, XX ; Interrupt level 7 2798 ; 2799 ; ;For PC AT, in addition to the above commands, 2800 ; ;need to handle the secondary interrupt handler 2801 ; OUT 06F2h, XX ; Interrupt level 10 2802 ; OUT 06F3h, XX ; Interrupt level 11 2803 ; OUT 06F4h, XX ; Interrupt level 12 2804 ; OUT 06F6h, XX ; Interrupt level 14 2805 ; OUT 06F7h, XX ; Interrupt level 15 2806 ; 2807 ; ;For Round-Up machine 2808 ; None. 2809 ; where XX stands for any value. 2810 ; For your information, after Naples level machine, the system service bios 2811 ; call (INT 15h), function AH=0C0h returns the system configuration parameters 2812 ; 2813 2814 sys_model_byte equ Sys_Model_Byte ; NASM port label 0 0000179E 803E[5308]FD cmp byte [sys_model_byte], 0FDh ;PCjr? 2816 ; je GoCheckInstall 0 000017A3 7441 je Set_Sysinit_Base 2818 ;SB33045******************************************************************* 0 000017A5 50 push ax ;Save Regs ;SB ;3.30* 0 000017A6 53 push bx ; * ;SB ;3.30* 0 000017A7 52 push dx ; * ;SB ;3.30* 0 000017A8 06 push es ; * ;SB ;3.30* 0 000017A9 B0FF mov al,0ffh ;Reset h/w by writing to port ;SB ;3.30* 0 000017AB BAF202 mov dx,2f2h ;Get starting address ;SB ;3.30* 0 000017AE EE out dx,al ; out 02f2h,0ffh 0 000017AF 42 inc dx 0 000017B0 EE out dx,al ; out 02f3h,0ffh 0 000017B1 42 inc dx 0 000017B2 EE out dx,al ; out 02f4h,0ffh 0 000017B3 42 inc dx 0 000017B4 EE out dx,al ; out 02f5h,0ffh 0 000017B5 42 inc dx 0 000017B6 EE out dx,al ; out 02f6h,0ffh 0 000017B7 42 inc dx 0 000017B8 EE out dx,al ; out 02f7h,0ffh 2836 ;SB33045******************************************************************* 2837 2838 ;SB33046******************************************************************* 2839 ;SB Secondary global rearm ;3.30 0 000017B9 B800F0 mov ax,0f000h ;Get machine type ;SB ;3.30* 0 000017BC 8EC0 mov es,ax ; * ;SB ;3.30* 0 000017BE 26803EFEFFFC cmp byte ptr [es:0fffeh],0fch ;Q:Is it a AT type machine ;SB ;3.30* 0 000017C4 740D je startrearm ; *if AT no need to check 0 000017C6 B4C0 mov ah,0c0h ;Get system configuration ;SB ;3.30* 0 000017C8 CD15 int 15h ; * ;SB ;3.30* 0 000017CA 7216 jc finishrearm ; *jmp if old rom ;SB ;3.30* 2847 ; ;SB ;3.30* 2848 ; Test feature byte for secondary interrupt controller ;SB ;3.30* 2849 ; ;SB ;3.30* 0 000017CC 26F6470540 test byte [es:bx + bios_SD_featurebyte1],ScndIntController ; ;SB ;3.30* 0 000017D1 740F je finishrearm ;Jmp if it is there ;SB ;3.30* 2852 startrearm: 0 000017D3 B0FF mov al,0ffh ;Write any pattern to port ;SB ;3.30* 0 000017D5 BAF206 mov dx,6f2h ;Get starting address ;SB ;3.30* 0 000017D8 EE out dx,al ;out 06f2h,0ffh 0 000017D9 42 inc dx ;Bump address ;SB ;3.30* 0 000017DA EE out dx,al ;out 06f3h,0ffh 0 000017DB 42 inc dx ;Bump address ;SB ;3.30* 0 000017DC EE out dx,al ;out 06f4h,0ffh 0 000017DD 42 inc dx ;Bump address ;SB ;3.30* 0 000017DE 42 inc dx ;Bump address ;SB ;3.30* 0 000017DF EE out dx,al ;out 06f6h,0ffh 0 000017E0 42 inc dx ;Bump address ;SB ;3.30* 0 000017E1 EE out dx,al ;out 06f7h,0ffh 2865 finishrearm: ; ;SB ;3.30* 0 000017E2 07 pop es ;Restore regs ;SB ;3.30* 0 000017E3 5A pop dx ; * ;SB ;3.30* 0 000017E4 5B pop bx ; * ;SB ;3.30* 0 000017E5 58 pop ax ; * ;SB ;3.30* 2870 ;SB33046******************************************************************* 2871 2872 ;J.K. 9/29/86 Global Rearm end ******************* 2873 2874 ;------------------------------------------------------------------------------ 2875 ; Allocate SYSINIT_BASE for INSTALL= command 2876 ;------------------------------------------------------------------------------ 2877 ;J.K. SYSINIT_BASE allocation. 2878 ;Check if ENDFILE has been called to handle INSTALL= command. 2879 2880 Set_Sysinit_Base: 2881 ;GoCheckInstall: 2882 ; test [Install_Flag], HAVE_INSTALL_CMD ;AN019;;AN021;install sysinit base all the time. 2883 ; jz Skip_SYSINIT_BASE ;AN019; 2884 2885 %if 0 2886 ;J.K.-------------------------------------------------------------------------- 2887 ;SYSINIT_BASE will be established in the secure area of 2888 ;lower memory when it handles the first INSTALL= command. 2889 ;SYSINIT_BASE is the place where the actual EXEC function will be called and 2890 ;will check SYSINIT module in high memory if it is damaged by the application 2891 ;program. If SYSINIT module has been broken, then "Memory error..." message 2892 ;is displayed by SYSINIT_BASE. 2893 ;------------------------------------------------------------------------------ 2894 push ax ;AN013; Set DEVMARK for MEM command 2895 mov ax, [memhi] ;AN013; 2896 sub ax, [area] ;AN013; 2897 Impossible_owner_size equ Impossible_Owner_Size ; NASM port label 2898 mov [Impossible_owner_size], ax ;AN013;Remember the size in case. 2899 mov al, DEVMARK_INST ;AN013; 2900 call SetDevMark ;AN013; 2901 pop ax ;AN013; 2902 2903 mov di, [memhi] ;AN000; 2904 mov es, di ;AN000; 2905 assume es:nothing ;AN000; 2906 sysinit_base_ptr equ Sysinit_Base_Ptr ; NASM port label 2907 mov word ptr [sysinit_base_ptr+2],di ;AN000; save this entry for the next use. 2908 xor di, di ;AN000; 2909 mov word ptr [sysinit_base_ptr], di ;AN000; es:di -> destination. 2910 SYSINIT_BASE equ Sysinit_Base ; NASM port label 2911 mov si, offset SYSINIT_BASE ;AN000; ds:si -> source code to be relocated. 2912 Size_SYSINIT_BASE equ SIZE_SYSINIT_BASE ; NASM port equate 2913 mov cx, Size_SYSINIT_BASE ;AN000; 2914 nop ; identicalise 2915 add [memlo],cx ;AN000; 2916 or byte [cs:SetDevMarkFlag], FOR_DEVMARK ;AN013; 2917 invoke Round ;AN000; check mem error. Also, readjust MEMHI for the next use. 2918 rep movsb ;AN000; reallocate it. 2919 2920 mov word ptr [Sysinit_Ptr], offset SYSINITPTR ;AN000; Returing address from 2921 mov word ptr [Sysinit_Ptr+2], cs ;AN000; SYSINIT_BASE back to SYSINIT. 2922 or word [Install_Flag],HAS_INSTALLED ;AN000; Set the flag. 2923 2924 ;------------------------------------------------------------------------------ 2925 ; Free the rest of the memory from MEMHI to CONFBOT. Still from CONFBOT to 2926 ; the top of the memory will be allocated for SYSINIT and CONFIG.SYS if 2927 ; HAVE_INSTALL_CMD. 2928 ;------------------------------------------------------------------------------ 2929 ;Skip_SYSINIT_BASE: ;AN021; 2930 2931 INVOKE ROUND 2932 MOV BX,[MEMHI] 2933 MOV AX,[AREA] 2934 mov [Old_Area], ax ;AN013; Save [AREA] 2935 MOV ES,AX ;CALC WHAT WE NEEDED 2936 SUB BX,AX 2937 MOV AH,SETBLOCK 2938 INT 21H ;GIVE THE REST BACK 2939 PUSH ES 2940 MOV AX,ES 2941 DEC AX 2942 MOV ES,AX ;Point to arena 2943 MOV word [ES:arena_owner],8 ;Set impossible owner 2944 mov word ptr [es:arena_name], "SD" ; set SD name ; NASM port swapped text literals 2945 and word ptr [es:arena_name + 2], 0 ; NUL 2946 POP ES 2947 2948 mov bx,0ffffh ;AN000; 2949 mov ah,Alloc ;AN000; 2950 int 21h ;AN000; 2951 mov ah,Alloc ;AN000; 2952 int 21h ;AN000; Allocate the rest of the memory 2953 2954 mov [memhi],ax ;AN000; Start of the allocated memory 2955 mov word [memlo],0 ;AN000; to be used next. 2956 2957 ;;;; At this moment, memory from [MEMHI]:0 to Top-of-the memory is 2958 ;;;; allocated. 2959 ;;;; To protect sysinit, confbot module (From CONFBOT (or =ALLOCLIM at 2960 ;;;; this time) to the Top-of-the memory), here we are going to 2961 ;;;; 1). "SETBLOCK" from MEMHI to CONFBOT. 2962 ;;;; 2). "ALLOC" from CONFBOT to the top of the memory. 2963 ;;;; 3). "Free Alloc Memory" from MEMHI to CONFBOT. 2964 ;Memory allocation for SYSINIT, CONFBOT module. 2965 mov es, ax ;AN000; 2966 mov bx, [confbot] ;AN000; 2967 sub bx, ax ;AN000; CONFBOT - MEMHI 2968 dec bx ;AN000; Make a room for the memory block id. 2969 dec bx ;AN000; make sure!!!. 2970 mov ah, SETBLOCK ;AN000; 2971 int 21h ;AN000; this will free (CONFBOT to top of memory) 2972 mov bx, 0ffffh ;AN000; 2973 mov ah, ALLOC ;AN000; 2974 int 21h ;AN000; 2975 mov ah, ALLOC ;AN000; 2976 int 21h ;AN000; allocate (CONFBOT to top of memory) 2977 mov [area],ax ;AN000; Save Allocated memory segment. 2978 ;AN000; Need this to free this area for COMMAND.COM. 2979 mov es, [memhi] ;AN000; 2980 mov ah, 49h ;AN000; Free Allocated Memory. 2981 int 21h ;AN000; Free (Memhi to CONFBOT(=AREA)) 2982 %endif 2983 2984 ; IF NOEXEC 2985 ; MOV BX,0FFFFH ;ALLOCATE THE REST OF MEM FOR COMMAND 2986 ; MOV AH,ALLOC 2987 ; INT 21H 2988 ; MOV AH,ALLOC 2989 ; INT 21H 2990 ; MOV DS,AX 2991 ; ENDIF 2992 2993 ; test [cs:Install_Flag],IS_INSTALL ;AN000; 2994 ; jnz DO_Install_Exec ;AN000; 2995 2996 ENDFILE_Ret: 0 000017E6 C3 return 2998 2999 3000 Do_Install_Exec proc near ;AN000; Now, handles INSTALL= command. 3001 0 000017E7 56 push si ;AN000; save SI for config.sys again. 3003 3004 ;;;; We are going to call LOAD/EXEC function. 3005 ;;;;;Set ES:BX to the parameter block here;;;;;;; 3006 ;;;;;Set DS:DX to the ASCIIZ string. Remember that we already has 0 3007 ;;;;;after the filename. So parameter starts after that. If next 3008 ;;;;;character is a line feed (i.e. 10), then assume that the 0 3009 ;;;;;we already encountered used to be a carrage return. In this 3010 ;;;;;case, let's set the length to 0 which will be followed by 3011 ;;;;;carridge return. 3012 ;J.K. ES:SI -> command line in CONFIG.SYS. Points to the first non blank 3013 ;character after =. 0 000017E8 06 push es ;AN000; 0 000017E9 1E push ds ;AN000; 0 000017EA 07 pop es ;AN000; 0 000017EB 1F pop ds ;AN000; es->sysinitseg, ds->confbot seg 3018 assume ds:nothing ;AN000; 0 000017EC 89F2 mov dx, si ;AN000; ds:dx->file name,0 in CONFIG.SYS image. 3020 ;AN016; UNDO THE EXTENDED ATTRIBUTES HANDLING 3021 ; mov ax, OPEN SHL 8 ;AN008; 3022 ; int 21h ;AN008; 3023 ; jc SysInitPtr ;AN008; 3024 ; mov bx, ax ;AN008;handle 3025 ; call Get_Ext_Attribute ;AN008;Get the extended attribute. 3026 ; cmp al, EA_INSTALLABLE ;AN008; 3027 ; je EA_Installable_OK ;AN012; 3028 ; stc ;AN012; 3029 ; jmp SysInitPtr ;AN012; 3030 ;EA_Installable_OK: ;AN012; 0 000017EE 31C9 xor cx,cx ;AN000; 0 000017F0 FC cld ;AN000; 0 000017F1 2EC606[8108]20 mov byte [cs:Ldexec_start], ' ' ;AN015; Clear out the parm area 0 000017F7 BF[8208] mov di, offset Ldexec_parm ;AN000; 3035 InstallFilename: ;AN000; skip the file name 0 000017FA AC lodsb ;AN000; al = ds:si; si++ 0 000017FB 3C00 cmp al, 0 ;AN000; 0 000017FD 7402 je Got_InstallParm ;AN000; 0 000017FF EBF9 jmp InstallFilename ;AN000; 3040 Got_InstallParm: ;AN000; copy the parameters to Ldexec_parm 0 00001801 41 inc cx ;AN000; # of char. in the parm. 0 00001802 AC lodsb ;AN000; 0 00001803 AA stosb 0 00001804 3C0D cmp al, CR 0 00001806 7406 je .cr 0 00001808 3C0A cmp al, LF ;AN000;AN028; line feed? 0 0000180A 7402 je .lf 3048 Got_Installparm equ Got_InstallParm ; NASM port label 0 0000180C EBF3 jmp Got_Installparm ;AN000; 3050 3051 .cr: 3052 .lf: 0 0000180E 26C645FF0D mov byte [es:di - 1], CR 3054 Done_Installparm: ;AN000; 3055 Ldexec_line equ Ldexec_Line ; NASM port label 0 00001813 2E880E[8008] mov byte ptr [cs:Ldexec_line], cl ;AN000; length of the parm. 0 00001818 80F900 cmp cl, 0 ;AN015;If no parm, then 0 0000181B 7506 jne Install_Seg_Set ;AN015; let the parm area 3059 Ldexec_Start equ Ldexec_start ; NASM port label 0 0000181D 2EC606[8108]0D mov byte ptr [cs:Ldexec_Start],CR ;AN015; starts with CR. 3061 Install_Seg_Set: ;AN015; 0 00001823 2E8326000000 and word [cs:0], 0 ;AN000; Make a null environment segment 0 00001829 8CC8 mov ax, cs ;AN000; by overlap JMP instruction of SYSINITSEG. 3064 EXEC0_ENVIRON equ Exec0_environ ; NASM port equate 0 0000182B 2EA3[D208] mov [cs:INSTEXE + EXEC0_ENVIRON],ax ;AN000; Set the environment seg. 0 0000182F 2EA3[D608] mov word ptr [cs:INSTEXE + EXEC0_COM_LINE+2],ax ;AN000; Set the seg. 0 00001833 2EA3[DA08] mov word ptr [cs:INSTEXE + EXEC0_5C_FCB+2],ax ;AN000; 0 00001837 2EA3[DE08] mov word ptr [cs:INSTEXE + EXEC0_6C_FCB+2],ax ;AN000; 0 0000183B 06 push es ;AN000; Save es,ds for Load/Exec 0 0000183C 1E push ds ;AN000; these registers will be restored in SYSINIT_BASE. 3071 SYSINIT_BASE_SS equ Sysinit_Base_SS ; NASM port equate 0 0000183D 2E8C16[DB18] mov word ptr [cs:SYSINIT_BASE_SS], SS ;AN000; save stack 3073 SYSINIT_BASE_SP equ Sysinit_Base_SP ; NASM port equate 0 00001842 2E8926[DD18] mov word ptr [cs:SYSINIT_BASE_SP], SP ;AN000; 0 00001847 E86400 call Sum_up ;AN000; 0 0000184A 26A3[6A08] mov [es:CheckSum], ax ;AN000; save the value of the sum 0 0000184E B8004B mov ax, EXEC << 8 ;AN000; Load/Exec 0 00001851 2ED006[0000] rol byte [cs:devicehighflag], 1 0 00001856 D0D8 rcr al, 1 ; al = 80h if installhigh= 0 00001858 BB[D208] mov bx, offset INSTEXE ;AN000; ES:BX -> parm block. 3081 SYSINIT_BASE equ Sysinit_Base ; NASM port label 0 0000185B EB29 jmp SYSINIT_BASE ;AN000; jmp to SYSINIT_BASE to execute 3083 ; LOAD/EXEC function and check sum. 3084 3085 ;J.K. This is the returning address from SYSINIT_BASE. 3086 SYSINITPTR: ;AN000; returning far address from SYSINIT_BASE 0 0000185D 5E pop si ;AN000; restore SI for CONFIG.SYS file. 0 0000185E 06 push es ;AN000; 0 0000185F 1E push ds ;AN000; 0 00001860 07 pop es ;AN000; 0 00001861 1F pop ds ;AN000; now ds - sysinitseg, es - confbot 0 00001862 7311 jnc Exec_Exit_Code 0 00001864 2EF706[6608]0400 test word [cs:Install_Flag], SHARE_INSTALL ;AN021; Called by LoadShare proc? 0 0000186B 750B jnz Install_Error_Exit ;AN021; Just exit with carry set. 0 0000186D 56 push si ;AN000; Error in loading the file for INSTALL=. 0 0000186E E8[0000] call BadLoad ;AN000; ES:SI-> path,filename,0. 0 00001871 5E pop si ;AN000; 0 00001872 EB05 jmp Install_Exit_Ret 0 00001874 90 nop ; identicalise 3100 Exec_Exit_Code: 3101 ; test cs:Install_Flag, SHARE_INSTALL ;AN021; Called by LoadShare proc? 0 00001875 EB02 jmp Install_Exit_Ret ;AN021; Just exit. 0 00001877 90 nop ; identicalise 3104 ; mov ah, 4dh ;AN017; 3105 ; int 21h ;AN017; 3106 ; cmp ah, 3 ;AN017;Only accept "Stay Resident" prog. 3107 ; je Install_Exit_Ret ;AN017; 3108 ; call Error_Line ;AN017;Inform the user 3109 Install_Error_Exit: ;AN021; 0 00001878 F9 stc ;AN021; 3111 Install_Exit_Ret: 0 00001879 C3 ret 3113 Do_Install_Exec endp 3114 3115 Public ParaRound 3116 ParaRound: 0 0000187A 83C00F ADD AX,15 0 0000187D D1D8 RCR AX,1 0 0000187F D1E8 SHR AX,1 0 00001881 D1E8 SHR AX,1 0 00001883 D1E8 SHR AX,1 0 00001885 C3 return 3123 3124 ;------------------------------------------------------------------------------ 3125 ;J.K. SYSINIT_BASE module. 3126 ;In: After relocation, 3127 ; AX = 4B00h - Load and execute the program DOS function. 3128 ; DS = CONFBOT. Segment of CONFIG.SYS file image 3129 ; ES = Sysinitseg. Segment of SYSINIT module itself. 3130 ; DS:DX = pointer to ASCIIZ string of the path,filename to be executed. 3131 ; ES:BX = pointer to a parameter block for load. 3132 ; SYSSIZE (Byte) - offset value of End of SYSINIT module label 3133 ; BIGSIZE (word) - # of word from CONFBOT to SYSSIZE. 3134 ; CHKSUM (word) - Sum of every byte from CONFBOT to SYSSIZE in a 3135 ; word boundary moduler form. 3136 ; SYSINIT_PTR (dword ptr) - Return address to SYSINIT module. 3137 ;Note: SYSINIT should save necessary registers and when the control is back 3138 3139 3140 Sysinit_Base: ;AN000; 0 00001886 CD21 int 21h ;AN000; LOAD/EXEC DOS call. 0 00001888 2E8E16[DB18] mov SS, word ptr [cs:SYSINIT_BASE_SS] ;AN000; restore stack 0 0000188D 2E8B26[DD18] mov SP, word ptr [cs:SYSINIT_BASE_SP] ;AN000; 0 00001892 1F pop ds ;AN000; restore CONFBOT seg 0 00001893 07 pop es ;AN000; restore SYSINITSEG 0 00001894 7216 jc SysInit_Base_End ;AN000; LOAD/EXEC function failed. 3147 ;At this time, I don't have to worry about 3148 ;that SYSINIT module has been broken or not. 0 00001896 E81500 call Sum_up ;AN000; Otherwise, check if it is good. 0 00001899 263906[6A08] cmp [es:CheckSum], AX ;AN000; 0 0000189E 740C je SysInit_Base_End ;AN000; 3152 ;Memory broken. Show "Memory allocation error" message and stall. 0 000018A0 B409 mov ah, 09h ;AN000; 0 000018A2 0E push cs ;AN000; 0 000018A3 1F pop ds ;AN000; 3156 Mem_alloc_err_msg equ Mem_Alloc_Err_msg ; NASM port equate 0 000018A4 BA[DF18] mov dx, Mem_alloc_err_msg ;AN000; 0 000018A7 90 nop ; identicalise 0 000018A8 CD21 int 21h ;AN000; 0 000018AA EBFE Stall_now: jmp Stall_now ;AN000; 3161 0 000018AC EBAF SysInit_Base_End: jmp SYSINITPTR ;AN000; return back to sysinit module 3163 3164 Sum_up: ;AN000; 3165 ;In: 3166 ; ES - SYSINITSEG. 3167 ;OUT: AX - Result 3168 ;Remark: Since this routine will only check starting from "LocStack" to the end of 3169 ; Sysinit segment, the data area, and the current stack area are not 3170 ; coverd. In this sense, this check sum routine only gives a minimal 3171 ; gaurantee to be safe. 3172 ;First sum up CONFBOT seg. 0 000018AE 1E push ds ;AN021; 0 000018AF 26A1[1F08] mov ax,[es:config_block] ;AN021; 0 000018B3 8ED8 mov ds,ax ;AN021; 0 000018B5 31F6 xor si,si ;AN000; 0 000018B7 31C0 xor ax,ax ;AN000; 0 000018B9 268B0E[6808] mov cx,[es:Config_Size] ;AN000; If CONFIG_SIZE has been broken, then this 3179 ;whole test better fail. 0 000018BE D1E9 shr cx, 1 ;AN000; make it a word count 0 000018C0 7406 jz Sum_Sys_Code ;AN025; When CONFIG.SYS file not exist. 3182 Sum1: ;AN000; 0 000018C2 0304 add ax, word ptr [si] ;AN000; 0 000018C4 46 inc si ;AN000; 0 000018C5 46 inc si ;AN000; 0 000018C6 E2FA loop Sum1 ;AN000; 3187 ;Now, sum up SYSINIT module. 3188 Sum_Sys_Code: ;AN025; 3189 LocStack equ LOCSTACK ; NASM port label 0 000018C8 BE[DA0C] mov si, offset LocStack ;AN000; Starting after the stack. 3191 ;AN000; This does not cover the possible STACK code!!! 0 000018CB B9[0000] mov cx, offset SYSSIZE wrt SYSINITSEG ;AN000; SYSSIZE is the label at the end of SYSINIT 0 000018CE 29F1 sub cx, si ;AN000; From After_Checksum to SYSSIZE 0 000018D0 D1E9 shr cx, 1 ;AN000; 3195 Sum2: ;AN000; 0 000018D2 260304 add ax, word ptr [es:si] ;AN000; 0 000018D5 46 inc si ;AN000; 0 000018D6 46 inc si ;AN000; 0 000018D7 E2F9 loop Sum2 ;AN000; 0 000018D9 1F pop ds ;AN021; 0 000018DA C3 ret ;AN000; 3202 3203 Sysinit_Base_SS equ $ ;AN000; 0 000018DB ???? dw ? ;AN000; 3205 Sysinit_Base_SP equ $ ;AN000; 0 000018DD ???? dw ? ;AN000; 3207 Mem_Alloc_Err_msg equ $ ;AN000; 3208 ;include BASEMES.INC ;AN000; Memory allocation error message 3209 ;=== Push trace listing source: msbio.cl4 3210 %include "msbio.cl4" ;AN011; Memory allocation error message ; NASM included file 1 <1> ; msbio.cl4 2 <1> 3 <1> 4 <1> ;_______________________ 5 <1> 0 000018DF 0D0A4D656D6F727920 Mem_alloc_err DB 13,10,"Memory allocation error ","$" 0 000018E8 616C6C6F636174696F 0 000018F1 6E206572726F722024 3211 ;=== Pop trace listing source 3212 3213 ; 3214 ;AN016; Undo the extended attribute handling 3215 ; public Get_Ext_Attribute 3216 ;Get_Ext_Attribute proc near ;AN008; 3217 ;;In: BX - file handle 3218 ;;Out: AL = The extended attribute got from the handle. 3219 ;; AX destroyed. 3220 ;; Carry set when DOS function call fails. 3221 ; 3222 ; push ds ;AN008; 3223 ; push si ;AN008; 3224 ; push es ;AN008; 3225 ; push di ;AN008; 3226 ; push cx ;AN008; 3227 ; 3228 ; push cs ;AN008; 3229 ; pop ds ;AN008; 3230 ; push cs ;AN008; 3231 ; pop es ;AN008; 3232 ; 3233 ; mov Ext_Attr_Value, 0ffh ;AN008; Initialize to unrealistic value 3234 ; mov ax, 5702h ;AN008;Get extended attribute by handle thru LIST 3235 ; mov si, offset EA_QueryList ;AN008; 3236 ; mov di, offset Ext_Attr_List ;AN008; 3237 ; mov cx, SIZE_EXT_ATTR_LIST ;AN008; 3238 ; int 21h ;AN008; 3239 ; mov al, Ext_Attr_Value ;AN008; 3240 ; pop cx ;AN008; 3241 ; pop di ;AN008; 3242 ; pop es ;AN008; 3243 ; pop si ;AN008; 3244 ; pop ds ;AN008; 3245 ; ret ;AN008; 3246 ;Get_Ext_Attribute endp ;AN008; 3247 3248 3249 ;------------------------------------------------------------------------------ 3250 3251 %ifndef BUF2 3252 DoEMS proc near 3253 ;******************************************************************************* 3254 ; Function: Called prior to DOBUFF subroutine. Only called when /E option * 3255 ; for the buffers= command has been specified. * 3256 ; This routine will check if the extended memory is avaiable, * 3257 ; and determine what is the page number. We only use physical page * 3258 ; 254. if it is there, then this routine will calculate the number * 3259 ; of pages needed for buffers and will allocate logical pages in the * 3260 ; extended memory and get the page handle of them. * 3261 ; * 3262 ; Input : * 3263 ; Buffers - Number of buffers * 3264 ; Buffer_LineNum - Saved line number to be used in case of Error case * 3265 ; * 3266 ; Output: * 3267 ; BuffINFO.EMS_Handle * 3268 ; Buffer_Pages = Number of pages for buffer in the extended memory. * 3269 ; BuffINFO.EMS_MODE = -1 No extended memory or Non-IBM compatible mode. * 3270 ; Buffers = the number will be changed to be a multiple of 30. * 3271 ; Carry set if no extended memory exist or if it is not big enough. * 3272 ; AX, BX, CX, DX destroyed. * 3273 ; * 3274 ; Logic: * 3275 ; { * 3276 ; Get EMS Version (AH=46h); * 3277 ; If (EMS not installed or it is not IBM compatible or * 3278 ; (Available_pages * 30 < Buffers) then * 3279 ; {Show error message "Error in CONFIG.SYS line #"; * 3280 ; Set carry; Exit }; * 3281 ; else * 3282 ; Buffer_Pages = Roundup(BUFFERS/30); /* Round up 30 buffers per page*/ * 3283 ; Buffers = Buffer_Pages * 30; /* Set the new number of Buffers*/* 3284 ; Allocate Buffer_Pages (AH=43h) and set EMS_Handle; * 3285 ; }; * 3286 ; * 3287 ;******************************************************************************* 3288 3289 push es ;AN000; 3290 push di ;AN000; save es, di 3291 push si ;AN010; 3292 push bx ;AN010; 3293 xor di,di ;AN004; if vector pointer of 3294 mov es, di ;AN004; EMS (INT 67h) is 0,0 3295 mov di, word ptr [es:EMS_INT * 4] ;AN004; then error. 3296 mov ax, word ptr [es:EMS_INT * 4 +2] ;AN009; 3297 or ax,di ;AN009; 3298 ; $IF NZ,AND,LONG ;AN004; 3299 JNZ DD_XL2 3300 JMP DD_IF18 3301 DD_XL2: 3302 les di, [cs:DosInfo] ;AN000; es:di -> SYSINITVAR 3303 les di, [es:di + SYSI_BUF] ;AN000; now, es:di -> BuffInfo 3304 3305 mov ah, EMS_STATUS ;AN000; get the status of EMS = 40h 3306 int EMS_INT ;AN000; 3307 or ah, ah ;AN000; EMS installed? 3308 ; $IF Z,AND,LONG ;AN000; 3309 JZ DD_XL3 3310 JMP DD_IF18 3311 DD_XL3: 3312 mov ah, EMS_VERSION ;AN010;=46h 3313 int EMS_INT ;AN010; 3314 cmp AL, EMSVERSION ;AN010;40h = 4.0 3315 ; $IF AE,AND,LONG ;AN010; 3316 JAE DD_XL4 3317 JMP DD_IF18 3318 DD_XL4: 3319 call Check_IBM_PageID ;AN000; IBM (compatible) mode? 3320 3321 %IF BUFFERFLAG 3322 mov ax, [cs:LAST_PAGE] 3323 mov [es:di + EMS_LAST_PAGE], ax 3324 mov ax, [cs:LAST_PAGE+2] 3325 mov [es:di + EMS_LAST_PAGE+2], ax 3326 mov ax, [cs:FIRST_PAGE] 3327 mov [es:di + EMS_FIRST_PAGE], ax 3328 mov ax, [cs:FIRST_PAGE+2] 3329 mov [es:di + EMS_FIRST_PAGE+2], ax 3330 mov ax, [cs:NPA640] 3331 mov [es:di + EMS_NPA640], ax 3332 mov byte [es:di + EMS_SAFE_FLAG], 1 3333 %ENDIF 3334 3335 ; $IF NC,AND,LONG ;AN000; 3336 JNC DD_XL5 3337 JMP DD_IF18 3338 DD_XL5: 3339 mov ah, EMAP_STATE ;AN010; Check if the size of 3340 mov al, GET_MAP_SIZE ;AN010; the MAP state table 3341 mov bx, 1 ;AN010; # of pages 3342 int EMS_INT ;AN010; is acceptable. 3343 or ah, ah ;AN010; 3344 ; $IF Z,AND ;AN010; 3345 JNZ DD_IF18 3346 cmp al, EMS_MAP_BUFF_SIZE ;AN010; Curretly=12 bytes 3347 ; $IF BE,AND ;AN010; 3348 JNBE DD_IF18 3349 mov ah, EQ_PAGES ;AN000; Get number of unallocated & total pages = 42h 3350 int EMS_INT ;AN000; result in BX 3351 xor dx, dx ;AN000; 3352 mov ax, [cs:Buffers] ;AN000; 3353 MAXBUFFINBUCKET equ MaxBuffinBucket ; NASM port equate 3354 mov cx, MAXBUFFINBUCKET*MAXBUCKETINPAGE ;AN000; 3355 call Roundup ;AN000; find out how many pages are needed. 3356 cmp bx, ax ;AN000; AX is the number of pages for [buffers] 3357 ; $IF AE,AND ;AN000; 3358 JNAE DD_IF18 3359 mov [cs:Buffer_Pages], ax ;AN000; 3360 mov bx, ax ;AN000; prepare for Get handle call. 3361 mul cx ;AN000; 3362 mov [cs:Buffers], ax ;AN000; set new [Buffers] for the extended memory. 3363 mov ah, E_GET_HANDLE ;AN000; allocate pages = 43h 3364 int EMS_INT ;AN000; page handle in DX. 3365 or ah, ah ;AN000; 3366 ; $IF Z ;AN000; pages allocated. 3367 JNZ DD_IF18 3368 mov ah, EMS_HANDLE_NAME ;AN010; 3369 mov al, SET_HANDLE_NAME ;AN010; 3370 push es ;AN010; 3371 push di ;AN010; 3372 push ds ;AN010; 3373 push cs ;AN010; 3374 pop ds ;AN010; 3375 mov si, offset EMSHandleName ;AN010; 3376 int EMS_INT ;AN010; Set the handle name 3377 pop ds ;AN010; 3378 pop di ;AN010; 3379 pop es ;AN010; 3380 xor ah,ah ;AN010; 3381 mov [es:di + EMS_MODE], ah ;AN000; put 0 in EMS_mode. 3382 EMS_HANDLE equ EMS_handle ; NASM port equate 3383 mov [es:di + EMS_HANDLE], dx ;AN000; save EMS handle 3384 mov ax, [cs:IBM_Frame_Seg] ;AN010; 3385 EMS_PAGE_FRAME equ EMS_Page_Frame ; NASM port equate 3386 mov [es:di + EMS_PAGE_FRAME],ax ;AN010; 3387 mov ax, [cs:Real_IBM_Page_Id] ;AN029; 3388 EMS_PAGEFRAME_NUMBER equ EMS_PageFrame_Number ; NASM port equate 3389 mov [es:di + EMS_PAGEFRAME_NUMBER], ax;AN029; 3390 mov ax, es ;AN010; 3391 EMS_Ctrl_tab equ EMS_Ctrl_Tab ; NASM port label 3392 mov word ptr [cs:EMS_Ctrl_tab+2],ax ;AN010; 3393 EMS_state_buf equ EMS_State_Buf ; NASM port label 3394 mov word ptr [cs:EMS_state_buf+2],ax;AN010; 3395 push di ;AN010;save di-> Buffinfo 3396 EMS_SEG_CNT equ EMS_Seg_Cnt ; NASM port equate 3397 add di, EMS_SEG_CNT ;AN010; 3398 mov word ptr [cs:EMS_Ctrl_tab], di ;AN010; 3399 pop di ;AN010; 3400 EMS_MAP_BUFF equ EMS_Map_Buff ; NASM port equate 3401 add di, EMS_MAP_BUFF ;AN010; 3402 EMS_state_Buf equ EMS_State_Buf ; NASM port label 3403 mov word ptr [cs:EMS_state_Buf],di ;AN010; 3404 clc ;AN000; 3405 ; $ELSE ;AN000; 3406 JMP SHORT DD_EN18 3407 DD_IF18: 3408 mov ax, [cs:Buffer_LineNum] ;AN000; Show error message. 3409 push word [cs:LineCount] ;AN017; Save current line count 3410 mov [cs:LineCount], ax ;AN000; Now, we can change Linecount 3411 call Error_Line ;AN000; since we are through with CONFIG.SYS file. 3412 pop word [cs:LineCount] ;AN017; Restore line count 3413 stc ;AN000; 3414 ; $ENDIF 3415 DD_EN18: 3416 pop bx ;AN010; 3417 pop si ;AN010; 3418 pop di ;AN000; 3419 pop es ;AN000; 3420 ret ;AN000; 3421 DoEMS endp 3422 3423 ; 3424 Set_Buffer proc near 3425 ;******************************************************************************* 3426 ;Function: Set buffers in the real memory. * 3427 ; For each hash table entry, set the pointer to the * 3428 ; corresponding hash bucket. * 3429 ; Lastly set the memhi, memlo for the next available free address. * 3430 ; ** At the request of IBMDOS, each hash bucket will start at the * 3431 ; ** new segment. * 3432 ; * 3433 ;Input: ds:bx -> BuffInfo. * 3434 ; [Memhi]:[MemLo = 0] = available space for the hash bucket. * 3435 ; BufferInfo.Hash_Ptr -> Hash table. * 3436 ; BufferBuckets = # of buckets to install. * 3437 ; SingleBufferSize = Buffer header size + Sector size * 3438 ; MaxNumBuff1 = Number of buffers in the first group of buckets * 3439 ; MaxNumBuff2 = Number of buffers in the second group of buckets * 3440 ; NthBuck = 1st thru Nth bucket are the first group * 3441 ; * 3442 ;Output: Buffers, hash buckets and Hash table entries established. * 3443 ; [Memhi]:[Memlo] = address of the next available free space. * 3444 ; * 3445 ; { For (every bucket) * 3446 ; { Set Hash table entry; * 3447 ; Next buffer ptr = buffer size; * 3448 ; For (every buffer in the bucket) * 3449 ; { Calll Set_Buffer_Info; /*Set link, id... */ * 3450 ; IF (last buffer in a bucket) THEN * 3451 ; {last buffer's next_ptr -> first buffer; * 3452 ; first buffer's prev_ptr -> last buffer; * 3453 ; }; * 3454 ; Next buffer ptr += buffer size; * 3455 ; }; * 3456 ; }; * 3457 ; MEMHI:MEMLO = Current Buffer_Bucket add + (# of odd * buffer size)* 3458 ; }; * 3459 ;******************************************************************************* 3460 3461 assume ds:nothing ;AN000;to make sure. 3462 lds bx, [bx + HASH_PTR] ;AN000;now, ds:bx -> hash table 3463 xor dx, dx ;AN026;To be used to count buckets 3464 ; $DO ;AN000;For each bucket 3465 DD_DO21: 3466 inc dl ;AN026; Current bucket number 3467 mov word ptr [bx + BUFFER_BUCKET],0 ;AN000;Memlo is 0 after ROUND. 3468 mov di, [ss:MemHi] ;AN000; 3469 mov word ptr [bx + BUFFER_BUCKET+2], di ;AN000;Hash entry set. 3470 mov word ptr [bx + DIRTY_COUNT], 0 ;AN020;set DIRTY_COUNT, BUFFER_RESERVED to 0. 3471 mov es, di ;AN000; 3472 xor di, di ;AN000;es:di -> hash bucket 3473 xor cx, cx ;AN000 3474 xor ax, ax ;AN000 3475 ; $DO ;AN000;For each buffer in the bucket 3476 DD_DO22: 3477 call Set_Buffer_Info ;AN000;Set buf_link, buf_id... 3478 inc cx ;AN000;buffer number 3479 cmp dl, [ss:NthBuck] ;AN026;Current bucket number > NthBuck? 3480 ; $IF BE ;AN026; 3481 JNBE DD_IF23 3482 cmp cl, [ss:MaxNumBuf1] ;AN026; last buffer of the 1st group? 3483 ; $ELSE ;AN026; 3484 JMP SHORT DD_EN23 3485 DD_IF23: 3486 cmp cl, [ss:MaxNumBuf2] ;AN026; last buffer of the 2nd group? 3487 ; $ENDIF ;AN026; 3488 DD_EN23: 3489 3490 ; $IF E ;AN020;Yes, last buffer 3491 JNE DD_IF26 3492 mov word ptr [es:di + BUF_NEXT], 0 ;AN020;the last buffer's next -> the first buffer in bucket (Circular chain) 3493 mov word ptr [es:BUF_PREV], di ;AN020;the first buffer's prev -> the last buffer 3494 ; $ENDIF ;AN020; 3495 DD_IF26: 3496 mov di, ax ;AN000;adjust next buffer position 3497 ; $ENDDO E ;AN000;flag set already for testing last buffer. 3498 JNE DD_DO22 3499 add [ss:Memlo], ax ;AN000;AX is the size of this bucket. 3500 or byte [ss:SetDevMarkFlag], FOR_DEVMARK ;AN005;Update DEVMARK_SIZE 3501 call Round ;AN000;memhi:memlo adjusted for the next bucket. 3502 add bx, BUFFER_HASH_ENTRY_struc_size ;AN000;ds:bx -> next hash entry. 3503 dec word [ss:BufferBuckets] ;AN000; 3504 ; $ENDDO Z ;AN000; 3505 JNZ DD_DO21 3506 ret ;AN000; 3507 Set_Buffer endp 3508 3509 ; 3510 Set_EMS_Buffer proc near 3511 ;******************************************************************************* 3512 ;Function: Set buffers in the extended memory. * 3513 ; For each hash table entry, set the pointer to the corresponding * 3514 ; hash bucket. * 3515 ; * 3516 ;Input: ds:bx -> BuffInfo. * 3517 ; BuffINFO.Hash_Ptr -> Hash table. * 3518 ; BuffINFO.EMS_Handle = EMS handle * 3519 ; Buffers = tatal # of buffers to install. * 3520 ; Multiple of MAXBUFFINBUCKET*MAXBUCKETINPAGE. * 3521 ; Buffer_Pages = # of extended memory pages for buffers. * 3522 ; BufferBuckets = # of buckets to install. * 3523 ; SingleBufferSize = Buffer header size + Sector size. * 3524 ; * 3525 ;Output: Buffers, hash buckets and Hash table entries established. * 3526 ; * 3527 ; { For (each page) * 3528 ; { Map the page; /*Map the page into Page frame * 3529 ; For (each bucket) /*Each page has two buckets */ * 3530 ; { * 3531 ; Set EMS_Page; * 3532 ; Set Buffer_Bucket; * 3533 ; Next buffer ptr = buffer size; * 3534 ; For (every buffer) /*A bucket has 15 buffers */ * 3535 ; { Set Buf_link to Next buffer ptr; * 3536 ; Set Buffer_ID to free; * 3537 ; If (last buffer in this bucket) THEN * 3538 ; {Buf_link = -1; * 3539 ; Next buffer ptr = 0; * 3540 ; }; * 3541 ; Next buffer ptr += buffer size; * 3542 ; }; * 3543 ; }; * 3544 ; }; * 3545 ; }; * 3546 ;******************************************************************************* 3547 3548 assume ds:nothing ;AN000;to make sure. 3549 3550 %IF BUFFERFLAG 3551 3552 push ax 3553 ems_save_buf equ EMS_SAVE_BUF ; NASM port label 3554 mov ax, offset ems_save_buf 3555 ems_state_buf equ EMS_State_Buf ; NASM port label 3556 mov word ptr [cs:ems_state_buf], ax 3557 push cs 3558 pop word ptr [cs:ems_state_buf+2] 3559 pop ax 3560 3561 %ENDIF 3562 3563 Save_MAP_State equ Save_Map_State ; NASM port label 3564 call Save_MAP_State ;AN010; 3565 EMS_Handle equ EMS_handle ; NASM port equate 3566 mov dx, [es:bx + EMS_Handle] ;AN000;save EMS_Handle 3567 lds si, [bx + HASH_PTR] ;AN000;now ds:si -> Hash table 3568 xor bx, bx ;AN000;starting logical page number. 3569 ; $DO ;AN000;For each page, 3570 DD_DO30: 3571 call Map_Page ;AN000;map it to IBM physical page 254. 3572 mov di, [cs:IBM_Frame_Seg] ;AN000; 3573 mov es, di ;AN000 3574 xor di, di ;AN000;es:di -> bucket 3575 xor ax, ax ;AN000 3576 xor cx, cx ;AN000 3577 ; $DO ;AN000;For each bucket, 3578 DD_DO31: 3579 mov [si + EMS_PAGE_NUM], bx ;AN000;set the logical page number in Hash table. 3580 mov word ptr [si + BUFFER_BUCKET], di ;AN000;set the offset in hash table for this bucket. 3581 mov word ptr [si + BUFFER_BUCKET+2], es ;AN000;set the segment value in hash table. 3582 mov word ptr [si + DIRTY_COUNT], 0 ;AN020;set DIRTY_COUNT, BUFFER_RESERVED to 0. 3583 push cx ;AN000;save bucket number 3584 xor cx, cx ;AN000; 3585 ; $DO ;AN000;For each buffer in a bucket, 3586 DD_DO32: 3587 call Set_Buffer_Info ;AN000;AX adjusted for the next buffer. 3588 inc cx ;AN000;inc number of buffers in this bucket. 3589 cmp cx, 1 ;AN020;The first buffer in the bucket? 3590 ; $IF E ;AN020; 3591 JNE DD_IF33 3592 mov [cs:EMS_Buf_First], di ;AN020;then save the offset value 3593 ; $ENDIF ;AN020; 3594 DD_IF33: 3595 cmp cx, MAXBUFFINBUCKET ;AN000; 3596 ; $IF E ;AN000 3597 JNE DD_IF35 3598 push word ptr [cs:EMS_Buf_First] ;AN020; 3599 pop word ptr [es:di + BUF_NEXT] ;AN020;the last buffer's next -> the first buffer in bucket (Circular chain) 3600 push di ;AN020;save di 3601 push di ;AN020;di-> last buffer 3602 mov di, [cs:EMS_Buf_First] ;AN020;es:di-> first buffer 3603 pop word ptr [es:di + BUF_PREV] ;AN020;the first buffer's prev -> the last buffer 3604 pop di ;AN020;restore di 3605 ; $ENDIF ;AN000; 3606 DD_IF35: 3607 mov di, ax ;AN000;advance di to the next buffer position. 3608 ; $ENDDO E ;AN000; 3609 JNE DD_DO32 3610 add si, BUFFER_HASH_ENTRY_struc_size ;AN000;ds:si -> next hash table entry 3611 pop cx ;AN000;restore bucket number 3612 inc cx ;AN000;next bucket 3613 cmp cx, MAXBUCKETINPAGE ;AN000;2 buckets per page 3614 ; $ENDDO E ;AN000; 3615 JNE DD_DO31 3616 inc bx ;AN000;increse logical page number 3617 cmp bx, [cs:Buffer_Pages] ;AN000;reached the maximum page number? 3618 ; $ENDDO E ;AN000; 3619 JNE DD_DO30 3620 Restore_MAP_State equ Restore_Map_State ; NASM port label 3621 call Restore_MAP_State ;AN010; 3622 ret ;AN000; 3623 Set_EMS_Buffer endp 3624 3625 3626 Set_Buffer_Info proc 3627 ;Function: Set buf_link, buf_id, Buf_Sector 3628 ;In: ES:DI -> Buffer header to be set. 3629 ; AX = DI 3630 ;Out: 3631 ; Above entries set. 3632 3633 3634 Buf_Prev_Off equ BUF_PREV_OFF ; NASM port label 3635 push word [ss:Buf_Prev_Off] ;AN020; 3636 pop word [es:di + BUF_PREV] ;AN020; 3637 mov [ss:Buf_Prev_Off], ax ;AN020; 3638 add ax, [ss:SingleBufferSize] ;AN000;adjust ax 3639 mov word ptr [es:di + BUF_NEXT], ax ;AN020; 3640 mov word ptr [es:di + BUF_ID], 00FFh ;AN000;new buffer free 3641 mov word ptr [es:di + BUF_SECTOR], 0 ;AN000;To compensate the MASM 3 bug 3642 mov word ptr [es:di + BUF_SECTOR+2],0 ;AN000;To compensate the MASM 3 bug 3643 ret ;AN000; 3644 Set_Buffer_Info endp 3645 3646 Check_IBM_PageID proc near 3647 ;Function: check if the physical page 255 exists. (Physical page 255 is only 3648 ; one we are intereseted in, and this will be used for BUFFER 3649 ; manipulation by IBMBIO, IBMDOS) 3650 ;In: nothing 3651 ;Out: Carry clear and IBM_Frame_Seg set if it exist. All registers saved. 3652 push es ;AN000; 3653 push ax ;AN000; 3654 push bx ;AN000; 3655 push cx ;AN000; 3656 push dx ;AN000; 3657 push di ;AN010; 3658 3659 %IFN BUFFERFLAG 3660 3661 mov ax, 1B00h ;AN029;AN030;AN0 Check EMS int 2fh installed. 3662 int 2fh ;AN029; 3663 cmp al, 0ffh ;AN029; 3664 jne Cp_IBM_Err ;AN029;If not installed, then no IBM page. 3665 mov ax, 1B01h ;AN029;AN030;Then ask if IBM page exists. 3666 mov di, IBM_PAGE_ID ;AN029;=255 3667 int 2fh ;AN029; 3668 or ah, ah ;AN029; 3669 jnz Cp_IBM_Err ;AN029;;No IBM Page 3670 mov [cs:IBM_Frame_Seg], es ;AN029;;Save Physical IBM page frame addr. 3671 mov [cs:Real_IBM_Page_Id], di ;AN029;;Real page number for it. 3672 clc ;AN029; 3673 jmp short Cp_ID_Ret ;AN029; 3674 3675 %ELSE 3676 push cs ;AN000; 3677 pop es ;AN000; 3678 mov ah, GET_PAGE_FRAME ;AN010;=58h 3679 mov al, GET_NUM_PAGEFRAME ;AN010;=01h How many page frames? 3680 int EMS_INT ;AN010; 3681 or ah, ah ;AN010; 3682 jnz hkn_err ;AN010; 3683 cmp cx, MAX_NUM_PAGEFRAME ;AN010; 3684 ja hkn_err ;AN010; cannot handle this big number 3685 push cx ;AN010; 3686 mov ah, GET_PAGE_FRAME ;AN010; 3687 mov al, GET_PAGEFRAME_TAB ;AN010; 3688 Frame_info_Buffer equ Frame_Info_Buffer ; NASM port label 3689 mov di, offset Frame_info_Buffer ;AN010; 3690 int EMS_INT ;AN010; 3691 pop cx ;AN010; 3692 or ah, ah ;AN010; 3693 cp_IBM_Err equ Cp_IBM_Err ; NASM port label 3694 jnz cp_IBM_Err ;AN010; 3695 Cp_IBM_ID: ;AN010; 3696 3697 ; mov dx, [es:di] 3698 ; mov [cs:FIRST_PAGE], dx 3699 ; mov dx, [es:di+2] 3700 ; mov [cs:FIRST_PAGE+2], dx 3701 3702 xor dx, dx 3703 3704 ; int 3 3705 find_page: 3706 cmp word [es:di], 0a000h ; is current page above 640K 3707 jb next ; NO - goto check_last 3708 3709 inc dx ; count the no. of pages above 640K 3710 3711 cmp dx, 1 3712 jne first_ok 3713 3714 mov ax, [es:di] 3715 mov [cs:FIRST_PAGE], ax 3716 mov ax, [es:di+2] 3717 mov [cs:FIRST_PAGE+2], ax 3718 3719 first_ok: 3720 mov ax, [cs:FIRST_PAGE] 3721 cmp ax, [es:di] ; is this page less than the one we have in 3722 ; FIRST_PAGE 3723 jbe check_last ; NO - goto check_last 3724 mov ax, [es:di] ; update FIRST_PAGE with this page segment 3725 mov [cs:FIRST_PAGE], ax 3726 mov ax, [es:di+2] 3727 mov [cs:FIRST_PAGE+2], ax 3728 jmp next 3729 nop ; identicalise 3730 3731 cp_ibm_err equ Cp_IBM_Err ; NASM port label 3732 hkn_err: jmp cp_ibm_err 3733 nop ; identicalise 3734 3735 check_last: 3736 mov ax, [cs:LAST_PAGE] ; 3737 cmp ax, [es:di] ; is this page greater than the one we have in 3738 ; LAST_PAGE? 3739 ja next ; NO - goto next 3740 mov ax, [es:di] ; update LAST_PAGE with this value. 3741 mov [cs:LAST_PAGE], ax 3742 mov ax, [es:di+2] 3743 mov [cs:LAST_PAGE+2], ax 3744 3745 next: 3746 add di, 4 3747 loop find_page 3748 3749 cmp dx, 3 ; there should be at least 3 pages 3750 ; above 640K for the buffers to be 3751 ; installed. 3752 jb Cp_IBM_Err 3753 3754 mov ax, [cs:LAST_PAGE] 3755 mov [cs:IBM_Frame_Seg], ax 3756 mov ax, [cs:LAST_PAGE+2] 3757 mov [cs:Real_IBM_Page_Id], ax 3758 mov [cs:NPA640], dx 3759 clc 3760 Cp_Id_Ret equ Cp_ID_Ret ; NASM port label 3761 jmp short Cp_Id_Ret 3762 3763 %ENDIF 3764 3765 3766 ; cmp word ptr [es:di+2], IBM_PAGE_ID ;AN010; the second word is the id 3767 ; je Got_IBM_ID ;AN010; 3768 ; add di, 4 ;AN010; advance to the next row (4 bytes) 3769 ; loop Cp_IBM_ID ;AN010; 3770 3771 Cp_IBM_Err: ;AN010;;AN029; 3772 stc ;AN000;;AN029; 3773 jmp short Cp_ID_Ret ;AN000;;AN029; 3774 3775 ;Got_IBM_ID: ;AN000; 3776 ; mov ax, word ptr [es:di] ;AN010;Physical seg. addr. 3777 ; mov cs:IBM_Frame_Seg, ax ;AN000; 3778 ; clc ;AN000; 3779 Cp_ID_Ret: ;AN000; 3780 pop di ;AN010; 3781 pop dx ;AN000; 3782 pop cx ;AN000; 3783 pop bx ;AN000; 3784 pop ax ;AN000; 3785 pop es ;AN000; 3786 ret ;AN000; 3787 Check_IBM_PageID endp 3788 3789 ; 3790 Save_Map_State proc ;AN010; 3791 ;Function: Save the map state. 3792 ;In) 3793 ; EMS_Ctrl_Tab = double word pointer to EMS_state control table address 3794 ; EMS_state_Buf = double word pointer to EMS_MAP_BUFF address 3795 ;Out) Map state saved 3796 push ax ;AN010; 3797 push ds ;AN010; 3798 push si ;AN010; 3799 push es ;AN010; 3800 push di ;AN010; 3801 lds si, [cs:EMS_Ctrl_Tab] ;AN010; 3802 les di, [cs:EMS_state_Buf] ;AN010; 3803 mov ah, EMAP_STATE ;AN010; =4Fh 3804 mov al, GET_MAP_STATE ;AN010; =00h 3805 int EMS_INT ;AN010; 3806 pop di ;AN010; 3807 pop es ;AN010; 3808 pop si ;AN010; 3809 pop ds ;AN010; 3810 pop ax ;AN010; 3811 ret ;AN010; 3812 Save_Map_State endp 3813 ; 3814 Restore_Map_State proc ;AN010; 3815 push ax ;AN010; 3816 push ds ;AN010; 3817 push si ;AN010; 3818 lds si, [cs:EMS_state_Buf] ;AN010; 3819 mov ah, EMAP_STATE ;AN010; 3820 mov al, SET_MAP_STATE ;AN010; 3821 int EMS_INT ;AN010; 3822 pop si ;AN010; 3823 pop ds ;AN010; 3824 pop ax ;AN010; 3825 ret ;AN010; 3826 Restore_Map_State endp 3827 ; 3828 Map_Page proc near ;AN000; 3829 ;Function: Map the logical page in BX of handle in DX to the physical page 255 3830 ;In) 3831 ; BX = logical page number 3832 ; DX = EMS handle 3833 ; EMS_Ctrl_Tab = double word pointer to EMS_state control table address 3834 ; EMS_state_Buf = double word pointer to EMS_MAP_BUFF address 3835 ;Out) Logical page mapped into first phsical page frame. 3836 ; AX saved. 3837 3838 push ax ;AN000; 3839 mov ah, EMAP_L_TO_P ;AN000; 3840 Real_IBM_PAGE_ID equ Real_IBM_Page_Id ; NASM port label 3841 mov al, byte ptr [cs:Real_IBM_PAGE_ID] ;AN029;= 255 3842 int EMS_INT ;AN000; 3843 pop ax ;AN000; 3844 ret ;AN000; 3845 Map_Page endp ;AN000; 3846 ; 3847 %endif ; BUF2 3848 3849 Roundup proc 3850 ;In: DX;AX - operand 3851 ; CX - divisor 3852 ; Important: DX should be less than CX. 3853 ;out: AX - Quotient (Rounded up) 3854 0 000018FA F7F1 div cx ;AN000; 0 000018FC 09D2 or dx, dx ;AN000; 0 000018FE 7401 jz RU_ret ;AN000; 0 00001900 40 inc AX ;AN000; 3859 RU_ret: ;AN000; 0 00001901 C3 ret ;AN000; 3861 Roundup endp 3862 ;------------------------------------------------------------------------------ 3863 ;J.K. 5/6/86. IBMSTACK initialization routine. 3864 %IF STACKSW 3865 ;.SALL 3866 3867 ;=== Push trace listing source: stkinit.nas 3868 %include "stkinit.nas" ; NASM included file 1 <1> ; 2 <1> ; To follow the standard interrupt sharing scheme, MSSTACK.ASM ;3.30 3 <1> ; has been modified. This initialization routine also has to ;3.30 4 <1> ; be modified because for the interrupt level 7 and 15, FirstFlag ;3.30 5 <1> ; should be set to signal that this interrupt handler is the ;3.30 6 <1> ; first handler hooked to this interrupt vector. ;3.30 7 <1> ; We determine this by looking at the instruction pointed by ;3.30 8 <1> ; this vector. If it is IRET, then this handler should be the ;3.30 9 <1> ; first one. In our case, only the interrupt vector 77h is the ;3.30 10 <1> ; interrupt level 15. (We don't hook interrupt level 7.) ;3.30 11 <1> ; 9/10/1986 ;3.30 12 <1> ; The followings are mainly due to M.R.T; PTM fix of P886 12/3/86;3.30 13 <1> ; Some design changes are needed to the above interrupt sharing ;3.30 14 <1> ; method. The above sharing scheme assumes that 1). Interrupt ;3.30 15 <1> ; sharing is NEVER done on levels that have BIOS support. 2). "Phantom" ;3.30 16 <1> ; interrupts would only be generated on levels 7 and 15. ;3.30 17 <1> ; These assumptions are not true any more. We have to use the FirstFlag ;3.30 18 <1> ; for EVERY level of interrupt. We will set the firstFlag on the following;3.30 19 <1> ; conditions: ;3.30 20 <1> ; a. if the CS portion of the vector is 0000, then "first" ;3.30 21 <1> ; b. else if CS:IP points to valid shared header, then NOT "first" ;3.30 22 <1> ; c. else if CS:IP points to an IRET, then "first" ;3.30 23 <1> ; d. else if CS:IP points to DUMMY, then "first" ;3.30 24 <1> ; where DUMMY is - the CS portion must be F000, and the IP portion must ;3.30 25 <1> ; be equal to the value at F000:FF01. This location is the initial value ;3.30 26 <1> ; from VECTOR_TABLE for interrupt 7, one of the preserved addresses in all;3.30 27 <1> ; the BIOSes for all of the machines. ;3.30 28 <1> ; ;3.30 29 <1> ; System design group requests BIOS to handle the phantom interrupts. ;3.30 30 <1> ; ;3.30 31 <1> ; The "Phantom" interrupt is an illegal interrupt such as an interrupt ;3.30 32 <1> ; produced by the bogus adapter card even without interrupt request is ;3.30 33 <1> ; set. More specifically, 1). The 8259 has a feature when running in ;3.30 34 <1> ; edge triggered mode to latch a pulse and present the interrupt when ;3.30 35 <1> ; the processor indicates interrupt acknowledge (INTA). The interrupt ;3.30 36 <1> ; pulse was exist at the time of INTA to get a "phantom" interrupt. ;3.30 37 <1> ; 2). or, this is caused by adapter cards placing a glitch on the ;3.30 38 <1> ; interrupt line. ;3.30 39 <1> ; ;3.30 40 <1> ; To handle those "phantom" interrupts, the main stack code will check ;3.30 41 <1> ; the own FirstFlag, and if it is not "first" (which means the forward ;3.30 42 <1> ; pointer points to the legal shared interrupt handler), then pass the ;3.30 43 <1> ; control. If it is the first, then the following action should be ;3.30 44 <1> ; taken. We don't have to implement skack logic in this case. ;3.30 45 <1> ; ;3.30 46 <1> ; To implement this logic, we rather choose a simple method. ;3.30 47 <1> ; If ont of the above "FirstFlag" conditions is met, we are not ;3.30 48 <1> ; going to hook this interrupt vector. The reason is if the original ;3.30 49 <1> ; vector points to "IRET" and do nothing, we don't need ;3.30 50 <1> ; to implement the stack logic for it. This will simplify implementation;3.30 51 <1> ; while maintaining compatibility with the old version of DOS. ;3.30 52 <1> ; This implies that in the main stack code, there might be a stack code ;3.30 53 <1> ; that will never be used, a dead code. ;3.30 54 <1> ; ;3.30 55 <1> ; 12/3/86 ;3.30 56 <1> ;3.30 57 <1> ;In - CS, DS -> sysinitseg, ES -> relocated stack code & data. ;3.30 58 <1> ;3.30 59 <1> ; PAGE ;3.30 60 <1> assume ds:sysinitseg ; sunilp SB340 61 <1> StackInit proc near ;3.30 62 <1> ;3.30 0 00001902 50 PUSH AX ;SAVE ALL ;3.30 0 00001903 1E PUSH DS ;3.30 0 00001904 06 PUSH ES ;3.30 0 00001905 53 PUSH BX ;3.30 0 00001906 51 PUSH CX ;3.30 0 00001907 52 PUSH DX ;3.30 0 00001908 57 PUSH DI ;3.30 0 00001909 56 PUSH SI ;3.30 0 0000190A 55 PUSH BP ;3.30 72 <1> ;3.30 73 <1> ;Currently ES -> stack code area ;3.30 0 0000190B 2EA1[0A08] MOV AX, [cs:STACK_COUNT] ;defined in CS ;3.30 75 <1> STACKCOUNT equ StackCount ; NASM port label 0 0000190F 26A3[0200] MOV [es:STACKCOUNT], AX ;defined in STACK CODE AREA ;3.30 0 00001913 A1[0C08] MOV AX, [STACK_SIZE] ;in CS ;3.30 78 <1> STACKSIZE equ StackSize ; NASM port label 0 00001916 26A3[0600] MOV [es:STACKSIZE], AX ; ;3.30 0 0000191A 2EA1[0E08] MOV AX, WORD PTR [cs:STACK_ADDR] ; OFFSET ;3.30 0 0000191E 26A3[0800] MOV WORD PTR [es:STACKS], AX ;3.30 0 00001922 2EA1[1008] MOV AX, WORD PTR [cs:STACK_ADDR+2] ; SEGMENT ;3.30 0 00001926 26A3[0A00] MOV WORD PTR [es:STACKS+2], AX ;3.30 84 <1> ;3.30 85 <1> ; INITIALIZE THE DATA FIELDS WITH THE PARAMETERS ;3.30 86 <1> ;3.30 87 <1> ; "FIRSTENTRY" WILL ALWAYS BE AT STACKS ;3.30 88 <1> ;3.30 0 0000192A 268B2E[0800] MOV BP, word ptr [es:STACKS] ; GET OFFSET OF STACK ;3.30 90 <1> FIRSTENTRY equ FirstEntry ; NASM port label 0 0000192F 26892E[0C00] MOV [es:FIRSTENTRY],BP ;3.30 92 <1> ;3.30 93 <1> ; THE STACKS WILL ALWAYS IMMEDIATELY FOLLOW THE TABLE ENTRIES ;3.30 94 <1> ;3.30 95 <1> ENTRYSIZE equ EntrySize ; NASM port equate 0 00001934 B80800 MOV AX,ENTRYSIZE ;3.30 0 00001937 268B0E[0200] MOV CX,[es:STACKCOUNT] ;3.30 0 0000193C F7E1 MUL CX ;3.30 0 0000193E 01E8 ADD AX,BP ;3.30 100 <1> STACKAT equ StackAt ; NASM port label 0 00001940 26A3[0400] MOV [es:STACKAT],AX ;3.30 0 00001944 89C3 MOV BX,AX ;3.30 0 00001946 83EB02 SUB BX,2 ;3.30 104 <1> ;3.30 105 <1> ; ZERO THE ENTIRE STACK AREA TO START WITH ;3.30 106 <1> ;3.30 0 00001949 268B3E[0400] MOV DI,[es:STACKAT] ;3.30 0 0000194E 26A1[0600] MOV AX,[es:STACKSIZE] ;3.30 0 00001952 F7E1 MUL CX ;3.30 0 00001954 89C1 MOV CX,AX ;3.30 0 00001956 31C0 xor ax,ax ;3.30 0 00001958 06 push es ;3.30 0 00001959 1F pop ds ;ds = Relocated stack code seg.;3.30 114 <1> assume ds:nothing ;3.30 115 <1> ;Now, DS -> stack code area ;3.30 0 0000195A 8E06[0A00] MOV ES, word ptr [STACKS+2] ; GET SEGMENT OF STACK AREA.;3.30 0 0000195E FC CLD ;3.30 0 0000195F F3AA REP STOSB ;3.30 119 <1> ;3.30 0 00001961 8B0E[0200] MOV CX, [STACKCOUNT] ;3.30 121 <1> ;3.30 122 <1> ; LOOP FOR "COUNT" TIMES, BUILDING A TABLE ENTRY ;3.30 123 <1> ; cs = sysinitseg, ds = Relocated stack code seg , es = segment of stack space;3.30 124 <1> ; CX = NUMBER OF ENTRIES ;3.30 125 <1> ; ES:BP => BASE OF STACKS - 2 ;3.30 126 <1> ; ES:BX => FIRST TABLE ENTRY ;3.30 127 <1> ;3.30 128 <1> BUILDLOOP: ;3.30 129 <1> FREE equ Free ; NASM port equate 0 00001965 26C6460000 MOV byte [ALLOCBYTE],FREE ;3.30 0 0000196A 26884601 MOV [INTLEVEL],AL ;AX = 0 ;3.30 0 0000196E 26894602 MOV [SAVEDSP],AX ;3.30 0 00001972 26894604 MOV [SAVEDSS],AX ;3.30 0 00001976 031E[0600] ADD BX,[STACKSIZE] ;3.30 0 0000197A 26895E06 MOV [NEWSP],BX ;3.30 0 0000197E 26892F MOV [ES:BX],BP ;3.30 0 00001981 83C508 ADD BP,ENTRYSIZE ;3.30 138 <1> ;3.30 0 00001984 E2DF LOOP BUILDLOOP ;3.30 140 <1> ;3.30 0 00001986 83ED08 SUB BP,ENTRYSIZE ;3.30 142 <1> LASTENTRY equ LastEntry ; NASM port label 0 00001989 892E[0E00] MOV [LASTENTRY],BP ;3.30 144 <1> NEXTENTRY equ NextEntry ; NASM port label 0 0000198D 892E[1000] MOV [NEXTENTRY],BP ;3.30 146 <1> ;3.30 0 00001991 1E push ds ;3.30 0 00001992 B800F0 mov ax, 0f000h ;loook at the model byte ;3.30 0 00001995 8ED8 mov ds, ax ;3.30 0 00001997 803EFEFFF9 cmp byte ptr [0fffeh], mdl_convert ;convertible? ;3.30 0 0000199C 1F pop ds ;3.30 0 0000199D 7504 jne Skip_disableNMIS ;3.30 153 <1> ;3.30 0 0000199F B007 MOV AL,07H ; DISABLE Convertible NMIS ;3.30 0 000019A1 E672 OUT 72H,AL ;3.30 156 <1> ;3.30 157 <1> Skip_disableNMIS: ;3.30 0 000019A3 31C0 XOR AX,AX ;3.30 0 000019A5 8EC0 MOV es,AX ;es - SEGID OF VECTOR TABLE AT 0;3.30 160 <1> ASSUME es:NOTHING ;ds - Relocated Stack code segment;3.30 161 <1> ;3.30 0 000019A7 FA CLI ;3.30 163 <1> 164 <1> %macro init_first_irq 1-* 165 <1> %rep %0 166 <1> MOV SI, offset %1H*4 ;PASS WHERE VECTOR IS TO BE ADJUSTED ;3.30 167 <1> mov di, offset Int19OLD%1 ;we have to set OLD&AA for Int19 handler too.;3.30 168 <1> MOV BX,OFFSET OLD%1 ;PASS WHERE TO SAVE ORIGINAL OWNER POINTER;3.30 169 <1> MOV DX,OFFSET INT%1 ;PASS WHERE NEW HANDLER IS ;3.30 170 <1> CALL NEW_INIT_LOOP ;ADJUST THE VECTOR TO NEW HANDLER, ;3.30 171 <1> ; SAVING POINTER TO ORIGINAL OWNER ;3.30 172 <1> %rotate 1 173 <1> %endrep 174 <1> %endmacro 175 <1> 176 <1> init_first_irq 02,08,09,70 165 <2> %rep %0 166 <2> MOV SI, offset %1H*4 167 <2> mov di, offset Int19OLD%1 168 <2> MOV BX,OFFSET OLD%1 169 <2> MOV DX,OFFSET INT%1 170 <2> CALL NEW_INIT_LOOP 171 <2> 172 <2> %rotate 1 173 <2> %endrep 0 000019A8 BE0800 MOV SI, offset %1H*4 0 000019AB BF[0000] mov di, offset Int19OLD%1 0 000019AE BB[1200] MOV BX,OFFSET OLD%1 0 000019B1 BA[1600] MOV DX,OFFSET INT%1 0 000019B4 E8D402 CALL NEW_INIT_LOOP 171 <3> 172 <3> %rotate 1 0 000019B7 BE2000 MOV SI, offset %1H*4 0 000019BA BF[0000] mov di, offset Int19OLD%1 0 000019BD BB[A700] MOV BX,OFFSET OLD%1 0 000019C0 BA[AB00] MOV DX,OFFSET INT%1 0 000019C3 E8C502 CALL NEW_INIT_LOOP 171 <3> 172 <3> %rotate 1 0 000019C6 BE2400 MOV SI, offset %1H*4 0 000019C9 BF[0000] mov di, offset Int19OLD%1 0 000019CC BB[2101] MOV BX,OFFSET OLD%1 0 000019CF BA[2501] MOV DX,OFFSET INT%1 0 000019D2 E8B602 CALL NEW_INIT_LOOP 171 <3> 172 <3> %rotate 1 0 000019D5 BEC001 MOV SI, offset %1H*4 0 000019D8 BF[0000] mov di, offset Int19OLD%1 0 000019DB BB[A001] MOV BX,OFFSET OLD%1 0 000019DE BA[A401] MOV DX,OFFSET INT%1 0 000019E1 E8A702 CALL NEW_INIT_LOOP 171 <3> 172 <3> %rotate 1 177 <1> 178 <1> %macro init_second_irq 1-* 179 <1> %rep %0 180 <1> MOV SI, offset %1H*4 ;PASS WHERE VECTOR IS TO BE ADJUSTED ;3.30 181 <1> push ds ;save relocated stack code segment ;3.30 182 <1> lds bx, [es:si] ;ds:bx -> original interrupt handler ;3.30 183 <1> push ds ;3.30 184 <1> pop dx ;dx = segment value ;3.30 185 <1> 186 <1> cmp dx,0 187 <1> jz int%1_first 188 <1> 189 <1> cmp byte ptr [bx],0cfh ;Does vector point to an IRET? 190 <1> jz int%1_first 191 <1> 192 <1> cmp word ptr [bx + 6],424Bh ;Magic offset (see INT&AA, msstack.inc) 193 <1> jz int%1_Not_first 194 <1> 195 <1> cmp dx,0f000h ;ROM BIOS segment 196 <1> jnz int%1_Not_first 197 <1> 198 <1> push es 199 <1> push dx 200 <1> mov dx,0f000h 201 <1> mov es,dx 202 <1> cmp bx,word ptr [es:0ff01h] 203 <1> pop dx 204 <1> pop es 205 <1> jz int%1_first 206 <1> 207 <1> int%1_Not_first: ;Not the first. We are going to hook vector.;3.30 208 <1> pop ds ;3.30 209 <1> mov di, offset Int19OLD%1 ;we have to set OLD&AA for Int19 handler too.;3.30 210 <1> mov BX, OFFSET OLD%1 ;PASS WHERE TO SAVE ORIGINAL OWNER POINTER;3.30 211 <1> MOV DX, OFFSET INT%1 ;PASS WHERE NEW HANDLER IS ;3.30 212 <1> CALL NEW_INIT_LOOP ;ADJUST THE VECTOR TO NEW HANDLER, SAVING;3.30 213 <1> ;POINTER TO ORIGINAL OWNER. ;3.30 214 <1> jmp short int%1_end ;3.30 215 <1> int%1_first: ;the first. Don't have to hook stack code.;3.30 216 <1> pop ds ;3.30 217 <1> int%1_end: ;3.30 218 <1> ;3.30 219 <1> %rotate 1 220 <1> %endrep 221 <1> %endmacro 222 <1> 223 <1> init_second_irq 0A,0B,0C,0D,0E,72,73,74,76,77 ;shared interrupts 179 <2> %rep %0 180 <2> MOV SI, offset %1H*4 181 <2> push ds 182 <2> lds bx, [es:si] 183 <2> push ds 184 <2> pop dx 185 <2> 186 <2> cmp dx,0 187 <2> jz int%1_first 188 <2> 189 <2> cmp byte ptr [bx],0cfh 190 <2> jz int%1_first 191 <2> 192 <2> cmp word ptr [bx + 6],424Bh 193 <2> jz int%1_Not_first 194 <2> 195 <2> cmp dx,0f000h 196 <2> jnz int%1_Not_first 197 <2> 198 <2> push es 199 <2> push dx 200 <2> mov dx,0f000h 201 <2> mov es,dx 202 <2> cmp bx,word ptr [es:0ff01h] 203 <2> pop dx 204 <2> pop es 205 <2> jz int%1_first 206 <2> 207 <2> int%1_Not_first: 208 <2> pop ds 209 <2> mov di, offset Int19OLD%1 210 <2> mov BX, OFFSET OLD%1 211 <2> MOV DX, OFFSET INT%1 212 <2> CALL NEW_INIT_LOOP 213 <2> 214 <2> jmp short int%1_end 215 <2> int%1_first: 216 <2> pop ds 217 <2> int%1_end: 218 <2> 219 <2> %rotate 1 220 <2> %endrep 0 000019E4 BE2800 MOV SI, offset %1H*4 0 000019E7 1E push ds 0 000019E8 26C51C lds bx, [es:si] 0 000019EB 1E push ds 0 000019EC 5A pop dx 185 <3> 0 000019ED 83FA00 cmp dx,0 0 000019F0 7431 jz int%1_first 188 <3> 0 000019F2 803FCF cmp byte ptr [bx],0cfh 0 000019F5 742C jz int%1_first 191 <3> 0 000019F7 817F064B42 cmp word ptr [bx + 6],424Bh 0 000019FC 7416 jz int%1_Not_first 194 <3> 0 000019FE 81FA00F0 cmp dx,0f000h 0 00001A02 7510 jnz int%1_Not_first 197 <3> 0 00001A04 06 push es 0 00001A05 52 push dx 0 00001A06 BA00F0 mov dx,0f000h 0 00001A09 8EC2 mov es,dx 0 00001A0B 263B1E01FF cmp bx,word ptr [es:0ff01h] 0 00001A10 5A pop dx 0 00001A11 07 pop es 0 00001A12 740F jz int%1_first 206 <3> 207 <3> int%1_Not_first: 0 00001A14 1F pop ds 0 00001A15 BF[0000] mov di, offset Int19OLD%1 0 00001A18 BB[1C02] mov BX, OFFSET OLD%1 0 00001A1B BA[1A02] MOV DX, OFFSET INT%1 0 00001A1E E86A02 CALL NEW_INIT_LOOP 213 <3> 0 00001A21 EB01 jmp short int%1_end 215 <3> int%1_first: 0 00001A23 1F pop ds 217 <3> int%1_end: 218 <3> 219 <3> %rotate 1 0 00001A24 BE2C00 MOV SI, offset %1H*4 0 00001A27 1E push ds 0 00001A28 26C51C lds bx, [es:si] 0 00001A2B 1E push ds 0 00001A2C 5A pop dx 185 <3> 0 00001A2D 83FA00 cmp dx,0 0 00001A30 7431 jz int%1_first 188 <3> 0 00001A32 803FCF cmp byte ptr [bx],0cfh 0 00001A35 742C jz int%1_first 191 <3> 0 00001A37 817F064B42 cmp word ptr [bx + 6],424Bh 0 00001A3C 7416 jz int%1_Not_first 194 <3> 0 00001A3E 81FA00F0 cmp dx,0f000h 0 00001A42 7510 jnz int%1_Not_first 197 <3> 0 00001A44 06 push es 0 00001A45 52 push dx 0 00001A46 BA00F0 mov dx,0f000h 0 00001A49 8EC2 mov es,dx 0 00001A4B 263B1E01FF cmp bx,word ptr [es:0ff01h] 0 00001A50 5A pop dx 0 00001A51 07 pop es 0 00001A52 740F jz int%1_first 206 <3> 207 <3> int%1_Not_first: 0 00001A54 1F pop ds 0 00001A55 BF[0000] mov di, offset Int19OLD%1 0 00001A58 BB[A402] mov BX, OFFSET OLD%1 0 00001A5B BA[A202] MOV DX, OFFSET INT%1 0 00001A5E E82A02 CALL NEW_INIT_LOOP 213 <3> 0 00001A61 EB01 jmp short int%1_end 215 <3> int%1_first: 0 00001A63 1F pop ds 217 <3> int%1_end: 218 <3> 219 <3> %rotate 1 0 00001A64 BE3000 MOV SI, offset %1H*4 0 00001A67 1E push ds 0 00001A68 26C51C lds bx, [es:si] 0 00001A6B 1E push ds 0 00001A6C 5A pop dx 185 <3> 0 00001A6D 83FA00 cmp dx,0 0 00001A70 7431 jz int%1_first 188 <3> 0 00001A72 803FCF cmp byte ptr [bx],0cfh 0 00001A75 742C jz int%1_first 191 <3> 0 00001A77 817F064B42 cmp word ptr [bx + 6],424Bh 0 00001A7C 7416 jz int%1_Not_first 194 <3> 0 00001A7E 81FA00F0 cmp dx,0f000h 0 00001A82 7510 jnz int%1_Not_first 197 <3> 0 00001A84 06 push es 0 00001A85 52 push dx 0 00001A86 BA00F0 mov dx,0f000h 0 00001A89 8EC2 mov es,dx 0 00001A8B 263B1E01FF cmp bx,word ptr [es:0ff01h] 0 00001A90 5A pop dx 0 00001A91 07 pop es 0 00001A92 740F jz int%1_first 206 <3> 207 <3> int%1_Not_first: 0 00001A94 1F pop ds 0 00001A95 BF[0000] mov di, offset Int19OLD%1 0 00001A98 BB[2C03] mov BX, OFFSET OLD%1 0 00001A9B BA[2A03] MOV DX, OFFSET INT%1 0 00001A9E E8EA01 CALL NEW_INIT_LOOP 213 <3> 0 00001AA1 EB01 jmp short int%1_end 215 <3> int%1_first: 0 00001AA3 1F pop ds 217 <3> int%1_end: 218 <3> 219 <3> %rotate 1 0 00001AA4 BE3400 MOV SI, offset %1H*4 0 00001AA7 1E push ds 0 00001AA8 26C51C lds bx, [es:si] 0 00001AAB 1E push ds 0 00001AAC 5A pop dx 185 <3> 0 00001AAD 83FA00 cmp dx,0 0 00001AB0 7431 jz int%1_first 188 <3> 0 00001AB2 803FCF cmp byte ptr [bx],0cfh 0 00001AB5 742C jz int%1_first 191 <3> 0 00001AB7 817F064B42 cmp word ptr [bx + 6],424Bh 0 00001ABC 7416 jz int%1_Not_first 194 <3> 0 00001ABE 81FA00F0 cmp dx,0f000h 0 00001AC2 7510 jnz int%1_Not_first 197 <3> 0 00001AC4 06 push es 0 00001AC5 52 push dx 0 00001AC6 BA00F0 mov dx,0f000h 0 00001AC9 8EC2 mov es,dx 0 00001ACB 263B1E01FF cmp bx,word ptr [es:0ff01h] 0 00001AD0 5A pop dx 0 00001AD1 07 pop es 0 00001AD2 740F jz int%1_first 206 <3> 207 <3> int%1_Not_first: 0 00001AD4 1F pop ds 0 00001AD5 BF[0000] mov di, offset Int19OLD%1 0 00001AD8 BB[B403] mov BX, OFFSET OLD%1 0 00001ADB BA[B203] MOV DX, OFFSET INT%1 0 00001ADE E8AA01 CALL NEW_INIT_LOOP 213 <3> 0 00001AE1 EB01 jmp short int%1_end 215 <3> int%1_first: 0 00001AE3 1F pop ds 217 <3> int%1_end: 218 <3> 219 <3> %rotate 1 0 00001AE4 BE3800 MOV SI, offset %1H*4 0 00001AE7 1E push ds 0 00001AE8 26C51C lds bx, [es:si] 0 00001AEB 1E push ds 0 00001AEC 5A pop dx 185 <3> 0 00001AED 83FA00 cmp dx,0 0 00001AF0 7431 jz int%1_first 188 <3> 0 00001AF2 803FCF cmp byte ptr [bx],0cfh 0 00001AF5 742C jz int%1_first 191 <3> 0 00001AF7 817F064B42 cmp word ptr [bx + 6],424Bh 0 00001AFC 7416 jz int%1_Not_first 194 <3> 0 00001AFE 81FA00F0 cmp dx,0f000h 0 00001B02 7510 jnz int%1_Not_first 197 <3> 0 00001B04 06 push es 0 00001B05 52 push dx 0 00001B06 BA00F0 mov dx,0f000h 0 00001B09 8EC2 mov es,dx 0 00001B0B 263B1E01FF cmp bx,word ptr [es:0ff01h] 0 00001B10 5A pop dx 0 00001B11 07 pop es 0 00001B12 740F jz int%1_first 206 <3> 207 <3> int%1_Not_first: 0 00001B14 1F pop ds 0 00001B15 BF[0000] mov di, offset Int19OLD%1 0 00001B18 BB[3C04] mov BX, OFFSET OLD%1 0 00001B1B BA[3A04] MOV DX, OFFSET INT%1 0 00001B1E E86A01 CALL NEW_INIT_LOOP 213 <3> 0 00001B21 EB01 jmp short int%1_end 215 <3> int%1_first: 0 00001B23 1F pop ds 217 <3> int%1_end: 218 <3> 219 <3> %rotate 1 0 00001B24 BEC801 MOV SI, offset %1H*4 0 00001B27 1E push ds 0 00001B28 26C51C lds bx, [es:si] 0 00001B2B 1E push ds 0 00001B2C 5A pop dx 185 <3> 0 00001B2D 83FA00 cmp dx,0 0 00001B30 7431 jz int%1_first 188 <3> 0 00001B32 803FCF cmp byte ptr [bx],0cfh 0 00001B35 742C jz int%1_first 191 <3> 0 00001B37 817F064B42 cmp word ptr [bx + 6],424Bh 0 00001B3C 7416 jz int%1_Not_first 194 <3> 0 00001B3E 81FA00F0 cmp dx,0f000h 0 00001B42 7510 jnz int%1_Not_first 197 <3> 0 00001B44 06 push es 0 00001B45 52 push dx 0 00001B46 BA00F0 mov dx,0f000h 0 00001B49 8EC2 mov es,dx 0 00001B4B 263B1E01FF cmp bx,word ptr [es:0ff01h] 0 00001B50 5A pop dx 0 00001B51 07 pop es 0 00001B52 740F jz int%1_first 206 <3> 207 <3> int%1_Not_first: 0 00001B54 1F pop ds 0 00001B55 BF[0000] mov di, offset Int19OLD%1 0 00001B58 BB[C404] mov BX, OFFSET OLD%1 0 00001B5B BA[C204] MOV DX, OFFSET INT%1 0 00001B5E E82A01 CALL NEW_INIT_LOOP 213 <3> 0 00001B61 EB01 jmp short int%1_end 215 <3> int%1_first: 0 00001B63 1F pop ds 217 <3> int%1_end: 218 <3> 219 <3> %rotate 1 0 00001B64 BECC01 MOV SI, offset %1H*4 0 00001B67 1E push ds 0 00001B68 26C51C lds bx, [es:si] 0 00001B6B 1E push ds 0 00001B6C 5A pop dx 185 <3> 0 00001B6D 83FA00 cmp dx,0 0 00001B70 7431 jz int%1_first 188 <3> 0 00001B72 803FCF cmp byte ptr [bx],0cfh 0 00001B75 742C jz int%1_first 191 <3> 0 00001B77 817F064B42 cmp word ptr [bx + 6],424Bh 0 00001B7C 7416 jz int%1_Not_first 194 <3> 0 00001B7E 81FA00F0 cmp dx,0f000h 0 00001B82 7510 jnz int%1_Not_first 197 <3> 0 00001B84 06 push es 0 00001B85 52 push dx 0 00001B86 BA00F0 mov dx,0f000h 0 00001B89 8EC2 mov es,dx 0 00001B8B 263B1E01FF cmp bx,word ptr [es:0ff01h] 0 00001B90 5A pop dx 0 00001B91 07 pop es 0 00001B92 740F jz int%1_first 206 <3> 207 <3> int%1_Not_first: 0 00001B94 1F pop ds 0 00001B95 BF[0000] mov di, offset Int19OLD%1 0 00001B98 BB[4C05] mov BX, OFFSET OLD%1 0 00001B9B BA[4A05] MOV DX, OFFSET INT%1 0 00001B9E E8EA00 CALL NEW_INIT_LOOP 213 <3> 0 00001BA1 EB01 jmp short int%1_end 215 <3> int%1_first: 0 00001BA3 1F pop ds 217 <3> int%1_end: 218 <3> 219 <3> %rotate 1 0 00001BA4 BED001 MOV SI, offset %1H*4 0 00001BA7 1E push ds 0 00001BA8 26C51C lds bx, [es:si] 0 00001BAB 1E push ds 0 00001BAC 5A pop dx 185 <3> 0 00001BAD 83FA00 cmp dx,0 0 00001BB0 7431 jz int%1_first 188 <3> 0 00001BB2 803FCF cmp byte ptr [bx],0cfh 0 00001BB5 742C jz int%1_first 191 <3> 0 00001BB7 817F064B42 cmp word ptr [bx + 6],424Bh 0 00001BBC 7416 jz int%1_Not_first 194 <3> 0 00001BBE 81FA00F0 cmp dx,0f000h 0 00001BC2 7510 jnz int%1_Not_first 197 <3> 0 00001BC4 06 push es 0 00001BC5 52 push dx 0 00001BC6 BA00F0 mov dx,0f000h 0 00001BC9 8EC2 mov es,dx 0 00001BCB 263B1E01FF cmp bx,word ptr [es:0ff01h] 0 00001BD0 5A pop dx 0 00001BD1 07 pop es 0 00001BD2 740F jz int%1_first 206 <3> 207 <3> int%1_Not_first: 0 00001BD4 1F pop ds 0 00001BD5 BF[0000] mov di, offset Int19OLD%1 0 00001BD8 BB[D405] mov BX, OFFSET OLD%1 0 00001BDB BA[D205] MOV DX, OFFSET INT%1 0 00001BDE E8AA00 CALL NEW_INIT_LOOP 213 <3> 0 00001BE1 EB01 jmp short int%1_end 215 <3> int%1_first: 0 00001BE3 1F pop ds 217 <3> int%1_end: 218 <3> 219 <3> %rotate 1 0 00001BE4 BED801 MOV SI, offset %1H*4 0 00001BE7 1E push ds 0 00001BE8 26C51C lds bx, [es:si] 0 00001BEB 1E push ds 0 00001BEC 5A pop dx 185 <3> 0 00001BED 83FA00 cmp dx,0 0 00001BF0 7431 jz int%1_first 188 <3> 0 00001BF2 803FCF cmp byte ptr [bx],0cfh 0 00001BF5 742C jz int%1_first 191 <3> 0 00001BF7 817F064B42 cmp word ptr [bx + 6],424Bh 0 00001BFC 7416 jz int%1_Not_first 194 <3> 0 00001BFE 81FA00F0 cmp dx,0f000h 0 00001C02 7510 jnz int%1_Not_first 197 <3> 0 00001C04 06 push es 0 00001C05 52 push dx 0 00001C06 BA00F0 mov dx,0f000h 0 00001C09 8EC2 mov es,dx 0 00001C0B 263B1E01FF cmp bx,word ptr [es:0ff01h] 0 00001C10 5A pop dx 0 00001C11 07 pop es 0 00001C12 740F jz int%1_first 206 <3> 207 <3> int%1_Not_first: 0 00001C14 1F pop ds 0 00001C15 BF[0000] mov di, offset Int19OLD%1 0 00001C18 BB[5C06] mov BX, OFFSET OLD%1 0 00001C1B BA[5A06] MOV DX, OFFSET INT%1 0 00001C1E E86A00 CALL NEW_INIT_LOOP 213 <3> 0 00001C21 EB01 jmp short int%1_end 215 <3> int%1_first: 0 00001C23 1F pop ds 217 <3> int%1_end: 218 <3> 219 <3> %rotate 1 0 00001C24 BEDC01 MOV SI, offset %1H*4 0 00001C27 1E push ds 0 00001C28 26C51C lds bx, [es:si] 0 00001C2B 1E push ds 0 00001C2C 5A pop dx 185 <3> 0 00001C2D 83FA00 cmp dx,0 0 00001C30 7431 jz int%1_first 188 <3> 0 00001C32 803FCF cmp byte ptr [bx],0cfh 0 00001C35 742C jz int%1_first 191 <3> 0 00001C37 817F064B42 cmp word ptr [bx + 6],424Bh 0 00001C3C 7416 jz int%1_Not_first 194 <3> 0 00001C3E 81FA00F0 cmp dx,0f000h 0 00001C42 7510 jnz int%1_Not_first 197 <3> 0 00001C44 06 push es 0 00001C45 52 push dx 0 00001C46 BA00F0 mov dx,0f000h 0 00001C49 8EC2 mov es,dx 0 00001C4B 263B1E01FF cmp bx,word ptr [es:0ff01h] 0 00001C50 5A pop dx 0 00001C51 07 pop es 0 00001C52 740F jz int%1_first 206 <3> 207 <3> int%1_Not_first: 0 00001C54 1F pop ds 0 00001C55 BF[0000] mov di, offset Int19OLD%1 0 00001C58 BB[E406] mov BX, OFFSET OLD%1 0 00001C5B BA[E206] MOV DX, OFFSET INT%1 0 00001C5E E82A00 CALL NEW_INIT_LOOP 213 <3> 0 00001C61 EB01 jmp short int%1_end 215 <3> int%1_first: 0 00001C63 1F pop ds 217 <3> int%1_end: 218 <3> 219 <3> %rotate 1 224 <1> 0 00001C64 1E push ds ;3.30 0 00001C65 B800F0 mov ax, 0f000h ;loook at the model byte ;3.30 0 00001C68 8ED8 mov ds, ax ;3.30 0 00001C6A 803EFEFFF9 cmp byte ptr [0fffeh], mdl_convert ;PC convertible? ;3.30 0 00001C6F 1F pop ds ;3.30 0 00001C70 7504 jne Skip_EnableNMIS ;3.30 231 <1> ;3.30 0 00001C72 B027 MOV AL,27H ; ENABLE Convertible NMIS ;3.30 0 00001C74 E672 OUT 72H,AL ;3.30 234 <1> ;3.30 235 <1> Skip_EnableNMIS: ;3.30 0 00001C76 FB STI ;3.30 0 00001C77 B8[0000] MOV AX, DOSENTRY ;3.30 0 00001C7A 8ED8 MOV DS,AX ;3.30 239 <1> ASSUME DS:BIOCODE ;3.30 240 <1> ;3.30 241 <1> ; MOV SI,OFFSET STKMSG1 ;3.30 242 <1> ; CALL WRMSG ;3.30 243 <1> ;3.30 244 <1> INT19SEM equ Int19sem ; NASM port label 0 00001C7C C606[0000]01 mov byte [INT19SEM],1 ; INDICATE THAT INT 19 ;3.30 246 <1> ; INITIALIZATION IS COMPLETE ;3.30 247 <1> ;3.30 0 00001C81 5D POP BP ; RESTORE ALL ;3.30 0 00001C82 5E POP SI ;3.30 0 00001C83 5F POP DI ;3.30 0 00001C84 5A POP DX ;3.30 0 00001C85 59 POP CX ;3.30 0 00001C86 5B POP BX ;3.30 254 <1> ;3.30 0 00001C87 07 POP ES ;3.30 0 00001C88 1F POP DS ;3.30 257 <1> assume ds:sysinitseg ;3.30 0 00001C89 58 POP AX ;3.30 0 00001C8A C3 RET ;3.30 260 <1> STACKINIT ENDP ;3.30 261 <1> ; ;3.30 262 <1> ;3.30 263 <1> NEW_INIT_LOOP PROC NEAR ;3.30 264 <1> ;INPUT: SI=OFSET INTO VECTOR TABLE OF THE PARTICULAR INT VECTOR BEING ADJUSTED ;3.30 265 <1> ; BX=ds:OFFSET OF OLDxx, WHERE WILL BE SAVED THE POINTER TO ORIGINAL OWNER;3.30 266 <1> ; DX=ds:OFFSET OF INTxx, THE NEW INTERRUPT HANDLER ;3.30 267 <1> ; di=offset value of Int19OLD&AA variable in BIOS. ;3.30 268 <1> ; es=ZERO, SEGID OF VECTOR TABLE ;3.30 269 <1> ; ds=Relocated Stack code segment ;3.30 270 <1> ;3.30 0 00001C8B 268B04 MOV AX,[es:SI+0] ;REMEMBER OFFSET IN VECTOR ;3.30 0 00001C8E 8907 MOV WORD PTR [BX],AX ; TO ORIGINAL OWNER in DS ;3.30 0 00001C90 268B4402 MOV AX,[es:SI+2] ;REMEMBER SEGID IN VECTOR ;3.30 0 00001C94 894702 MOV WORD PTR [BX + 2],AX ; TO ORIGINAL OWNER in DS ;3.30 0 00001C97 1E push ds ;3.30 0 00001C98 B8[0000] mov ax, DOSENTRY ;3.30 0 00001C9B 8ED8 mov ds, ax ;Set Int19OLDxx value in BIOS for ;3.30 0 00001C9D 268B04 mov ax,[es:si+0] ;Int 19 handler ;3.30 0 00001CA0 8905 mov word ptr [di],ax ;3.30 0 00001CA2 268B4402 mov ax,[es:si+2] ;3.30 0 00001CA6 894502 mov word ptr [di + 2],ax ;3.30 0 00001CA9 1F pop ds ;3.30 283 <1> ;3.30 0 00001CAA 268914 MOV WORD PTR [es:SI+0],DX ;SET VECTOR TO POINT TO NEW INT HANDLER ;3.30 0 00001CAD 268C5C02 MOV [es:SI+2],ds ;3.30 0 00001CB1 C3 RET ;3.30 287 <1> NEW_INIT_LOOP ENDP ;3.30 288 <1> ;3.30 3869 ;=== Pop trace listing source 3870 3871 ;.XALL 3872 %ENDIF 3873 ;------------------------------------------------------------------------------ 3874 3875 %if 0 3876 public SetDevMark 3877 SetDevMark proc 3878 ;Set the DEVMARK for MEM command. 3879 ;In: [MEMHI] - the address to place DEVMARK 3880 ; [MEMLO] = 0 3881 ; AL = ID for DEVMARK_ID 3882 ;OUT: DEVMARK established. 3883 ; the address saved in [cs:DevMark_Addr] 3884 ; [MEMHI] increase by 1. 3885 3886 push es ;AN005; 3887 push cx ;AN005; 3888 3889 mov cx, [cs:memhi] ;AN005; 3890 mov [cs:DevMark_Addr],cx ;AN005; 3891 mov es, cx ;AN005; 3892 mov [es:DEVMARK_ID], al ;AN005; 3893 inc cx ;AN007; 3894 mov [es:DEVMARK_SEG], cx ;AN007; 3895 3896 pop cx ;AN005; 3897 pop es ;AN005; 3898 inc word [cs:memhi] ;AN005; 3899 ret ;AN005; 3900 SetDevMark endp 3901 %endif 3902 3903 ;******************************************************************************* 3904 ;Function: Load SHARE.EXE, if Big_Media_Flag = 1 and SHARE.EXE has not been * 3905 ; loaded yet. * 3906 ; This routine will use the same path for SHELL= command. * 3907 ; If SHELL= command has not been entered, then default to the root * 3908 ; directory. * 3909 ; If load fails, then issue message "Warning: SHARE.EXE not loaded" * 3910 ; * 3911 ;Input: Big_Media_Flag, COMMND * 3912 ;Output: Share.exe loaded if necessary. * 3913 ; * 3914 ;******************************************************************************* 3915 LoadShare proc near ;AN021; 0 00001CB2 803E[0908]01 cmp byte [Big_Media_Flag], 1 ;AN021; 0 00001CB7 754E jne LShare_Ret ;AN021; 3918 ;Check if SHARE is already loaded. 0 00001CB9 B80010 mov ax, 1000h ;AN021;multShare installation check 0 00001CBC CD2F int 2fh ;AN021; 0 00001CBE 3CFF cmp al, 0ffh ;AN021; 0 00001CC0 7445 jz LShare_Ret ;AN021;Share already loaded! 3923 ;SHARE not loaded. 0 00001CC2 0E push cs ;AN021; 0 00001CC3 1F pop ds ;AN021; 0 00001CC4 0E push cs ;AN021; 0 00001CC5 07 pop es ;AN021; 0 00001CC6 BE[0000] mov si, offset COMMND ;AN021; 0 00001CC9 BF[0000] mov di, offset PathString ;AN021; 3930 LShare_String: ;AN021; 0 00001CCC A4 movsb ;AN021; 0 00001CCD 807DFF00 cmp byte ptr [di-1], 0 ;AN021;reached to the end? 3933 LShare_string equ LShare_String ; NASM port label 0 00001CD1 75F9 jne LShare_string ;AN021; 0 00001CD3 BE[0000] mov si, offset PathString ;AN021;SI= start of PathString 3936 LShare_Tail: ;AN021; 0 00001CD6 4F dec di ;AN021; 0 00001CD7 803D5C cmp byte ptr [di], "\" ;AN021; 0 00001CDA 740B je LShare_Got_Tail ;AN021; 0 00001CDC 803D3A cmp byte ptr [di], ":" ;AN021; 0 00001CDF 7406 je LShare_Got_Tail ;AN021; 0 00001CE1 39F7 cmp di, si ;AN021;No path case (e.g. SHELL=command.com) 0 00001CE3 7403 je LShare_Got_Tail_0 ;AN021; 0 00001CE5 EBEF jmp LShare_Tail ;AN021; 3945 LShare_Got_Tail: ;AN021;di -> "\" or ":" 0 00001CE7 47 inc di ;AN021; 3947 LShare_Got_Tail_0: ;AN021; 0 00001CE8 BE[0000] mov si, offset LShare ;AN021; 3949 LShare_Set_Filename: ;AN021; 0 00001CEB A4 movsb ;AN021;Tag "SHARE.EXE",0,0Ah to the path. 0 00001CEC 807DFF0A cmp byte ptr [di-1], 0Ah ;AN021;Line feed? 0 00001CF0 75F9 jne LShare_Set_Filename ;AN021; 3953 ;Now, we got a path,filename with no parameters for SHARE.EXE 0 00001CF2 BE[0000] mov si, offset PathString ;AN021; 0 00001CF5 830E[6608]04 or word [Install_Flag], SHARE_INSTALL ;AN021;Signals Do_Install_Exec that this is for SHARE.EXE. 0 00001CFA E8EAFA call Do_Install_Exec ;AN021;execute it. 0 00001CFD 7308 jnc LShare_Ret ;AN021;No problem 3958 ;Load/Exec failed. Show "Warning: SHARE should be loaded for large media" 0 00001CFF 0E push cs ;AN021; 0 00001D00 1F pop ds ;AN021; 0 00001D01 BA[0000] mov dx, offset ShareWarnMsg ;AN021;WARNING! SHARE should be loaded... 0 00001D04 E8[0000] invoke Print ;AN021; 3963 LShare_Ret: ;AN021; 0 00001D07 C3 ret ;AN021; 3965 LoadShare endp ;AN021; 3966 3967 ; (no prior section) ; SYSINITSEG ENDS 3968 3969 3970 global init2_relocate_device 3971 global init2_SNextMCB 3972 extern dosentry_xmsentry 3973 %include "codesw.mac" 1 <1> DOSCODE_HMA_SEGMENT equ 0FFFEh 2 <1> ; address DOSCODE at this segment when in HMA 3 <1> DOSCODE_HMA_start_at equ (10000h - DOSCODE_HMA_SEGMENT) * 10h 4 <1> ; offset from DOSCODE offset 0 to address 10_0000h 5 <1> DOSCODE_HMA_OFFSET equ DOSCODE_HMA_start_at + 30h 6 <1> ; 50h = 20h ROM-BIOS, 20h VDISK header, 10h HMCB 3974 %include "init.asm" 1 <1> 2 <1> %if 0 3 <1> 4 <1> lDOS initialisation 5 <1> by E. C. Masloch, 2018--2025 6 <1> 7 <1> Usage of the works is permitted provided that this 8 <1> instrument is retained with the works, so that any entity 9 <1> that uses the works is notified of this instrument. 10 <1> 11 <1> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY. 12 <1> 13 <1> %endif 14 <1> 15 <1> 16 <1> %include "lmacros2.mac" 1 <2> [list -] 17 <1> %include "lstruct.mac" 1 <2> [list -] 18 <1> 19 <1> defaulting 20 <1> 21 <1> numdef DEBUG0 22 <1> numdef DEBUG1 23 <1> numdef DEBUG2 24 <1> numdef DEBUG3 25 <1> numdef DEBUG4 26 <1> numdef DEBUG5 27 <1> %idefine d5 _d 5, 28 <1> 29 <1> %assign _UMA 1 30 <1> %assign _COMBINED_DOSDATA_DOSCODE 0 31 <1> numdef DOSCODEHMA, 1 32 <1> numdef RELOCATEDOSCODE, 1 33 <1> numdef INT19_IN_DOSENTRY, 1 34 <1> strdef BIN_FILE_DEFAULT, "LDOS.COM" 35 <1> numdef TEST_PAYLOAD, 0 36 <1> numdef INIT_ENV_SIZE, 1024 37 <1> 38 <1> %if _RELOCATEDOSCODE 39 <1> %define DOSCODE_SIZE (doscode_end - doscode_start) 40 <1> %define DOSCODE_MCB_SIZE 16 41 <1> %else 42 <1> %define DOSCODE_SIZE 0 43 <1> %define DOSCODE_MCB_SIZE 0 44 <1> %endif 45 <1> 46 <1> 47 <1> %if 0 ; lMS-DOS doesn't use these parts yet 48 <1> 49 <1> struc FSPARM 50 <1> fspStart: resd 1 51 <1> fspLength: resd 1 52 <1> fspUnit: resb 1 53 <1> fspPartition: resb 1 54 <1> fspBoot: resb 1 55 <1> fspType: resb 1 56 <1> fspSectorSize: resw 1 57 <1> resw 1 58 <1> endstruc 59 <1> 60 <1> 61 <1> %ifndef _MAP 62 <1> %elifempty _MAP 63 <1> %else ; defined non-empty, str or non-str 64 <1> [map all _MAP] 65 <1> %endif 66 <1> 67 <1> 68 <1> cpu 8086 69 <1> ; section INIT0 start=0 vstart=0 70 <1> init0_start: 71 <1> nop 72 <1> align 32, nop 73 <1> init0_kernel_entry: 74 <1> ; cs:ip = load seg : 32 here 75 <1> %if ($ - $$) != 32 76 <1> %error Wrong kernel mode entrypoint 77 <1> %endif 78 <1> cld 79 <1> mov ax, cs 80 <1> add ax, (init0_end - init0_start) >> 4 81 <1> mov cx, ( 16 + (dosentry_end - dosentry_start) + DOSCODE_MCB_SIZE + DOSCODE_SIZE + 16 + (dosdata_end - dosdata_start) + 16 + (init1_end - init1_start) + 16 + (init2_end - init2_start) + 16 + (init3_end - init3_start) + 16 ) >> 4 95 <1> mov dx, word [ bp + ldLoadTop ] 96 <1> sub dx, cx 97 <1> call init0_movp 98 <1> 99 <1> mov ax, dx 100 <1> add ax, ( + 16 + (dosentry_end - dosentry_start) + DOSCODE_MCB_SIZE + DOSCODE_SIZE + 16 + (dosdata_end - dosdata_start) + 16 ) >> 4 109 <1> xor bx, bx 110 <1> push ax 111 <1> push bx 112 <1> retf 113 <1> 114 <1> align 64, nop 115 <1> init0_exe_entry: 116 <1> ; cs:ip = PSP : 256 + 64 here 117 <1> ; 118 <1> ; Code must be position independent enough. 119 <1> %if ($ - $$) != 64 120 <1> %error Wrong EXE mode entrypoint 121 <1> %endif 122 <1> mov cx, cs 123 <1> add cx, ( 256 + (init0_end - init0_start) + 16 + (dosentry_end - dosentry_start) + DOSCODE_MCB_SIZE + DOSCODE_SIZE + 16 + (dosdata_end - dosdata_start) + 16 + (init1_end - init1_start) + 16 + (init2_end - init2_start) + 16 + (init3_end - init3_start) + 16 + COMLOADER_position ) >> 4 140 <1> xor bx, bx 141 <1> push cx 142 <1> push bx 143 <1> retf 144 <1> 145 <1> 146 <1> ; Move paragraphs 147 <1> ; 148 <1> ; INP: ax:0-> source 149 <1> ; dx:0-> destination 150 <1> ; cx = number of paragraphs 151 <1> ; CHG: - 152 <1> ; Note: Doesn't work correctly on HMA; doesn't always wrap to LMA either. 153 <1> ; Do not provide a wrapped/HMA source or destination! 154 <1> init0_movp: 155 <1> push cx 156 <1> push ds 157 <1> push si 158 <1> push es 159 <1> push di 160 <1> 161 <1> cmp ax, dx ; source above destination ? 162 <1> ja .up ; yes, move up (forwards) --> 163 <1> je .return ; same, no need to move --> 164 <1> push ax 165 <1> add ax, cx ; (expected not to carry) 166 <1> cmp ax, dx ; end of source is above destination ? 167 <1> pop ax 168 <1> ja .down ; yes, move from top down --> 169 <1> ; Here, the end of source is below-or-equal the destination, 170 <1> ; so they do not overlap. In this case we prefer moving up. 171 <1> 172 <1> .up: 173 <1> push ax 174 <1> push dx 175 <1> .uploop: 176 <1> mov ds, ax 177 <1> mov es, dx 178 <1> xor di, di 179 <1> xor si, si ; -> start of segment 180 <1> sub cx, 1000h ; 64 KiB left ? 181 <1> jbe .uplast ; no --> 182 <1> push cx 183 <1> mov cx, 10000h /2 184 <1> rep movsw ; move 64 KiB 185 <1> pop cx 186 <1> add ax, 1000h 187 <1> add dx, 1000h ; -> next segment 188 <1> jmp short .uploop ; proceed for more --> 189 <1> .uplast: 190 <1> add cx, 1000h ; restore counter 191 <1> shl cx, 1 192 <1> shl cx, 1 193 <1> shl cx, 1 ; *8, paragraphs to words 194 <1> rep movsw ; move last part 195 <1> pop dx 196 <1> pop ax 197 <1> jmp short .return 198 <1> 199 <1> .down: 200 <1> std ; _AMD_ERRATUM_109_WORKAROUND as below 201 <1> .dnloop: 202 <1> sub cx, 1000h ; 64 KiB left ? 203 <1> jbe .dnlast ; no --> 204 <1> push ax 205 <1> push dx 206 <1> add ax, cx 207 <1> add dx, cx 208 <1> mov ds, ax ; -> 64 KiB not yet moved 209 <1> mov es, dx 210 <1> pop dx 211 <1> pop ax 212 <1> mov di, -2 213 <1> mov si, di ; moved from last word down 214 <1> push cx 215 <1> mov cx, 10000h /2 216 <1> rep movsw ; move 64 KiB 217 <1> pop cx 218 <1> jmp short .dnloop ; proceed for more --> 219 <1> .dnlast: 220 <1> add cx, 1000h ; restore counter 221 <1> shl cx, 1 222 <1> shl cx, 1 223 <1> shl cx, 1 ; *8, paragraphs to words 224 <1> mov di, cx 225 <1> dec di 226 <1> shl di, 1 ; words to offset, -> last word 227 <1> mov si, di 228 <1> mov ds, ax 229 <1> mov es, dx ; first segment correct 230 <1> 231 <1> 232 <1> numdef AMD_ERRATUM_109_WORKAROUND, 1 233 <1> %if 0 234 <1> 235 <1> Jack R. Ellis pointed out this erratum: 236 <1> 237 <1> Quoting from https://www.amd.com/system/files/TechDocs/25759.pdf page 69: 238 <1> 239 <1> 109 Certain Reverse REP MOVS May Produce Unpredictable Behavior 240 <1> 241 <1> Description 242 <1> 243 <1> In certain situations a REP MOVS instruction may lead to 244 <1> incorrect results. An incorrect address size, data size 245 <1> or source operand segment may be used or a succeeding 246 <1> instruction may be skipped. This may occur under the 247 <1> following conditions: 248 <1> 249 <1> * EFLAGS.DF=1 (the string is being moved in the reverse direction). 250 <1> 251 <1> * The number of items being moved (RCX) is between 1 and 20. 252 <1> 253 <1> * The REP MOVS instruction is preceded by some microcoded instruction 254 <1> that has not completely retired by the time the REP MOVS begins 255 <1> execution. The set of such instructions includes BOUND, CLI, LDS, 256 <1> LES, LFS, LGS, LSS, IDIV, and most microcoded x87 instructions. 257 <1> 258 <1> Potential Effect on System 259 <1> 260 <1> Incorrect results may be produced or the system may hang. 261 <1> 262 <1> Suggested Workaround 263 <1> 264 <1> Contact your AMD representative for information on a BIOS update. 265 <1> 266 <1> %endif 267 <1> 268 <1> %if _AMD_ERRATUM_109_WORKAROUND 269 <1> jcxz @FF 270 <1> cmp cx, 20 271 <1> ja @FF 272 <1> @@: 273 <1> movsw 274 <1> loop @B 275 <1> @@: 276 <1> %endif 277 <1> rep movsw ; move first part 278 <1> cld 279 <1> .return: 280 <1> pop di 281 <1> pop es 282 <1> pop si 283 <1> pop ds 284 <1> pop cx 285 <1> retn 286 <1> 287 <1> align 16 288 <1> init0_end: 289 <1> istruc MCB 290 <1> at mcbSignature, db "M" 291 <1> at mcbOwner, dw 8 292 <1> at mcbSize, dw (dosentry_end - dosentry_start) >> 4 293 <1> at smcbName, dw "S" 294 <1> at smcbType, db S_DOSENTRY 295 <1> iend 296 <1> 297 <1> ; section DOSENTRY align=16 follows=INIT0 vstart=0 298 <1> dosentry_start: 299 <1> %include "entry.asm" 300 <1> 301 <1> %if _RELOCATEDOSCODE 302 <1> align 16 303 <1> dosentry_end: 304 <1> istruc MCB 305 <1> at mcbSignature, db "M" 306 <1> at mcbOwner, dw 8 307 <1> at mcbSize, dw (doscode_end - doscode_start) >> 4 308 <1> at smcbName, dw "S" 309 <1> at smcbType, db S_DOSCODE 310 <1> iend 311 <1> 312 <1> ; section DOSCODE align=16 follows=DOSENTRY vstart=40h 313 <1> ; vstart: 314 <1> ; +10h for end of ROM-BIOS image (at 0FFFFh:0) 315 <1> ; +20h for VDISK header 316 <1> ; +10h for first HMCB 317 <1> doscode_start: 318 <1> %endif 319 <1> 320 <1> %if !_COMBINED_DOSDATA_DOSCODE 321 <1> 322 <1> ; The following table and function is used by devicerelocate 323 <1> ; even if DOSCODE is merged into DOSENTRY (!_RELOCATEDOSCODE). 324 <1> 325 <1> write_entrypoint_list ENTRYPOINT_LIST 326 <1> 327 <1> 328 <1> %if _RELOCATEDOSCODE && _DOSCODEHMA 329 <1> _fill 0C0h + DOSCODE_HMA_start_at, 90h, doscode_start 330 <1> hma_call5: 331 <1> jmp 70h:call5 332 <1> %endif 333 <1> 334 <1> 335 <1> ; INP: byte [cs:ip] = displacement in doscode_entrypoint_list 336 <1> ; word [DOSCODE:(displaced)] 337 <1> ; = relocated entry address 338 <1> ; word [DOSCODE:(displaced + 2)] 339 <1> ; = optional pointer to device function table 340 <1> ; byte [DOSCODE:(displaced + 4)] 341 <1> ; = optional device unit 342 <1> ; ss:(sp + 8) -> arbitrary stack of entrypoint 343 <1> ; word [ss:sp + 6] = entrypoint's ip, 344 <1> ; word [ss:sp + 4] = entrypoint's cs, 345 <1> ; word [ss:sp + 2] = original flags value, 346 <1> ; word [ss:sp + 0] = original ax value, 347 <1> relocated_relocatedentry: 348 <1> lframe 0 349 <1> lpar word, entrypoint_ip 350 <1> lpar word, entrypoint_cs 351 <1> lpar word, orig_fl 352 <1> lpar word, orig_ax 353 <1> lenter 354 <1> push ds 355 <1> push si 356 <1> 357 <1> cld 358 <1> xor ax, ax 359 <1> mov ds, word [bp + ?entrypoint_cs] 360 <1> mov si, word [bp + ?entrypoint_ip] 361 <1> lodsb 362 <1> cmp al, 0CCh ; overwritten by debugger ? 363 <1> jne @F ; no --> 364 <1> int3 ; break to make it remove the breakpoint 365 <1> dec si 366 <1> lodsb ; reload the byte 367 <1> cmp al, 0CCh 368 <1> jne @F 369 <1> 370 <1> .error: 371 <1> mov si, doscode_msg.error_common 372 <1> call doscode_disp_msg_cs 373 <1> mov si, doscode_msg.error_table 374 <1> call doscode_disp_msg_cs 375 <1> mov si, doscode_msg.error_after 376 <1> call doscode_disp_msg_cs 377 <1> .loop: 378 <1> int3 379 <1> xor ax, ax 380 <1> int 16h 381 <1> jmp .loop 382 <1> 383 <1> @@: 384 <1> push cs 385 <1> pop ds 386 <1> 387 <1> add ax, doscode_entrypoint_list 388 <1> cmp ax, doscode_entrypoint_list.end 389 <1> jae .error 390 <1> xchg ax, si 391 <1> 392 <1> lodsw ; get relocated entry address 393 <1> cmp ax, DEVStrategy ; set ZF iff DEVStrategy 394 <1> 395 <1> xchg word [bp + ?orig_fl], ax ; store address in ?orig_fl, ax = fl 396 <1> xchg word [bp + ?orig_ax], ax ; store fl in ?orig_ax, ax = orig ax 397 <1> 398 <1> push ax 399 <1> lodsw 400 <1> mov word [bp + ?entrypoint_ip], ax 401 <1> 402 <1> mov ah, 0 403 <1> lodsb 404 <1> mov word [bp + ?entrypoint_cs], ax 405 <1> pop ax 406 <1> 407 <1> pop si 408 <1> pop ds 409 <1> lleave 410 <1> je .is_dev_strat ; dispatch based on ZF 411 <1> popf ; (fl = ?orig_ax = fl) 412 <1> retn 4 ; (ip = ?orig_fl = address) 413 <1> 414 <1> .is_dev_strat: 415 <1> popf 416 <1> retn 417 <1> 418 <1> 419 <1> doscode_disp_msg_cs: 420 <1> push ax 421 <1> @@: 422 <1> cs lodsb 423 <1> test al, al 424 <1> jz @F 425 <1> call doscode_disp_al 426 <1> jmp short @B 427 <1> 428 <1> 429 <1> doscode_disp_al: 430 <1> push ax 431 <1> push bx 432 <1> push bp 433 <1> mov ah, 0Eh 434 <1> mov bx, 7 435 <1> int 10h 436 <1> pop bp 437 <1> pop bx 438 <1> @@: 439 <1> pop ax 440 <1> retn 441 <1> 442 <1> 443 <1> doscode_disp_dxax_hex: ; dx:ax 444 <1> xchg ax, dx 445 <1> call doscode_disp_ax_hex 446 <1> xchg ax, dx 447 <1> doscode_disp_ax_hex: ; ax 448 <1> xchg al, ah 449 <1> call doscode_disp_al_hex 450 <1> ; display former ah 451 <1> xchg al, ah ; and fall trough for al 452 <1> doscode_disp_al_hex: ; al 453 <1> push cx 454 <1> mov cl, 4 455 <1> ror al, cl 456 <1> call doscode_disp_al_lownibble_hex 457 <1> ; display former high-nibble 458 <1> rol al, cl 459 <1> pop cx 460 <1> ; and fall trough for low-nibble 461 <1> doscode_disp_al_lownibble_hex: 462 <1> push ax ; save ax for call return 463 <1> and al, 00001111b 464 <1> ; high nibble must be zero 465 <1> add al, '0' ; if number is 0-9, now it's the correct character 466 <1> cmp al, '9' 467 <1> jna .decimalnum ; if we get decimal number with this, ok --> 468 <1> add al, 7 ; otherwise, add 7 and we are inside our alphabet 469 <1> .decimalnum: 470 <1> call doscode_disp_al 471 <1> pop ax 472 <1> retn 473 <1> 474 <1> 475 <1> doscode_msg: 476 <1> .error_common: asciz "DOSCODE error: " 477 <1> .error_table: asciz "Invalid doscode_entrypoint_list reference." 478 <1> .error_after: asciz 13,10,"System halted. " 479 <1> 480 <1> 481 <1> %include "biocode.asm" 482 <1> 483 <1> %assign DOSCODE_INSURE_COUNT 0 484 <1> 485 <1> ; The init2_to_doscode dispatcher in INIT2 (DOSINI) 486 <1> ; detects mistaken debugger breakpoints in its 487 <1> ; in-code-parameter by checking for a low-byte 488 <1> ; value equal to 0CCh (one-byte int3 opcode). 489 <1> ; Therefore, we insure that all functions called 490 <1> ; via that dispatcher do not happen to be located 491 <1> ; on an offset that gives 0CCh in the low byte. 492 <1> %imacro doscode_insure_low_byte_not_0CCh 0.nolist 493 <1> %if (($ - dosentry_start + 0) & 0FFh) == 0CCh 494 <1> nop 495 <1> %assign DOSCODE_INSURE_COUNT 1 + DOSCODE_INSURE_COUNT 496 <1> %endif 497 <1> %endmacro 498 <1> 499 <1> %include "doscode.asm" 500 <1> %endif 501 <1> 502 <1> %if DOSCODE_INSURE_COUNT 503 <1> %warning doscode_insure_low_byte_not_0CCh needed DOSCODE_INSURE_COUNT times 504 <1> %endif 505 <1> 506 <1> align 16 507 <1> %if _RELOCATEDOSCODE 508 <1> doscode_end: 509 <1> %else 510 <1> dosentry_end: 511 <1> %endif 512 <1> istruc MCB 513 <1> at mcbSignature, db "M" 514 <1> at mcbOwner, dw 8 515 <1> at mcbSize, dw (dosdata_end - dosdata_start) >> 4 516 <1> at smcbName, dw "S" 517 <1> at smcbType, db S_DOSDATA 518 <1> iend 519 <1> 520 <1> %if _RELOCATEDOSCODE 521 <1> ; section DOSDATA align=16 follows=DOSCODE vstart=0 522 <1> %else 523 <1> ; section DOSDATA align=16 follows=DOSENTRY vstart=0 524 <1> %endif 525 <1> dosdata_start: 526 <1> %if _COMBINED_DOSDATA_DOSCODE 527 <1> %include "RxDOS.ASM" 528 <1> %else 529 <1> %include "dosdata.asm" 530 <1> %endif 531 <1> 532 <1> align 16 533 <1> dosdata_end: 534 <1> istruc MCB 535 <1> at mcbSignature, db "M" 536 <1> at mcbOwner, dw 8 537 <1> at mcbSize, dw (init1_end - init1_start) >> 4 538 <1> at smcbName, dw "S" 539 <1> at smcbType, db S_INIT 540 <1> iend 541 <1> 542 <1> ; section INIT1 align=16 follows=DOSDATA vstart=0 543 <1> 544 <1> %assign INIT1_INSURE_COUNT 0 545 <1> 546 <1> ; The init2_to_init1 dispatcher in INIT2 (DOSINI) 547 <1> ; detects mistaken debugger breakpoints in its 548 <1> ; in-code-parameter by checking for a low-byte 549 <1> ; value equal to 0CCh (one-byte int3 opcode). 550 <1> ; Therefore, we insure that all functions called 551 <1> ; via that dispatcher do not happen to be located 552 <1> ; on an offset that gives 0CCh in the low byte. 553 <1> %imacro init1_insure_low_byte_not_0CCh 0.nolist 554 <1> %if (($ - init1_start) & 0FFh) == 0CCh 555 <1> nop 556 <1> %assign INIT1_INSURE_COUNT 1 + INIT1_INSURE_COUNT 557 <1> %endif 558 <1> %endmacro 559 <1> 560 <1> 561 <1> init1_start: 562 <1> ; S0 +28 563 <1> pushf ; +26 564 <1> jmp sig_valid 565 <1> 566 <1> msg: 567 <1> %if _TEST_PAYLOAD 568 <1> .test: asciz "Test payload loaded. Press any key to continue booting.",13,10 569 <1> %endif 570 <1> 571 <1> align 4 572 <1> .foundname: 573 <1> times 8+1+3+1 db 0 574 <1> ; buffer for base name (8) + dot (1) + ext (3) + NUL (1) 575 <1> align 2 576 <1> .foundname_default: 577 <1> asciz _BIN_FILE_DEFAULT 578 <1> _fill (8 + 1 + 3 + 1), 0, .foundname_default 579 <1> align 2 580 <1> .foundname_none: 581 <1> asciz "(None)" 582 <1> .foundname_none_size: equ $ - .foundname_none 583 <1> align 2 584 <1> .names: 585 <1> %if _TEST_PAYLOAD 586 <1> dw .name_first, 0 587 <1> dw .name_second, 0 588 <1> dw .name_third, 0 589 <1> dw .name_fourth, 0 590 <1> %else 591 <1> dw .foundname_none, 0 592 <1> %endif 593 <1> dw 0 594 <1> %if _TEST_PAYLOAD 595 <1> .name_first: asciz "1st name" 596 <1> .name_second: asciz "2nd name" 597 <1> .name_third: asciz "3rd name" 598 <1> .name_fourth: asciz "4th name" 599 <1> .name_before: asciz ": " 600 <1> .name_quote: asciz '"' 601 <1> .name_after: asciz 13,10 602 <1> %endif 603 <1> 604 <1> .bootfail: asciz "init: Boot failure: " 605 <1> .bootfail_read: db "Reading sector failed (error " 606 <1> .bootfail_read_errorcode: asciz "__h).",13,10 607 <1> .bootfail_sig: asciz "Boot sector signature missing (is not AA55h).",13,10 608 <1> .bootfail_sig_parttable: ascii "Partition table signature missing" 609 <1> asciz " (is not AA55h).",13,10 610 <1> .bootfail_secsizediffer: 611 <1> asciz "BPB BpS differs from actual sector size.",13,10 612 <1> .boot_too_many_partitions_error:asciz "Too many partitions (or a loop).",13,10 613 <1> .boot_partition_cycle_error: asciz "Partition table cycle detected.",13,10 614 <1> .boot_partition_not_found: asciz "Partition not found.",13,10 615 <1> .boot_access_error: asciz "Read error.", 13,10 616 <1> .boot_sector_too_large: asciz "Sector size too small (< 32 bytes).", 13,10 617 <1> .boot_sector_too_small: asciz "Sector size too large (> 8192 bytes).", 13,10 618 <1> .boot_sector_not_power: asciz "Sector size not a power of two.", 13,10 619 <1> .boot_invalid_sectors: asciz "Invalid geometry sectors.", 13,10 620 <1> .boot_invalid_heads: asciz "Invalid geometry heads.", 13,10 621 <1> .boot_badclusters: asciz "Bad amount of clusters.",13,10 622 <1> .boot_badchain: asciz "Bad cluster chain.",13,10 623 <1> .boot_internal_error: asciz "! Internal error !",13,10 624 <1> 625 <1> .login_partition_error_1: asciz "init: Error during unit " 626 <1> .login_partition_error_2: asciz "h partitions login.",13,10 627 <1> 628 <1> .excess_partitions_1: asciz "init: Found " 629 <1> .excess_partitions_2: asciz " excess partitions, ignored.",13,10 630 <1> 631 <1> .list_partition_1: asciz ": " 632 <1> .list_partition_4: asciz " s=" 633 <1> .list_partition_5: asciz "h (" 634 <1> .list_partition_6: asciz ") l=" 635 <1> .list_partition_7: asciz "h (" 636 <1> .list_partition_8: asciz ") " 637 <1> .list_partition_9: asciz " t=" 638 <1> .list_partition_10: asciz "h (" 639 <1> .list_partition_11: asciz ").",13,10 640 <1> 641 <1> .prefixes: asciz " kMGT" 642 <1> 643 <1> .bootname_1: asciz "init: Boot drive and file name: ",'"' 644 <1> .bootname_2: asciz '"',13,10 645 <1> 646 <1> 647 <1> %define pt_messages ..@pt_notype,"" 648 <1> 649 <1> %imacro pt_type 2.nolist 650 <1> dw %2, %%label 651 <1> %defstr %%str %1 652 <1> %xdefine pt_messages pt_messages,%%label,%%str 653 <1> %endmacro 654 <1> 655 <1> %imacro pt_msg 2-*.nolist 656 <1> %if %0 & 1 657 <1> %error Expected even number of parameters 658 <1> %endif 659 <1> %rotate 2 660 <1> %rep (%0 - 2) / 2 661 <1> %1: asciz %2 662 <1> %rotate 2 663 <1> %endrep 664 <1> %endmacro 665 <1> 666 <1> align 4 667 <1> pt_types: 668 <1> pt_type Empty, 0 669 <1> pt_type FAT12, 1 670 <1> pt_type FAT16 16BIT CHS,4 671 <1> pt_type ExtendedCHS, 5 672 <1> pt_type FAT16 CHS, 6 673 <1> pt_type FAT32 CHS, 0Bh 674 <1> pt_type FAT32, 0Ch 675 <1> pt_type FAT16, 0Eh 676 <1> pt_type Extended, 0Fh 677 <1> pt_type Linux, 83h 678 <1> pt_type ExtendedLinux, 85h 679 <1> dw -1, -1 680 <1> 681 <1> pt_msg pt_messages 682 <1> 683 <1> ptmsg_unknown: asciz "Unknown" 684 <1> 685 <1> %undef pt_messages 686 <1> %unimacro pt_type 2.nolist 687 <1> %unimacro pt_msg 2-*.nolist 688 <1> 689 <1> %endif 690 <1> 691 <1> init1_msg: 0 00001D08 696E69743A20457272 .alloc_error: asciz "init: Error " 0 00001D11 6F722000 0 00001D15 68207768696C652061 .alloc_error_q: asciz "h while allocating memory: " 0 00001D1E 6C6C6F636174696E67 0 00001D27 206D656D6F72793A20 0 00001D30 00 0 00001D31 0D0A00 .linebreak: asciz 13,10 695 <1> ; .internal_error_upb: asciz "init: Internal error during UPB allocation.",13,10 0 00001D34 48616C7465642E2050 .reboot_prompt: asciz "Halted. Press Ctrl+Alt+Del to reboot.",13,10 0 00001D3D 72657373204374726C 0 00001D46 2B416C742B44656C20 0 00001D4F 746F207265626F6F74 0 00001D58 2E0D0A00 697 <1> ; .loading_os: asciz "Starting ",RXDOSLONG_S,"...",13,10 0 00001D5C 52504C4F41444552 .rploader: db "RPLOADER" 699 <1> endarea .rploader 0 00001D64 00 db 0 0 00001D65 206B4D475400 .prefixes: asciz " kMGT" 702 <1> 0 00001D6B 90 align 2 704 <1> init1_msg_errors: 705 <1> .: 0 00001D6C [A01D] dw .no_error 0 00001D6E [A91D] dw .invalid_function 0 00001D70 [BA1D] dw .file_not_found 0 00001D72 [C91D] dw .path_not_found 0 00001D74 [D81D] dw .no_handles_available 0 00001D76 [ED1D] dw .access_denied 0 00001D78 [FB1D] dw .invalid_handle 0 00001D7A [0A1E] dw .mcb_destroyed 0 00001D7C [181E] dw .insufficient_memory 0 00001D7E [2C1E] dw .mcb_invalid 0 00001D80 [381E] dw .environment_invalid 0 00001D82 [4C1E] dw .format_invalid 0 00001D84 [5B1E] dw .access_code_invalid 0 00001D86 [6F1E] dw .data_invalid 0 00001D88 [7C1E] dw .fixup_overflow 0 00001D8A [8B1E] dw .invalid_drive 0 00001D8C [991E] dw .attempted_to_remove_current_directory 0 00001D8E [BF1E] dw .not_same_device 0 00001D90 [CF1E] dw .no_more_files 725 <1> .count equ ($ - .) / 2 0 00001D92 556E6B6E6F776E2065 .unknown_error: db "Unknown error",0 0 00001D9B 72726F7200 0 00001DA0 4E6F206572726F7200 .no_error: db "No error",0 0 00001DA9 496E76616C69642066 .invalid_function: db "Invalid function",0 0 00001DB2 756E6374696F6E00 0 00001DBA 46696C65206E6F7420 .file_not_found: db "File not found",0 0 00001DC3 666F756E6400 0 00001DC9 50617468206E6F7420 .path_not_found: db "Path not found",0 0 00001DD2 666F756E6400 0 00001DD8 4E6F2068616E646C65 .no_handles_available: db "No handles available",0 0 00001DE1 7320617661696C6162 0 00001DEA 6C6500 0 00001DED 416363657373206465 .access_denied: db "Access denied",0 0 00001DF6 6E69656400 0 00001DFB 496E76616C69642068 .invalid_handle: db "Invalid handle",0 0 00001E04 616E646C6500 0 00001E0A 4D4342206465737472 .mcb_destroyed: db "MCB destroyed",0 0 00001E13 6F79656400 0 00001E18 496E73756666696369 .insufficient_memory: db "Insufficient memory",0 0 00001E21 656E74206D656D6F72 0 00001E2A 7900 0 00001E2C 4D434220696E76616C .mcb_invalid: db "MCB invalid",0 0 00001E35 696400 0 00001E38 456E7669726F6E6D65 .environment_invalid: db "Environment invalid",0 0 00001E41 6E7420696E76616C69 0 00001E4A 6400 0 00001E4C 466F726D617420696E .format_invalid: db "Format invalid",0 0 00001E55 76616C696400 0 00001E5B 41636365737320636F .access_code_invalid: db "Access code invalid",0 0 00001E64 646520696E76616C69 0 00001E6D 6400 0 00001E6F 4461746120696E7661 .data_invalid: db "Data invalid",0 0 00001E78 6C696400 0 00001E7C 4669787570206F7665 .fixup_overflow: db "Fixup overflow",0 0 00001E85 72666C6F7700 0 00001E8B 496E76616C69642064 .invalid_drive: db "Invalid drive",0 0 00001E94 7269766500 0 00001E99 417474656D70746564 .attempted_to_remove_current_directory: db "Attempted to remove current directory",0 0 00001EA2 20746F2072656D6F76 0 00001EAB 652063757272656E74 0 00001EB4 206469726563746F72 0 00001EBD 7900 0 00001EBF 4E6F742073616D6520 .not_same_device: db "Not same device",0 0 00001EC8 64657669636500 0 00001ECF 4E6F206D6F72652066 .no_more_files: db "No more files",0 0 00001ED8 696C657300 746 <1> 747 <1> 748 <1> %if 0 749 <1> 750 <1> align 4 751 <1> init1_rploader_callback: dw entry_iret, 70h 752 <1> %define load_sectors (bp + bsBPB + bpbCHSSectors) 753 <1> %define load_heads (bp + bsBPB + bpbCHSHeads) 754 <1> %define load_sectorsize (bp + ldBytesPerSector) 755 <1> %define load_sectorsizepara (bp + ldParaPerSector) 756 <1> %define load_sectorseg (bp + ldSectorSeg) 757 <1> load_partition_cycle: dw 0 758 <1> %define load_lba (bp + ldHasLBA) 759 <1> %define load_unit (bp + bsBPB + ebpbNew + bpbnBootUnit) 760 <1> load_current_partition: db 0 761 <1> 762 <1> %endif 763 <1> 764 <1> 765 <1> init1_disp_msg_asciz: 766 <1> disp_msg_asciz: 0 00001EDD 1E push ds 0 00001EDE 56 push si 0 00001EDF 50 push ax 0 00001EE0 0E push cs 0 00001EE1 1F pop ds 0 00001EE2 89D6 mov si, dx 0 00001EE4 E80400 call disp_msg 0 00001EE7 58 pop ax 0 00001EE8 5E pop si 0 00001EE9 1F pop ds 0 00001EEA C3 retn 778 <1> 779 <1> init1_disp_msg: 780 <1> disp_msg: 781 <1> @@: 0 00001EEB AC lodsb 0 00001EEC 84C0 test al, al 0 00001EEE 7412 jz @F 0 00001EF0 E80200 call disp_al 0 00001EF3 EBF6 jmp short @B 787 <1> 788 <1> init1_disp_al: 789 <1> disp_al: 0 00001EF5 50 push ax 0 00001EF6 53 push bx 0 00001EF7 55 push bp 0 00001EF8 B40E mov ah, 0Eh 0 00001EFA BB0700 mov bx, 7 0 00001EFD CD10 int 10h 0 00001EFF 5D pop bp 0 00001F00 5B pop bx 0 00001F01 58 pop ax 799 <1> @@: 0 00001F02 C3 retn 801 <1> 802 <1> 803 <1> %if 0 804 <1> 805 <1> sig_valid: 806 <1> ; S0 +28 807 <1> ; pushf ; +26 808 <1> sti 809 <1> cld 810 <1> push ax ; +24 811 <1> push bx ; +22 812 <1> push cx ; +20 813 <1> push dx ; +18 814 <1> push si ; +16 815 <1> push di ; +14 816 <1> push bp ; +12 817 <1> mov ax, sp 818 <1> add ax, 16 819 <1> push ax ; +10 SP 820 <1> xor ax, ax 821 <1> push ax ; +8 IP 822 <1> push cs ; +6 823 <1> push ds ; +4 824 <1> push es ; +2 825 <1> push ss ; +0 826 <1> %if _TEST_PAYLOAD 827 <1> mov si, sp 828 <1> push ss 829 <1> pop ds 830 <1> mov di, table 831 <1> push cs 832 <1> pop es 833 <1> loop_table: 834 <1> mov bx, [es:di + 0] 835 <1> mov al, 32 836 <1> call disp_al 837 <1> mov ax, [es:di + 2] 838 <1> call disp_al 839 <1> xchg al, ah 840 <1> call disp_al 841 <1> cmp bx, -1 842 <1> je @F 843 <1> mov al, '=' 844 <1> call disp_al 845 <1> mov ax, [si + bx] 846 <1> call disp_ax_hex 847 <1> @@: 848 <1> add di, 4 849 <1> cmp di, table.end 850 <1> jb loop_table 851 <1> %endif 852 <1> 853 <1> 854 <1> init_mcb_chain: 855 <1> push cs 856 <1> pop ds 857 <1> push cs 858 <1> pop es 859 <1> mov ax, 60h ; where 860 <1> xor cx, cx ; owner 861 <1> mov bx, cs 862 <1> sub bx, ax ; size 863 <1> dec bx ; less 1 864 <1> sub bx, ( 16 + (dosentry_end - dosentry_start) + DOSCODE_MCB_SIZE + DOSCODE_SIZE + 16 + (dosdata_end - dosdata_start) + 16 ) >> 4 872 <1> ; point at DOSENTRY MCB 873 <1> mov dx, "M" | (0 << 8) 874 <1> call init_an_mcb 875 <1> 876 <1> mov bx, mcbtable 877 <1> mov ax, cs 878 <1> add ax, ( (init1_end - init1_start) + 16 + (init2_end - init2_start) + 16 + (init3_end - init3_start) + 16 ) >> 4 885 <1> mov word [bx], ax 886 <1> mov word [bx + 2], -1 887 <1> 888 <1> add bx, 4 889 <1> mov ax, ss 890 <1> mov word [bx], ax 891 <1> mov word [bx + 2], S_INITSTACKBPB 892 <1> 893 <1> add bx, 4 894 <1> mov ax, [bp + lsvFATSeg] 895 <1> dec ax 896 <1> mov word [bx], ax 897 <1> mov word [bx + 2], S_INITFATSEG 898 <1> 899 <1> add bx, 4 900 <1> mov ax, [bp + ldSectorSeg] 901 <1> dec ax 902 <1> mov word [bx], ax 903 <1> mov word [bx + 2], S_INITSECTORSEG 904 <1> 905 <1> add bx, 4 906 <1> mov dx, [bp + ldMemoryTop] ; => in front of RPL, or end of memory 907 <1> mov word [bx], dx 908 <1> mov word [bx + 2], S_EXCLDUMA 909 <1> 910 <1> int 12h 911 <1> mov cl, 6 912 <1> shl ax, cl ; => after RPL, or same as ldMemoryTop 913 <1> cmp dx, ax 914 <1> je @F 915 <1> mov word [bx + 2], 'R' << 8 916 <1> 917 <1> add bx, 4 918 <1> mov word [bx], ax 919 <1> mov word [bx + 2], S_EXCLDUMA 920 <1> @@: 921 <1> 922 <1> 923 <1> .next_bubble: 924 <1> mov bx, mcbtable 925 <1> xor cx, cx 926 <1> .next: 927 <1> mov ax, word [bx] 928 <1> cmp ax, word [bx + 4] 929 <1> jbe @F 930 <1> push word [bx] 931 <1> push word [bx + 2] 932 <1> push word [bx + 4] 933 <1> push word [bx + 6] 934 <1> pop word [bx + 2] 935 <1> pop word [bx] 936 <1> pop word [bx + 6] 937 <1> pop word [bx + 4] 938 <1> inc cx 939 <1> @@: 940 <1> add bx, 4 941 <1> cmp word [bx], -1 942 <1> jne .next 943 <1> test cx, cx 944 <1> jnz .next_bubble 945 <1> 946 <1> init_end_mcb_chain: 947 <1> mov si, mcbtable 948 <1> .next: 949 <1> mov ax, word [si] 950 <1> dec ax ; = where to place MCB 951 <1> mov dx, word [si + 2] ; dl = S MCB type, -1 if none, 952 <1> ; 0 (S_OTHER) if RPL (dh = 'R' then) 953 <1> mov cx, 8 ; owner = 8 954 <1> cmp dl, -1 ; none type ? 955 <1> jne @F ; no --> 956 <1> xor cx, cx ; yes, owner = 0 957 <1> @@: 958 <1> push dx 959 <1> xchg dl, dh ; dh = S MCB type 960 <1> mov dl, "M" ; dl = MCB signature 961 <1> mov di, word [si + 4] 962 <1> mov bx, di 963 <1> sub bx, ax 964 <1> dec bx 965 <1> dec bx ; size = to next 966 <1> cmp di, -1 ; any next ? 967 <1> jne @F ; yes --> 968 <1> mov dl, "Z" ; else, mcbSignature = "Z" 969 <1> xor bx, bx ; size = zero 970 <1> @@: 971 <1> call init_an_mcb 972 <1> pop dx 973 <1> cmp dx, 'R' << 8 974 <1> jne @F 975 <1> push ds 976 <1> mov ds, ax 977 <1> mov word [mcbName], "RP" 978 <1> mov word [mcbName + 2], "L" 979 <1> pop ds 980 <1> @@: 981 <1> add si, 4 982 <1> cmp word [si], -1 983 <1> jne .next 984 <1> 985 <1> mov bx, cs 986 <1> sub bx, ((dosdata_end - dosdata_start) + 16) >> 4 987 <1> mov ds, bx 988 <1> mov word [first_umcb], ax 989 <1> 990 <1> 991 <1> init_dosentry: 992 <1> mov ax, cs 993 <1> sub ax, ( 16 + (dosentry_end - dosentry_start) + DOSCODE_MCB_SIZE + DOSCODE_SIZE + 16 + (dosdata_end - dosdata_start) + 16) >> 4 1000 <1> mov dx, 6Fh 1001 <1> mov cx, (16 + (dosentry_end - dosentry_start)) >> 4 1002 <1> call init1_movp ; move DOSENTRY to 70h:0 1003 <1> 1004 <1> add cx, dx ; => behind DOSENTRY 1005 <1> mov ax, cx 1006 <1> mov bx, cs 1007 <1> sub bx, ax ; size 1008 <1> dec bx ; less 1 1009 <1> sub bx, ( DOSCODE_MCB_SIZE + DOSCODE_SIZE + 16 + (dosdata_end - dosdata_start) + 16 ) >> 4 ; ax + bx + 1 => DOSCODE MCB 1015 <1> xor cx, cx ; owner 1016 <1> mov dx, "M" | (0 << 8) 1017 <1> call init_an_mcb 1018 <1> 1019 <1> mov ax, 60h ; where 1020 <1> xor cx, cx ; owner 1021 <1> mov bx, 6Fh 1022 <1> sub bx, ax ; size 1023 <1> dec bx ; less 1 1024 <1> ; ax + bx + 1 => point at DOSENTRY MCB 1025 <1> mov dx, "M" | (0 << 8) 1026 <1> call init_an_mcb 1027 <1> 1028 <1> 1029 <1> listnames: 1030 <1> push cs 1031 <1> pop es 1032 <1> mov bx, msg.names 1033 <1> 1034 <1> %assign _NEW_BPB_NAME_SCAN_SIZE 1 1035 <1> %if _NEW_BPB_NAME_SCAN_SIZE 1036 <1> mov ax, ss 1037 <1> dec ax 1038 <1> mov ds, ax 1039 <1> mov cx, word [mcbSize] ; get size of stack/BPB 1040 <1> shl cx, 1 1041 <1> jc @F 1042 <1> shl cx, 1 1043 <1> jc @F 1044 <1> shl cx, 1 1045 <1> jc @F 1046 <1> shl cx, 1 ; <<= 4, *= 16, to byte offset 1047 <1> jnc @FF 1048 <1> @@: 1049 <1> xor cx, cx ; 0 = full 64 KiB 1050 <1> @@: 1051 <1> %endif 1052 <1> 1053 <1> push ss 1054 <1> pop ds 1055 <1> lea si, [bp + bsBPB + ebpbNew + BPBN_size] 1056 <1> %if _NEW_BPB_NAME_SCAN_SIZE 1057 <1> sub cx, si ; byte offset end - byte offset start = length 1058 <1> dec cx 1059 <1> dec cx ; don't scan into AA55h sig 1060 <1> %else 1061 <1> mov cx, (512 - (bsBPB + ebpbNew + BPBN_size)) - 2 1062 <1> ; -2 = AA55h sig 1063 <1> cmp word [bp + bsBPB + bpbSectorsPerFAT], 0 1064 <1> je @F 1065 <1> mov cx, (512 + (ebpbNew - bpbNew) - (bsBPB + ebpbNew + BPBN_size)) - 2 1066 <1> @@: 1067 <1> %endif 1068 <1> .nextname: 1069 <1> call findname 1070 <1> lahf 1071 <1> %if _TEST_PAYLOAD 1072 <1> mov dx, [cs:bx] 1073 <1> call disp_msg_asciz 1074 <1> mov dx, msg.name_before 1075 <1> call disp_msg_asciz 1076 <1> sahf 1077 <1> jc @F ; skip quote if no name --> 1078 <1> mov dx, msg.name_quote 1079 <1> call disp_msg_asciz 1080 <1> @@: 1081 <1> mov dx, msg.foundname 1082 <1> call disp_msg_asciz 1083 <1> sahf 1084 <1> jc @F ; skip quote if no name --> 1085 <1> mov dx, msg.name_quote 1086 <1> call disp_msg_asciz 1087 <1> @@: 1088 <1> mov dx, msg.name_after 1089 <1> call disp_msg_asciz 1090 <1> sahf 1091 <1> %endif 1092 <1> mov ax, 0 1093 <1> jc @F ; set to zero if no name --> 1094 <1> lea ax, [si - 11] ; -> name in buffer 1095 <1> @@: 1096 <1> mov word [cs:bx + 2], ax ; -> name in buffer, or 0 1097 <1> add bx, 4 1098 <1> cmp word [cs:bx], 0 1099 <1> jne .nextname 1100 <1> 1101 <1> 1102 <1> set_bootname.filename: 1103 <1> mov si, word [cs:msg.names + 2] 1104 <1> test si, si 1105 <1> jnz @F 1106 <1> 1107 <1> mov si, msg.foundname_default 1108 <1> jmp @FF 1109 <1> 1110 <1> @@: 1111 <1> call convert_name_to_asciz 1112 <1> 1113 <1> mov si, msg.foundname 1114 <1> @@: 1115 <1> push cs 1116 <1> pop ds ; ds:si -> name 1117 <1> 1118 <1> mov cx, (8 + 1 + 3) >> 1 1119 <1> ; note: last byte is already initialised to zero 1120 <1> 1121 <1> mov bx, cs 1122 <1> sub bx, ((dosdata_end - dosdata_start) + 16) >> 4 1123 <1> mov es, bx 1124 <1> mov di, bootname.filename ; es:di -> buffer in DOSDATA 1125 <1> rep movsw 1126 <1> 1127 <1> 1128 <1> store_boot_partition: 1129 <1> push cs 1130 <1> pop ds 1131 <1> mov al, [bp + bsBPB + ebpbNew + bpbnBootUnit] 1132 <1> mov byte [boot_unit], al 1133 <1> mov ax, [bp + bsBPB + bpbHiddenSectors] 1134 <1> mov dx, [bp + bsBPB + bpbHiddenSectors + 2] 1135 <1> mov word [boot_partition], ax 1136 <1> mov word [boot_partition + 2], dx 1137 <1> 1138 <1> scan_for_partitions: 1139 <1> lea sp, [bp + LOADDATA2] ; allow space for LOADDATA2 1140 <1> push cs 1141 <1> pop ds 1142 <1> and word [bp + bsBPB + bpbHiddenSectors], 0 1143 <1> and word [bp + bsBPB + bpbHiddenSectors + 2], 0 1144 <1> 1145 <1> scan_diskettes: 1146 <1> mov dl, 80h 1147 <1> mov ah, 08 1148 <1> stc 1149 <1> int 13h ; get number of fixed disks 1150 <1> mov bx, 0 1151 <1> jc @F ; fail ? then set bx = 0 and try diskettes 1152 <1> mov bl, dl 1153 <1> @@: 1154 <1> mov dl, 0 1155 <1> mov ah, 08h 1156 <1> stc 1157 <1> int 13h ; get number of diskettes 1158 <1> mov ch, 0 1159 <1> mov cl, dl ; cx = result 1160 <1> jc @F ; fail --> 1161 <1> cmp bx, cx ; differs from number of fixed disks ? 1162 <1> jne @FF ; yes, use --> 1163 <1> @@: 1164 <1> ; else, 1165 <1> int 11h ; query int 11 "get equipment list" 1166 <1> xor cx, cx ; initialise to zero 1167 <1> test ax, 1 ; any specified ? 1168 <1> jz @F ; no --> 1169 <1> 1170 <1> mov cl, al 1171 <1> rol cl, 1 1172 <1> rol cl, 1 ; get bits 6 & 7 1173 <1> and cl, 3 ; separate 1174 <1> inc cx ; +1 1175 <1> @@: 1176 <1> xor dl, dl 1177 <1> call scan_given_partitions 1178 <1> 1179 <1> ; manufacture units 0 and 1 if not existant 1180 <1> mov si, word [fsparm_pointer] 1181 <1> cmp si, fsparm + FSPARM_size*2 ; got at least 2 diskettes ? 1182 <1> jae @FF ; yes --> 1183 <1> cmp si, fsparm + FSPARM_size ; got 1 diskette ? 1184 <1> jae @F ; yes --> 1185 <1> mov di, si 1186 <1> push cs 1187 <1> pop es 1188 <1> xor ax, ax 1189 <1> mov cx, FSPARM_size >> 1 1190 <1> rep stosw ; initialise 1191 <1> mov byte [si + fspUnit], 0 1192 <1> mov word [si + fspSectorSize], 512 1193 <1> mov byte [si + fspType], -1 ; initialise to unit 0 1194 <1> inc byte [fsparm_number] 1195 <1> add si, FSPARM_size ; -> next 1196 <1> @@: 1197 <1> mov di, si 1198 <1> push cs 1199 <1> pop es 1200 <1> xor ax, ax 1201 <1> mov cx, FSPARM_size >> 1 1202 <1> rep stosw 1203 <1> mov byte [si + fspUnit], 1 1204 <1> mov word [si + fspSectorSize], 512 1205 <1> mov byte [si + fspType], -1 1206 <1> inc byte [fsparm_number] 1207 <1> add si, FSPARM_size 1208 <1> mov word [fsparm_pointer], si 1209 <1> @@: 1210 <1> 1211 <1> scan_fixed_disk_partitions: 1212 <1> mov dl, 80h 1213 <1> mov ah, 08h 1214 <1> stc 1215 <1> int 13h ; get number of fixed disks 1216 <1> mov ch, 0 1217 <1> mov cl, dl 1218 <1> jnc @F ; success --> 1219 <1> 1220 <1> mov ax, 40h 1221 <1> mov es, ax 1222 <1> mov cl, byte [es:bdaNumberFixedDisks] ; get from BDA instead 1223 <1> @@: 1224 <1> mov dl, 80h 1225 <1> call scan_given_partitions 1226 <1> 1227 <1> display_excess_partitions: 1228 <1> push cs 1229 <1> pop ds 1230 <1> mov ax, word [fsparm_excess] 1231 <1> test ax, ax 1232 <1> jz @F 1233 <1> mov dx, msg.excess_partitions_1 1234 <1> call disp_msg_asciz 1235 <1> call disp_ax_dec 1236 <1> mov dx, msg.excess_partitions_2 1237 <1> call disp_msg_asciz 1238 <1> @@: 1239 <1> 1240 <1> 1241 <1> display_partitions: 1242 <1> push cs 1243 <1> pop ds 1244 <1> mov byte [boot_drive], -1 1245 <1> xor cx, cx 1246 <1> mov cl, byte [fsparm_number] 1247 <1> mov si, fsparm 1248 <1> mov bx, 'A' 1249 <1> test cx, cx 1250 <1> jz .end 1251 <1> .loop: 1252 <1> 1253 <1> mov al, bl 1254 <1> call disp_al 1255 <1> 1256 <1> mov dx, msg.list_partition_1 1257 <1> call disp_msg_asciz 1258 <1> mov al, [si + fspUnit] 1259 <1> 1260 <1> push ax 1261 <1> cmp al, byte [boot_unit] 1262 <1> jne @FF 1263 <1> 1264 <1> cmp byte [boot_drive], -1 ; found any on this unit yet ? 1265 <1> jne @F ; yes --> 1266 <1> mov byte [boot_drive], bh ; default initialise to first part 1267 <1> @@: 1268 <1> 1269 <1> mov ax, [si + fspStart] ; does it match the partition ? 1270 <1> mov dx, [si + fspStart + 2] 1271 <1> cmp word [boot_partition], ax 1272 <1> jne @F 1273 <1> cmp word [boot_partition + 2], dx 1274 <1> jne @F ; no --> 1275 <1> 1276 <1> mov byte [boot_drive], bh ; yes, store this drive 1277 <1> @@: 1278 <1> pop ax 1279 <1> 1280 <1> mov dl, 'h' 1281 <1> test al, 80h 1282 <1> jnz @F 1283 <1> mov dl, 'f' 1284 <1> @@: 1285 <1> and al, ~80h 1286 <1> add al, 'a' 1287 <1> cmp al, 'z' 1288 <1> jbe @F 1289 <1> 1290 <1> mov al, 'u' 1291 <1> call disp_al 1292 <1> mov al, [si + fspUnit] 1293 <1> call disp_al_hex 1294 <1> mov al, '_' 1295 <1> call disp_al 1296 <1> 1297 <1> jmp @FF 1298 <1> 1299 <1> @@: 1300 <1> push ax 1301 <1> mov al, dl 1302 <1> call disp_al 1303 <1> mov al, 'd' 1304 <1> call disp_al 1305 <1> pop ax 1306 <1> call disp_al 1307 <1> 1308 <1> @@: 1309 <1> xor ax, ax 1310 <1> mov al, [si + fspPartition] 1311 <1> test ax, ax 1312 <1> jz .disp_2_blank 1313 <1> 1314 <1> call disp_ax_dec 1315 <1> cmp ax, 10 1316 <1> jb .disp_1_blank 1317 <1> jmp .disp_0_blank 1318 <1> 1319 <1> .disp_2_blank: 1320 <1> mov al, 32 1321 <1> call disp_al 1322 <1> .disp_1_blank: 1323 <1> mov al, 32 1324 <1> call disp_al 1325 <1> .disp_0_blank: 1326 <1> 1327 <1> mov dx, msg.list_partition_4 1328 <1> call disp_msg_asciz 1329 <1> 1330 <1> mov ax, [si + fspStart] 1331 <1> mov dx, [si + fspStart + 2] 1332 <1> call disp_dxax_hex 1333 <1> 1334 <1> push dx 1335 <1> mov dx, msg.list_partition_5 1336 <1> call disp_msg_asciz 1337 <1> pop dx 1338 <1> 1339 <1> push cx 1340 <1> push bx 1341 <1> mov cx, [si + fspSectorSize] 1342 <1> mov bx, 4+4 1343 <1> call disp_dxax_times_cx_width_bx_size 1344 <1> 1345 <1> mov dx, msg.list_partition_6 1346 <1> call disp_msg_asciz 1347 <1> 1348 <1> mov ax, [si + fspLength] 1349 <1> mov dx, [si + fspLength + 2] 1350 <1> call disp_dxax_hex 1351 <1> 1352 <1> push dx 1353 <1> mov dx, msg.list_partition_7 1354 <1> call disp_msg_asciz 1355 <1> pop dx 1356 <1> 1357 <1> call disp_dxax_times_cx_width_bx_size 1358 <1> pop bx 1359 <1> pop cx 1360 <1> 1361 <1> mov dx, msg.list_partition_8 1362 <1> call disp_msg_asciz 1363 <1> 1364 <1> mov al, [si + fspBoot] 1365 <1> test al, 80h 1366 <1> mov al, 32 1367 <1> jz @F 1368 <1> mov al, 'B' 1369 <1> @@: 1370 <1> call disp_al 1371 <1> 1372 <1> mov dx, msg.list_partition_9 1373 <1> call disp_msg_asciz 1374 <1> 1375 <1> xor ax, ax 1376 <1> mov al, byte [si + fspType] 1377 <1> call disp_al_hex 1378 <1> 1379 <1> mov dx, msg.list_partition_10 1380 <1> call disp_msg_asciz 1381 <1> 1382 <1> push si 1383 <1> mov si, pt_types 1384 <1> .types_loop: 1385 <1> cmp word [si], -1 1386 <1> je .types_unknown 1387 <1> cmp word [si], ax 1388 <1> je .types_known 1389 <1> add si, 4 1390 <1> jmp .types_loop 1391 <1> 1392 <1> .types_known: 1393 <1> mov dx, word [si + 2] 1394 <1> jmp .types_common 1395 <1> 1396 <1> .types_unknown: 1397 <1> mov dx, ptmsg_unknown 1398 <1> .types_common: 1399 <1> pop si 1400 <1> call disp_msg_asciz 1401 <1> 1402 <1> mov dx, msg.list_partition_11 1403 <1> call disp_msg_asciz 1404 <1> 1405 <1> add si, FSPARM_size 1406 <1> add bx, 0101h 1407 <1> loop .loop_jmp 1408 <1> jmp .end 1409 <1> .loop_jmp: 1410 <1> jmp .loop 1411 <1> .end: 1412 <1> 1413 <1> mov al, byte [boot_drive] 1414 <1> cmp al, -1 1415 <1> jne @F 1416 <1> mov al, [boot_unit] 1417 <1> cmp al, 2 1418 <1> jb @F 1419 <1> mov al, 2 1420 <1> @@: 1421 <1> mov byte [boot_drive], al 1422 <1> 1423 <1> mov bx, cs 1424 <1> sub bx, ((dosdata_end - dosdata_start) + 16) >> 4 1425 <1> mov es, bx 1426 <1> 1427 <1> mov byte [es:_RxDOS_CurrentDrive], al 1428 <1> inc ax 1429 <1> mov byte [es:bootdrive], al 1430 <1> 1431 <1> mov di, bootname.drive 1432 <1> add al, 'A'-1 1433 <1> stosb 1434 <1> 1435 <1> 1436 <1> display_bootname: 1437 <1> mov dx, msg.bootname_1 1438 <1> call disp_msg_asciz 1439 <1> push es 1440 <1> pop ds 1441 <1> mov si, bootname 1442 <1> call disp_msg 1443 <1> mov dx, msg.bootname_2 1444 <1> call disp_msg_asciz 1445 <1> 1446 <1> 1447 <1> setup_rploader_callback: 1448 <1> xor ax, ax 1449 <1> mov es, ax 1450 <1> lds si, [es:2Fh * 4] 1451 <1> push si 1452 <1> push cs 1453 <1> pop es 1454 <1> mov di, init1_msg.rploader 1455 <1> mov cx, init1_msg.rploader_size 1456 <1> add si, 3 1457 <1> repe cmpsb 1458 <1> pop si 1459 <1> jne .none 1460 <1> mov word [cs:init1_rploader_callback], si 1461 <1> mov word [cs:init1_rploader_callback + 2], ds 1462 <1> .none: 1463 <1> 1464 <1> 1465 <1> save_interrupts: 1466 <1> mov dx, 70h 1467 <1> mov ds, dx 1468 <1> xor ax, ax 1469 <1> mov es, ax 1470 <1> mov si, InterruptRestorationTable 1471 <1> .loop: 1472 <1> xor ax, ax 1473 <1> lodsb 1474 <1> cmp al, -1 1475 <1> je .end 1476 <1> xchg ax, bx 1477 <1> add bx, bx 1478 <1> add bx, bx 1479 <1> push word [es:bx + 2] 1480 <1> push word [es:bx] 1481 <1> pop word [si] 1482 <1> pop word [si + 2] 1483 <1> add si, 4 1484 <1> jmp .loop 1485 <1> .end: 1486 <1> 1487 <1> 1488 <1> ; ds = 70h 1489 <1> set_dos_segments: 1490 <1> mov bx, cs 1491 <1> sub bx, ((dosdata_end - dosdata_start) + 16) >> 4 1492 <1> mov word [dosentry_to_dosdata_segment], bx 1493 <1> mov es, bx 1494 <1> %if !_COMBINED_DOSDATA_DOSCODE 1495 <1> %if _RELOCATEDOSCODE 1496 <1> mov cx, cs 1497 <1> sub cx, ( (doscode_end - doscode_start) + 16 + (dosdata_end - dosdata_start) + 16 + 40h) >> 4 1502 <1> %else 1503 <1> mov cx, 70h 1504 <1> %endif 1505 <1> %else 1506 <1> mov cx, bx 1507 <1> %endif 1508 <1> mov word [es:dosdata_to_doscode_segment], cx 1509 <1> mov ax, word [bp + ldSectorSeg] 1510 <1> mov word [es:dosdata_to_diskbuffer_segment], ax 1511 <1> mov ax, word [bp + ldMemoryTop] 1512 <1> mov word [es:_RxDOS_MaxMemory], ax 1513 <1> mov word [es:p_buffer_info_record + 2], bx 1514 <1> 1515 <1> 1516 <1> ; ds = 70h 1517 <1> ; bx = DOSDATA 1518 <1> set_interrupts: 1519 <1> xor ax, ax 1520 <1> mov es, ax 1521 <1> mov word [es:21h * 4], i21 1522 <1> mov word [es:21h * 4 + 2], ds 1523 <1> 1524 <1> %imacro setint 2.nolist 1525 <1> mov dx, %1 1526 <1> mov ax, (25h << 8) | %2 1527 <1> int 21h 1528 <1> %endmacro 1529 <1> 1530 <1> clc 1531 <1> int3 1532 <1> jc .skip_ints_00_06 1533 <1> setint i00, 00h 1534 <1> setint entry_iret, 01h 1535 <1> setint entry_iret, 03h 1536 <1> setint i06, 06h 1537 <1> .skip_ints_00_06: 1538 <1> setint entry_iret, 02h 1539 <1> setint entry_iret, 04h 1540 <1> setint entry_iret, 05h 1541 <1> setint entry_iret, 07h 1542 <1> setint entry_iret, 33h 1543 <1> setint i19, 19h 1544 <1> setint i20, 20h 1545 <1> ; i21 set prior by direct IVT modification 1546 <1> setint entry_iret, 22h 1547 <1> setint i23, 23h 1548 <1> setint i24, 24h 1549 <1> setint i25, 25h 1550 <1> setint i26, 26h 1551 <1> setint i27, 27h 1552 <1> setint i28, 28h 1553 <1> setint i29, 29h 1554 <1> setint entry_iret, 2Ah 1555 <1> setint entry_iret, 2Bh 1556 <1> setint entry_iret, 2Ch 1557 <1> setint entry_iret, 2Dh 1558 <1> setint entry_iret, 2Eh 1559 <1> setint i2F, 2Fh 1560 <1> 1561 <1> mov byte [es:30h * 4], 0EAh 1562 <1> mov word [es:30h * 4 + 1], call5 1563 <1> mov word [es:30h * 4 + 3], ds 1564 <1> mov byte [es:30h * 4 + 5], 0 1565 <1> mov word [es:30h * 4 + 6], bx ; DR-DOS compatible DOSDATA reference 1566 <1> 1567 <1> mov ax, 5803h 1568 <1> xor bx, bx 1569 <1> int 21h ; disable UMB link 1570 <1> ; As we have an UMCB, this sets the LMCB linking to it to "Z". 1571 <1> 1572 <1> 1573 <1> ; ds = 70h 1574 <1> initialise_psp: 1575 <1> push ds 1576 <1> mov ax, cs 1577 <1> add ax, ( (init1_end - init1_start) + 16 + (init2_end - init2_start) + 16 ) >> 4 ; => INIT3 (PSP) 1582 <1> mov ds, ax 1583 <1> mov word [pspInt22 + 2], ax 1584 <1> mov word [pspParent], ax 1585 <1> mov word [pspStack + 2], ax 1586 <1> mov word [pspPHTAddress + 2], ax 1587 <1> 1588 <1> mov bx, ax 1589 <1> mov cl, S_ENVIRONMENT 1590 <1> mov ax, _INIT_ENV_SIZE 1591 <1> call init1_alloc_s_mcb_top 1592 <1> mov word [pspEnvironment], es 1593 <1> 1594 <1> pop ds 1595 <1> mov es, word [dosentry_to_dosdata_segment] 1596 <1> mov word [es:_RxDOS_CurrentPSP], bx 1597 <1> 1598 <1> 1599 <1> call_rploader_phase_1: 1600 <1> mov dx, 1 1601 <1> call init1_call_rploader 1602 <1> 1603 <1> 1604 <1> initialise_upb_chain: 1605 <1> xor cx, cx 1606 <1> mov cl, byte [cs:fsparm_number] 1607 <1> mov ax, DISKBLOCK_size 1608 <1> mul cx 1609 <1> test dx, dx 1610 <1> jz @F 1611 <1> 1612 <1> push cs 1613 <1> pop ds 1614 <1> mov si, init1_msg.internal_error_upb 1615 <1> call init1_disp_msg 1616 <1> jmp init1_reboot_prompt 1617 <1> 1618 <1> @@: 1619 <1> push cx 1620 <1> push cx 1621 <1> mov cl, S_UPB 1622 <1> call init1_alloc_s_mcb_top 1623 <1> pop cx 1624 <1> 1625 <1> mov dx, 70h 1626 <1> mov ds, dx 1627 <1> mov ds, word [dosentry_to_dosdata_segment] 1628 <1> mov si, ptrStartBlockedDeviceTable - _dskNextPointer ; -> -> UPB 1629 <1> mov bx, fsparm 1630 <1> xor ax, ax 1631 <1> 1632 <1> mov word [si + _dskNextPointer], -1 1633 <1> mov word [si + _dskNextPointer + 2], -1 1634 <1> test cx, cx 1635 <1> jz .end 1636 <1> 1637 <1> ; es:di -> next UPB to initialise 1638 <1> ; ds:si -> previous UPB (_dskNextPointer uninitialised) 1639 <1> .next: 1640 <1> mov al, [cs:bx + fspUnit] 1641 <1> mov byte [es:di + _dskPhysDriveNumber], al 1642 <1> mov byte [es:di + _dskDOSLogicalDiskUnit], ah 1643 <1> 1644 <1> push ax 1645 <1> 1646 <1> mov al, byte [cs:bx + fspType] 1647 <1> mov byte [es:di + _dskFATSystemType], al 1648 <1> 1649 <1> push word [cs:bx + fspStart + 2] 1650 <1> push word [cs:bx + fspStart] 1651 <1> pop word [es:di + _dskBPB + bpbHiddenSectors] 1652 <1> pop word [es:di + _dskBPB + bpbHiddenSectors + 2] 1653 <1> and word [es:di + _dskBPB + bpbTotalSectors], 0 1654 <1> push word [cs:bx + fspLength + 2] 1655 <1> push word [cs:bx + fspLength] 1656 <1> pop word [es:di + _dskBPB + bpbTotalSectorsLarge] 1657 <1> pop word [es:di + _dskBPB + bpbTotalSectorsLarge + 2] 1658 <1> push word [cs:bx + fspSectorSize] 1659 <1> pop word [es:di + _dskBPB + bpbBytesPerSector] 1660 <1> 1661 <1> push word [cs:bx + fspStart + 2] 1662 <1> push word [cs:bx + fspStart] 1663 <1> pop word [es:di + _dskDefaultBPB + bpbHiddenSectors] 1664 <1> pop word [es:di + _dskDefaultBPB + bpbHiddenSectors + 2] 1665 <1> and word [es:di + _dskDefaultBPB + bpbTotalSectors], 0 1666 <1> push word [cs:bx + fspLength + 2] 1667 <1> push word [cs:bx + fspLength] 1668 <1> pop word [es:di + _dskDefaultBPB + bpbTotalSectorsLarge] 1669 <1> pop word [es:di + _dskDefaultBPB + bpbTotalSectorsLarge + 2] 1670 <1> push word [cs:bx + fspSectorSize] 1671 <1> pop word [es:di + _dskDefaultBPB + bpbBytesPerSector] 1672 <1> 1673 <1> push word [cs:bx + fspStart + 2] 1674 <1> push word [cs:bx + fspStart] 1675 <1> pop word [es:di + _dskExtHiddenSectors] 1676 <1> pop word [es:di + _dskExtHiddenSectors + 2] 1677 <1> 1678 <1> mov word [es:di + _dskPartitionType], 1 1679 <1> mov byte [es:di + _dskDeviceType], -1 1680 <1> 1681 <1> cmp byte [es:di + _dskPhysDriveNumber], 80h 1682 <1> jb @F 1683 <1> or word [es:di + _dskStatusFlag], IsNonRemovable 1684 <1> @@: 1685 <1> 1686 <1> push dx 1687 <1> push cx 1688 <1> push bx 1689 <1> mov ah, 41h 1690 <1> mov dl, [es:di + _dskPhysDriveNumber] 1691 <1> mov bx, 55AAh 1692 <1> stc 1693 <1> int 13h ; 13.41.bx=55AA extensions installation check 1694 <1> mov al, 0 ; zero in case of no LBA support 1695 <1> jc .no_lba 1696 <1> cmp bx, 0AA55h 1697 <1> jne .no_lba 1698 <1> test cl, 1 ; support bitmap bit 0 1699 <1> jz .no_lba 1700 <1> inc ax ; al = 1 to indicate LBA support 1701 <1> .no_lba: 1702 <1> pop bx 1703 <1> pop cx 1704 <1> pop dx 1705 <1> mov byte [es:di + _dskExtReadWrite], al 1706 <1> 1707 <1> pop ax 1708 <1> mov word [es:di + _dskNextPointer], -1 1709 <1> mov word [es:di + _dskNextPointer + 2], -1 1710 <1> mov word [si + _dskNextPointer], di 1711 <1> mov word [si + _dskNextPointer + 2], es 1712 <1> 1713 <1> add bx, FSPARM_size 1714 <1> inc ah 1715 <1> add di, DISKBLOCK_size 1716 <1> lds si, [si + _dskNextPointer] 1717 <1> loop .loop_jmp_next 1718 <1> jmp .end 1719 <1> .loop_jmp_next: 1720 <1> jmp .next 1721 <1> .end: 1722 <1> 1723 <1> mov ds, dx 1724 <1> pop cx 1725 <1> mov byte [block + devUnits], cl 1726 <1> 1727 <1> 1728 <1> relocate_int1E_table: 1729 <1> xor ax, ax 1730 <1> mov es, ax 1731 <1> lds si, [es:1Eh * 4] 1732 <1> mov cx, 10h 1733 <1> mov di, 522h 1734 <1> push di 1735 <1> rep movsb 1736 <1> mov word [es:1Eh * 4 + 2], es 1737 <1> pop word [es:1Eh * 4] 1738 <1> 1739 <1> 1740 <1> finish: 1741 <1> push cs 1742 <1> pop ds 1743 <1> %if _TEST_PAYLOAD 1744 <1> mov si, msg.test 1745 <1> call disp_msg 1746 <1> int3 1747 <1> xor ax, ax 1748 <1> int 16h 1749 <1> %else 1750 <1> int3 1751 <1> %endif 1752 <1> 1753 <1> mov al, 20h 1754 <1> out 20h, al ; reset interrupts 1755 <1> 1756 <1> mov ax, 0500h 1757 <1> int 10h ; set page zero 1758 <1> 1759 <1> mov si, init1_msg.loading_os 1760 <1> call disp_msg 1761 <1> 1762 <1> mov bx, cs 1763 <1> add bx, ( (init1_end - init1_start) + 16 ) >> 4 ; => INIT2 1766 <1> mov ax, init2_start 1767 <1> push bx 1768 <1> push ax 1769 <1> 1770 <1> mov es, bx 1771 <1> mov word [es:init2_to_init1_segment], cs 1772 <1> 1773 <1> xor cx, cx 1774 <1> mov cl, byte [cs:fsparm_number] 1775 <1> 1776 <1> 1777 <1> ; INP: cs = INIT2 1778 <1> ; word [DOSDATA:dosdata_to_doscode_segment] = DOSCODE segment 1779 <1> ; word [DOSENTRY:dosentry_to_dosdata_segment] = DOSDATA segment 1780 <1> ; 70h = DOSENTRY segment 1781 <1> ; ip = 0 1782 <1> ; cx = number of default block device's units (<= 32) 1783 <1> ; word [INIT2:init2_to_init1_segment] = INIT1 1784 <1> init1_retf: 1785 <1> retf 1786 <1> 1787 <1> 1788 <1> ; INP: dx = phase code 1789 <1> ; OUT: - 1790 <1> ; CHG: - 1791 <1> ; (EDR-DOS pushes es,ax,bx,cx,dx and notes that 1792 <1> ; this function doesn't modify any registers.) 1793 <1> %if 0 1794 <1> 1795 <1> The phase codes are: 1796 <1> 1797 <1> 1 = early before DOS loading, BIO has been relocated to LMA top 1798 <1> 2 = before CONFIG.SYS processing 1799 <1> 3 = after CONFIG.SYS processing (before shell is loaded) 1800 <1> 1801 <1> These are described in RBIL 61, 2F4A06, in the Notes. However, code 1's 1802 <1> description there is misguided. The relocation of "BIOS init code and data" 1803 <1> doesn't mean into the HMA; rather, it's to the top of the LMA. 1804 <1> In EDR-DOS/dr70108/DRBIO/biosinit.a86:273, this is noted as 1805 <1> "BIOSINIT CODE and DATA have now been relocated to high memory", 1806 <1> but this means the top of the LMA. The HMA is only available later, 1807 <1> during CONFIG.SYS processing, so it can't be used at this point. 1808 <1> 1809 <1> %endif 1810 <1> 1811 <1> init1_insure_low_byte_not_0CCh 1812 <1> init1_call_rploader: 1813 <1> push es 1814 <1> push ax 1815 <1> push bx 1816 <1> push cx 1817 <1> push dx 1818 <1> 1819 <1> mov ax, 12FFh 1820 <1> mov bx, 5 1821 <1> xor cx, cx 1822 <1> mov dx, 1 1823 <1> 1824 <1> ; The callback variable is initialised to the address of an 1825 <1> ; iret in the DOSENTRY segment if RPLOADER wasn't detected. 1826 <1> pushf 1827 <1> cli 1828 <1> call far [cs:init1_rploader_callback] 1829 <1> 1830 <1> pop dx 1831 <1> pop cx 1832 <1> pop bx 1833 <1> pop ax 1834 <1> pop es 1835 <1> retn 1836 <1> 1837 <1> 1838 <1> ; INP: ax = space in bytes to allocate at top of LMA 1839 <1> ; cl = allocation type 1840 <1> ; OUT: es:di-> allocated space, initialised to all zeros 1841 <1> ; (di = 0) 1842 <1> ; ax = cx = space in bytes allocated, 1843 <1> ; ! 0 if size is 65536 1844 <1> ; does not return after allocation failure 1845 <1> ; CHG: - 1846 <1> init1_insure_low_byte_not_0CCh 1847 <1> init1_alloc_s_mcb_top: 1848 <1> push si 1849 <1> push bx 1850 <1> xchg si, ax 1851 <1> 1852 <1> mov ax, 5802h 1853 <1> int 21h 1854 <1> mov ah, 0 1855 <1> push ax 1856 <1> mov ax, 5800h 1857 <1> int 21h 1858 <1> push ax 1859 <1> 1860 <1> mov ax, 5803h 1861 <1> xor bx, bx 1862 <1> int 21h ; link out UMB chain 1863 <1> mov ax, 5801h 1864 <1> mov bx, 2 1865 <1> int 21h ; alloc strategy: last fit, LMA only 1866 <1> 1867 <1> xchg ax, si ; reset ax to allocation size, cl = type 1868 <1> call init1_alloc_s_mcb ; allocate 1869 <1> 1870 <1> pop bx 1871 <1> mov ax, 5801h 1872 <1> int 21h ; alloc strategy: restore 1873 <1> pop bx 1874 <1> mov ax, 5803h 1875 <1> int 21h ; restore UMB chain linkage 1876 <1> 1877 <1> mov ax, cx ; ax = allocated size (! 0 if size is 65536) 1878 <1> pop bx 1879 <1> pop si 1880 <1> retn 1881 <1> %endif 1882 <1> 1883 <1> 1884 <1> ; INP: ax = space in bytes to allocate 1885 <1> ; cl = allocation type 1886 <1> ; OUT: es:di-> allocated space, initialised to all zeros 1887 <1> ; (di = 0) 1888 <1> ; ax = cx = space in bytes allocated, 1889 <1> ; ! 0 if size is 65536 1890 <1> ; does not return after allocation failure 1891 <1> ; CHG: - 1892 <1> ; init1_insure_low_byte_not_0CCh 1893 <1> ; init1_alloc_s_mcb: 1894 <1> init2_alloc_s_mcb: 0 00001F03 53 push bx 0 00001F04 83C00F add ax, 15 0 00001F07 7304 jnc @F 0 00001F09 B80080 mov ax, 1_0000h >> 1 0 00001F0C A9 db __TEST_IMM16 1900 <1> @@: 0 00001F0D D1E8 shr ax, 1 0 00001F0F D1E8 shr ax, 1 0 00001F11 D1E8 shr ax, 1 0 00001F13 D1E8 shr ax, 1 ; = paragraphs 1905 <1> 0 00001F15 89C3 mov bx, ax 0 00001F17 B448 mov ah, 48h 0 00001F19 F9 stc 0 00001F1A CD21 int 21h 0 00001F1C 723F jc .alloc_fail 1911 <1> 0 00001F1E 48 dec ax 0 00001F1F 8EC0 mov es, ax 0 00001F21 26C70601000800 mov word [es:mcbOwner], 8 ; system-owned MCB 0 00001F28 26C70608005300 mov word [es:smcbName], "S" ; S MCB 0 00001F2F B500 mov ch, 0 0 00001F31 26890E0A00 mov word [es:smcbType], cx ; type = cl, reserved = 0 0 00001F36 B100 mov cl, 0 0 00001F38 26890E0C00 mov word [es:smcbLink], cx ; link = 0 0 00001F3D 26890E0E00 mov word [es:smcbLink + 2], cx ; reserved = 0 1921 <1> 0 00001F42 40 inc ax 0 00001F43 8EC0 mov es, ax 0 00001F45 31FF xor di, di ; -> allocated space 0 00001F47 89D9 mov cx, bx 0 00001F49 D1E1 shl cx, 1 0 00001F4B D1E1 shl cx, 1 0 00001F4D D1E1 shl cx, 1 ; = number of words 0 00001F4F 31C0 xor ax, ax 0 00001F51 57 push di 0 00001F52 51 push cx 0 00001F53 F3AB rep stosw ; initialise allocated memory to zeros 0 00001F55 59 pop cx 0 00001F56 5F pop di 0 00001F57 D1E1 shl cx, 1 0 00001F59 89C8 mov ax, cx 0 00001F5B 5B pop bx 0 00001F5C C3 retn 1939 <1> 1940 <1> 1941 <1> .alloc_fail: 0 00001F5D 0E push cs 0 00001F5E 1F pop ds 0 00001F5F 50 push ax 0 00001F60 BE[081D] mov si, init1_msg.alloc_error 0 00001F63 E885FF call init1_disp_msg 0 00001F66 58 pop ax 0 00001F67 E84A07 call init1_disp_ax_hex 0 00001F6A 50 push ax 0 00001F6B BE[151D] mov si, init1_msg.alloc_error_q 0 00001F6E E87AFF call init1_disp_msg 0 00001F71 58 pop ax 1953 <1> 0 00001F72 83F813 cmp ax, init1_msg_errors.count 0 00001F75 7205 jb .valid 0 00001F77 BE[921D] mov si, init1_msg_errors.unknown_error 0 00001F7A EB08 jmp short .disp_error 1958 <1> .valid: 0 00001F7C 89C3 mov bx, ax 0 00001F7E 01DB add bx, bx 0 00001F80 8BB7[6C1D] mov si, [ init1_msg_errors + bx ] 1962 <1> .disp_error: 0 00001F84 E864FF call init1_disp_msg 0 00001F87 BE[311D] mov si, init1_msg.linebreak 0 00001F8A E85EFF call init1_disp_msg 1966 <1> 1967 <1> init1_reboot_prompt: 0 00001F8D 0E push cs 0 00001F8E 1F pop ds 0 00001F8F BE[341D] mov si, init1_msg.reboot_prompt 0 00001F92 E856FF call init1_disp_msg 1972 <1> .loop: 0 00001F95 CC int3 0 00001F96 31C0 xor ax, ax 0 00001F98 CD16 int 16h 0 00001F9A EBF9 jmp .loop 1977 <1> 1978 <1> 1979 <1> %if 0 1980 <1> ; Move paragraphs 1981 <1> ; 1982 <1> ; INP: ax:0-> source 1983 <1> ; dx:0-> destination 1984 <1> ; cx = number of paragraphs 1985 <1> ; CHG: - 1986 <1> ; Note: Doesn't work correctly on HMA; doesn't always wrap to LMA either. 1987 <1> ; Do not provide a wrapped/HMA source or destination! 1988 <1> init1_movp: 1989 <1> push cx 1990 <1> push ds 1991 <1> push si 1992 <1> push es 1993 <1> push di 1994 <1> 1995 <1> cmp ax, dx ; source above destination ? 1996 <1> ja .up ; yes, move up (forwards) --> 1997 <1> je .return ; same, no need to move --> 1998 <1> push ax 1999 <1> add ax, cx ; (expected not to carry) 2000 <1> cmp ax, dx ; end of source is above destination ? 2001 <1> pop ax 2002 <1> ja .down ; yes, move from top down --> 2003 <1> ; Here, the end of source is below-or-equal the destination, 2004 <1> ; so they do not overlap. In this case we prefer moving up. 2005 <1> 2006 <1> .up: 2007 <1> push ax 2008 <1> push dx 2009 <1> .uploop: 2010 <1> mov ds, ax 2011 <1> mov es, dx 2012 <1> xor di, di 2013 <1> xor si, si ; -> start of segment 2014 <1> sub cx, 1000h ; 64 KiB left ? 2015 <1> jbe .uplast ; no --> 2016 <1> push cx 2017 <1> mov cx, 10000h /2 2018 <1> rep movsw ; move 64 KiB 2019 <1> pop cx 2020 <1> add ax, 1000h 2021 <1> add dx, 1000h ; -> next segment 2022 <1> jmp short .uploop ; proceed for more --> 2023 <1> .uplast: 2024 <1> add cx, 1000h ; restore counter 2025 <1> shl cx, 1 2026 <1> shl cx, 1 2027 <1> shl cx, 1 ; *8, paragraphs to words 2028 <1> rep movsw ; move last part 2029 <1> pop dx 2030 <1> pop ax 2031 <1> jmp short .return 2032 <1> 2033 <1> .down: 2034 <1> std ; _AMD_ERRATUM_109_WORKAROUND as below 2035 <1> .dnloop: 2036 <1> sub cx, 1000h ; 64 KiB left ? 2037 <1> jbe .dnlast ; no --> 2038 <1> push ax 2039 <1> push dx 2040 <1> add ax, cx 2041 <1> add dx, cx 2042 <1> mov ds, ax ; -> 64 KiB not yet moved 2043 <1> mov es, dx 2044 <1> pop dx 2045 <1> pop ax 2046 <1> mov di, -2 2047 <1> mov si, di ; moved from last word down 2048 <1> push cx 2049 <1> mov cx, 10000h /2 2050 <1> rep movsw ; move 64 KiB 2051 <1> pop cx 2052 <1> jmp short .dnloop ; proceed for more --> 2053 <1> .dnlast: 2054 <1> add cx, 1000h ; restore counter 2055 <1> shl cx, 1 2056 <1> shl cx, 1 2057 <1> shl cx, 1 ; *8, paragraphs to words 2058 <1> mov di, cx 2059 <1> dec di 2060 <1> shl di, 1 ; words to offset, -> last word 2061 <1> mov si, di 2062 <1> mov ds, ax 2063 <1> mov es, dx ; first segment correct 2064 <1> 2065 <1> 2066 <1> numdef AMD_ERRATUM_109_WORKAROUND, 1 2067 <1> ; Refer to comment in init0_movp. 2068 <1> 2069 <1> %if _AMD_ERRATUM_109_WORKAROUND 2070 <1> jcxz @FF 2071 <1> cmp cx, 20 2072 <1> ja @FF 2073 <1> @@: 2074 <1> movsw 2075 <1> loop @B 2076 <1> @@: 2077 <1> %endif 2078 <1> rep movsw ; move first part 2079 <1> cld 2080 <1> .return: 2081 <1> pop di 2082 <1> pop es 2083 <1> pop si 2084 <1> pop ds 2085 <1> pop cx 2086 <1> retn 2087 <1> 2088 <1> %endif 2089 <1> 2090 <1> ; INP: dx:ax = numerator 2091 <1> ; cx = multiplier 2092 <1> ; bx = field width 2093 <1> ; STT: UP 2094 <1> ; OUT: displayed 2095 <1> ; init1_insure_low_byte_not_0CCh 2096 <1> disp_dxax_times_cx_width_bx_size: 2097 <1> init2_disp_dxax_times_cx_width_bx_size: 2098 <1> lframe near 2099 <1> lvar 4 + 4 + 2, buffer 2100 <1> lvar 6, dividend 0 00001F9C 5589E58D66F0 lenter 2102 <1> lvar word, width 0 00001FA2 53 push bx 0 00001FA3 56 push si 0 00001FA4 57 push di 0 00001FA5 1E push ds 0 00001FA6 06 push es 0 00001FA7 51 push cx 0 00001FA8 50 push ax 0 00001FA9 52 push dx 2111 <1> 0 00001FAA 0E push cs 0 00001FAB 1F pop ds 0 00001FAC 16 push ss 0 00001FAD 07 pop es 2116 <1> 0 00001FAE 52 push dx 0 00001FAF F7E1 mul cx 0 00001FB1 97 xchg ax, di 0 00001FB2 87D6 xchg dx, si ; si:di = first mul 2121 <1> 0 00001FB4 58 pop ax 0 00001FB5 F7E1 mul cx 0 00001FB7 01F0 add ax, si 0 00001FB9 83D200 adc dx, 0 ; dx:ax = second mul + adj, dx:ax:di = mul 2126 <1> 0 00001FBC 89F9 mov cx, di ; dx:ax:cx = mul 2128 <1> 0 00001FBE 894EF0 mov word [bp + ?dividend], cx 0 00001FC1 8946F2 mov word [bp + ?dividend + 2], ax 0 00001FC4 8956F4 mov word [bp + ?dividend + 4], dx 2132 <1> 0 00001FC7 BE[651D] mov si, init1_msg.prefixes 2134 <1> .loop: 0 00001FCA 837EF400 cmp word [bp + ?dividend + 4], 0 0 00001FCE 750D jnz .divide 0 00001FD0 837EF200 cmp word [bp + ?dividend + 2], 0 0 00001FD4 7507 jnz .divide 0 00001FD6 817EF00008 cmp word [bp + ?dividend], 2048 0 00001FDB 7617 jbe .end 2141 <1> .divide: 0 00001FDD 46 inc si 0 00001FDE B90004 mov cx, 1024 ; 1000 here if SI units 0 00001FE1 31D2 xor dx, dx 0 00001FE3 BF0600 mov di, 6 2146 <1> .loop_divide: 0 00001FE6 8B43EE mov ax, [bp + ?dividend - 2 + di] 0 00001FE9 F7F1 div cx 0 00001FEB 8943EE mov word [bp + ?dividend - 2 + di], ax 0 00001FEE 4F dec di 0 00001FEF 4F dec di 0 00001FF0 75F4 jnz .loop_divide 2153 <1> ; dx = last remainder 0 00001FF2 EBD6 jmp .loop 2155 <1> 2156 <1> .end: 0 00001FF4 8D7EFF lea di, [bp + ?buffer + 4 + 4 + 1] 0 00001FF7 FD std ; _AMD_ERRATUM_109_WORKAROUND does not apply 0 00001FF8 B042 mov al, "B" 0 00001FFA AA stosb 0 00001FFB 8A04 mov al, [si] 0 00001FFD 3C20 cmp al, 32 0 00001FFF 7408 je @F 2164 <1> 0 00002001 24DF and al, ~20h ; uppercase, don't do this if SI units 0 00002003 50 push ax 0 00002004 B069 mov al, "i" 0 00002006 AA stosb ; don't store this if SI units 0 00002007 58 pop ax 0 00002008 AA stosb 2171 <1> @@: 0 00002009 B020 mov al, 32 0 0000200B AA stosb 2174 <1> 0 0000200C 8B46F0 mov ax, word [bp + ?dividend] 0 0000200F B90A00 mov cx, 10 2177 <1> .loop_write: 0 00002012 31D2 xor dx, dx 0 00002014 F7F1 div cx 0 00002016 92 xchg ax, dx 2181 <1> ; ax = remainder (next digit) 2182 <1> ; dx = result of div 0 00002017 0430 add al, '0' 0 00002019 AA stosb 0 0000201A 92 xchg ax, dx ; ax = result of div 0 0000201B 85C0 test ax, ax ; any more ? 0 0000201D 75F3 jnz .loop_write ; loop --> 2188 <1> 0 0000201F FC cld 2190 <1> 0 00002020 8D5EFF lea bx, [bp + ?buffer + 4 + 4 + 1] 0 00002023 29FB sub bx, di 2193 <1> 0 00002025 8B4EEE mov cx, [bp + ?width] 0 00002028 29D9 sub cx, bx 0 0000202A 7607 jbe .none_blank 2197 <1> .loop_blank: 0 0000202C B020 mov al, 32 0 0000202E E8C4FE call disp_al 0 00002031 E2F9 loop .loop_blank 2201 <1> .none_blank: 2202 <1> 0 00002033 89D9 mov cx, bx 2204 <1> .loop_disp: 0 00002035 47 inc di 0 00002036 368A05 mov al, [ss:di] 0 00002039 E8B9FE call disp_al 0 0000203C E2F7 loop .loop_disp 2209 <1> 0 0000203E 5A pop dx 0 0000203F 58 pop ax 0 00002040 59 pop cx 0 00002041 07 pop es 0 00002042 1F pop ds 0 00002043 5F pop di 0 00002044 5E pop si 0 00002045 5B pop bx 0 00002046 89EC5D lleave 0 00002049 C3 lret 2220 <1> 2221 <1> 2222 <1> ; INP: ax = number to display 2223 <1> ; CHG: - 2224 <1> ; init1_insure_low_byte_not_0CCh 2225 <1> disp_ax_dec: ; ax (no leading zeros) 2226 <1> ; In: number in ax 2227 <1> ; Out: displayed 0 0000204A 53 push bx 0 0000204B 31DB xor bx, bx 2230 <1> .pushax: 0 0000204D 50 push ax 2232 <1> .pushend: 0 0000204E 08DB or bl, bl 0 00002050 7405 jz .nobl 0 00002052 80EB05 sub bl, 5 0 00002055 F6DB neg bl 2237 <1> .nobl: 0 00002057 51 push cx 0 00002058 B91027 mov cx, 10000 0 0000205B E81A00 call .divide_out 0 0000205E B9E803 mov cx, 1000 0 00002061 E81400 call .divide_out 0 00002064 B96400 mov cx, 100 0 00002067 E80E00 call .divide_out 0 0000206A B10A mov cl, 10 0 0000206C E80900 call .divide_out 2247 <1> ; (Divisor 1 is useless) 0 0000206F 0430 add al, '0' 0 00002071 E881FE call disp_al 0 00002074 59 pop cx 0 00002075 58 pop ax 0 00002076 5B pop bx ; Caller's register 0 00002077 C3 retn 2254 <1> 2255 <1> .divide_out: 2256 <1> ; In: ax = number 2257 <1> ; cx = divisor 2258 <1> ; Out: ax = remainder of operation 2259 <1> ; result displayed 0 00002078 52 push dx 0 00002079 31D2 xor dx, dx 0 0000207B F7F1 div cx ; 0:ax / cx 0 0000207D 52 push dx ; remainder 0 0000207E FECB dec bl 0 00002080 7503 jnz .nobl2 0 00002082 80CF01 or bh, 1 2267 <1> .nobl2: 0 00002085 08C7 or bh, al 0 00002087 7405 jz .leadingzero 0 00002089 0430 add al, '0' 0 0000208B E867FE call disp_al ; display result 2272 <1> .leadingzero: 0 0000208E 58 pop ax ; remainder 0 0000208F 5A pop dx 0 00002090 C3 retn 2276 <1> 2277 <1> 2278 <1> %if 0 ; lMS-DOS 2279 <1> 2280 <1> ; INP: es:si -> partition table entry, 2281 <1> ; si = partition_table .. (partition_table.end - 16), 2282 <1> ; es = cs 2283 <1> ; ss:bx + di -> above part table metadata, 2284 <1> ; dwo [ss:bx + di - 4] = root (outermost extended position) 2285 <1> ; dwo [ss:bx + di - 8] = base (current table position) 2286 <1> ; ss:bp -> BPB area, LOADSTACKVARS, LOADDATA, LOADDATA2 2287 <1> ; CHG: ax, (cx), dx 2288 <1> login_partition: 2289 <1> mov al, byte [es:si + piType] 2290 <1> cmp al, ptFAT12 2291 <1> je .isfat 2292 <1> cmp al, ptFAT16_16BIT_CHS 2293 <1> je .isfat 2294 <1> cmp al, ptFAT16_CHS 2295 <1> je .isfat 2296 <1> cmp al, ptFAT32_CHS 2297 <1> je .isfat 2298 <1> cmp al, ptFAT32 2299 <1> je .isfat 2300 <1> cmp al, ptFAT16 2301 <1> je .isfat 2302 <1> 2303 <1> retn 2304 <1> 2305 <1> .isfat: 2306 <1> push ds 2307 <1> push cx 2308 <1> push bx 2309 <1> push si 2310 <1> push di 2311 <1> push es 2312 <1> push cs 2313 <1> pop ds 2314 <1> cmp byte [fsparm_number], 32 2315 <1> jne @F 2316 <1> 2317 <1> inc word [fsparm_excess] 2318 <1> .return: 2319 <1> pop es 2320 <1> pop di 2321 <1> pop si 2322 <1> pop bx 2323 <1> pop cx 2324 <1> pop ds 2325 <1> retn 2326 <1> 2327 <1> @@: 2328 <1> mov dl, al 2329 <1> inc byte [fsparm_number] 2330 <1> mov di, [fsparm_pointer] 2331 <1> add word [fsparm_pointer], FSPARM_size 2332 <1> push cs 2333 <1> pop es ; -> FSPARM 2334 <1> xor ax, ax 2335 <1> mov cx, FSPARM_size >> 1 2336 <1> push di 2337 <1> rep stosw ; initialise 2338 <1> pop di 2339 <1> mov al, [load_unit] 2340 <1> mov byte [di + fspUnit], al 2341 <1> push word [load_sectorsize] 2342 <1> pop word [di + fspSectorSize] 2343 <1> mov byte [di + fspType], dl 2344 <1> mov cx, di 2345 <1> pop es 2346 <1> pop di 2347 <1> pop si 2348 <1> push si 2349 <1> push di 2350 <1> push es 2351 <1> 2352 <1> mov ax, word [ss:bx + di - 8] 2353 <1> mov dx, word [ss:bx + di - 6] ; root 2354 <1> add ax, word [es:si + piStart] 2355 <1> adc dx, word [es:si + piStart + 2] ; add partition offset 2356 <1> 2357 <1> mov di, cx 2358 <1> mov word [di + fspStart], ax 2359 <1> mov word [di + fspStart + 2], dx 2360 <1> push word [es:si + piLength + 2] 2361 <1> push word [es:si + piLength] 2362 <1> pop word [di + fspLength] 2363 <1> pop word [di + fspLength + 2] 2364 <1> 2365 <1> mov al, byte [load_current_partition] 2366 <1> mov byte [di + fspPartition], al 2367 <1> mov al, byte [es:si + piBoot] 2368 <1> mov byte [di + fspBoot], al 2369 <1> 2370 <1> jmp .return 2371 <1> 2372 <1> 2373 <1> ; INP: dl = first unit to log in 2374 <1> ; cx = number of units to log in 2375 <1> scan_given_partitions: 2376 <1> jcxz .none 2377 <1> .loop: 2378 <1> push cx 2379 <1> push dx 2380 <1> 2381 <1> mov word [throw_sp], sp 2382 <1> mov word [throw_ip], .fail 2383 <1> 2384 <1> mov byte [load_unit], dl 2385 <1> call query_geometry 2386 <1> 2387 <1> mov cx, login_partition 2388 <1> call scan_partitions 2389 <1> push cs 2390 <1> pop ds 2391 <1> db __TEST_IMM8 ; (NC) 2392 <1> .fail: 2393 <1> stc 2394 <1> push cs 2395 <1> pop ds 2396 <1> pop dx 2397 <1> pop cx 2398 <1> 2399 <1> jnc @F 2400 <1> push dx 2401 <1> xchg ax, dx 2402 <1> mov dx, msg.login_partition_error_1 2403 <1> call disp_msg_asciz 2404 <1> call disp_al_hex 2405 <1> mov dx, msg.login_partition_error_2 2406 <1> call disp_msg_asciz 2407 <1> pop dx 2408 <1> @@: 2409 <1> inc dx 2410 <1> loop .loop 2411 <1> .none: 2412 <1> retn 2413 <1> 2414 <1> 2415 <1> hexword: 2416 <1> xchg al, ah 2417 <1> call hexbyte 2418 <1> xchg al, ah 2419 <1> 2420 <1> hexbyte: 2421 <1> push cx 2422 <1> mov cl, 4 2423 <1> rol al, cl 2424 <1> call hexnyb 2425 <1> rol al, cl 2426 <1> pop cx 2427 <1> 2428 <1> hexnyb: 2429 <1> push ax 2430 <1> and al, 0Fh 2431 <1> add al, 90h 2432 <1> daa 2433 <1> adc al, 40h 2434 <1> daa ; these four instructions change to ASCII hex 2435 <1> stosb 2436 <1> pop ax 2437 <1> retn 2438 <1> 2439 <1> 2440 <1> cmd3: 2441 <1> push cs 2442 <1> pop ds 2443 <1> push cs 2444 <1> pop es 2445 <1> mov sp, [throw_sp] 2446 <1> jmp near [throw_ip] 2447 <1> 2448 <1> 2449 <1> bootcmd: 2450 <1> .fail_read: 2451 <1> push cs 2452 <1> pop es 2453 <1> mov di, msg.bootfail_read_errorcode 2454 <1> mov al, ah 2455 <1> call hexbyte 2456 <1> mov dx, msg.bootfail_read 2457 <1> 2458 <1> .fail: 2459 <1> push dx 2460 <1> mov dx, msg.bootfail 2461 <1> call disp_msg_asciz 2462 <1> pop dx 2463 <1> call disp_msg_asciz 2464 <1> jmp cmd3 2465 <1> 2466 <1> %define _SCANPTAB_PREFIX 2467 <1> %define _SCANPTAB_DEBUG4_PREFIX init1_ 2468 <1> %include "scanptab.asm" 2469 <1> 2470 <1> 2471 <1> query_geometry: 2472 <1> mov dl, [load_unit] 2473 <1> ; test dl, dl ; floppy? 2474 <1> ; jns @F ; don't attempt query, might fail --> 2475 <1> ; Note that while the original PC BIOS doesn't support this function 2476 <1> ; (for its diskettes), it does properly return the error code 01h. 2477 <1> ; https://sites.google.com/site/pcdosretro/ibmpcbios (IBM PC version 1) 2478 <1> mov ah, 08h 2479 <1> xor cx, cx ; initialise cl to 0 2480 <1> mov [load_heads], cx 2481 <1> mov [load_sectors], cx 2482 <1> stc ; initialise to CY 2483 <1> call .int13_retry ; query drive geometry 2484 <1> jc .try_bootsector ; apparently failed --> 2485 <1> mov dl, dh 2486 <1> mov dh, 0 ; dx = maximum head number 2487 <1> inc dx ; dx = number of heads (H is 0-based) 2488 <1> mov ax, cx ; ax & 3Fh = maximum sector number 2489 <1> and ax, 3Fh ; get sectors (number of sectors, S is 1-based) 2490 <1> jnz .got_sectors_heads ; valid (S is 1-based), use these --> 2491 <1> ; zero = invalid 2492 <1> .try_bootsector: 2493 <1> mov es, word [bp + ldSectorSeg] 2494 <1> xor bx, bx 2495 <1> mov ax, 0201h ; read sector, 1 sector 2496 <1> mov cx, 1 ; sector 1 (1-based!), cylinder 0 (0-based) 2497 <1> mov dh, 0 ; head 0 (0-based) 2498 <1> mov dl, [load_unit] 2499 <1> stc 2500 <1> call .int13_retry 2501 <1> jc .access_error 2502 <1> 2503 <1> ; note: the smallest supported sector size, 32 bytes, 2504 <1> ; does contain these entries (offset 18h and 1Ah in sector) 2505 <1> ; within the first BPB sector. 2506 <1> mov ax, word [es:bx + bsBPB + bpbCHSSectors] 2507 <1> mov dx, word [es:bx + bsBPB + bpbCHSHeads] 2508 <1> 2509 <1> .got_sectors_heads: 2510 <1> mov word [load_sectors], ax 2511 <1> mov word [load_heads], dx 2512 <1> 2513 <1> test ax, ax 2514 <1> jz .invalid_sectors 2515 <1> cmp ax, 63 2516 <1> ja .invalid_sectors 2517 <1> test dx, dx 2518 <1> jz .invalid_heads 2519 <1> cmp dx, 100h 2520 <1> ja .invalid_heads 2521 <1> 2522 <1> mov bx, 10h 2523 <1> mov di, bx 2524 <1> mov cx, (8192 + 2) >> 1 2525 <1> mov ax, word [bp + ldSectorSeg] 2526 <1> dec ax 2527 <1> mov es, ax ; es:bx -> buffer, es:di = same 2528 <1> xor ax, ax 2529 <1> rep stosw ; fill buffer, di -> behind (0:7C00h+8192+2) 2530 <1> mov ax, 0201h ; read sector, 1 sector 2531 <1> inc cx ; sector 1 (1-based!), cylinder 0 (0-based) 2532 <1> mov dh, 0 ; head 0 (0-based) 2533 <1> mov dl, [load_unit] 2534 <1> stc 2535 <1> call .int13_retry 2536 <1> jc .access_error 2537 <1> 2538 <1> std ; _AMD_ERRATUM_109_WORKAROUND does not apply 2539 <1> mov word [es:bx - 2], 5E5Eh 2540 <1> scasw ; -> 0:7C00h+8192 (at last word to sca) 2541 <1> mov cx, (8192 + 2) >> 1 2542 <1> xor ax, ax 2543 <1> repe scasw 2544 <1> add di, 4 ; di -> first differing byte (from top) 2545 <1> cld 2546 <1> push di 2547 <1> 2548 <1> mov di, bx 2549 <1> mov cx, (8192 + 2) >> 1 2550 <1> dec ax ; = FFFFh 2551 <1> rep stosw 2552 <1> 2553 <1> mov ax, 0201h 2554 <1> inc cx 2555 <1> mov dh, 0 2556 <1> mov dl, [load_unit] 2557 <1> stc 2558 <1> call .int13_retry 2559 <1> jc .access_error 2560 <1> 2561 <1> std ; _AMD_ERRATUM_109_WORKAROUND does not apply 2562 <1> scasw ; di -> 0:7C00h+8192 (last word to sca) 2563 <1> pop dx 2564 <1> mov ax, -1 2565 <1> mov cx, (8192 + 2) >> 1 2566 <1> repe scasw 2567 <1> %if 0 2568 <1> AAAB 2569 <1> ^ 2570 <1> sca B, match 2571 <1> ^ 2572 <1> sca B, mismatch 2573 <1> ^ 2574 <1> stop 2575 <1> %endif 2576 <1> add di, 4 ; di -> first differing byte (from top) 2577 <1> cld 2578 <1> 2579 <1> %if 0 2580 <1> 0000000000000 2581 <1> AAAAAAAA00000 2582 <1> ^ 2583 <1> FFFFFFFFFFFFF 2584 <1> AAAAAAAA00FFF 2585 <1> ^ 2586 <1> %endif 2587 <1> cmp dx, di ; choose the higher one 2588 <1> jae @F 2589 <1> mov dx, di 2590 <1> @@: 2591 <1> sub dx, bx ; dx = sector size 2592 <1> 2593 <1> cmp dx, 8192 + 2 2594 <1> jae .sector_too_large 2595 <1> mov ax, 32 2596 <1> cmp dx, ax 2597 <1> jb .sector_too_small 2598 <1> @@: 2599 <1> cmp dx, ax 2600 <1> je .got_match 2601 <1> cmp ax, 8192 2602 <1> jae .sector_not_power 2603 <1> shl ax, 1 2604 <1> jmp @B 2605 <1> 2606 <1> .got_match: 2607 <1> mov word [load_sectorsize], ax 2608 <1> mov cl, 4 2609 <1> shr ax, cl 2610 <1> mov word [load_sectorsizepara], ax 2611 <1> 2612 <1> mov byte [load_lba], 0 2613 <1> mov ah, 41h 2614 <1> mov dl, [load_unit] 2615 <1> mov bx, 55AAh 2616 <1> stc 2617 <1> int 13h ; 13.41.bx=55AA extensions installation check 2618 <1> jc .no_lba 2619 <1> cmp bx, 0AA55h 2620 <1> jne .no_lba 2621 <1> test cl, 1 ; support bitmap bit 0 2622 <1> jz .no_lba 2623 <1> 2624 <1> inc byte [load_lba] 2625 <1> .no_lba: 2626 <1> retn 2627 <1> 2628 <1> 2629 <1> .int13_retry: 2630 <1> pushf 2631 <1> push ax 2632 <1> int 13h ; first try 2633 <1> jnc @F ; NC, success on first attempt --> 2634 <1> 2635 <1> ; reset drive 2636 <1> xor ax, ax 2637 <1> int 13h 2638 <1> jc @F ; CY, reset failed, error in ah --> 2639 <1> 2640 <1> ; try read again 2641 <1> pop ax ; restore function number 2642 <1> popf 2643 <1> int 13h ; retry, CF error status, ah error number 2644 <1> retn 2645 <1> 2646 <1> @@: ; NC or CY, stack has function number 2647 <1> inc sp 2648 <1> inc sp 2649 <1> inc sp 2650 <1> inc sp ; discard two words on stack, preserve CF 2651 <1> retn 2652 <1> 2653 <1> 2654 <1> .access_error: 2655 <1> mov dx, msg.boot_access_error 2656 <1> jmp .error_common_j 2657 <1> .sector_too_large: 2658 <1> mov dx, msg.boot_sector_too_large 2659 <1> jmp .error_common_j 2660 <1> .sector_too_small: 2661 <1> mov dx, msg.boot_sector_too_small 2662 <1> jmp .error_common_j 2663 <1> .sector_not_power: 2664 <1> mov dx, msg.boot_sector_not_power 2665 <1> jmp .error_common_j 2666 <1> .invalid_sectors: 2667 <1> mov dx, msg.boot_invalid_sectors 2668 <1> jmp .error_common_j 2669 <1> .invalid_heads: 2670 <1> mov dx, msg.boot_invalid_heads 2671 <1> .error_common_j: 2672 <1> jmp .error_common 2673 <1> 2674 <1> .error_common: equ bootcmd.fail 2675 <1> 2676 <1> 2677 <1> ; INP: dx:ax = first sector 2678 <1> ; bx:0 -> buffer 2679 <1> ; OUT: dx:ax = sector number after last read 2680 <1> ; es = input bx 2681 <1> ; bx:0 -> buffer after last written 2682 <1> ; CHG: - 2683 <1> ; STT: ds = ss 2684 <1> read_ae_1536_bytes: 2685 <1> push cx 2686 <1> push bx 2687 <1> mov cx, 1536 2688 <1> .loop: 2689 <1> call read_sector 2690 <1> sub cx, word [bp + bsBPB + bpbBytesPerSector] 2691 <1> ja .loop 2692 <1> pop es 2693 <1> pop cx 2694 <1> retn 2695 <1> 2696 <1> ; INP: dx:ax = first sector 2697 <1> ; bx:0 -> buffer 2698 <1> ; OUT: dx:ax = sector number after last read 2699 <1> ; es = input bx 2700 <1> ; bx:0 -> buffer after last written 2701 <1> ; CHG: - 2702 <1> ; STT: ds = ss 2703 <1> read_ae_512_bytes: 2704 <1> push cx 2705 <1> push bx 2706 <1> mov cx, 512 2707 <1> .loop: 2708 <1> call read_sector 2709 <1> sub cx, word [bp + bsBPB + bpbBytesPerSector] 2710 <1> ja .loop 2711 <1> pop es 2712 <1> pop cx 2713 <1> retn 2714 <1> 2715 <1> 2716 <1> ; Read a sector using Int13.02 or Int13.42 2717 <1> ; 2718 <1> ; INP: dx:ax = sector number (absolute in unit) 2719 <1> ; bx:0-> buffer 2720 <1> ; OUT: If unable to read, 2721 <1> ; ! jumps to error instead of returning 2722 <1> ; If sector has been read, 2723 <1> ; dx:ax = next sector number (has been incremented) 2724 <1> ; bx:0-> next buffer (bx = es+word[load_sectorsizepara]) 2725 <1> ; es = input bx 2726 <1> ; CHG: - 2727 <1> ; 2728 <1> ; Note: If error 09h (data boundary error) is returned, 2729 <1> ; the read is done into the load_sectorseg buffer, 2730 <1> ; then copied into the user buffer. 2731 <1> read_sector: 2732 <1> .err: equ bootcmd.fail_read 2733 <1> d5 call init1_d5dumpregs 2734 <1> d5 call init1_d5message 2735 <1> d5 asciz 13,10,"In read_sector",13,10 2736 <1> 2737 <1> push ds 2738 <1> push ss 2739 <1> pop ds 2740 <1> push dx 2741 <1> push cx 2742 <1> push ax 2743 <1> push si 2744 <1> 2745 <1> push bx 2746 <1> 2747 <1> ; DX:AX==LBA sector number 2748 <1> ; add partition start (= number of hidden sectors) 2749 <1> add ax,[bp + bsBPB + bpbHiddenSectors + 0] 2750 <1> adc dx,[bp + bsBPB + bpbHiddenSectors + 2] 2751 <1> 2752 <1> xor cx, cx 2753 <1> push cx 2754 <1> push cx 2755 <1> push dx 2756 <1> push ax ; qword sector number (lpSector) 2757 <1> push bx 2758 <1> push cx ; bx:0 -> buffer (lpBuffer) 2759 <1> inc cx 2760 <1> push cx ; word number of sectors to read (lpCount) 2761 <1> mov cl, 10h 2762 <1> push cx ; word size of disk address packet (lpSize) 2763 <1> mov si, sp ; ds:si -> disk address packet (on stack) 2764 <1> 2765 <1> test byte [bp + ldHasLBA], 1 2766 <1> jz .no_lba 2767 <1> 2768 <1> d5 call init1_d5message 2769 <1> d5 asciz "In read_sector.lba",13,10 2770 <1> 2771 <1> mov dl, byte [load_unit] 2772 <1> mov ah, 42h 2773 <1> int 13h ; 13.42 extensions read 2774 <1> jnc .lba_done 2775 <1> 2776 <1> xor ax, ax 2777 <1> int 13h 2778 <1> jc .lba_error 2779 <1> 2780 <1> ; have to reset the LBAPACKET's lpCount, as the handler may 2781 <1> ; set it to "the number of blocks successfully transferred". 2782 <1> ; (in any case, the high byte is still zero.) 2783 <1> mov byte [si + lpCount], 1 2784 <1> 2785 <1> mov ah, 42h 2786 <1> int 13h 2787 <1> jnc .lba_done 2788 <1> 2789 <1> cmp ah, 9 ; data boundary error? 2790 <1> jne .lba_error 2791 <1> 2792 <1> d4 call init1_d4dumpregs 2793 <1> d4 call init1_d4message 2794 <1> d4 asciz 13,10,"In read_sector.lba_sectorseg",13,10 2795 <1> 2796 <1> ; the offset part of the pointer is already zero! 2797 <1> ; push word [si + lpBuffer + 0] 2798 <1> push word [si + lpBuffer + 2] ; user buffer 2799 <1> push word [load_sectorseg] 2800 <1> pop word [si + lpBuffer + 2] 2801 <1> ; and word [si + lpBuffer + 0], byte 0 2802 <1> 2803 <1> mov byte [si + lpCount], 1 2804 <1> mov ah, 42h 2805 <1> int 13h 2806 <1> jnc .lba_sectorseg_done 2807 <1> 2808 <1> xor ax, ax 2809 <1> int 13h 2810 <1> jc .lba_error 2811 <1> 2812 <1> mov byte [si + lpCount], 1 2813 <1> mov ah, 42h 2814 <1> int 13h 2815 <1> jc .lba_error 2816 <1> .lba_sectorseg_done: 2817 <1> 2818 <1> xor si, si 2819 <1> mov ds, word [load_sectorseg] 2820 <1> pop es 2821 <1> ; pop cx 2822 <1> push di 2823 <1> ; mov di, cx 2824 <1> xor di, di 2825 <1> mov cx, word [load_sectorsize] 2826 <1> rep movsb 2827 <1> pop di 2828 <1> 2829 <1> push ss 2830 <1> pop ds 2831 <1> .lba_done: 2832 <1> add sp, 10h 2833 <1> pop bx 2834 <1> jmp .chs_done 2835 <1> 2836 <1> .lba_error: equ .err 2837 <1> 2838 <1> .no_lba: 2839 <1> add sp, 8 2840 <1> pop ax 2841 <1> pop dx 2842 <1> pop cx 2843 <1> pop cx 2844 <1> 2845 <1> ; DX:AX=LBA sector number 2846 <1> ; divide by number of sectors per track to get sector number 2847 <1> ; Use 32:16 DIV instead of 64:32 DIV for 8088 compatability 2848 <1> ; Use two-step 32:16 divide to avoid overflow 2849 <1> mov cx,ax 2850 <1> mov ax,dx 2851 <1> xor dx,dx 2852 <1> div word [load_sectors] 2853 <1> xchg cx,ax 2854 <1> div word [load_sectors] 2855 <1> xchg cx,dx 2856 <1> 2857 <1> ; DX:AX=quotient, CX=remainder=sector (S) - 1 2858 <1> ; divide quotient by number of heads 2859 <1> mov bx, ax 2860 <1> xchg ax, dx 2861 <1> xor dx, dx 2862 <1> div word [load_heads] 2863 <1> xchg bx, ax 2864 <1> div word [load_heads] 2865 <1> 2866 <1> ; bx:ax=quotient=cylinder (C), dx=remainder=head (H) 2867 <1> ; move variables into registers for INT 13h AH=02h 2868 <1> mov dh, dl ; dh = head 2869 <1> inc cx ; cl5:0 = sector 2870 <1> xchg ch, al ; ch = cylinder 7:0, al = 0 2871 <1> shr ax, 1 2872 <1> shr ax, 1 ; al7:6 = cylinder 9:8 2873 <1> ; bx has bits set iff it's > 0, indicating a cylinder >= 65536. 2874 <1> or bl, bh ; collect set bits from bh 2875 <1> or cl, al ; cl7:6 = cylinder 9:8 2876 <1> ; ah has bits set iff it was >= 4, indicating a cylinder >= 1024. 2877 <1> or bl, ah ; collect set bits from ah 2878 <1> mov dl, [load_unit] 2879 <1> ; dl = drive 2880 <1> mov ah, 04h ; error number: sector not found 2881 <1> jnz .err ; error if cylinder >= 1024 --> 2882 <1> ; ! bx = 0 (for 13.02 call) 2883 <1> 2884 <1> ; we call INT 13h AH=02h once for each sector. Multi-sector reads 2885 <1> ; may fail if we cross a track or 64K boundary 2886 <1> pop es 2887 <1> 2888 <1> mov ax, 0201h 2889 <1> int 13h ; read one sector 2890 <1> jnc .done 2891 <1> ; reset drive 2892 <1> xor ax, ax 2893 <1> int 13h 2894 <1> jc .err 2895 <1> 2896 <1> ; try read again 2897 <1> mov ax, 0201h 2898 <1> int 13h 2899 <1> jnc .done 2900 <1> cmp ah, 9 ; data boundary error? 2901 <1> jne .err 2902 <1> 2903 <1> d4 call init1_d4dumpregs 2904 <1> d4 call init1_d4message 2905 <1> d4 asciz 13,10,"In read_sector.chs_sectorseg",13,10 2906 <1> 2907 <1> push es ; user buffer 2908 <1> mov es, word [load_sectorseg] 2909 <1> 2910 <1> mov ax, 0201h 2911 <1> int 13h 2912 <1> jnc .chs_sectorseg_done 2913 <1> 2914 <1> xor ax, ax 2915 <1> int 13h 2916 <1> jc .err 2917 <1> 2918 <1> mov ax, 0201h 2919 <1> int 13h 2920 <1> jc .err 2921 <1> .chs_sectorseg_done: 2922 <1> 2923 <1> xor si, si 2924 <1> mov ds, word [load_sectorseg] 2925 <1> pop es 2926 <1> push di 2927 <1> xor di, di 2928 <1> mov cx, word [load_sectorsize] 2929 <1> rep movsb 2930 <1> pop di 2931 <1> 2932 <1> push ss 2933 <1> pop ds 2934 <1> .done: 2935 <1> ; increment segment 2936 <1> mov bx, es 2937 <1> 2938 <1> .chs_done: 2939 <1> mov es, bx 2940 <1> add bx, word [load_sectorsizepara] 2941 <1> 2942 <1> pop si 2943 <1> pop ax 2944 <1> pop cx 2945 <1> pop dx 2946 <1> pop ds 2947 <1> ; increment LBA sector number 2948 <1> inc ax 2949 <1> jne @F 2950 <1> inc dx 2951 <1> @@: 2952 <1> retn 2953 <1> %endif 2954 <1> 2955 <1> 2956 <1> ; INP: ax => MCB to initialise 2957 <1> ; cx = owner to set (8 if S MCB) 2958 <1> ; bx = size to set 2959 <1> ; dl = MCB signature, "M" or "Z" 2960 <1> ; dh = S MCB type 2961 <1> ; OUT: - 2962 <1> ; CHG: - 2963 <1> ; init1_insure_low_byte_not_0CCh 2964 <1> init2_init_an_mcb: 0 00002091 50 push ax 0 00002092 1E push ds 0 00002093 06 push es 0 00002094 57 push di 0 00002095 8ED8 mov ds, ax 0 00002097 8EC0 mov es, ax 0 00002099 31FF xor di, di 0 0000209B 31C0 xor ax, ax 0 0000209D 51 push cx 0 0000209E B90800 mov cx, MCB_size >> 1 0 000020A1 F3AB rep stosw 0 000020A3 59 pop cx 0 000020A4 894DF1 mov word [di - MCB_size + mcbOwner], cx 0 000020A7 895DF3 mov word [di - MCB_size + mcbSize], bx 0 000020AA 8855F0 mov byte [di - MCB_size + mcbSignature], dl 0 000020AD 83F908 cmp cx, 8 0 000020B0 7507 jne @F 0 000020B2 C645F853 mov byte [di - MCB_size + smcbName], "S" 0 000020B6 8875FA mov byte [di - MCB_size + smcbType], dh 2984 <1> @@: 0 000020B9 5F pop di 0 000020BA 07 pop es 0 000020BB 1F pop ds 0 000020BC 58 pop ax 0 000020BD C3 retn 2990 <1> 2991 <1> 2992 <1> %if 0 ; lMS-DOS 2993 <1> disp_dxax_hex: ; dx:ax 2994 <1> xchg ax, dx 2995 <1> call disp_ax_hex 2996 <1> xchg ax, dx 2997 <1> init1_disp_ax_hex: 2998 <1> disp_ax_hex: ; ax 2999 <1> xchg al,ah 3000 <1> call disp_al_hex ; display former ah 3001 <1> xchg al,ah ; and fall trough for al 3002 <1> disp_al_hex: ; al 3003 <1> push cx 3004 <1> mov cl,4 3005 <1> ror al,cl 3006 <1> call disp_al_lownibble_hex ; display former high-nibble 3007 <1> rol al,cl 3008 <1> pop cx 3009 <1> ; and fall trough for low-nibble 3010 <1> disp_al_lownibble_hex: 3011 <1> push ax ; save ax for call return 3012 <1> and al,00001111b ; high nibble must be zero 3013 <1> add al,'0' ; if number is 0-9, now it's the correct character 3014 <1> cmp al,'9' 3015 <1> jna .decimalnum ; if we get decimal number with this, ok --> 3016 <1> add al,7 ; otherwise, add 7 and we are inside our alphabet 3017 <1> .decimalnum: 3018 <1> call disp_al 3019 <1> pop ax 3020 <1> retn 3021 <1> 3022 <1> 3023 <1> ; INP: ds:si -> first byte to check for name 3024 <1> ; cx = number of bytes left 3025 <1> ; OUT: (8+1+3+1)bytes[es:msg.foundname] = found name, 3026 <1> ; converted to 8.3 ASCIZ format, 3027 <1> ; "(None)" if none 3028 <1> ; CY if no filename found, 3029 <1> ; si = INP:si + INP:cx 3030 <1> ; cx = 0 3031 <1> ; NC if filename found, 3032 <1> ; ds:si -> byte behind the name, thus ds:(si-11)-> name 3033 <1> ; cx = number of bytes left 3034 <1> ; CHG: di, ax 3035 <1> findname: 3036 <1> .: 3037 <1> cmp cx, 11 ; enough for another name ? 3038 <1> jb .none ; no --> 3039 <1> ; (cx == 0 jumps here too) 3040 <1> .check: 3041 <1> push cx 3042 <1> push si 3043 <1> mov cx, 11 3044 <1> lodsb 3045 <1> mov ah, al ; check for same char in all 11 places 3046 <1> cmp al, 32 ; first character must not be blank 3047 <1> je .check_fail ; if it is --> 3048 <1> ; cmp al, 5 ; first character may be 05h to indicate 0E5h 3049 <1> ; je .check_pass 3050 <1> db __TEST_IMM8 ; (skip lodsb) 3051 <1> .check_loop_same: 3052 <1> lodsb 3053 <1> cmp ah, al 3054 <1> jne .check_loop_differs 3055 <1> call .check_character 3056 <1> jc .check_fail 3057 <1> loop .check_loop_same 3058 <1> ; if we arrive here, all characters (while valid) are the 3059 <1> ; same character repeated 11 times. we disallow this in case 3060 <1> ; that the padding character is an allowed one (eg '&' 26h). 3061 <1> .check_fail: 3062 <1> pop si 3063 <1> pop cx 3064 <1> dec cx ; lessen the counter 3065 <1> inc si ; -> next position to check 3066 <1> jmp . 3067 <1> 3068 <1> .check_character: 3069 <1> cmp al, 32 3070 <1> jb .check_character_fail 3071 <1> cmp al, 127 3072 <1> ; je .check_character_fail 3073 <1> jae .check_character_fail 3074 <1> ; note: with all characters >= 128 allowed, 3075 <1> ; we get false positives in our sectors. 3076 <1> cmp al, '.' 3077 <1> je .check_character_fail 3078 <1> cmp al, '/' 3079 <1> je .check_character_fail 3080 <1> cmp al, '\' 3081 <1> je .check_character_fail 3082 <1> cmp al, 'a' 3083 <1> jb .check_character_pass 3084 <1> cmp al, 'z' 3085 <1> ja .check_character_pass 3086 <1> .check_character_fail: 3087 <1> stc 3088 <1> retn 3089 <1> 3090 <1> .check_character_pass: 3091 <1> clc 3092 <1> retn 3093 <1> 3094 <1> .check_loop: 3095 <1> lodsb 3096 <1> .check_loop_differs: 3097 <1> call .check_character 3098 <1> jc .check_fail 3099 <1> .check_pass: 3100 <1> loop .check_loop 3101 <1> 3102 <1> pop ax ; (discard si) 3103 <1> sub si, 11 ; -> at name 3104 <1> 3105 <1> call convert_name_to_asciz 3106 <1> ; si -> behind name 3107 <1> pop cx 3108 <1> sub cx, 11 ; lessen the counter 3109 <1> clc 3110 <1> retn 3111 <1> 3112 <1> .none: 3113 <1> add si, cx 3114 <1> mov di, msg.foundname 3115 <1> push si 3116 <1> push ds 3117 <1> push cs 3118 <1> pop ds 3119 <1> mov si, msg.foundname_none 3120 <1> mov cx, (msg.foundname_none_size + 1) >> 1 3121 <1> rep movsw 3122 <1> pop ds 3123 <1> pop si 3124 <1> xor cx, cx 3125 <1> stc 3126 <1> retn 3127 <1> 3128 <1> 3129 <1> ; INP: ds:si -> 11-byte blank-padded name 3130 <1> ; es:msg.foundname -> (8+1+3+1)-byte buffer 3131 <1> ; OUT: ds:si -> behind 11-byte blank-padded name 3132 <1> ; es:msg.foundname filled 3133 <1> ; CHG: cx, di, ax 3134 <1> convert_name_to_asciz: 3135 <1> mov di, msg.foundname 3136 <1> mov cx, 8 3137 <1> rep movsb ; copy over base name, si -> extension 3138 <1> cmp byte [es:di - 8], 05h ; is it 05h ? 3139 <1> jne @F ; no --> 3140 <1> mov byte [es:di - 8], 0E5h ; yes, convert to 0E5h 3141 <1> @@: 3142 <1> 3143 <1> db __TEST_IMM8 ; (skip dec) 3144 <1> @@: 3145 <1> dec di ; decrement -> at previous trailing blank 3146 <1> cmp byte [es:di - 1], 32 ; trailing blank ? 3147 <1> je @B ; yes --> 3148 <1> 3149 <1> mov al, '.' 3150 <1> stosb ; store dot (if needed) 3151 <1> mov cl, 3 3152 <1> rep movsb ; copy over extension, si -> behind name 3153 <1> 3154 <1> db __TEST_IMM8 ; (skip dec) 3155 <1> @@: 3156 <1> dec di ; decrement -> at previous trailing blank 3157 <1> cmp byte [es:di - 1], 32 ; trailing blank ? 3158 <1> je @B ; yes --> 3159 <1> 3160 <1> cmp byte [es:di - 1], '.' ; trailing dot ? (only occurs if all-blank ext) 3161 <1> jne @F ; no --> 3162 <1> dec di ; -> at the dot 3163 <1> @@: 3164 <1> mov al, 0 3165 <1> stosb ; store filename terminator 3166 <1> retn 3167 <1> 3168 <1> 3169 <1> %if _DEBUG5 || _DEBUG4 3170 <1> init1_d5dumpregs: 3171 <1> init1_d4dumpregs: 3172 <1> pushf 3173 <1> push ax 3174 <1> push bx 3175 <1> push cx 3176 <1> push dx 3177 <1> push si 3178 <1> push di 3179 <1> push bp 3180 <1> mov ax, sp 3181 <1> add ax, byte 18 3182 <1> push ax 3183 <1> push cs 3184 <1> push ss 3185 <1> push ds 3186 <1> push es 3187 <1> 3188 <1> mov bx, sp 3189 <1> mov ax, 1<<8|7 3190 <1> push ax 3191 <1> mov ax, 14 3192 <1> push cs 3193 <1> pop ds 3194 <1> mov dx, .regnames 3195 <1> 3196 <1> mov bp, sp 3197 <1> %assign _columns 0 3198 <1> %assign _blanks 1 3199 <1> 3200 <1> xor cx, cx 3201 <1> 3202 <1> .looprows: 3203 <1> push ax 3204 <1> mov al, 13 3205 <1> call init1_disp_al 3206 <1> mov al, 10 3207 <1> call init1_disp_al 3208 <1> %if 0 3209 <1> push cx 3210 <1> push dx 3211 <1> xor cx, cx 3212 <1> mov cl, byte [ _blanks + bp ] 3213 <1> jcxz .doneblanks 3214 <1> mov al, 32 3215 <1> .loopblanks: 3216 <1> call init1_disp_al 3217 <1> loop .loopblanks 3218 <1> .doneblanks: 3219 <1> pop dx 3220 <1> pop cx 3221 <1> %endif 3222 <1> pop ax 3223 <1> 3224 <1> mov cl, byte [ _columns + bp ] 3225 <1> .loopcolumns: 3226 <1> call init1_disp_reg 3227 <1> add dx, byte 2 3228 <1> add bx, byte 2 3229 <1> dec ax 3230 <1> jz .done 3231 <1> loop .loopcolumns 3232 <1> jmp short .looprows 3233 <1> 3234 <1> .done: 3235 <1> pop ax 3236 <1> 3237 <1> pop es 3238 <1> pop ds 3239 <1> pop ax 3240 <1> pop ax 3241 <1> pop ax 3242 <1> pop bp 3243 <1> pop di 3244 <1> pop si 3245 <1> pop dx 3246 <1> pop cx 3247 <1> pop bx 3248 <1> pop ax 3249 <1> popf 3250 <1> retn 3251 <1> 3252 <1> .regnames: 3253 <1> db "esdssscsspbpdisidxcxbxaxflip" 3254 <1> 3255 <1> 3256 <1> ; ss:bx-> word value 3257 <1> ; ds:dx-> 2-byte message 3258 <1> init1_disp_reg: 3259 <1> push ax 3260 <1> xchg bx, dx 3261 <1> mov ax, [ bx ] ; get 2 bytes at [ ds:dx ] 3262 <1> xchg bx, dx 3263 <1> call init1_disp_al 3264 <1> xchg al, ah 3265 <1> call init1_disp_al 3266 <1> 3267 <1> mov al, '=' 3268 <1> call init1_disp_al 3269 <1> 3270 <1> mov ax, [ ss:bx ] 3271 <1> call disp_ax_hex 3272 <1> 3273 <1> mov al, 32 3274 <1> call init1_disp_al 3275 <1> pop ax 3276 <1> retn 3277 <1> 3278 <1> init1_disp_stack_hex: 3279 <1> push ax 3280 <1> push bp 3281 <1> mov bp, sp 3282 <1> mov ax, [bp+6] 3283 <1> pop bp 3284 <1> call init1_disp_ax_hex 3285 <1> pop ax 3286 <1> retn 2 3287 <1> 3288 <1> init1_d5message: 3289 <1> init1_d4message: 3290 <1> push ax 3291 <1> push bx 3292 <1> push si 3293 <1> push ds 3294 <1> push bp 3295 <1> mov bp, sp 3296 <1> mov si, [bp+10] 3297 <1> pushf 3298 <1> push cs 3299 <1> pop ds 3300 <1> call init1_disp_msg 3301 <1> popf 3302 <1> mov word [bp+10], si 3303 <1> pop bp 3304 <1> pop ds 3305 <1> pop si 3306 <1> pop bx 3307 <1> pop ax 3308 <1> retn 3309 <1> 3310 <1> init1_d4uppercase: 3311 <1> pushf 3312 <1> cmp al, 'a' 3313 <1> jb .return 3314 <1> cmp al, 'z' 3315 <1> ja .return 3316 <1> and al, ~ 20h 3317 <1> .return: 3318 <1> popf 3319 <1> retn 3320 <1> %endif 3321 <1> 3322 <1> 3323 <1> %if _TEST_PAYLOAD 3324 <1> align 4 3325 <1> table: 3326 <1> dw +0, "SS" 3327 <1> dw +12, "BP" 3328 <1> dw +10, "SP" 3329 <1> dw +6, "CS" 3330 <1> dw +8, "IP" 3331 <1> dw +26, "FL" 3332 <1> db -1, -1, 13,10 3333 <1> dw +4, "DS" 3334 <1> dw +16, "SI" 3335 <1> dw +2, "ES" 3336 <1> dw +14, "DI" 3337 <1> db -1, -1, 13,10 3338 <1> dw +24, "AX" 3339 <1> dw +22, "BX" 3340 <1> dw +20, "CX" 3341 <1> dw +18, "DX" 3342 <1> db -1, -1, 13,10 3343 <1> dw +28, "S0" 3344 <1> dw +30, "S1" 3345 <1> dw +32, "S2" 3346 <1> dw +34, "S3" 3347 <1> dw +36, "S4" 3348 <1> dw +38, "S5" 3349 <1> dw +40, "S6" 3350 <1> dw +42, "S7" 3351 <1> db -1, -1, 13,10 3352 <1> dw +44, "S8" 3353 <1> dw +46, "S9" 3354 <1> dw +48, "SA" 3355 <1> dw +50, "SB" 3356 <1> dw +52, "SC" 3357 <1> dw +54, "SD" 3358 <1> dw +56, "SE" 3359 <1> dw +58, "SF" 3360 <1> db -1, -1, 13,10 3361 <1> .end: 3362 <1> %endif 3363 <1> 3364 <1> 3365 <1> align 4 3366 <1> mcbtable: 3367 <1> times 6 dd -1 3368 <1> ; MCB after INIT3 3369 <1> ; S_INITSTACKBPB 3370 <1> ; S_INITFATSEG 3371 <1> ; S_SECTORSEG 3372 <1> ; ldMemoryTop (in front of RPL, or last) 3373 <1> ; int 12h memory top (if RPL exists) 3374 <1> dd -1 3375 <1> 3376 <1> boot_partition: 3377 <1> dd 0 3378 <1> boot_unit: 3379 <1> db 0 3380 <1> boot_drive: 3381 <1> db 0 3382 <1> 3383 <1> 3384 <1> align 4 3385 <1> throw_sp: dw 0 3386 <1> throw_ip: dw 0 3387 <1> 3388 <1> fsparm_pointer: dw fsparm 3389 <1> fsparm_excess: dw 0 3390 <1> fsparm_number: db 0 3391 <1> 3392 <1> align 16 3393 <1> partition_table: 3394 <1> times 4 * 16 db 0 3395 <1> .end: 3396 <1> 3397 <1> align 16 3398 <1> fsparm: 3399 <1> times FSPARM_size * 32 db 0 3400 <1> 3401 <1> 3402 <1> align 16 3403 <1> init1_end: 3404 <1> 3405 <1> %if INIT1_INSURE_COUNT 3406 <1> %warning init1_insure_low_byte_not_0CCh needed INIT1_INSURE_COUNT times 3407 <1> %endif 3408 <1> 3409 <1> istruc MCB 3410 <1> at mcbSignature, db "M" 3411 <1> at mcbOwner, dw 8 3412 <1> at mcbSize, dw (init2_end - init2_start) >> 4 3413 <1> at smcbName, dw "S" 3414 <1> at smcbType, db S_INIT 3415 <1> iend 3416 <1> 3417 <1> ; section INIT2 align=16 follows=INIT1 vstart=0 3418 <1> init2_start: 3419 <1> jmp near RxDOS_initialize 3420 <1> 3421 <1> align 2 3422 <1> init2_to_init1_segment: dw 0 3423 <1> 3424 <1> %endif 3425 <1> 3426 <1> 3427 <1> %if 1 || (_RELOCATEDOSCODE && _DOSCODEHMA) 0 000020BE 90 align 4 0 000020C0 00000000 init2_xmsentry: dd 0 3430 <1> %endif 3431 <1> 3432 <1> 0 000020C4 90 align 16 3434 <1> init2_hma_vdisk_header: 3435 <1> istruc BS 0 000020D0 000000 at bsJump, db 0,0,0 0 000020D3 564449534B332E33 at bsOEM, db "VDISK3.3" 3438 <1> at bsBPB 3439 <1> iend 3440 <1> istruc EBPB 0 000020DB 80 at bpbBytesPerSector, db 80h ; (128) 0 000020DC 0001 at bpbSectorsPerCluster,db 1 0 000020DE 0100 at bpbReservedSectors, dw 1 0 000020E0 01 at bpbNumFATs, db 1 0 000020E1 4000 at bpbNumRootDirEnts, dw 40h ; (64) 0 000020E3 0002 at bpbTotalSectors, dw 200h ; (512) ; 512 sectors * 128 B/sector = 64 KiB 0 000020E5 FE at bpbMediaID, db 0FEh 0 000020E6 0600 at bpbSectorsPerFAT, dw 6 0 000020E8 0800 at bpbCHSSectors, dw 8 0 000020EA 0100 at bpbCHSHeads, dw 1 0 000020EC 0000 at bpbHiddenSectors, dw 0 3452 <1> %pop ; iend 0 000020EE 4004 dw 0440h ; (1088) 3454 <1> ; VCPI.txt: size word in boot block, "KB addr" 3455 <1> endarea init2_hma_vdisk_header 3456 <1> 3457 <1> 3458 <1> %if 0 3459 <1> ; INP: word [cs:ip] = near function to call in other segment 3460 <1> ; cs:(ip + 2) -> where to return to 3461 <1> ; word [DOSDATA:dosdata_to_doscode_segment] = DOSCODE 3462 <1> ; word [70h:dosentry_to_dosdata_segment] = DOSDATA 3463 <1> ; DOSCODE:doscode_retf -> retf opcode 3464 <1> ; INIT1 3465 <1> init2_to_doscode: 3466 <1> push ax ; word space for ?returnaddress_ip, is ax 3467 <1> push bx ; word space for ?returnaddress_other_ip, is bx 3468 <1> push ds 3469 <1> mov ax, 70h 3470 <1> mov ds, ax ; => DOSENTRY 3471 <1> mov ds, word [dosentry_to_dosdata_segment] ; => DOSDATA 3472 <1> mov ax, word [dosdata_to_doscode_segment] ; => DOSCODE 3473 <1> pop ds 3474 <1> mov bx, doscode_retf ; other:bx -> retf opcode 3475 <1> jmp init2_to_other_segment_common 3476 <1> 3477 <1> init2_to_init1: 3478 <1> push ax ; word space for ?returnaddress_ip 3479 <1> push bx ; word space for ?returnaddress_other_ip 3480 <1> mov ax, word [cs:init2_to_init1_segment] ; => INIT1 3481 <1> mov bx, init1_retf ; other:bx -> retf opcode 3482 <1> 3483 <1> init2_to_other_segment_common: 3484 <1> push ax 3485 <1> push ax ; dword space for ?jumpaddress 3486 <1> lframe 0 3487 <1> lpar word, returnaddress_cs_and_orig_ip 3488 <1> lpar word, returnaddress_ip 3489 <1> lpar word, returnaddress_other_ip 3490 <1> lpar dword, jumpaddress 3491 <1> lenter 3492 <1> 3493 <1> push si 3494 <1> pushf 3495 <1> cld 3496 <1> 3497 <1> mov word [bp + ?jumpaddress + 2], ax ; fill function segment 3498 <1> mov si, cs 3499 <1> xchg si, word [bp + ?returnaddress_cs_and_orig_ip] ; fill cs 3500 <1> cs lodsw 3501 <1> cmp al, 0CCh ; debugger breakpoint ? 3502 <1> jne @F ; no --> 3503 <1> int3 ; break to make it remove the breakpoint 3504 <1> dec si 3505 <1> dec si 3506 <1> cs lodsw ; reload the word 3507 <1> cmp al, 0CCh 3508 <1> jne @F 3509 <1> 3510 <1> .l: 3511 <1> int3 3512 <1> jmp .l 3513 <1> 3514 <1> @@: 3515 <1> mov word [bp + ?jumpaddress + 0], ax ; fill function offset 3516 <1> xchg ax, si ; ip in our cs 3517 <1> xchg ax, [bp + ?returnaddress_ip] ; fill ip 3518 <1> ; (and restore ax) 3519 <1> 3520 <1> xchg bx, word [bp + ?returnaddress_other_ip] ; fill near ip in other 3521 <1> ; (and restore bx) 3522 <1> 3523 <1> popf 3524 <1> pop si 3525 <1> 3526 <1> lleave 3527 <1> retf ; jump to dword [bp + ?jumpaddress] 3528 <1> 3529 <1> 3530 <1> ; INP: ax = space in bytes to allocate at top of LMA 3531 <1> ; cl = allocation type 3532 <1> ; OUT: es:di-> allocated space, initialised to all zeros 3533 <1> ; ax = cx = space in bytes allocated, 3534 <1> ; ! 0 if size is 65536 3535 <1> ; does not return after allocation failure 3536 <1> ; CHG: - 3537 <1> init2_alloc_s_mcb_top: 3538 <1> call init2_to_init1 3539 <1> dw init1_alloc_s_mcb_top 3540 <1> retn 3541 <1> 3542 <1> 3543 <1> ; INP: ax = space in bytes to allocate 3544 <1> ; cl = allocation type 3545 <1> ; OUT: es:di-> allocated space, initialised to all zeros 3546 <1> ; ax = cx = space in bytes allocated, 3547 <1> ; ! 0 if size is 65536 3548 <1> ; does not return after allocation failure 3549 <1> ; CHG: - 3550 <1> init2_alloc_s_mcb: 3551 <1> call init2_to_init1 3552 <1> dw init1_alloc_s_mcb 3553 <1> retn 3554 <1> 3555 <1> 3556 <1> init2_call_rploader: 3557 <1> call init2_to_init1 3558 <1> dw init1_call_rploader 3559 <1> retn 3560 <1> %endif 3561 <1> 3562 <1> 3563 <1> ; CHG: ds, si, ax 3564 <1> ; OUT: NZ if A20 line is switched on 3565 <1> ; ZR if A20 line is switched off 3566 <1> ; may return with IF=0 3567 <1> ; UP 3568 <1> init2_check_a20: 0 000020F0 FC cld 0 000020F1 06 push es 0 000020F2 57 push di 0 000020F3 51 push cx 0 000020F4 31F6 xor si, si 0 000020F6 8EDE mov ds, si ; ds = 0000h 0 000020F8 4E dec si 0 000020F9 8EC6 mov es, si ; es = FFFFh 0 000020FB 46 inc si ; ds:si = 0000h:0000h = 00000h 0 000020FC BF1000 mov di, 0010h ; es:di = FFFFh:0010h = 100000h 3579 <1> ; (same address if bit 20 off) 0 000020FF 89F9 mov cx, di ; 32 byte (16 = 10h word) 0 00002101 F3A7 repe cmpsw ; compare, A20 line switched on if differing 0 00002103 7512 jne .ret ; differing --> 3583 <1> 0 00002105 FA cli ; try not to run interrupt handlers during this 0 00002106 BF1000 mov di, 10h ; -> FFFFh:0010h = 10_0000h 3586 <1> ; (in the HMA, part of the VDISK header) 0 00002109 8D75F0 lea si, [di - 10h] ; -> 0000h:0000h = 00_0000h 3588 <1> ; (in the LMA, offset word of int 00h handler) 0 0000210C 26FF35 push word [es:di] ; save value 0 0000210F 26FF0D dec word [es:di] ; change value (in HMA, or wrapped around LMA) 0 00002112 A7 cmpsw ; compare values, NZ if A20 is switched on 0 00002113 268F45FE pop word [es:di - 2] ; restore value 3593 <1> ; This can still report a false negative (A20 detected off 3594 <1> ; when actually it is on), but we don't care about that. 3595 <1> .ret: 0 00002117 59 pop cx 0 00002118 5F pop di 0 00002119 07 pop es 0 0000211A C3 retn 3600 <1> 3601 <1> 3602 <1> extern dosdata_to_doscode_segment 3603 <1> 3604 <1> ; This is to be called after each device driver is installed. 3605 <1> ; It relocates DOSCODE to the HMA if it is available. 3606 <1> ; May be extended to relocate more things later. 3607 <1> ; 3608 <1> ; INP: ax = flags 3609 <1> ; CHG: ds, es, si, di, ax, bx, cx, dx 3610 <1> init2_relocate_device: 3611 <1> lframe 0 3612 <1> lvar word, umb_first_umcb 3613 <1> lvar word, umb_last_umcb 3614 <1> lvar word, last_mcb 0 0000211B 5589E58D66FA lenter 3616 <1> lvar word, flags 0 00002121 50 push ax 3618 <1> lvar word, first_mcb 0 00002122 B452 mov ah, 52h 0 00002124 CD21 int 21h 0 00002126 26FF77FE push word [es:bx - 2] 3622 <1> lvar word, first_umcb 0 0000212A B86112 mov ax, 1261h 0 0000212D CD2F int 2Fh 0 0000212F 50 push ax 3626 <1> 3627 <1> %if !_COMBINED_DOSDATA_DOSCODE && _RELOCATEDOSCODE && _DOSCODEHMA 3628 <1> 3629 <1> %if 0 3630 <1> mov ax, 70h 3631 <1> mov ds, ax 3632 <1> mov ds, word [dosentry_to_dosdata_segment] 3633 <1> %else 0 00002130 31C0 xor ax, ax 0 00002132 8ED8 mov ds, ax 0 00002134 8E1EC600 mov ds, word [31h * 4 + 2] ; => DOSDATA 3637 <1> %endif 0 00002138 8B1E[0000] mov bx, word [dosdata_to_doscode_segment] 0 0000213C 83FBFE cmp bx, DOSCODE_HMA_SEGMENT ; already in HMA ? 0 0000213F 7203E92901 jae .not_doscode_to_hma ; yes, return --> 3641 <1> 0 00002144 F746F80200 test word [bp + ?flags], DOSFLAGS_RELOCATE_DOSCODE_HMA 0 00002149 7503E91F01 jz .not_doscode_to_hma 3644 <1> 0 0000214E B80043 mov ax, 4300h 0 00002151 CD2F int 2Fh ; XMS present ? 0 00002153 3C80 cmp al, 80h 0 00002155 7403E91301 jne .not_doscode_to_hma ; no --> 3649 <1> 0 0000215A CC int3 0 0000215B B81043 mov ax, 4310h 0 0000215E CD2F int 2Fh ; get XMS entrypoint 0 00002160 2E891E[C020] mov word [cs:init2_xmsentry], bx 0 00002165 2E8C06[C220] mov word [cs:init2_xmsentry + 2], es ; store 3655 <1> 0 0000216A B80001 mov ax, 0100h 0 0000216D BAFFFF mov dx, -1 0 00002170 E8EF02 call .call_xms ; allocate HMA 0 00002173 7303E9F500 jc .not_doscode_to_hma ; failure --> 3660 <1> 0 00002178 B403 mov ah, 03h 0 0000217A E8E502 call .call_xms ; enable A20 0 0000217D BA[DA25] mov dx, init2_msg.error_enabling_a20_xms 0 00002180 7303E9E000 jc .not_doscode_free ; error --> 3665 <1> 0 00002185 E868FF call init2_check_a20 ; check A20 is enabled 0 00002188 BA[0726] mov dx, init2_msg.error_enabling_a20_actual 0 0000218B 7503E9D500 jz .not_doscode_free ; error --> 3669 <1> 0 00002190 B8[0000] mov ax, DOSENTRY 0 00002193 8ED8 mov ds, ax 0 00002195 2EFF36[C220] push word [cs:init2_xmsentry + 2] 0 0000219A 2EFF36[C020] push word [cs:init2_xmsentry] 0 0000219F 8F06[0000] pop word [dosentry_xmsentry] 0 000021A3 8F06[0200] pop word [dosentry_xmsentry + 2] 3676 <1> 0 000021A7 BAFFFF mov dx, -1 0 000021AA 8EC2 mov es, dx 0 000021AC BF1000 mov di, 10h 0 000021AF 0E push cs 0 000021B0 1F pop ds 0 000021B1 BE[D020] mov si, init2_hma_vdisk_header 0 000021B4 B91000 mov cx, init2_hma_vdisk_header_size_w 0 000021B7 F3A5 rep movsw 3685 <1> %if init2_hma_vdisk_header_size != 32 3686 <1> %error Expected HMA VDISK header to be 32 bytes long 3687 <1> %endif 0 000021B9 B90800 mov cx, 10h >> 1 0 000021BC 31C0 xor ax, ax 0 000021BE F3AB rep stosw 0 000021C0 83EF10 sub di, 10h 3692 <1> 3693 <1> %if 0 3694 <1> mov cx, (doscode_end - doscode_start) 3695 <1> %else 3696 <1> extern afterdoscodelabel 0 000021C3 B9[0000] mov cx, afterdoscodelabel wrt DOSCODEGROUP 0 000021C6 83E950 sub cx, DOSCODE_HMA_OFFSET 3699 <1> %endif 3700 <1> 0 000021C9 BAFEFF mov dx, DOSCODE_HMA_SEGMENT 0 000021CC 26C7054D53 mov word [es:di + hmcbSignature], "MS" 0 000021D1 26895502 mov word [es:di + hmcbOwner], dx 0 000021D5 26894D04 mov word [es:di + hmcbSize], cx 0 000021D9 89FB mov bx, di 0 000021DB 83C310 add bx, HMCB_size 0 000021DE 01CB add bx, cx 0 000021E0 26895D06 mov word [es:di + hmcbNext], bx 0 000021E4 26C74508444F mov word [es:di + hmcbName], "DO" 0 000021EA 26C7450A5343 mov word [es:di + hmcbName + 2], "SC" 0 000021F0 26C7450C4F44 mov word [es:di + hmcbName + 4], "OD" 0 000021F6 26C6450E45 mov byte [es:di + hmcbName + 6], "E" 3713 <1> 0 000021FB 89DF mov di, bx 0 000021FD 31C0 xor ax, ax 0 000021FF 51 push cx 0 00002200 B90800 mov cx, 16 >> 1 0 00002203 F3AB rep stosw 0 00002205 59 pop cx 0 00002206 89DF mov di, bx 0 00002208 26C7054D53 mov word [es:di + hmcbSignature], "MS" 3722 <1> ; word [es:di + hmcbOwner] already == 0 0 0000220D 89DE mov si, bx 0 0000220F 83C610 add si, 10h 0 00002212 F7DE neg si 0 00002214 26897504 mov word [es:di + hmcbSize], si 3727 <1> ; word [es:di + hmcbNext] already == 0 3728 <1> 0 00002218 8EC2 mov es, dx 0 0000221A BF5000 mov di, DOSCODE_HMA_OFFSET 0 0000221D 89FE mov si, di 3732 <1> %if 0 3733 <1> mov dx, 70h 3734 <1> mov ds, dx 3735 <1> mov ds, word [dosentry_to_dosdata_segment] 3736 <1> %else 0 0000221F 31D2 xor dx, dx 0 00002221 8EDA mov ds, dx 0 00002223 8E1EC600 mov ds, word [31h * 4 + 2] 3740 <1> %endif 0 00002227 8B1E[0000] mov bx, word [dosdata_to_doscode_segment] 0 0000222B 8EDB mov ds, bx 0 0000222D D1E9 shr cx, 1 0 0000222F F3A5 rep movsw 3745 <1> 0 00002231 8EDA mov ds, dx 3747 <1> %if 0 3748 <1> mov ds, word [dosentry_to_dosdata_segment] 3749 <1> %else 0 00002233 8E1EC600 mov ds, word [31h * 4 + 2] 3751 <1> %endif 0 00002237 8C06[0000] mov word [dosdata_to_doscode_segment], es 3753 <1> 3754 <1> extern doslocation3306 0 0000223B 800E[0000]10 or byte [doslocation3306], 10h 3756 <1> 0 00002240 8CD0 mov ax, ss 0 00002242 39D8 cmp ax, bx 0 00002244 7502 jne @F 0 00002246 06 push es 0 00002247 17 pop ss 3762 <1> @@: 3763 <1> 0 00002248 83C305 add bx, DOSCODE_HMA_OFFSET / 16 0 0000224B 8EC3 mov es, bx ; => DOSCODE source 0 0000224D B449 mov ah, 49h 0 0000224F CD21 int 21h ; free it 3768 <1> 3769 <1> extern first_hmcb 0 00002251 8EDA mov ds, dx 3771 <1> %if 0 3772 <1> mov ds, word [dosentry_to_dosdata_segment] 3773 <1> %else 0 00002253 8E1EC600 mov ds, word [31h * 4 + 2] 3775 <1> %endif 0 00002257 C706[0000]3000 mov word [first_hmcb], 30h 3777 <1> 0 0000225D BA[5326] mov dx, init2_msg.relocated_to_hma 0 00002260 E82504 call init2_disp_msg_asciz_cs_dx 3780 <1> 0 00002263 EB08 jmp .not_doscode_to_hma 3782 <1> 3783 <1> 3784 <1> .not_doscode_free: 0 00002265 E82004 call init2_disp_msg_asciz_cs_dx 3786 <1> 0 00002268 B402 mov ah, 02h 0 0000226A E8F501 call .call_xms ; free HMA 3789 <1> 3790 <1> .not_doscode_to_hma: 3791 <1> %endif 3792 <1> 0 0000226D 56 push si ; loop detection counter word 0 0000226E BE4000 mov si, 40h ; "UMA only" (+ first fit) 0 00002271 56 push si 0 00002272 89E6 mov si, sp ; ss:si -> area flags and strategy word 3797 <1> 0 00002274 F746F80800 test word [bp + ?flags], DOSFLAGS_LINK_UMB 0 00002279 7503E9DE01 jz .not_link_umb 3800 <1> 0 0000227E B80043 mov ax, 4300h 0 00002281 CD2F int 2Fh ; XMS present ? 0 00002283 3C80 cmp al, 80h 0 00002285 7403E9D201 jne .not_link_umb ; no --> 3805 <1> 0 0000228A B81043 mov ax, 4310h 0 0000228D CD2F int 2Fh ; get XMS entrypoint 0 0000228F 2E891E[C020] mov word [cs:init2_xmsentry], bx 0 00002294 2E8C06[C220] mov word [cs:init2_xmsentry + 2], es ; store 3810 <1> 3811 <1> .link_next_umb: 0 00002299 B410 mov ah, 10h 0 0000229B BAFFFF mov dx, -1 ; size 0 0000229E E8C101 call .call_xms ; request UMB 0 000022A1 7203E9B001 jnc .not_link_umb_error_succeeded_unexpectedly 0 000022A6 80FBB0 cmp bl, 0B0h ; "only smaller UMB available" ? 0 000022A9 7403E9AE01 jne .not_link_umb ; no, done --> 3818 <1> 0 000022AE 52 push dx 0 000022AF B410 mov ah, 10h ; (size initialised by prior call) 0 000022B1 E8AE01 call .call_xms ; request UMB 0 000022B4 58 pop ax 0 000022B5 7325 jnc .link_umb 3824 <1> 0 000022B7 BA[0E25] mov dx, init2_msg.umb_unavailable_1 0 000022BA E8CB03 call init2_disp_msg_asciz_cs_dx 3827 <1> 0 000022BD E8F403 call init2_disp_ax_hex 0 000022C0 BA[2125] mov dx, init2_msg.umb_unavailable_2 0 000022C3 E8C203 call init2_disp_msg_asciz_cs_dx 3831 <1> 0 000022C6 53 push bx 0 000022C7 31D2 xor dx, dx 0 000022C9 B91000 mov cx, 16 0 000022CC BB0800 mov bx, 4+4 0 000022CF E8CAFC call init2_disp_dxax_times_cx_width_bx_size 0 000022D2 5B pop bx 0 000022D3 BA[2525] mov dx, init2_msg.umb_unavailable_3 0 000022D6 E8AF03 call init2_disp_msg_asciz_cs_dx 3840 <1> 0 000022D9 E98001 jmp .not_link_umb 3842 <1> 3843 <1> .link_umb: 3844 <1> ; dx = allocated UMB size 3845 <1> ; bx = allocated UMB segment 0 000022DC 3683640200 and word [ss:si + 2], 0 ; initialise loop detection counter to zero 3847 <1> 0 000022E1 52 push dx 0 000022E2 89D0 mov ax, dx 0 000022E4 BA[0E25] mov dx, init2_msg.umb_allocated_1 0 000022E7 E89E03 call init2_disp_msg_asciz_cs_dx 3852 <1> 0 000022EA E8C703 call init2_disp_ax_hex 0 000022ED BA[2125] mov dx, init2_msg.umb_allocated_2 0 000022F0 E89503 call init2_disp_msg_asciz_cs_dx 3856 <1> 0 000022F3 53 push bx 0 000022F4 31D2 xor dx, dx 0 000022F6 B91000 mov cx, 16 0 000022F9 BB0800 mov bx, 4+4 0 000022FC E89DFC call init2_disp_dxax_times_cx_width_bx_size 0 000022FF 5B pop bx 0 00002300 BA[4F25] mov dx, init2_msg.umb_allocated_3 0 00002303 E88203 call init2_disp_msg_asciz_cs_dx 3865 <1> 0 00002306 89D8 mov ax, bx 0 00002308 E8A903 call init2_disp_ax_hex 0 0000230B BA[5525] mov dx, init2_msg.umb_allocated_4 0 0000230E E87703 call init2_disp_msg_asciz_cs_dx 0 00002311 5A pop dx 3871 <1> 3872 <1> ; dx = size, bx = segment 0 00002312 31C9 xor cx, cx ; step = 0 3874 <1> 0 00002314 51 push cx 0 00002315 53 push bx 0 00002316 52 push dx 0 00002317 31C9 xor cx, cx ; free 0 00002319 93 xchg ax, bx ; ax => MCB 0 0000231A 89D3 mov bx, dx ; size = size of UMB 0 0000231C 83EB02 sub bx, 2 ; -1 for initial MCB, -1 for end MCB 0 0000231F 721B jc @F ; too small! 0 00002321 BA4D00 mov dx, "M" ; "M" 0 00002324 8946FE mov word [bp + ?umb_first_umcb], ax 3885 <1> ; INP: ax => MCB to initialise 3886 <1> ; cx = owner to set (8 if S MCB) 3887 <1> ; bx = size to set 3888 <1> ; dl = MCB signature, "M" or "Z" 3889 <1> ; dh = S MCB type 3890 <1> ; OUT: - 3891 <1> ; CHG: - 0 00002327 E867FD call init2_init_an_mcb 3893 <1> 0 0000232A 01D8 add ax, bx 0 0000232C 40 inc ax ; => end MCB 0 0000232D 31DB xor bx, bx ; size zero (may be changed to link next UMB) 0 0000232F BA5A30 mov dx, (S_EXCLDUMA << 8) | "Z" ; type, and signature 0 00002332 B90800 mov cx, 8 ; allocate S MCB 0 00002335 8946FC mov word [bp + ?umb_last_umcb], ax 0 00002338 E856FD call init2_init_an_mcb 3901 <1> 0 0000233B A8 db __TEST_IMM8 ; (NC) skip stc 3903 <1> @@: 0 0000233C F9 stc 0 0000233D 5A pop dx 0 0000233E 5B pop bx 0 0000233F 59 pop cx 0 00002340 7303E9F200 jc .not_link_umb_error_mcb_chain 3909 <1> 0 00002345 31C0 xor ax, ax ; = 0 = get first UMCB 3911 <1> .search_umb: 0 00002347 B101 mov cl, 1 ; step = 1 0 00002349 8946FA mov word [bp + ?last_mcb], ax 3914 <1> %if 0 3915 <1> call init2_to_doscode 3916 <1> dw SNextMCB ; get next (U)MCB 3917 <1> %else 0 0000234C E81F01 call init2_SNextMCB 3919 <1> %endif 0 0000234F 7303E9E300 jc .not_link_umb_error_mcb_chain ; chain corrupted 0 00002354 7403E9B100 jnz .umb_case_3 ; end of chain, word [bp + ?last_mcb] has last 0 00002359 41 inc cx ; step = 2 0 0000235A 39C3 cmp bx, ax ; area to add is below ? 0 0000235C 7703E9D600 jbe .not_link_umb_error_mcb_chain ; if so, error out --> 0 00002361 8ED8 mov ds, ax 0 00002363 89C7 mov di, ax ; => MCB 0 00002365 033E0300 add di, word [mcbSize] 0 00002369 47 inc di ; => next MCB (if any) 0 0000236A 39FB cmp bx, di 0 0000236C 77D9 ja .search_umb ; next --> 0 0000236E 7541 jne .umb_case_2 ; UMB is below where next points to 3932 <1> 3933 <1> .umb_case_1: 3934 <1> %if 0 3935 <1> case 1: S_EXCLDUMA MCB ends at where our UMB starts 3936 <1> 0123456789 3937 <1> S2 E 3938 <1> U3 L 3939 <1> 3940 <1> %endif 0 00002370 B108 mov cl, 8 ; step = 8 3942 <1> 0 00002372 833E010008 cmp word [mcbOwner], 8 0 00002377 7403E9BB00 jne .not_link_umb_error_mcb_chain 0 0000237C 41 inc cx ; step = 9 0 0000237D 833E080053 cmp word [smcbName], "S" 0 00002382 7403E9B000 jne .not_link_umb_error_mcb_chain 0 00002387 41 inc cx ; step = A 0 00002388 803E0A0030 cmp byte [smcbType], S_EXCLDUMA 0 0000238D 7403E9A500 jne .not_link_umb_error_mcb_chain 0 00002392 41 inc cx ; step = B 3952 <1> 0 00002393 803E00005A cmp byte [mcbSignature], "Z" 0 00002398 7403E99A00 jne .not_link_umb_error_mcb_chain 0 0000239D C60600004D mov byte [mcbSignature], "M" 0 000023A2 833E030000 cmp word [mcbSize], 0 ; empty area ? 0 000023A7 7505 jne @F 0 000023A9 8326010000 and word [mcbOwner], 0 ; yes, clear owner 3959 <1> @@: 3960 <1> 0 000023AE E9E8FE jmp .link_next_umb 3962 <1> 3963 <1> 3964 <1> .umb_case_2: 3965 <1> %if 0 3966 <1> case 2: S_EXCLDUMA MCB around entire area 3967 <1> 0123456789 3968 <1> S8 E 3969 <1> U3 L 3970 <1> S2 U3 L1E 3971 <1> S=0 3972 <1> S size=8 3973 <1> di=9 3974 <1> L=7 3975 <1> E=9 3976 <1> L want size=1 3977 <1> L want size=E-L-1 3978 <1> S want size=2 3979 <1> S want size=U-S-1 3980 <1> %endif 3981 <1> 0 000023B1 833E010008 cmp word [mcbOwner], 8 0 000023B6 757F jne .not_link_umb_error_mcb_chain 0 000023B8 41 inc cx ; step = 3 0 000023B9 833E080053 cmp word [smcbName], "S" 0 000023BE 7577 jne .not_link_umb_error_mcb_chain 0 000023C0 41 inc cx ; step = 4 0 000023C1 803E0A0030 cmp byte [smcbType], S_EXCLDUMA 0 000023C6 756F jne .not_link_umb_error_mcb_chain 0 000023C8 41 inc cx ; step = 5 3991 <1> 0 000023C9 8E46FC mov es, word [bp + ?umb_last_umcb] 0 000023CC 8A2E0000 mov ch, byte [mcbSignature] 0 000023D0 26882E0000 mov byte [es:mcbSignature], ch 0 000023D5 2B7EFC sub di, word [bp + ?umb_last_umcb] 3996 <1> ; (E-L) size of UMB's last UMCB 0 000023D8 4F dec di ; (E-L-1) minus last UMCB itself 0 000023D9 26893E0300 mov word [es:mcbSize], di 0 000023DE 26803E00005A cmp byte [es:mcbSignature], "Z" ; last ? 0 000023E4 740A je @F ; yes, do not clear owner (even if empty) --> 0 000023E6 85FF test di, di ; empty area ? 0 000023E8 7506 jnz @F 0 000023EA 268326010000 and word [es:mcbOwner], 0 ; yes, clear owner 4004 <1> @@: 4005 <1> .umb_case_2_3_common: 0 000023F0 89DF mov di, bx ; (U) 0 000023F2 29C7 sub di, ax ; (U-S) 0 000023F4 4F dec di ; (U-S-1) 0 000023F5 893E0300 mov word [mcbSize], di 0 000023F9 85FF test di, di ; empty area ? 0 000023FB 7505 jnz @F 0 000023FD 8326010000 and word [mcbOwner], 0 ; yes, clear owner 4013 <1> @@: 0 00002402 C60600004D mov byte [mcbSignature], "M" ; link to UMB's first UMCB 4015 <1> 0 00002407 E98FFE jmp .link_next_umb 4017 <1> 4018 <1> 4019 <1> .umb_case_3: 4020 <1> %if 0 4021 <1> case 1: S_EXCLDUMA MCB ends somewhere below our UMB 4022 <1> 0123456789 4023 <1> S1E 4024 <1> U3 L 4025 <1> S want size=2 4026 <1> S want size=U-S-1 4027 <1> %endif 0 0000240A B110 mov cl, 10h ; step = 10 4029 <1> 0 0000240C 8B46FA mov ax, word [bp + ?last_mcb] 0 0000240F 85C0 test ax, ax 0 00002411 7424 jz .not_link_umb_error_mcb_chain 0 00002413 41 inc cx ; step = 11 0 00002414 8ED8 mov ds, ax 0 00002416 833E010008 cmp word [mcbOwner], 8 0 0000241B 751A jne .not_link_umb_error_mcb_chain 0 0000241D 41 inc cx ; step = 12 0 0000241E 833E080053 cmp word [smcbName], "S" 0 00002423 7512 jne .not_link_umb_error_mcb_chain 0 00002425 41 inc cx ; step = 13 0 00002426 803E0A0030 cmp byte [smcbType], S_EXCLDUMA 0 0000242B 750A jne .not_link_umb_error_mcb_chain 0 0000242D 41 inc cx ; step = 14 4044 <1> 0 0000242E 803E00005A cmp byte [mcbSignature], "Z" 0 00002433 7502 jne .not_link_umb_error_mcb_chain 4047 <1> 0 00002435 EBB9 jmp .umb_case_2_3_common 4049 <1> 4050 <1> 4051 <1> .not_link_umb_error_mcb_chain: 0 00002437 50 push ax 0 00002438 BA[6425] mov dx, init2_msg.umb_mcb_chain_corrupted_1 0 0000243B E84A02 call init2_disp_msg_asciz_cs_dx 4055 <1> 0 0000243E 88C8 mov al, cl 0 00002440 E87802 call init2_disp_al_hex 0 00002443 BA[8625] mov dx, init2_msg.umb_mcb_chain_corrupted_2 0 00002446 E83F02 call init2_disp_msg_asciz_cs_dx 4060 <1> 0 00002449 58 pop ax 0 0000244A E86702 call init2_disp_ax_hex 0 0000244D BA[8625] mov dx, init2_msg.umb_mcb_chain_corrupted_2 0 00002450 E83502 call init2_disp_msg_asciz_cs_dx 4065 <1> 4066 <1> ; Note that we do not free the UMB here! In case the user 4067 <1> ; wants to do that, the address has already been displayed. 0 00002453 E943FE jmp .link_next_umb 4069 <1> 4070 <1> 4071 <1> .not_link_umb_error_succeeded_unexpectedly: 0 00002456 BA[9225] mov dx, init2_msg.umb_succeeded_unexpectedly 0 00002459 E82C02 call init2_disp_msg_asciz_cs_dx 4074 <1> 4075 <1> .not_link_umb: 0 0000245C 5E pop si ; (discard area flags and strategy word) 0 0000245D 5E pop si ; (discard loop detection counter) 4078 <1> 0 0000245E 89EC5D lleave code 0 00002461 C3 retn 4081 <1> 4082 <1> %if 1 || (_RELOCATEDOSCODE && _DOSCODEHMA) 4083 <1> .call_xms: 0 00002462 2EFF1E[C020] call far [cs:init2_xmsentry] 0 00002467 83F801 cmp ax, 1 0 0000246A 7401 je @F ; (NC) --> 0 0000246C F9 stc 4088 <1> @@: 0 0000246D C3 retn 4090 <1> %endif 4091 <1> 4092 <1> ; Get next MCB, insuring the chain doesn't loop 4093 <1> ; 4094 <1> ; INP: word [ss:si] = area flags and allocation strategy 4095 <1> ; word [ss:si + 2] = loop detection counter, init to 0 4096 <1> ; ax = former MCB (0000h to get first) 4097 <1> ; OUT: CY if MCB chain corrupted or loops, 4098 <1> ; ax = error code 4099 <1> ; NC if MCB chain intact, 4100 <1> ; NZ if no next MCB, 4101 <1> ; ax = error code (0008h) 4102 <1> ; ZR if next MCB available, 4103 <1> ; ax = next MCB 4104 <1> ; di = 0 4105 <1> ; CHG: - 4106 <1> ; STK: 8 word 4107 <1> ; doscode_insure_low_byte_not_0CCh 4108 <1> init2_SNextMCB: 0 0000246E 31FF xor di, di 0 00002470 36FF4C02 dec word [ss:si + 2] 0 00002474 7505 jnz @F 4112 <1> ; This doesn't branch if ZR, meaning if the 1_0000h iterations 4113 <1> ; have run out (if counter was 1 prior to the dec). 0 00002476 F9 stc 0 00002477 B8FE00 mov ax, errorMCBLoops 0 0000247A C3 retn 4117 <1> 4118 <1> @@: 4119 <1> ; (fall through to NextMCB) 4120 <1> 4121 <1> 4122 <1> ; Get next MCB 4123 <1> ; 4124 <1> ; INP: word [ss:si] = area flags and allocation strategy 4125 <1> ; word [ss:si + 2] = loop detection counter 4126 <1> ; ax = former MCB (0000h to get first) 4127 <1> ; OUT: CY if MCB chain corrupted, 4128 <1> ; ax = error code 4129 <1> ; NC if MCB chain intact, 4130 <1> ; NZ if no next MCB, 4131 <1> ; ax = error code 0008h (Not enough memory) 4132 <1> ; ZR if next MCB available, 4133 <1> ; ax = next MCB 4134 <1> ; di = 0 4135 <1> ; CHG: - 4136 <1> ; STK: 3 word 4137 <1> ; 4138 <1> ; An interesting effect of how this code handles the first UMCB 4139 <1> ; is that it doesn't care whether the previous MCB contains an 4140 <1> ; 'M' (normal MCB chain extended into UMA) or 'Z' (normal MCB 4141 <1> ; chain limited to LMA). Also, the parsed area flags allow to 4142 <1> ; ignore the actual requested UMB link: If it was zero, all 4143 <1> ; area flags are cleared and forced to 10h (LMA only) instead. 4144 <1> %ifn _UMA 4145 <1> NextMCB: 4146 <1> push ds 4147 <1> test ax, ax ; request for first ? 4148 <1> jz .first ; yes --> 4149 <1> 4150 <1> call VerifyMCB ; check input MCB first 4151 <1> jc .return 4152 <1> inc ax 4153 <1> add ax, word [di+mcbSize] ; get address of next (if any) 4154 <1> cmp byte [di+mcbSignature], 'M' ; current in-chain ? 4155 <1> je .verify ; yes, verify it --> 4156 <1> ; If this was NZ and didn't jump, then the mcbSignature 4157 <1> ; contains the letter 'Z', which is above 'M'. Therefore, 4158 <1> ; it is always true that it is NC at this point. 4159 <1> mov ax, errorInsufficientMemory ; (NC, NZ) 4160 <1> pop ds 4161 <1> retn 4162 <1> .first: 4163 <1> mov ax, word [bp + ?first_mcb] 4164 <1> .verify: 4165 <1> call VerifyMCB ; NC, ZR if valid - CY if invalid 4166 <1> .return: 4167 <1> pop ds 4168 <1> retn 4169 <1> %else 4170 <1> ; The UMA build has to evaluate the (parsed) area flags 4171 <1> ; here to show the caller a continuous chain of MCBs. 4172 <1> ; This requires special handling in two cases: If the 4173 <1> ; caller's input was 0000h (to get the first MCB) or if 4174 <1> ; it was the MCB before the first UMCB. Area flags of 4175 <1> ; 80h and 40h want to start their search with the first 4176 <1> ; UMCB instead. Flags 20h want to proceed at the first 4177 <1> ; UMCB, all other flags want to stop there. The first 4178 <1> ; UMCB's handling ignores whether the preceeding MCB 4179 <1> ; contained 'M' or 'Z'. 4180 <1> NextMCB: 0 0000247B 1E push ds 0 0000247C 85C0 test ax, ax ; request for first ? 0 0000247E 742C jz .first ; yes --> 4184 <1> 0 00002480 E84900 call VerifyMCB ; check input MCB first 0 00002483 723B jc .return 0 00002485 40 inc ax 0 00002486 034503 add ax, word [di+mcbSize] ; get address of next (whether current is 'M' or 'Z') 4189 <1> 0 00002489 E83600 call IsFirstUMCB? ; is the one behind this the first UMCB ? 0 0000248C 7508 jne .notfirstumcb ; nope, check if last --> 0 0000248E 36F604D0 test byte [ss:si], ~2Fh ; "LMA then UMA" ? 4193 <1> ; x = D0h --> x & ~20h != 00h if area other than LMA-then-UMA, 4194 <1> ; x = 20h --> x & ~20h = 00h if area is LMA-then-UMA 0 00002492 7429 jz .verify ; yes, proceed here --> 4196 <1> ; After test, it is always NC here. 0 00002494 EB11 jmp short .last ; (NC, NZ) else it's the last one (even if 'M') --> 4198 <1> .notfirstumcb: 0 00002496 803D4D cmp byte [di+mcbSignature], 'M' ; current in-chain ? 0 00002499 7422 je .verify ; no --> 0 0000249B 837EF4FE cmp word [bp + ?first_umcb], byte -2 ; any UMA ? 0 0000249F 7706 ja .last ; (NC, NZ) no, really last --> 0 000024A1 36F60470 test byte [ss:si], ~8Fh ; "UMA then LMA" ? 4204 <1> ; x = 70h --> x & ~80h != 00h if area other than UMA-then-LMA, 4205 <1> ; x = 80h --> x & ~80h = 00h if area is UMA-then-LMA 0 000024A5 7413 jz .firstlma ; yes, start to search LMA instead --> 4207 <1> ; After test, it is always NC here. 4208 <1> .last: 0 000024A7 B80800 mov ax, errorInsufficientMemory ; (NC, NZ) 0 000024AA 1F pop ds 0 000024AB C3 retn 4212 <1> .first: 0 000024AC 36F604C0 test byte [ss:si], (80h|40h) ; "UMA then LMA" or "UMA only" ? 0 000024B0 7408 jz .firstlma ; no, start with LMA --> 0 000024B2 8B46F4 mov ax, word [bp + ?first_umcb] ; yes, start with UMA 0 000024B5 83F8FF cmp ax, -1 ; UMA valid ? 0 000024B8 7503 jne .verify ; yes --> 4218 <1> .firstlma: 0 000024BA 8B46F6 mov ax, word [bp + ?first_mcb] ; start with LMA 4220 <1> .verify: 0 000024BD E80C00 call VerifyMCB ; NC, ZR if valid - CY if invalid 4222 <1> .return: 0 000024C0 1F pop ds 0 000024C1 C3 retn 4225 <1> 4226 <1> 4227 <1> ; Compare ax to first UMCB 4228 <1> ; 4229 <1> ; INP: ax = MCB 4230 <1> ; OUT: NZ if not first UMCB (or if there's no UMCB) 4231 <1> ; ZR if first UMCB 4232 <1> ; CHG: - 4233 <1> ; STK: 1 word 4234 <1> IsFirstUMCB?: 0 000024C2 837EF4FE cmp word [bp + ?first_umcb], byte -2 0 000024C6 7703 ja .return ; (NZ if it jumps) --> 0 000024C8 3B46F4 cmp ax, word [bp + ?first_umcb] 4238 <1> .return: 0 000024CB C3 retn 4240 <1> %endif 4241 <1> 4242 <1> 4243 <1> ; Verify MCB 4244 <1> ; 4245 <1> ; INP: ax = MCB 4246 <1> ; OUT: ds = MCB 4247 <1> ; di = 0 4248 <1> ; NZ, CY if invalid MCB, 4249 <1> ; ax = error code 0007h (MCB chain corrupted) 4250 <1> ; ZR, NC if valid MCB 4251 <1> ; CHG: - 4252 <1> ; STK: 1 word 4253 <1> VerifyMCB: 0 000024CC 31FF xor di, di 0 000024CE 8ED8 mov ds, ax ; set up working registers 0 000024D0 40 inc ax 0 000024D1 83F802 cmp ax, byte 2 ; passed value FFFFh or 0000h ? 0 000024D4 720B jb .invalid ; (NZ, CY) yes --> 0 000024D6 48 dec ax 0 000024D7 803D4D cmp byte [di+mcbSignature], 'M' ; valid 'M' signature ? 0 000024DA 7409 je .return ; yes --> (ZR, NC) 0 000024DC 803D5A cmp byte [di+mcbSignature], 'Z' ; valid 'Z' signature ? 0 000024DF 7404 je .return ; yes --> (ZR, NC) 4264 <1> .invalid: 0 000024E1 F9 stc 0 000024E2 B80700 mov ax, errorMCBDestroyed ; (CY, NZ) else invalid 4267 <1> .return: 0 000024E5 C3 retn 4269 <1> 4270 <1> lleave ctx 4271 <1> 4272 <1> 4273 <1> init2_msg: 4274 <1> 4275 <1> %if 0 4276 <1> .internal_error_handles: db "init: Internal error during " 4277 <1> asciz "handle allocation.",13,10 4278 <1> .con: asciz "CON" 4279 <1> .aux: asciz "AUX" 4280 <1> .prn: asciz "PRN" 4281 <1> .rxconfigsys: asciz "RxCONFIG.SYS" 4282 <1> .configsys: asciz "CONFIG.SYS" 4283 <1> .config_error_reading_1:asciz "init: Error " 4284 <1> .config_error_reading_2:asciz "h while reading configuration.",13,10 4285 <1> .config_too_long_line_1:asciz "init: Line " 4286 <1> .config_too_long_line_2:asciz " is too long. Ignoring!",13,10 4287 <1> .config_too_long_file_1: db "init: Configuration file too long, " 4288 <1> asciz "ignoring remainder starting at line " 4289 <1> .config_too_long_file_2:asciz ".",13,10 4290 <1> .internal_error_config: asciz "init: Internal error in CONFIG processing.",13,10 4291 <1> %endif 4292 <1> 0 000024E6 48616C7465642E2050 .reboot_prompt: asciz "Halted. Press Ctrl+Alt+Del to reboot.",13,10 0 000024EF 72657373204374726C 0 000024F8 2B416C742B44656C20 0 00002501 746F207265626F6F74 0 0000250A 2E0D0A00 4294 <1> 4295 <1> .umb_unavailable_1: 4296 <1> .umb_allocated_1: 0 0000250E 696E69743A20554D42 asciz "init: UMB of size " 0 00002517 206F662073697A6520 0 00002520 00 4298 <1> .umb_unavailable_2: 4299 <1> .umb_allocated_2: 0 00002521 68202800 asciz "h (" 4301 <1> .umb_unavailable_3: 0 00002525 29207265706F727465 asciz ") reported free but failed to allocate.",13,10 0 0000252E 642066726565206275 0 00002537 74206661696C656420 0 00002540 746F20616C6C6F6361 0 00002549 74652E0D0A00 4303 <1> .umb_allocated_3: 0 0000254F 292061742000 asciz ") at " 4305 <1> .umb_allocated_4: 0 00002555 6820616C6C6F636174 asciz "h allocated.",13,10 0 0000255E 65642E0D0A00 4307 <1> .umb_mcb_chain_corrupted_1: 0 00002564 696E69743A20554D43 asciz "init: UMCB chain corrupted, step=" 0 0000256D 4220636861696E2063 0 00002576 6F727275707465642C 0 0000257F 20737465703D00 4309 <1> .umb_mcb_chain_corrupted_2: 0 00002586 682C2061783D00 asciz "h, ax=" 4311 <1> .umb_mcb_chain_corrupted_3: 0 0000258D 682E0D0A00 asciz "h.",13,10 4313 <1> .umb_succeeded_unexpectedly: 0 00002592 696E69743A20526571 db "init: Requested UMB allocation of size 0FFFFh" 0 0000259B 75657374656420554D 0 000025A4 4220616C6C6F636174 0 000025AD 696F6E206F66207369 0 000025B6 7A6520304646464668 0 000025BF 20756E657870656374 asciz " unexpectedly succeeded.",13,10 0 000025C8 65646C792073756363 0 000025D1 65656465642E0D0A00 4316 <1> 4317 <1> %if _RELOCATEDOSCODE && _DOSCODEHMA 4318 <1> .error_enabling_a20_xms: 0 000025DA 696E69743A20457272 asciz "init: Error enabling A20, XMS call failed.",13,10 0 000025E3 6F7220656E61626C69 0 000025EC 6E67204132302C2058 0 000025F5 4D532063616C6C2066 0 000025FE 61696C65642E0D0A00 4320 <1> .error_enabling_a20_actual: 0 00002607 696E69743A20457272 asciz "init: Error enabling A20, XMS call reported success but A20 is still off.", 13,10 0 00002610 6F7220656E61626C69 0 00002619 6E67204132302C2058 0 00002622 4D532063616C6C2072 0 0000262B 65706F727465642073 0 00002634 756363657373206275 0 0000263D 742041323020697320 0 00002646 7374696C6C206F6666 0 0000264F 2E0D0A00 4324 <1> .relocated_to_hma: 0 00002653 696E69743A20537563 asciz "init: Successfully relocated DOSCODE into the HMA.",13,10 0 0000265C 6365737366756C6C79 0 00002665 2072656C6F63617465 0 0000266E 6420444F53434F4445 0 00002677 20696E746F20746865 0 00002680 20484D412E0D0A00 4326 <1> %endif 4327 <1> 4328 <1> %if 1 || (_RELOCATEDOSCODE && _DOSCODEHMA) 4329 <1> init2_disp_msg_asciz_cs_dx: 0 00002688 1E push ds 0 00002689 56 push si 0 0000268A 50 push ax 0 0000268B 0E push cs 0 0000268C 1F pop ds 0 0000268D 89D6 mov si, dx 0 0000268F E80400 call init2_disp_msg 0 00002692 58 pop ax 0 00002693 5E pop si 0 00002694 1F pop ds 0 00002695 C3 retn 4341 <1> 4342 <1> init2_disp_msg: 0 00002696 50 push ax 4344 <1> @@: 0 00002697 AC lodsb 0 00002698 84C0 test al, al 0 0000269A 7411 jz @F 0 0000269C E80200 call init2_disp_al 0 0000269F EBF6 jmp short @B 4350 <1> 4351 <1> init2_disp_al: 0 000026A1 50 push ax 0 000026A2 53 push bx 0 000026A3 55 push bp 0 000026A4 B40E mov ah, 0Eh 0 000026A6 BB0700 mov bx, 7 0 000026A9 CD10 int 10h 0 000026AB 5D pop bp 0 000026AC 5B pop bx 4360 <1> @@: 0 000026AD 58 pop ax 0 000026AE C3 retn 4363 <1> 4364 <1> init2_disp_dxax_hex: ; dx:ax 0 000026AF 92 xchg ax, dx 0 000026B0 E80100 call init2_disp_ax_hex 0 000026B3 92 xchg ax, dx 4368 <1> init1_disp_ax_hex: ; ax 4369 <1> init2_disp_ax_hex: ; ax 0 000026B4 86C4 xchg al,ah 0 000026B6 E80200 call init2_disp_al_hex ; display former ah 0 000026B9 86C4 xchg al,ah ; and fall trough for al 4373 <1> init2_disp_al_hex: ; al 0 000026BB 51 push cx 0 000026BC B104 mov cl,4 0 000026BE D2C8 ror al,cl 0 000026C0 E80300 call init2_disp_al_lownibble_hex; display former high-nibble 0 000026C3 D2C0 rol al,cl 0 000026C5 59 pop cx 4380 <1> ; and fall trough for low-nibble 4381 <1> init2_disp_al_lownibble_hex: 0 000026C6 50 push ax ; save ax for call return 0 000026C7 240F and al,00001111b ; high nibble must be zero 0 000026C9 0430 add al,'0' ; if number is 0-9, now it's the correct character 0 000026CB 3C39 cmp al,'9' 0 000026CD 7602 jna .decimalnum ; if we get decimal number with this, ok --> 0 000026CF 0407 add al,7 ; otherwise, add 7 and we are inside our alphabet 4388 <1> .decimalnum: 0 000026D1 E8CDFF call init2_disp_al 0 000026D4 58 pop ax 0 000026D5 C3 retn 4392 <1> %endif 4393 <1> 4394 <1> 4395 <1> ; This is to be called after all device drivers are installed. 4396 <1> ; It relocates DOSCODE and DOSDATA. 4397 <1> ; May be extended to relocate more things later. 4398 <1> ; 4399 <1> ; INP: ax = flags 4400 <1> ; CHG: ds, es, si, di, ax, bx, cx, dx 4401 <1> init2_relocate_end: 4402 <1> lframe 0 4403 <1> lvar word, count 4404 <1> lvar dword, prior 0 000026D6 5589E58D66FA lenter 4406 <1> lvar word, flags 0 000026DC 50 push ax 4408 <1> 0 000026DD B80258 mov ax, 5802h 0 000026E0 CD21 int 21h 0 000026E2 B400 mov ah, 0 0 000026E4 50 push ax 0 000026E5 B80058 mov ax, 5800h 0 000026E8 CD21 int 21h 0 000026EA 50 push ax 4416 <1> 0 000026EB B80358 mov ax, 5803h 0 000026EE 31DB xor bx, bx 0 000026F0 CD21 int 21h ; link out UMB chain 0 000026F2 B80158 mov ax, 5801h 0 000026F5 31DB xor bx, bx 0 000026F7 CD21 int 21h ; alloc strategy: first fit, LMA only 4423 <1> 4424 <1> %if 0 4425 <1> test word [bp + ?flags], DOSFLAGS_RELOCATE_DOSDATA_UMA 4426 <1> jz .got_dosdata_strat 4427 <1> 4428 <1> mov ax, 5803h 4429 <1> mov bx, 1 4430 <1> int 21h ; link in UMB chain 4431 <1> mov ax, 5801h 4432 <1> mov bx, 80h 4433 <1> int 21h ; alloc strategy: first fit, try UMA then LMA 4434 <1> .got_dosdata_strat: 4435 <1> 4436 <1> mov ax, (dosdata_end - dosdata_start) 4437 <1> mov cl, S_DOSDATA 4438 <1> call init2_alloc_s_mcb ; es:di -> DOSDATA destination 4439 <1> 4440 <1> int3 4441 <1> 4442 <1> mov ax, 70h 4443 <1> mov ds, ax ; => DOSENTRY 4444 <1> mov bx, word [dosentry_to_dosdata_segment] 4445 <1> ; get DOSDATA segment 4446 <1> mov ds, bx 4447 <1> xor si, si ; ds:si -> DOSDATA source 4448 <1> shr cx, 1 ; get number of words 4449 <1> rep movsw ; move 4450 <1> 4451 <1> mov word [es:p_buffer_info_record + 2], es 4452 <1> ; DOSDATA reference in DOSDATA 4453 <1> mov ds, ax 4454 <1> mov word [dosentry_to_dosdata_segment], es 4455 <1> ; DOSDATA reference in DOSENTRY 4456 <1> %if _COMBINED_DOSDATA_DOSCODE 4457 <1> push es 4458 <1> pop ds 4459 <1> mov word [dosdata_to_doscode_segment], es 4460 <1> %endif 4461 <1> xor ax, ax 4462 <1> mov ds, ax 4463 <1> mov word [30h * 4 + 6], es ; DR-DOS compatible DOSDATA reference 4464 <1> 4465 <1> mov ax, ss 4466 <1> cmp ax, bx 4467 <1> jne @F 4468 <1> push es 4469 <1> pop ss 4470 <1> @@: 4471 <1> 4472 <1> mov es, bx ; => DOSDATA source 4473 <1> mov ah, 49h 4474 <1> int 21h ; free it 4475 <1> %endif 4476 <1> 4477 <1> %if !_COMBINED_DOSDATA_DOSCODE && _RELOCATEDOSCODE 4478 <1> 0 000026F9 B80358 mov ax, 5803h 0 000026FC 31DB xor bx, bx 0 000026FE CD21 int 21h ; link out UMB chain 0 00002700 B80158 mov ax, 5801h 0 00002703 31DB xor bx, bx 0 00002705 CD21 int 21h ; alloc strategy: first fit, LMA only 4485 <1> 0 00002707 F746F80100 test word [bp + ?flags], DOSFLAGS_RELOCATE_DOSCODE_UMA 0 0000270C 7410 jz .got_doscode_strat 4488 <1> 0 0000270E B80358 mov ax, 5803h 0 00002711 BB0100 mov bx, 1 0 00002714 CD21 int 21h ; link in UMB chain 0 00002716 B80158 mov ax, 5801h 0 00002719 BB8000 mov bx, 80h 0 0000271C CD21 int 21h ; alloc strategy: first fit, try UMA then LMA 4495 <1> .got_doscode_strat: 4496 <1> 4497 <1> %if 0 4498 <1> mov ax, 70h 4499 <1> mov ds, ax 4500 <1> mov ds, word [dosentry_to_dosdata_segment] 4501 <1> %else 0 0000271E 31C0 xor ax, ax 0 00002720 8ED8 mov ds, ax 0 00002722 8E1EC600 mov ds, word [31h * 4 + 2] ; => DOSDATA 4505 <1> %endif 0 00002726 833E[0000]FE cmp word [dosdata_to_doscode_segment], DOSCODE_HMA_SEGMENT 0 0000272B 7344 jae .skip_doscode 4508 <1> 4509 <1> %if 0 4510 <1> mov ax, (doscode_end - doscode_start) 4511 <1> %else 4512 <1> extern afterdoscodelabel 0 0000272D B8[0000] mov ax, afterdoscodelabel wrt DOSCODEGROUP 0 00002730 83E850 sub ax, DOSCODE_HMA_OFFSET 4515 <1> %endif 0 00002733 B102 mov cl, S_DOSCODE 0 00002735 E8CBF7 call init2_alloc_s_mcb 4518 <1> 4519 <1> %if 0 4520 <1> mov ax, 70h 4521 <1> mov ds, ax ; => DOSENTRY 4522 <1> mov ds, word [dosentry_to_dosdata_segment] ; => DOSDATA 4523 <1> %else 0 00002738 31C0 xor ax, ax 0 0000273A 8ED8 mov ds, ax 0 0000273C 8E1EC600 mov ds, word [31h * 4 + 2] ; => DOSDATA 4527 <1> %endif 0 00002740 8CC3 mov bx, es 0 00002742 83EB05 sub bx, DOSCODE_HMA_OFFSET / 16 ; start offset 0 00002745 8EC3 mov es, bx 0 00002747 BF5000 mov di, DOSCODE_HMA_OFFSET ; es:di -> DOSCODE destination 0 0000274A 8B1E[0000] mov bx, word [dosdata_to_doscode_segment] 0 0000274E 8EDB mov ds, bx 0 00002750 89FE mov si, di ; ds:si -> DOSCODE source 0 00002752 D1E9 shr cx, 1 ; = number of words 0 00002754 F3A5 rep movsw ; move 4537 <1> 4538 <1> %if 0 4539 <1> mov ds, ax 4540 <1> mov ds, word [dosentry_to_dosdata_segment] 4541 <1> %else 0 00002756 8ED8 mov ds, ax 0 00002758 8E1EC600 mov ds, word [31h * 4 + 2] ; => DOSDATA 4544 <1> %endif 0 0000275C 8C06[0000] mov word [dosdata_to_doscode_segment], es 4546 <1> 0 00002760 8CD0 mov ax, ss 0 00002762 39D8 cmp ax, bx 0 00002764 7502 jne @F 0 00002766 06 push es 0 00002767 17 pop ss 4552 <1> @@: 4553 <1> 0 00002768 83C305 add bx, DOSCODE_HMA_OFFSET / 16 ; start offset 0 0000276B 8EC3 mov es, bx ; => DOSCODE source 0 0000276D B449 mov ah, 49h 0 0000276F CD21 int 21h ; free it 4558 <1> 4559 <1> .skip_doscode: 4560 <1> %endif 4561 <1> 4562 <1> 4563 <1> %if 0 4564 <1> .sft: 4565 <1> d4bp 4566 <1> 4567 <1> mov ax, 5803h 4568 <1> xor bx, bx 4569 <1> int 21h ; link out UMB chain 4570 <1> mov ax, 5801h 4571 <1> xor bx, bx 4572 <1> int 21h ; alloc strategy: first fit, LMA only 4573 <1> 4574 <1> test word [bp + ?flags], DOSFLAGS_RELOCATE_SFT_UMA 4575 <1> jz .got_sft_strat 4576 <1> 4577 <1> mov ax, 5803h 4578 <1> mov bx, 1 4579 <1> int 21h ; link in UMB chain 4580 <1> mov ax, 5801h 4581 <1> mov bx, 80h 4582 <1> int 21h ; alloc strategy: first fit, try UMA then LMA 4583 <1> 4584 <1> .got_sft_strat: 4585 <1> 4586 <1> mov ax, 70h 4587 <1> mov es, ax ; => DOSENTRY 4588 <1> mov es, word [es:dosentry_to_dosdata_segment] 4589 <1> ; => DOSDATA 4590 <1> mov di, first_sftc - sftcNext ; -> pseudo 0th SFTC 4591 <1> and word [bp + ?count], 0 4592 <1> 4593 <1> .next_sftc: 4594 <1> mov word [bp + ?prior + 2], es 4595 <1> mov word [bp + ?prior], di 4596 <1> les di, [es:di + sftcNext] 4597 <1> cmp di, -1 4598 <1> je .done_sftc 4599 <1> 4600 <1> mov cx, word [es:di + sftcEntries] 4601 <1> add word [bp + ?count], cx ; count up the number of SFTs seen 4602 <1> 4603 <1> test di, di 4604 <1> jnz .next_sftc 4605 <1> 4606 <1> mov ax, sizeSFT 4607 <1> mul cx 4608 <1> 4609 <1> add ax, SFTC_size 4610 <1> adc dx, 0 ; add in size for SFTC 4611 <1> 4612 <1> test dx, dx 4613 <1> jz @F 4614 <1> 4615 <1> int3 4616 <1> jmp .next_sftc 4617 <1> 4618 <1> @@: 4619 <1> 4620 <1> mov si, di 4621 <1> push es 4622 <1> pop ds 4623 <1> mov cl, S_SFT 4624 <1> call init2_alloc_s_mcb 4625 <1> 4626 <1> push di 4627 <1> shr cx, 1 4628 <1> rep movsw ; relocate content 4629 <1> jnc @F 4630 <1> movsb ; relocate content last byte if odd 4631 <1> @@: 4632 <1> pop di 4633 <1> push es 4634 <1> push ds 4635 <1> lds si, [bp + ?prior] ; -> prior SFTC 4636 <1> mov word [si + sftcNext], di 4637 <1> mov word [si + sftcNext + 2], es 4638 <1> ; relocate pointer to here 4639 <1> 4640 <1> pop es 4641 <1> mov ah, 49h 4642 <1> int 21h ; free source block 4643 <1> 4644 <1> pop es 4645 <1> 4646 <1> jmp .next_sftc 4647 <1> 4648 <1> 4649 <1> .done_sftc: 4650 <1> mov cx, word [cs:init2_sfts] 4651 <1> sub cx, word [bp + ?count] 4652 <1> ; wanted - count = additional 4653 <1> jbe .no_add_sftc ; wanted <= count ? if yes --> 4654 <1> 4655 <1> mov ax, sizeSFT 4656 <1> mul cx ; size for amount of SFTs 4657 <1> 4658 <1> add ax, SFTC_size 4659 <1> adc dx, 0 ; add in size for SFTC 4660 <1> 4661 <1> test dx, dx ; below 64 KiB ? 4662 <1> jz @F ; yes --> 4663 <1> 4664 <1> int3 4665 <1> jmp .no_add_sftc 4666 <1> 4667 <1> @@: 4668 <1> push cx 4669 <1> mov cl, S_SFT 4670 <1> call init2_alloc_s_mcb ; allocate, initialised to all zeros 4671 <1> or word [es:di + sftcNext], -1 4672 <1> or word [es:di + sftcNext + 2], -1 ; initialise end pointer 4673 <1> pop cx 4674 <1> mov word [es:di + sftcEntries], cx ; initialise count 4675 <1> 4676 <1> lds si, [bp + ?prior] 4677 <1> mov word [si + sftcNext], di 4678 <1> mov word [si + sftcNext + 2], es ; link into prior 4679 <1> 4680 <1> .no_add_sftc: 4681 <1> 4682 <1> 4683 <1> mov ax, 5803h 4684 <1> xor bx, bx 4685 <1> int 21h ; link out UMB chain 4686 <1> mov ax, 5801h 4687 <1> xor bx, bx 4688 <1> int 21h ; alloc strategy: first fit, LMA only 4689 <1> 4690 <1> test word [bp + ?flags], DOSFLAGS_RELOCATE_CDS_UMA 4691 <1> jz .got_cds_strat 4692 <1> 4693 <1> mov ax, 5803h 4694 <1> mov bx, 1 4695 <1> int 21h ; link in UMB chain 4696 <1> mov ax, 5801h 4697 <1> mov bx, 80h 4698 <1> int 21h ; alloc strategy: first fit, try UMA then LMA 4699 <1> 4700 <1> .got_cds_strat: 4701 <1> 4702 <1> push word [cs:init2_cds] 4703 <1> pop word [bp + ?count] 4704 <1> 4705 <1> mov cx, 70h ; ! ch = 0 4706 <1> mov ds, cx ; => DOSENTRY 4707 <1> mov ds, word [dosentry_to_dosdata_segment] 4708 <1> ; => DOSDATA 4709 <1> mov cl, [number_cds_entries] ; cx = current CDS size 4710 <1> lds si, [first_cds] ; -> CDS 4711 <1> 4712 <1> .loop_cds_size: 4713 <1> cmp cx, 1 4714 <1> je .got_cds_size 4715 <1> cmp cx, word [bp + ?count] 4716 <1> jbe .got_cds_size 4717 <1> 4718 <1> dec cx 4719 <1> 4720 <1> mov al, sizeCDS 4721 <1> mul cl 4722 <1> mov bx, ax 4723 <1> test word [si + bx + _cdsFlags], _CDS_VALID 4724 <1> jz .loop_cds_size 4725 <1> 4726 <1> inc cx 4727 <1> 4728 <1> .got_cds_size: 4729 <1> mov dx, cx 4730 <1> mov al, sizeCDS 4731 <1> mul cl 4732 <1> push ax 4733 <1> mov cl, S_CDS 4734 <1> call init2_alloc_s_mcb 4735 <1> pop cx 4736 <1> push di 4737 <1> rep movsb 4738 <1> pop di 4739 <1> 4740 <1> push ds 4741 <1> 4742 <1> mov cx, 70h ; ! ch = 0 4743 <1> mov ds, cx ; => DOSENTRY 4744 <1> mov ds, word [dosentry_to_dosdata_segment] 4745 <1> ; => DOSDATA 4746 <1> mov byte [number_cds_entries], dl 4747 <1> mov word [first_cds + 2], es 4748 <1> mov word [first_cds], di 4749 <1> 4750 <1> mov cx, dx 4751 <1> lds si, [_RxDOS_pLFNCDS] 4752 <1> push si 4753 <1> @@: 4754 <1> mov word [si + _lfnPtrToCDS + 2], es 4755 <1> mov word [si + _lfnPtrToCDS], di 4756 <1> ; relocate LFNCDS's reference to CDS 4757 <1> add si, sizeLFNCDS ; -> next LFNCDS 4758 <1> add di, sizeCDS ; -> next CDS 4759 <1> loop @B 4760 <1> pop si 4761 <1> 4762 <1> 4763 <1> mov ax, 5803h 4764 <1> xor bx, bx 4765 <1> int 21h ; link out UMB chain 4766 <1> mov ax, 5801h 4767 <1> xor bx, bx 4768 <1> int 21h ; alloc strategy: first fit, LMA only 4769 <1> 4770 <1> test word [bp + ?flags], DOSFLAGS_RELOCATE_LFNCDS_UMA 4771 <1> jz .got_lfncds_strat 4772 <1> 4773 <1> mov ax, 5803h 4774 <1> mov bx, 1 4775 <1> int 21h ; link in UMB chain 4776 <1> mov ax, 5801h 4777 <1> mov bx, 80h 4778 <1> int 21h ; alloc strategy: first fit, try UMA then LMA 4779 <1> 4780 <1> .got_lfncds_strat: 4781 <1> 4782 <1> 4783 <1> push ds 4784 <1> mov ax, sizeLFNCDS ; (1032) 4785 <1> mul dx ; at most 32 KiB + 8 * 32 = 32768 + 256 4786 <1> test dx, dx 4787 <1> jz @F 4788 <1> 4789 <1> int3 ; shouldn't happen 4790 <1> pop es 4791 <1> jmp .fail_after_lfncds 4792 <1> 4793 <1> @@: 4794 <1> push ax 4795 <1> mov cl, S_LFNCDS 4796 <1> call init2_alloc_s_mcb ; allocate memory for LFNCDS 4797 <1> pop cx 4798 <1> push di 4799 <1> rep movsb 4800 <1> pop di 4801 <1> 4802 <1> mov cx, 70h ; ! ch = 0 4803 <1> mov ds, cx ; => DOSENTRY 4804 <1> mov ds, word [dosentry_to_dosdata_segment] 4805 <1> ; => DOSDATA 4806 <1> mov word [_RxDOS_pLFNCDS + 2], es 4807 <1> mov word [_RxDOS_pLFNCDS], di 4808 <1> 4809 <1> pop es 4810 <1> mov ah, 49h 4811 <1> int 21h ; free init LFNCDS 4812 <1> 4813 <1> .fail_after_lfncds: 4814 <1> pop es 4815 <1> mov ah, 49h 4816 <1> int 21h ; free init CDS 4817 <1> 4818 <1> 4819 <1> %endif 0 00002771 5B pop bx 0 00002772 B80158 mov ax, 5801h 0 00002775 CD21 int 21h ; alloc strategy: restore 0 00002777 5B pop bx 0 00002778 B80358 mov ax, 5803h 0 0000277B CD21 int 21h ; restore UMB chain linkage 4826 <1> 0 0000277D 89EC5D lleave 0 00002780 C3 retn 4829 <1> 4830 <1> 4831 <1> init2_internal_error_reboot_prompt: 0 00002781 E812FF call init2_disp_msg 4833 <1> 4834 <1> init2_reboot_prompt: 0 00002784 0E push cs 0 00002785 1F pop ds 0 00002786 BE[E624] mov si, init2_msg.reboot_prompt 0 00002789 E80AFF call init2_disp_msg 4839 <1> .loop: 0 0000278C CC int3 0 0000278D 31C0 xor ax, ax 0 0000278F CD16 int 16h 0 00002791 EBF9 jmp .loop 4844 <1> 4845 <1> 4846 <1> %if 0 4847 <1> align 4 4848 <1> %include "RxDOSINI.ASM" 4849 <1> 4850 <1> align 16 4851 <1> init2_end: 4852 <1> istruc MCB 4853 <1> at mcbSignature, db "M" 4854 <1> at mcbOwner, dw 8 4855 <1> at mcbSize, dw (init3_end - init3_start) >> 4 4856 <1> at smcbName, dw "S" 4857 <1> at smcbType, db S_INITPSP 4858 <1> iend 4859 <1> 4860 <1> ; section INIT3 align=16 follows=INIT2 vstart=0 4861 <1> init3_start: 4862 <1> istruc PSP 4863 <1> at pspCall0, int 20h 4864 <1> at pspCall5, call 0:(30h * 4) 4865 <1> at pspInt22, dw init3_terminated, 0 ; +2 segment here 4866 <1> at pspInt23, dw i23, 70h 4867 <1> at pspInt24, dw i24, 70h 4868 <1> at pspParent, dw 0 ; +0 segment here 4869 <1> at pspPHT, times pspPHT_size db -1 4870 <1> at pspEnvironment, dw 0 ; +0 env segment here 4871 <1> at pspStack, dw init3_stack.end - 32, 0 ; +2 segment here 4872 <1> at pspPHTEntries, dw pspPHT_size 4873 <1> at pspPHTAddress, dw pspPHT, 0 ; +2 segment here 4874 <1> at pspShareNext, dd -1 4875 <1> at pspVersion, dw RXDOS_MS_VERSION 4876 <1> at pspInt21Far, int 21h 4877 <1> retf 4878 <1> at pspCommandLine 4879 <1> ; iend 4880 <1> %pop ; (pop off the istruc context) 4881 <1> 4882 <1> init3_msg: 4883 <1> .internal_error_terminated: db "init: Internal error, init PSP " 4884 <1> asciz "has been terminated.",13,10 4885 <1> .reboot_prompt: asciz "Halted. Press Ctrl+Alt+Del to reboot.",13,10 4886 <1> 4887 <1> init3_terminated: 4888 <1> cli 4889 <1> cld 4890 <1> mov ax, cs 4891 <1> mov ss, ax 4892 <1> mov sp, init3_stack.end 4893 <1> sti 4894 <1> 4895 <1> push cs 4896 <1> pop ds 4897 <1> mov si, init3_msg.internal_error_terminated 4898 <1> init3_internal_error_reboot_prompt: 4899 <1> call init3_disp_msg 4900 <1> 4901 <1> init3_reboot_prompt: 4902 <1> push cs 4903 <1> pop ds 4904 <1> mov si, init3_msg.reboot_prompt 4905 <1> call init3_disp_msg 4906 <1> .loop: 4907 <1> int3 4908 <1> xor ax, ax 4909 <1> int 16h 4910 <1> jmp .loop 4911 <1> 4912 <1> init3_disp_msg_asciz: 4913 <1> push ds 4914 <1> push si 4915 <1> push ax 4916 <1> push cs 4917 <1> pop ds 4918 <1> mov si, dx 4919 <1> call init3_disp_msg 4920 <1> pop ax 4921 <1> pop si 4922 <1> pop ds 4923 <1> retn 4924 <1> 4925 <1> init3_disp_msg: 4926 <1> push ax 4927 <1> @@: 4928 <1> lodsb 4929 <1> test al, al 4930 <1> jz @F 4931 <1> call init3_disp_al 4932 <1> jmp short @B 4933 <1> 4934 <1> init3_disp_al: 4935 <1> push ax 4936 <1> push bx 4937 <1> push bp 4938 <1> mov ah, 0Eh 4939 <1> mov bx, 7 4940 <1> int 10h 4941 <1> pop bp 4942 <1> pop bx 4943 <1> @@: 4944 <1> pop ax 4945 <1> retn 4946 <1> 4947 <1> 4948 <1> align 16 4949 <1> init3_stack: 4950 <1> times 512 db 0 4951 <1> .end: 4952 <1> 4953 <1> align 16 4954 <1> init3_end: 4955 <1> istruc MCB 4956 <1> at mcbSignature, db "Z" 4957 <1> at mcbOwner, dw 0 4958 <1> at mcbSize, dw 0 4959 <1> iend 4960 <1> 4961 <1> %include "comload.asm" 4962 <1> %endif 4963 <1> 4964 <1> struc ALLOCDATA 0 00000000 ?? adSMCBType: resb 1 0 00000001 ?? adSDSign: resb 1 0 00000002 ???????????????? adHMCBName: resb 8 4968 <1> endstruc 4969 <1> 4970 <1> %imacro allocdata 4.nolist 4971 <1> %1: 4972 <1> istruc ALLOCDATA 4973 <1> at adSMCBType, db %2 4974 <1> at adSDSign, db %3 4975 <1> at adHMCBName, db %4 4976 <1> iend 4977 <1> %endmacro 4978 <1> 0 00002793 00 align 2, db 0 0 00002794 0A4653465400 allocdata alloc_sft, S_SFT, DEVMARK_FILES, "SFT" 4980 00002794 <1> 0 0000279E 0B5846434253465400 allocdata alloc_fcb, S_FCBSFT, DEVMARK_FCBS, "FCBSFT" 4981 0000279E <1> 0 000027A8 0C4242756666657273 allocdata alloc_buffers, S_CCB, DEVMARK_BUF, "Buffers" 0 000027B1 00 0 000027B2 064C43445300 allocdata alloc_cds, S_CDS, DEVMARK_CDS, "CDS" 4983 000027B2 <1> 0 000027BC 0453FF00 allocdata alloc_stack, S_IRQSCODE, DEVMARK_STK, -1 ; not for HMA 0 000027C6 1F00FF00 allocdata alloc_init, S_INIT, 0, -1 0 000027D0 1800FF00 allocdata alloc_initcds, S_INITCDS, 0, -1 0 000027DA 1900FF00 allocdata alloc_initconfig, S_INITCONFIG, 0, -1 0 000027E4 0900FF00 allocdata alloc_upb_temporary, S_UPB, 0, -1 0 000027EE 090055504200 allocdata alloc_upb, S_UPB, 0, "UPB" 4989 000027EE <1> 4990 <1> alloc_dpb_temporary: 0 000027F8 0800FF00 allocdata alloc_dpb_no_hma, S_DPB, 0, -1 0 00002802 080044504200 allocdata alloc_dpb, S_DPB, 0, "DPB" 4992 00002802 <1> 0 0000280C 1700496E6953746163 allocdata alloc_initstack, S_INITSTACK, 0, "IniStack" 0 00002815 6B 4994 <1> 4995 <1> global alloc_init, alloc_initcds, alloc_initconfig, alloc_dpb_no_hma 4996 <1> global alloc_upb_temporary, alloc_upb 4997 <1> global alloc_dpb_temporary, alloc_dpb 4998 <1> global allocate_relocate_block 4999 <1> global allocate_temporary_block 5000 <1> global allocate_temporary_block.large_allow_error 5001 <1> 5002 <1> align 2, db 0 0 00002816 00 db 0 ; pad so start is odd 5004 <1> smcb_template: 0 00002817 000000 .: db 0, 0, 0 0 0000281A 5300 db "S", 0 0 0000281C 00 times 6 db 0 5008 <1> .end: 5009 <1> .size equ .end - . 5010 <1> 5011 <1> ; INP: cs:si -> data 5012 <1> ; (dx:)ax = bytes needed 5013 <1> ; OUT: es:di -> memory allocated, zeroed 5014 <1> ; di = 0 if not in HMA 5015 <1> allocate_relocate_block: 0 00002822 31D2 xor dx, dx 5017 <1> .large: 5018 <1> lframe 5019 <1> lvar word, parasize 0 00002824 5589E550 lenter 5021 <1> lvar word, data 0 00002828 56 push si 5023 <1> lvar dword, size 0 00002829 52 push dx 0 0000282A 50 push ax 5026 <1> 0 0000282B 2E807C02FF cmp byte [cs:si + adHMCBName], -1 0 00002830 7445 je .nothma ; if cannot relocate to HMA --> 0 00002832 85D2 test dx, dx ; >= 64 KiB ? 0 00002834 7541 jnz .nothma ; cannot fit in the HMA --> 0 00002836 93 xchg bx, ax ; bx = how many bytes needed 0 00002837 BFFFFF mov di, -1 ; harden 0 0000283A B92600 mov cx, 26h ; owner 0 0000283D B200 mov dl, 0 ; allocate low in the largest free block 0 0000283F B8034A mov ax, 4A03h 0 00002842 CD2F int 2Fh ; allocate HMA memory block 0 00002844 83FFFF cmp di, -1 0 00002847 742E je .nothma 0 00002849 83C7F8 add di, - HMCB_size + hmcbName 5040 <1> ; -> HMCB name field 0 0000284C 0E push cs 0 0000284D 1F pop ds 0 0000284E 83C602 add si, adHMCBName ; -> our data's name field 0 00002851 B90400 mov cx, words(8) ; length of name 0 00002854 F3A5 rep movsw ; es:di -> at data again 0 00002856 57 push di 0 00002857 31C0 xor ax, ax 0 00002859 89D9 mov cx, bx 0 0000285B D1E9 shr cx, 1 ; amount words actually allocated 0 0000285D F3AB rep stosw 0 0000285F 85FF test di, di 0 00002861 740F jz @F 0 00002863 83FFF0 cmp di, 0FFF0h ; near end ? 0 00002866 730A jae @F ; yes --> 0 00002868 BFFEFF mov di, 0FFFEh ; no, address with segment 0FFFEh instead 0 0000286B 8EC7 mov es, di ; es => HMA 0 0000286D 5F pop di 0 0000286E 83C710 add di, 10h ; -> allocation in segment 0FFFEh 0 00002871 A8 db __TEST_IMM8 ; (skip pop) 5060 <1> @@: 0 00002872 5F pop di ; es:di -> allocated memory block 5062 <1> .ret: 0 00002873 89EC5D lleave code 0 00002876 C3 retn 5065 <1> 5066 <1> .nothma: 0 00002877 B80058 mov ax, 5800h 0 0000287A CD21 int 21h ; get strategy 0 0000287C 50 push ax 0 0000287D B80158 mov ax, 5801h 0 00002880 BB4101 mov bx, 0141h ; UMA only, best fit, ignore UMB link status 0 00002883 CD21 int 21h ; set strategy 5073 <1> 0 00002885 8B56FA mov dx, word [bp + ?size + 2] 0 00002888 8B46F8 mov ax, word [bp + ?size] 0 0000288B 83C00F add ax, 15 ; round up 0 0000288E 83D200 adc dx, 0 5078 <1> .err_CY: 0 00002891 7303E9[0000] jc MEM_ERR 5080 <1> 0 00002896 B90400 mov cx, 4 5082 <1> @@: 0 00002899 D1EA shr dx, 1 0 0000289B D1D8 rcr ax, 1 0 0000289D E2FA loop @B 0 0000289F 85D2 test dx, dx ; >= 1 MiB ? 0 000028A1 F9 stc 0 000028A2 75ED jnz .err_CY ; error --> 5089 <1> 0 000028A4 8946FE mov word [bp + ?parasize], ax 0 000028A7 93 xchg bx, ax 0 000028A8 B448 mov ah, 48h 0 000028AA CD21 int 21h 0 000028AC 7311 jnc .success 5095 <1> 0 000028AE B80158 mov ax, 5801h 0 000028B1 BB8001 mov bx, 0180h ; UMA then LMA, first fit, ignore UMB link status 0 000028B4 CD21 int 21h ; set strategy 5099 <1> 0 000028B6 8B5EFE mov bx, word [bp + ?parasize] 0 000028B9 B448 mov ah, 48h 0 000028BB CD21 int 21h 0 000028BD 7257 jc .fail 5104 <1> 5105 <1> .success: 0 000028BF 50 push ax ; => UMA memory block 0 000028C0 48 dec ax 0 000028C1 8EC0 mov es, ax ; => UMCB 0 000028C3 BF0500 mov di, mcbReserved ; -> UMCB reserved field 0 000028C6 0E push cs 0 000028C7 1F pop ds 0 000028C8 8A04 mov al, byte [si + adSMCBType] 5113 <1> ; al = S MCB type 0 000028CA BE[1728] mov si, smcb_template ; -> our template 0 000028CD B90B00 mov cx, smcb_template.size 0 000028D0 26C70601000800 mov word [es:mcbOwner], 8 5117 <1> ; MCB owner = 8 (system) 0 000028D7 F3A4 rep movsb 0 000028D9 26A20A00 mov byte [es:smcbType], al 5120 <1> ; set the type 5121 <1> 0 000028DD 07 pop es ; => UMA memory block 0 000028DE 31FF xor di, di ; -> start of allocation 0 000028E0 89D9 mov cx, bx ; size in paras 5125 <1> 0 000028E2 5B pop bx 0 000028E3 B80158 mov ax, 5801h 0 000028E6 CD21 int 21h ; restore strategy 5129 <1> 0 000028E8 89CB mov bx, cx ; = amount paragraphs 5131 <1> 5132 <1> .ret_init_bx: 0 000028EA 06 push es 0 000028EB 57 push di 5135 <1> 5136 <1> @@: 0 000028EC B90080 mov cx, 8000h ; words in 64 KiB 0 000028EF 81EB0010 sub bx, 1000h ; another 64 KiB ? 0 000028F3 730D jae @F ; yes --> 0 000028F5 80C710 add bh, 10h ; restore bx 0 000028F8 31C9 xor cx, cx ; cx = 0 0 000028FA 87D9 xchg bx, cx ; bx = 0, cx = amount paragraphs 0 000028FC D1E1 shl cx, 1 0 000028FE D1E1 shl cx, 1 0 00002900 D1E1 shl cx, 1 ; cx = amount words 5146 <1> @@: 0 00002902 31C0 xor ax, ax 0 00002904 F3AB rep stosw ; zero the memory 0 00002906 8CC0 mov ax, es 0 00002908 050010 add ax, 1000h 0 0000290B 8EC0 mov es, ax ; => next segment (skip 64 KiB) 0 0000290D 85DB test bx, bx ; any remaining ? 0 0000290F 75DB jnz @BB ; yes --> 5154 <1> 0 00002911 5F pop di 0 00002912 07 pop es ; -> back at start 0 00002913 E95DFF jmp .ret 5158 <1> 5159 <1> .fail: 0 00002916 5B pop bx 0 00002917 B80158 mov ax, 5801h 0 0000291A CD21 int 21h ; restore strategy 5163 <1> 0 0000291C 0E push cs 0 0000291D 1F pop ds 5166 <1> %if 0 5167 <1> INVOKE ROUND 5168 <1> mov al, [si + adSDSign] 5169 <1> ; cmp al, 1 5170 <1> ; jb .err_CY 5171 <1> call SetDevMark 5172 <1> mov bx, [bp + ?parasize] 5173 <1> les di, [ss:MEMLO] ; es:di -> allocated data block 5174 <1> add word [ss:MEMHI], bx ; size in paragraphs 5175 <1> or byte [ss:SetDevMarkFlag], FOR_DEVMARK 5176 <1> INVOKE ROUND ; allocate, will error out if not enough 5177 <1> jmp .ret_init_bx 5178 <1> %else 0 0000291E E9[0000] jmp MEM_ERR 5180 <1> %endif 5181 <1> 5182 <1> lleave ctx 5183 <1> 5184 <1> 5185 <1> ; INP: cs:si -> data 5186 <1> ; (dx:)ax = bytes needed 5187 <1> ; OUT: es:di -> memory allocated, zeroed 5188 <1> ; di = 0 5189 <1> ; ds = cs 5190 <1> allocate_temporary_block: 0 00002921 31D2 xor dx, dx 5192 <1> .large: 0 00002923 A8 db __TEST_IMM8 ; skip stc, NC 5194 <1> .large_allow_error: 0 00002924 F9 stc 5196 <1> lframe 5197 <1> lvar word, parasize 0 00002925 5589E550 lenter 5199 <1> lvar word, bit0_allow_error 0 00002929 9C pushf 5201 <1> lvar word, data 0 0000292A 56 push si 5203 <1> lvar dword, size 0 0000292B 52 push dx 0 0000292C 50 push ax 5206 <1> 0 0000292D B80058 mov ax, 5800h 0 00002930 CD21 int 21h ; get strategy 0 00002932 50 push ax 0 00002933 B80158 mov ax, 5801h 0 00002936 BB1201 mov bx, 0112h ; LMA only, last fit, ignore UMB link status 0 00002939 CD21 int 21h ; set strategy 5213 <1> 0 0000293B 8B56F8 mov dx, word [bp + ?size + 2] 0 0000293E 8B46F6 mov ax, word [bp + ?size] 0 00002941 83C00F add ax, 15 ; round up 0 00002944 83D200 adc dx, 0 5218 <1> .err_CY: 0 00002947 7303E9[0000] jc MEM_ERR 5220 <1> 0 0000294C B90400 mov cx, 4 5222 <1> @@: 0 0000294F D1EA shr dx, 1 0 00002951 D1D8 rcr ax, 1 0 00002953 E2FA loop @B 0 00002955 85D2 test dx, dx ; >= 1 MiB ? 0 00002957 F9 stc 0 00002958 75ED jnz .err_CY ; error --> 5229 <1> 0 0000295A 8946FE mov word [bp + ?parasize], ax 0 0000295D 93 xchg bx, ax 0 0000295E B448 mov ah, 48h 0 00002960 CD21 int 21h 0 00002962 7312 jnc .success 0 00002964 F646FC01 test byte [bp + ?bit0_allow_error], 1 0 00002968 F9 stc 0 00002969 74DC jz .err_CY 5238 <1> 0 0000296B 5B pop bx 0 0000296C B80158 mov ax, 5801h 0 0000296F CD21 int 21h ; restore strategy 5242 <1> 0 00002971 0E push cs 0 00002972 1F pop ds 0 00002973 F9 stc 0 00002974 EB54 jmp .ret 5247 <1> 5248 <1> .success: 0 00002976 50 push ax ; => LMA memory block 0 00002977 48 dec ax 0 00002978 8EC0 mov es, ax ; => LMCB 0 0000297A BF0500 mov di, mcbReserved ; -> LMCB reserved field 0 0000297D 0E push cs 0 0000297E 1F pop ds ; ! ds = cs 0 0000297F 8A04 mov al, byte [si + adSMCBType] 5256 <1> ; al = S MCB type 0 00002981 BE[1728] mov si, smcb_template ; -> our template 0 00002984 B90B00 mov cx, smcb_template.size 0 00002987 26C70601000800 mov word [es:mcbOwner], 8 5260 <1> ; MCB owner = 8 (system) 0 0000298E F3A4 rep movsb 0 00002990 26A20A00 mov byte [es:smcbType], al 5263 <1> ; set the type 5264 <1> 0 00002994 07 pop es ; => LMA memory block 0 00002995 31FF xor di, di ; -> start of allocation 0 00002997 89D9 mov cx, bx ; size in paras 5268 <1> 0 00002999 5B pop bx 0 0000299A B80158 mov ax, 5801h 0 0000299D CD21 int 21h ; restore strategy 5272 <1> 0 0000299F 89CB mov bx, cx ; = amount paragraphs 5274 <1> 0 000029A1 06 push es 0 000029A2 57 push di 5277 <1> 5278 <1> @@: 0 000029A3 B90080 mov cx, 8000h ; words in 64 KiB 0 000029A6 81EB0010 sub bx, 1000h ; another 64 KiB ? 0 000029AA 730D jae @F ; yes --> 0 000029AC 80C710 add bh, 10h ; restore bx 0 000029AF 31C9 xor cx, cx ; cx = 0 0 000029B1 87D9 xchg bx, cx ; bx = 0, cx = amount paragraphs 0 000029B3 D1E1 shl cx, 1 0 000029B5 D1E1 shl cx, 1 0 000029B7 D1E1 shl cx, 1 ; cx = amount words 5288 <1> @@: 0 000029B9 31C0 xor ax, ax 0 000029BB F3AB rep stosw ; zero the memory 0 000029BD 8CC0 mov ax, es 0 000029BF 050010 add ax, 1000h 0 000029C2 8EC0 mov es, ax ; => next segment (skip 64 KiB) 0 000029C4 85DB test bx, bx ; any remaining ? (NC) 0 000029C6 75DB jnz @BB ; yes --> 5296 <1> 0 000029C8 5F pop di 0 000029C9 07 pop es ; -> back at start 5299 <1> .ret: 0 000029CA 89EC5D lleave 0 000029CD C3 retn 3975 3976 sysinit_msg: 0 000029CE 5761726E696E673A20 .warn_upb: db "Warning: init unable to relocate UPBs!",13,10 0 000029D7 696E697420756E6162 0 000029E0 6C6520746F2072656C 0 000029E9 6F6361746520555042 0 000029F2 73210D0A 3978 .warn_upb.size: equ $ - .warn_upb 0 000029F6 5761726E696E673A20 .warn_dpb: db "Warning: init unable to relocate DPBs!",13,10 0 000029FF 696E697420756E6162 0 00002A08 6C6520746F2072656C 0 00002A11 6F6361746520445042 0 00002A1A 73210D0A 3980 .warn_dpb.size: equ $ - .warn_dpb 3981 3982 END === Trace listing source: sysconf.lst 1 ; PAGE ,132 ; 2 ; SCCSID = @(#)sysconf.asm 0.0 86/10/20 3 ;TITLE BIOS SYSTEM INITIALIZATION 4 %warning out: ...SYSCONF 4 ****************** warning: out: ...SYSCONF [-w+user] 5 6 ;============================================================================== 7 ;REVISION HISTORY: 8 ;AN000 - New for DOS Version 4.00 - J.K. 9 ;AC000 - Changed for DOS Version 4.00 - J.K. 10 ;AN00x - PTM number for DOS Version 4.00 - J.K. 11 ;============================================================================== 12 ;AN001; P132 Multiple character device installation problem. 06/27/87 J.K. 13 ;AN002; D24 MultiTrack= command added. 06/29/87 J.K. 14 ;AN003; D41 REM command in CONFIG.SYS. 07/6/87 J.K. 15 ;AN004; D184 Set DEVMARK for MEM command 08/25/87 J.K. 16 ;AN005; P568 CONFIG.SYS parsing error with FCBS=10,15 08/31/87 J.K. 17 ;AN006; P887 STACKS=0 does not show "ERROR in CONFIG.SYS..." 09/09/87 J.K. 18 ;AN007; D246, P976 Show "Bad command or parameters - ..." msg 09/22/87 J.K. 19 ;AN008; P1299 Set the second entry of DEVMARK for MEM command 09/25/87 J.K. 20 ;AN009; P1326 New Extended attribute 09/28/87 J.K. 21 ;AN010; P1820 New message SKL file 10/20/87 J.K. 22 ;AN011; P1970 AUTOTEST FCBS= command error msg inconsistent 10/23/87 J.K. 23 ;AN012; P2211 Setting the EA=7 for ANSI.SYS hangs the system 11/02/87 J.K. 24 ;AN013; P2342 REM not allowed after INSTALL command 11/09/87 J.K. 25 ;AN014; P2546 DEVICE= command still allowed after IFS= 11/17/87 J.K. 26 ;AN015; D358 New device driver INIT function package 12/03/87 J.K. 27 ;AN016; D285 Undo the extended error handling 12/17/87 J.K. 28 ;AN017; P3170 Do not call block device driver when drive # > 26 01/20/88 J.K. 29 ;AN018; P3111 Take out the order dependency of the INSTALL= 01/25/88 J.K. 30 ;AN019; D479 New option to disable extended INT 16h function call 02/12/88 J.K. 31 ;AN020; P3607 MEM does not give correct filename 02/24/88 J.K. 32 ;AN021; D493 Undo D358 & do not show error message for device driv 02/24/88 J.K. 33 ;AN022; P3807 Single buffer unprotected - System hangs 03/10/88 J.K. 34 ;AN023; P3797 An INSTALL cmd right after Bad cmd is not executed 03/10/88 J.K. 35 ;AN024; D503 Version change to 4.0 - IBMCACHE.SYS is an exception 03/15/88 J.K. 36 ;AN025; D474 Change BUFFERS= /E option to /X for expanded memory 03/16/88 J.K. 37 ;AN026; D506 Take out the order dependency of the IFS= 03/28/88 J.K. 38 ;AN027; P3957 Undo D503 - IBMCACHE.SYS version check problem 03/30/88 J.K. 39 ;AN028; P4086 Memory allocation error when loading share.exe 03/31/88 J.K. 40 ;AN029; D528 Install XMAEM.SYS first before everything else 04/29/88 J.K. 41 ;AN030; P4759 INT2f, INT 67h handlers for XMA 05/11/88 J.K. 42 ;AN031; P4889 Should check the validity of INT 67h call 05/17/88 G.A. 43 ;AN032; P4934 P4759 INT 2fh number should be changed to 1Bh 05/20/88 J.K. 44 ;AN033; P5002 EMS w/single page allocated now works 05/20/88 G.A. 45 ;AN034; P5128 EMS INT 2FH HANDLER BUG 06/24/88 46 ;============================================================================== 47 48 TRUE EQU 0FFFFh 49 FALSE EQU 0 50 LF equ 10 51 CR equ 13 52 TAB equ 9 53 SEMICOLON equ ';' 54 55 IBMVER EQU TRUE 56 IBM EQU IBMVER 57 STACKSW EQU TRUE ;Include Switchable Hardware Stacks 58 IBMJAPVER EQU FALSE ;If TRUE set KANJI true also 59 %iassign MSVER FALSE 60 ALTVECT EQU FALSE ;Switch to build ALTVECT version 61 KANJI EQU FALSE 62 63 HAVE_INSTALL_CMD equ 00000001b ;AN018; CONFIG.SYS has INSTALL= commands 64 HAS_INSTALLED equ 00000010b ;AN018; SYSINIT_BASE installed. 65 66 IS_IFS equ 00000001b ;IFS command? 67 NOT_IFS equ 11111110b 68 ; 69 ;AN016; Undo the extended attribute handling 70 ;;Extended attribute value 71 ;EA_UNSPECIFIED equ 0 ;AN009; 72 ;EA_DEVICE_DRIVER equ 6 ;AN009; 73 ;EA_IFS_DRIVER equ 7 ;AN009; 74 75 DEFAULT_FILENUM equ 8 76 ; 77 %IF IBMJAPVER 78 NOEXEC EQU TRUE 79 %ELSE 80 NOEXEC EQU FALSE 81 %ENDIF 82 83 ;DOSSIZE EQU 0A000H 84 ;dossize equ 0C000H ;J.K. for the debugging version of IBMDOS. 85 86 [list -] 86 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 86 ****************** warning: out: BPB.INC... [-w+user] 86 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 86 ****************** warning: out: DEVSYM.INC... [-w+user] 86 ****************** warning: out: IOCTL.INC... [-w+user] 86 ****************** warning: out: BPB.INC... [-w+user] 86 ****************** warning: out: BIOSTRUC.INC... [-w+user] 86 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 86 ****************** warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi] 14 <2> [list -] 13 <1> [list -] 98 [list +] 99 100 %IFN IBMJAPVER 101 EXTRN RE_INIT:FAR 102 %ENDIF 103 104 ; 105 106 ;J.K. 6/29/87 External variable defined in IBMBIO module for Multi-track 107 MULTRK_ON EQU 10000000B ;User spcified Mutitrack=on, or System turns 108 ; it on after handling CONFIG.SYS file as a 109 ; default value, if MulTrk_flag = MULTRK_OFF1. 110 MULTRK_OFF1 EQU 00000000B ;initial value. No "Multitrack=" command entered. 111 MULTRK_OFF2 EQU 00000001B ;User specified Multitrack=off. 112 === Switch to base=000000h -> "DOSENTRY" 113 section DOSENTRY 114 EXTRN MulTrk_flag:word ;AN002; 115 extrn KEYRD_Func:byte ;AN019; 116 extrn KEYSTS_Func:byte ;AN019; 117 ; (no prior section) ; CODE ends 118 ;J.K. 6/29/87 End of Multi-track definition. 119 === Switch to base=002530h -> "SYSINITSEG" 120 section SYSINITSEG PUBLIC class=INIT === Switch to base=002530h -> "SYSINITSEG" 121 section SYSINITSEG 122 align 16, db 0 123 124 ASSUME CS:SYSINITSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING 125 126 extern alloc_initconfig, alloc_dpb_no_hma 127 extern allocate_relocate_block 128 extern allocate_temporary_block 129 extern allocate_temporary_block.large_allow_error 130 extern ParaRound, alloc_init 131 132 EXTRN BADOPM:BYTE,CRLFM:BYTE,BADCOM:BYTE,BADMEM:BYTE,BADBLOCK:BYTE 133 EXTRN BADSIZ_PRE:BYTE,BADLD_PRE:BYTE 134 ; EXTRN BADSIZ_POST:BYTE,BADLD_POST:BYTE 135 EXTRN BADSTACK:BYTE,BADCOUNTRYCOM:BYTE 136 EXTRN SYSSIZE:BYTE,BADCOUNTRY:BYTE,INSUFMEMORY:BYTE 137 extern config_overflow 138 EXTRN CONDEV:BYTE,AUXDEV:BYTE,PRNDEV:BYTE,COMMND:BYTE,CONFIG:BYTE 139 EXTRN Cntry_Drv:BYTE,Cntry_Root:BYTE,Cntry_Path:BYTE 140 EXTRN DeviceParameters:byte 141 EXTRN MEMORY_SIZE:word 142 EXTRN BUFFERS:word 143 EXTRN FILES:byte,NUM_CDS:byte 144 EXTRN DOSINFO:dword,ENTRY_POINT:dword 145 EXTRN FCBS:byte,KEEP:byte 146 EXTRN config_block:word,COMMAND_LINE:byte 147 EXTRN ZERO:byte,SEPCHR:byte 148 EXTRN COUNT:word,CHRPTR:word,CNTRYFILEHANDLE:word 149 EXTRN MEMLO:word,MEMHI:word,PRMBLK:word 150 EXTRN PACKET:byte,UNITCOUNT:byte,BREAK_ADDR:dword 151 EXTRN BPB_ADDR:dword,DRIVENUMBER:byte,SYSI_COUNTRY:dword 152 extrn Config_Size:word ;AN000; 153 extrn Install_Flag:word ;AN000; 154 extrn BadOrder:byte ;AN000; 155 extrn Errorcmd:byte ;AN000; 156 extrn LineCount:word ;AN000; 157 extrn ShowCount:byte ;AN000; 158 extrn Buffer_LineNum:word ;AN000; 159 extrn IFS_Flag:word ;AN000; 160 extrn IFS_RH:byte ;AN000; 161 extrn H_Buffers:word ;AN000; 162 extrn Buffer_Slash_X:byte ;AN000;AN025; 163 extrn Badparm:byte ;AN007; 164 extrn ConfigMsgFlag:Word ;AN015; 165 extrn Org_Count:Word ;AN018; 166 extrn Multi_Pass_Id:byte ;AN026; 167 168 EXTRN MEM_ERR:NEAR,SetDOSCountryInfo:NEAR 169 EXTRN PARAROUND:NEAR,TEMPCDS:NEAR 170 EXTRN Set_Country_Path:NEAR,Move_ASCIIZ:NEAR,DELIM:NEAR 171 EXTRN BADFIL:NEAR,ROUND:NEAR 172 extrn Do_Install_Exec:NEAR ;AN018; 173 extrn SetDevMark:NEAR ;AN030; 174 extern init2_SNextMCB 175 176 ;AN016; Undo the extended attribute handling 177 ; extrn Get_Ext_Attribute:near ;AN009; 178 179 %IF STACKSW 180 181 ; Internal Stack Parameters 182 EntrySize equ 8 183 184 MinCount equ 8 185 DefaultCount equ 9 186 MaxCount equ 64 187 188 MinSize equ 32 189 DefaultSize equ 128 190 MaxSize equ 512 191 192 extrn stack_count:word 193 extrn stack_size:word 194 extrn stack_addr:dword 195 196 %ENDIF 197 198 PUBLIC DOCONF 199 PUBLIC GETCHR 200 public Multi_Pass ;AN018;AN026; 201 202 public MultDeviceFlag 0 00002A20 00 MultDeviceFlag db 0 ;AN001; 204 public DevMark_Addr 0 00002A21 ???? DevMark_Addr dw ? ;AN004;Segment address for DEVMARK. 206 public SetDevMarkFlag 0 00002A23 00 SetDevMarkFlag db 0 ;AN004;Flag used for DEVMARK 208 209 %ifndef BUF2 210 EMS_Stub_Installed db 0 ;AN030; 211 %endif 212 213 Badparm_Ptr label dword 0 00002A24 0000 Badparm_Off dw 0 ;AN007; 0 00002A26 0000 Badparm_Seg dw 0 ;AN007; 216 217 global devicehighflag, devicehighdata, devicehighafter, devicehighsd 218 global deviceafter, shellhighflag 219 0 00002A28 0000 country_block: dw 0 0 00002A2A 0000 CONFIG_used: dw 0 0 00002A2C 0000 devicefilesizepara: dw 0 0 00002A2E 0000 devicehighsd: dw 0 0 00002A30 0000 devicehighdata: dw 0 0 00002A32 0000 devicehighsize: dw 0 0 00002A34 0000 devicehighafter: dw 0 0 00002A36 0000 deviceafter: dw 0 0 00002A38 FFFFFFFF devicelastdpb: dd -1 0 00002A3C 00 devicehighflag: db 0 0 00002A3D 00 device_init_first_dpb: db 0 0 00002A3E 00 shellhighflag: db 0 232 0 00002A3F 584D41454D2E535953 XMAEM_file db 'XMAEM.SYS',0 ;AN029; 0 00002A48 00 234 235 ;IBMCACHE_file db 'IBMCACHE.SYS',0;AN024;AN026;To cope with the IBMCACHE.SYS 236 ; problem of DOS version checking. 237 238 ;****************************************************************************** 239 ;Take care of Config.sys file. 240 ;SYSTEM parser data and code. 241 ;****************************************************************************** 242 [list -] 245 ;=== Push trace listing source: parse.nas 246 %include "parse.nas" ;together with PSDATA.INC ; NASM included file 1 <1> ; PAGE ;AN000; 2 <1> ; $SALUT (4,4,8,41) 3 <1> ;(deleted).XLIST 4 <1> ;(deleted)INCLUDE STRUC.INC ;AN020;structured macro definitions for .IF,.ELSE etc. 5 <1> ;(deleted).LIST 6 <1> ; 7 <1> ; NOTE: basesw must be set properly to allow the PARSER to access psdata. 8 <1> ; - basesw undefined means CS seg. override for psdata access. 9 <1> ; - basesw = 1 means DS seg. override for psdata access & 10 <1> ; DS must point to psdata. 11 <1> ; - basesw = 0 means ES seg. override for psdata access & 12 <1> ; ES must point to psdata. 13 <1> ; 14 <1> ; 15 <1> %IFNDEF basesw ;AN022; 16 <1> %idefine psdata_seg CS ;AN022; 17 <1> %ELSE ;AN022; 18 <1> %IF basesw ;AN022;IF "basesw EQU 1" specified by caller THEN 19 <1> %idefine psdata_seg DS ;AN022; 20 <1> %ELSE ;AN022; 21 <1> %idefine psdata_seg ES ;AN022;ELSE only other choice is ES (basesw EQU 0) 22 <1> %ENDIF ;AN022; 23 <1> %ENDIF ;AN022; 24 <1> 25 <1> %ifndef incsw ;AN000; (tm03) Someone doesn't want to include psdata 26 <1> %iassign incsw 1 ;AN000; include psdata.inc (tm03) 27 <1> %endif ;AN000; (tm03) 28 <1> %if incsw ;AN000; If incsw = 1 then (tm03) 29 <1> %include "psdata.mac" ;AN000; include psdata.inc (tm03) 1 <2> ;******************************************************************* 2 <2> ; Parser include file 3 <2> ;******************************************************************* 4 <2> %warning out: INCLUDING COMP=COMMON DSN=PSDATA.INC...;AN000; 4 ****************** <2> warning: out: INCLUDING COMP=COMMON DSN=PSDATA.INC... [-w+user] 5 <2> ; 6 <2> ;**** Default assemble switches definition ************************* 7 <2> 8 <2> %ifndef FarSW ;AN000; 9 <2> %iassign FarSW 0 ;AN000; Near call expected 10 <2> %endif ;AN000; 11 <2> 12 <2> %ifndef DateSW ;AN000; 13 <2> %iassign DateSW 1 ;AN000; Check date format 14 <2> %endif ;AN000; 15 <2> 16 <2> %ifndef TimeSW ;AN000; 17 <2> %iassign TimeSW 1 ;AN000; Check time format 18 <2> %endif ;AN000; 19 <2> 20 <2> %ifndef FileSW ;AN000; 21 <2> %iassign FileSW 1 ;AN000; Check file specification 22 <2> %endif ;AN000; 23 <2> 24 <2> %ifndef CAPSW ;AN000; 25 <2> %iassign CAPSW 1 ;AN000; Perform CAPS if specified 26 <2> %endif ;AN000; 27 <2> 28 <2> %ifndef CmpxSW ;AN000; 29 <2> %iassign CmpxSW 1 ;AN000; Check complex list 30 <2> %endif ;AN000; 31 <2> 32 <2> %ifndef NumSW ;AN000; 33 <2> %iassign NumSW 1 ;AN000; Check numeric value 34 <2> %endif ;AN000; 35 <2> 36 <2> %ifndef KeySW ;AN000; 37 <2> %iassign KeySW 1 ;AN000; Support keywords 38 <2> %endif ;AN000; 39 <2> 40 <2> %ifndef SwSW ;AN000; 41 <2> %iassign SwSW 1 ;AN000; Support switches 42 <2> %endif ;AN000; 43 <2> 44 <2> %ifndef Val1SW ;AN000; 45 <2> %iassign Val1SW 1 ;AN000; Support value definition 1 46 <2> %endif ;AN000; 47 <2> 48 <2> %ifndef Val2SW ;AN000; 49 <2> %iassign Val2SW 1 ;AN000; Support value definition 2 50 <2> %endif ;AN000; 51 <2> 52 <2> %ifndef Val3SW ;AN000; 53 <2> %iassign Val3SW 1 ;AN000; Support value definition 3 54 <2> %endif ;AN000; 55 <2> 56 <2> %ifndef DrvSW ;AN000; 57 <2> %iassign DrvSW 1 ;AN000; Support drive only format 58 <2> %endif ;AN000; 59 <2> 60 <2> %ifndef QusSW ;AN000; 61 <2> %iassign QusSW 1 ;AN000; Support quoted string format 62 <2> %endif ;AN000; 63 <2> 64 <2> %ifndef LFEOLSW ;AN028; 65 <2> %iassign LFEOLSW 1 ;AN028; Accept Line feed (0AH) as end of line 66 <2> %endif ;AN028; 67 <2> 68 <2> ;**** Equation field 69 <2> ;-------- Character code definition 70 <2> 71 <2> D_P_DBSP1 equ 81h ;AN000; 1st byte of DBCS blank 72 <2> D_P_DBSP2 equ 40h ;AN000; 2nd byte of DBCS blank 73 <2> D_P_Period equ "." ;AN020; 74 <2> D_P_Slash equ "/" ;AN020; 75 <2> D_P_Space equ " " ;AN000; SBCS blank 76 <2> D_P_Comma equ "," ;AN000; 77 <2> D_P_Switch equ "/" ;AN000; 78 <2> D_P_Keyword equ "=" ;AN000; 79 <2> D_P_Colon equ ":" ;AN000; 80 <2> D_P_Plus equ "+" ;AN000; 81 <2> D_P_Minus equ "-" ;AN000; 82 <2> D_P_Rparen equ ")" ;AN000; 83 <2> D_P_Lparen equ "(" ;AN000; 84 <2> ;(deleted ;AN025;) D_P_SQuote equ "'" 85 <2> D_P_DQuote equ '"' ;AN000; 86 <2> D_P_NULL equ 0 ;AN000; 87 <2> D_P_TAB equ 9 ;AN000; 88 <2> D_P_CR equ 0Dh ;AN000; 89 <2> D_P_LF equ 0Ah ;AN000; 90 <2> D_P_ASCII80 equ 80h ;AN000; ASCII 80h character code 91 <2> 92 <2> ;-------- Masks 93 <2> D_P_Make_Lower equ 20h ;AN000; make lower case character 94 <2> D_P_Make_Upper equ 0ffh-D_P_Make_Lower ;AN000; make upper case character 95 <2> 96 <2> ; PAGE ;AN000; 97 <2> ;-------- DOS function call related equs 98 <2> 99 <2> D_P_DOS_Get_CDI equ 3800h ;AN000; get country dependent information 100 <2> ; by this call, following information 101 <2> D_P_CDI struc ;AN000; is returned. 0 00002A20 ???? D_P_CDI_DateF dw ? ;0 ;AN000; 0 00002A22 ?????????? D_P_CDI_Money db ?,?,?,?,? ;0,0,0,0,0 ;AN000; 0 00002A27 ???? D_P_CDI_1000 db ?,? ;0,0 ;AN000; 0 00002A29 ???? D_P_CDI_Dec db ?,? ;0,0 ;AN000; 0 00002A2B ???? D_P_CDI_DateS db ?,? ;0,0 ;AN000; 0 00002A2D ???? D_P_CDI_TimeS db ?,? ;0,0 ;AN000; 0 00002A2F ?? db ? ;0 ;AN000; 0 00002A30 ?? db ? ;0 ;AN000; 0 00002A31 ?? D_P_CDI_TimeF db ? ;0 ;AN000; 0 00002A32 ???????? dw ?,? ;0,0 ;AN000; 0 00002A36 ???? db ?,? ;0,0 ;AN000; 113 00000018 <2> dw 5 dup (?) ;(0) ;AN000; 114 <2> D_P_CDI ends ;AN000; 115 <2> 116 <2> D_P_Date_MDY equ 0 ;AN000; 117 <2> D_P_Date_DMY equ 1 ;AN000; 118 <2> D_P_Date_YMD equ 2 ;AN000; 119 <2> ;------------- 120 <2> D_P_DOS_GetEV equ 6300h ;AN000; get DBCS EV call 121 <2> ;AN000; DS:SI will points to DBCS EV 122 <2> ;------------- 123 <2> D_P_DOS_Get_TBL equ 65h ;AN000; get uppercase table call 124 <2> ;AN000; following parameters are set 125 <2> ;AN000; to get casemap table. 126 <2> D_P_DOSTBL_Def equ -1 ;AN000; get default 127 <2> D_P_DOSTBL_BL equ 5 ;AN000; buffer length for Tbl pointer 128 <2> D_P_DOSTBL_File equ 4 ;AN000; get file uppercase table 129 <2> D_P_DOSTBL_Char equ 2 ;AN000; get character uppercase table 130 <2> ; By this call following information 131 <2> ; is returned. 132 <2> D_P_DOS_TBL struc ;AN000; 0 00002A20 ?? D_P_DOS_InfoID db ? ;0 ;AN000; information id for the table 0 00002A21 ???? D_P_DOS_TBL_Off dw ? ;0 ;AN000; offset address of the table 0 00002A23 ???? D_P_DOS_TBL_Seg dw ? ;0 ;AN000; segment address of the table 136 <2> D_P_DOS_TBL ends ;AN000; 137 <2> ; PAGE ;AN000; 138 <2> ;--------------------------------------------------------------------------------------------------------- 139 <2> ; PARMS LABEL BYTE 140 <2> ; DW PARMSX 141 <2> ; DB 2 ; NUMBER OF STRINGS (0, 1, 2) 142 <2> ; DB length ; LENGTH OF THE NEXT LIST, 0 IF NONE 143 <2> ; DB " .. " ; EXTRA DELIMITER LIST, 144 <2> ; ; TYPICAL ARE ";", "=" 145 <2> ; ; "," & WHITESPACE ALWAYS 146 <2> ; DB length ; LENGTH OF THE NEXT LIST, 0 IF NONE 147 <2> ; DB " .. " ; EXTRA END OF LINE LIST, CR, LF OR 0 ALWAYS 148 <2> ;--------------------------------------------------------------------------------------------------------- 149 <2> 150 <2> ;-------------------------------- PARMS block structure 151 <2> D_P_PARMS_Blk struc ;AN000; 0 00002A20 ???? D_P_PARMSX_Address dw ? ;0 ;AN000; Address of PARMSX 0 00002A22 ?? D_P_Num_Extra db ? ;0 ;AN000; Number of extra stuff 0 00002A23 ?? D_P_Len_Extra_Delim db ? ;0 ;AN000; Length of extra delimiter 155 <2> D_P_PARMS_Blk ends ;AN000; 156 <2> 157 <2> D_P_Len_PARMS equ 4 ;AN000; 158 <2> D_P_I_Use_Default equ 0 ;AN000; no extra stuff specified 159 <2> D_P_I_Have_Delim equ 1 ;AN000; extra delimiter specified 160 <2> D_P_I_Have_EOL equ 2 ;AN000; extra EOL specified 161 <2> 162 <2> ;--------------------------------------------------------------------------------------------------------- 163 <2> ; PARMSX LABEL BYTE 164 <2> ; DB minp,maxp ; MIN, MAX POSITIONAL OPERANDS ALLOWED 165 <2> ; DW CONTROL ; DESCRIPTION OF POSITIONAL 1 166 <2> ; : ; REPEATS maxp-1 TIMES 167 <2> ; DB maxs ; # OF SWITCHES 168 <2> ; DW CONTROL ; DESCRIPTION OF SWITCH 1 169 <2> ; : ; REPEATS maxs-1 TIMES 170 <2> ; DB maxk ; # OF KEYWORD 171 <2> ; DW CONTROL ; DESCRIPTION OF KEYWORD 1 172 <2> ; : ; REPEATS maxk-1 TIMES 173 <2> ;--------------------------------------------------------------------------------------------------------- 174 <2> 175 <2> ;-------------------------------- PARMSX block structure 176 <2> D_P_PARMSX_Blk struc ;AN000; 0 00002A20 ?? D_P_MinP db ? ;0 ;AN000; Minimum positional number 0 00002A21 ?? D_P_Maxp db ? ;0 ;AN000; Maximum positional number 0 00002A22 ???? D_P_1st_Control dw ? ;0 ;AN000; Address of the 1st CONTROL block 180 <2> D_P_PARMSX_Blk ends ;AN000; 181 <2> ; PAGE ;AN000; 182 <2> ;--------------------------------------------------------------------------------------------------------- 183 <2> ; << Control field definition >> 184 <2> ; 185 <2> ; 186 <2> ;CONTROL LABEL BYTE 187 <2> ; DW MATCH_FLAGS ; CONTROLS TYPE MATCHED 188 <2> ; ; 8000H=NUMERIC VALUE, (VALUE LIST WILL BE CHECKED) 189 <2> ; ; 4000H=SIGNED NUMERIC VALUE (VALUE LIST WILL BE CHECKED) 190 <2> ; ; 2000H=SIMPLE STRING(VALUE LIST WILL BE CHECKED) 191 <2> ; ; 1000H=DATE STRING (VALUE LIST WON'T BE CHECKED) 192 <2> ; ; 0800H=TIME STRING (VALUE LIST WON'T BE CHECKED) 193 <2> ; ; 0400H=COMPLEX LIST (VALUE LIST WON'T BE CHECKED) 194 <2> ; ; 0200H=FILE SPEC (VALUE LIST WON'T BE CHECKED) 195 <2> ; ; 0100H=DRIVE ONLY (VALUE LIST WON'T BE CHECKED) 196 <2> ; ; 0080H=QUOTED STRING (VALUE LIST WON'T BE CHECKED) 197 <2> ; ; 0010H=IGNORE ":" AT END IN MATCH 198 <2> ; ; 0002H=REPEATS ALLOWED 199 <2> ; ; 0001H=OPTIONAL 200 <2> ; DW FUNCTION_FLAGS 201 <2> ; ; 0001H=CAP RESULT BY FILE TABLE 202 <2> ; ; 0002H=CAP RESULT BY CHAR TABLE 203 <2> ; ; 0010H=REMOVE ":" AT END 204 <2> ; (tm10) ; 0020H=colon is not necessary for switch 205 <2> ; DW RESULT ; RESULT BUFFER 206 <2> ; DW VALUES ; VALUE LISTS 207 <2> ; DB nid ; NUMBER OF KEYWORD/SWITCH SYNONYMS IN FOLLOWING LIST 208 <2> ; DB "...",0 ; IF n >0, KEYWORD 1 209 <2> ; : 210 <2> ; 211 <2> ;Note: 212 <2> ; - The MATCH_FLAG is bit significant. You can set, for example, TIME bit and 213 <2> ; DATE bit simalteniously. 214 <2> ; 215 <2> ; The parser examins each bit along with the following priority. 216 <2> ; 217 <2> ; COMPLEX -> DATE -> TIME -> NUMERIC VAL -> SIGNED NUMERIC VAL -> DRIVE -> 218 <2> ; FILE SPEC -> SIMPLE STRING. 219 <2> ; 220 <2> ; 221 <2> ; - When the FUNCTION_FLAG is 0001 or 0002, the STRING pointed to by a pointer 222 <2> ; in the result buffer is capitalized. 223 <2> ; 224 <2> ; - Match_Flags 0001H and 0002H have meaning only for the positional. 225 <2> ; 226 <2> ; 227 <2> ; - The "...",0 (bottom most line) does require '=' or '/'. When you need a 228 <2> ; switch, for example, '/A', then STRING points to; 229 <2> ; 230 <2> ; DB 1 ; number of following synonyms 231 <2> ; DB '/A',0 232 <2> ; 233 <2> ; When you need a keyword, for example, 'CODEPAGE=', then "...",0 will be; 234 <2> ; 235 <2> ; DB 1 ; number of following synonyms 236 <2> ; DB 'CODEPAGE=',0 237 <2> ; 238 <2> ; 239 <2> ; - "..." must consist of upper case characters only because the parser 240 <2> ; performs pattern matching after converting input to upper case (by 241 <2> ; using the current country upper case table) 242 <2> ; 243 <2> ; 244 <2> ; - One "..." can contain only one switch or keyword. If you need, for 245 <2> ; example /A and /B, the format will be; 246 <2> ; 247 <2> ; DB 2 ; number of following synonyms 248 <2> ; DB '/A',0 249 <2> ; DB '/B',0 250 <2> ;--------------------------------------------------------------------------------------------------------- 251 <2> 252 <2> ;**** Match_Flags 253 <2> 254 <2> D_P_Num_Val equ 8000h ;AN000; Numeric Value 255 <2> D_P_SNum_Val equ 4000h ;AN000; Signed numeric value 256 <2> D_P_Simple_S equ 2000h ;AN000; Simple string 257 <2> D_P_Date_S equ 1000h ;AN000; Date string 258 <2> D_P_Time_S equ 0800h ;AN000; Time string 259 <2> D_P_Cmpx_S equ 0400h ;AN000; Complex string 260 <2> D_P_File_Spc equ 0200h ;AN000; File Spec 261 <2> D_P_Drv_Only equ 0100h ;AN000; Drive Only 262 <2> D_P_Qu_String equ 0080h ;AN000; Quoted string 263 <2> D_P_Ig_Colon equ 0010h ;AN000; Ignore colon at end in match 264 <2> D_P_Repeat equ 0002h ;AN000; Repeat allowed 265 <2> D_P_Optional equ 0001h ;AN000; Optional 266 <2> 267 <2> ;**** Function flags 268 <2> 269 <2> D_P_CAP_File equ 0001h ;AN000; CAP result by file table 270 <2> D_P_CAP_Char equ 0002h ;AN000; CAP result by character table 271 <2> D_P_Rm_Colon equ 0010h ;AN000; Remove ":" at the end 272 <2> D_P_colon_is_not_necessary equ 0020h ;AN000;(tm10) /+10 and /+:10 273 <2> 274 <2> ;-------------------------------- Control block structure 275 <2> D_P_Control_Blk struc ;AN000; 0 00002A20 ???? D_P_Match_Flag dw ? ;0 ;AN000; Controls type matched 0 00002A22 ???? D_P_Function_Flag dw ? ;0 ;AN000; Function should be taken 0 00002A24 ???? D_P_Result_Buf dw ? ;0 ;AN000; Result buffer address 0 00002A26 ???? D_P_Value_List dw ? ;0 ;AN000; Value list address 0 00002A28 ?? D_P_nid db ? ;0 ;AN000; # of keyword/SW synonyms 0 00002A29 ?? D_P_KeyorSW db ? ;0 ;AN000; keyword or sw 282 <2> D_P_Control_Blk ends ;AN000; 283 <2> ; PAGE ;AN000; 284 <2> ;--------------------------------------------------------------------------------------------------------- 285 <2> ; << Value List Definition >> 286 <2> ; 287 <2> ;VALUES LABEL BYTE 288 <2> ; DB nval ; NUMBER OF VALUE DEFINITIONS (0 - 3) 289 <2> ; Ú 290 <2> ; ³ DB nrng ; NUMBER OF RANGES 291 <2> ; ³ ÚDB ITEM_TAG ; RETURN VALUE IF RANGE MATCHED 292 <2> ; ³ ÀDD X,Y ; RANGE OF VALUES 293 <2> ; ³ : 294 <2> ; ³ DB nnval ; NUMBER OF CHOICES 295 <2> ; ³ ÚDB ITEM_TAG ; RETURN VALUE IF NUMBER CHOICE MATCHED 296 <2> ; ³ ÀDD VALUE ; SPECIFIC CHOICE IF NUMBER 297 <2> ; ³ : 298 <2> ; ³ DB nstrval ; NUMBER OF CHOICES 299 <2> ; ³ ÚDB ITEM_TAG ; RETURN VALUE IF STRING CHOICE MATCHED 300 <2> ; ³ ÀDW STRING ; SPECIFIC CHOICE IF STING 301 <2> ; À : 302 <2> ; 303 <2> ;STRING DB "...",0 ; ASCIIZ STRING IMAGE 304 <2> ; 305 <2> ;Note: 306 <2> ; - ITEM_TAG must not be 0FFH, which will be used in the result buffer 307 <2> ; when no choice lists are provided. 308 <2> ; 309 <2> ; - STRING must consist of upper case characters only because the parser 310 <2> ; performs pattern matching after converting input to upper case (by 311 <2> ; using the current country upper case table) 312 <2> ;--------------------------------------------------------------------------------------------------------- 313 <2> 314 <2> D_P_nval_None equ 0 ;AN000; no value list ID 315 <2> D_P_nval_Range equ 1 ;AN000; range list ID 316 <2> D_P_nval_Value equ 2 ;AN000; value list ID 317 <2> D_P_nval_String equ 3 ;AN000; string list ID 318 <2> D_P_Len_Range equ 9 ;AN000; Length of a range choice(two DD plus one DB) 319 <2> D_P_Len_Value equ 5 ;AN000; Length of a value choice(one DD plus one DB) 320 <2> D_P_Len_String equ 3 ;AN000; Length of a string choice(one DW plus one DB) 321 <2> D_P_No_nrng equ 0 ;AN000; (tm07) no nrng. nnval must not be 0. 322 <2> 323 <2> D_P_Val_List struc ;AN000; 0 00002A20 ?? D_P_NumofList db ? ;0 ;AN000; number of following choice 0 00002A21 ???? D_P_Val_XL dw ? ;0 ;AN000; lower word of value 0 00002A23 ???? D_P_Val_XH dw ? ;0 ;AN000; higher word of value 0 00002A25 ???? D_P_Val_YL dw ? ;0 ;AN000; lower word of another value 0 00002A27 ???? D_P_Val_YH dw ? ;0 ;AN000; higher word of another value 329 <2> D_P_Val_List ends ;AN000; 330 <2> ; PAGE ;AN000; 331 <2> ;--------------------------------------------------------------------------------------------------------- 332 <2> ; << Result Buffer Definition >> 333 <2> ; 334 <2> ;RESULT LABEL BYTE ; BELOW FILLED IN FOR DEFAULTS 335 <2> ; DB type ; TYPE RETURNED: 0=RESERVED, 336 <2> ; ; 1=NUMBER, 2=LIST INDEX, 337 <2> ; ; 3=STRING, 4=COMPLEX, 338 <2> ; ; 5=FILESPEC, 6=DRIVE 339 <2> ; ; 7=DATE, 8=TIME 340 <2> ; ; 9=QUOTED STRING 341 <2> ; DB ITEM_TAG ; MATCHED ITEM TAG 342 <2> ; 343 <2> ; dw synonym@ ; es:@ points to found SYNONYM if provided. 344 <2> ; 345 <2> ; 346 <2> ; Ú DD n ; VALUE IF NUMBER 347 <2> ; ³ or 348 <2> ; ³ DW i ; INDEX (OFFSET) INTO VALUE LIST 349 <2> ; ³ ; (ES presents Segment address) 350 <2> ; ³ or 351 <2> ; ³ DD STRING ; OFFSET OF STRING VALUE 352 <2> ; ³ or 353 <2> ; ³ DB drv ; DRIVE NUMBER (1-A, 2-B,..., 26-Z) 354 <2> ; ³ or 355 <2> ; ³ DW YEAR ;(1980-2099) IN CASE OF DATE 356 <2> ; ³ DB MONTH ;(1-12) Note: Range check is not performed. 357 <2> ; ³ DB DATE ;(1-31) 0 is filled when the corresponding field was not specified. 358 <2> ; ³ or 359 <2> ; ³ DB HOUR ;(0-23) IN CASE OF TIME 360 <2> ; ³ DB MINUTES ;(0-59) Note: Range check is not performed . 361 <2> ; ³ DB SECONDS ;(0-59) 0 is filled when the corresponding field was not specified . 362 <2> ; ³ DB HUNDREDTHS ;(0-99) 363 <2> ; À 364 <2> ; 365 <2> ; 366 <2> ;Note: ITEM_TAG is 0FFH when the caller does not specify the choice 367 <2> ; list. 368 <2> ; 369 <2> ; YEAR: If the input value for the year is less than 100, parser 370 <2> ; adds 1900 to it. For example, when 87 is input to parser for 371 <2> ; the year value, he returns 1987. 372 <2> ;--------------------------------------------------------------------------------------------------------- 373 <2> 374 <2> ;-------------------------------- Result block structure 375 <2> D_P_Result_Blk struc ;AN000; 0 00002A20 ?? D_P_Type db ? ;0 ;AN000; Type returned 0 00002A21 ?? D_P_Item_Tag db ? ;0 ;AN000; Matched item tag 0 00002A22 ???? D_P_SYNONYM_Ptr dw ? ;0 ;AN000; pointer to Synonym list returned 0 00002A24 ???????? D_P_Picked_Val db ?,?,?,? ;0,0,0,0 ;AN000; value 380 <2> D_P_Result_Blk ends ;AN000; 381 <2> ;-------------------------------- 382 <2> ;**** values for the type field in the result block 383 <2> 384 <2> D_P_EOL equ 0 ;AN000; End of line 385 <2> D_P_Number equ 1 ;AN000; Number 386 <2> D_P_List_Idx equ 2 ;AN000; List Index 387 <2> D_P_String equ 3 ;AN000; String 388 <2> D_P_Complex equ 4 ;AN000; Complex 389 <2> D_P_File_Spec equ 5 ;AN000; File Spec 390 <2> D_P_Drive equ 6 ;AN000; Drive 391 <2> D_P_Date_F equ 7 ;AN000; Date 392 <2> D_P_Time_F equ 8 ;AN000; Time 393 <2> D_P_Quoted_String equ 9 ;AN000; Quoted String 394 <2> 395 <2> D_P_No_Tag equ 0FFH ;AN000; No ITEM_TAG found 396 <2> ;**** Return code 397 <2> ; 398 <2> ; following return code will be returned in the AX register. 399 <2> 400 <2> D_P_No_Error equ 0 ;AN000; No error 401 <2> D_P_Too_Many equ 1 ;AN000; Too many operands 402 <2> D_P_Op_Missing equ 2 ;AN000; Required operand missing 403 <2> D_P_Not_In_SW equ 3 ;AN000; Not in switch list provided 404 <2> D_P_Not_In_Key equ 4 ;AN000; Not in keyword list provided 405 <2> D_P_Out_Of_Range equ 6 ;AN000; Out of range specified 406 <2> D_P_Not_In_Val equ 7 ;AN000; Not in value list provided 407 <2> D_P_Not_In_Str equ 8 ;AN000; Not in string list provided 408 <2> D_P_Syntax equ 9 ;AN000; Syntax error 409 <2> D_P_RC_EOL equ -1 ;AN000; End of command line 410 <2> 411 <2> ; PAGE ;AN000; 412 <2> ;********************** Local Data ************************************* 0 00002A49 0000 D_P_ORDINAL dw 0 ;AN000; Operand ordinal save area 0 00002A4B 0000 D_P_RC dw 0 ;AN000; Return code from parser 0 00002A4D 0000 D_P_SI_Save dw 0 ;AN000; Pointer of command buffer 0 00002A4F 0000 D_P_DX dw 0 ;AN000; Return result buffer address 0 00002A51 00 D_P_Terminator db 0 ;AN000; Terminator code (ASCII) 0 00002A52 0000 D_P_DBCSEV_OFF dw 0 ;AN000; Offset of DBCS EV 0 00002A54 0000 D_P_DBCSEV_SEG dw 0 ;AN000; Segment of DBCS EV 0 00002A56 0000 D_P_Flags dw 0 ;AN000; Parser internal flags 421 <2> labelsize D_P_Flags1, byte, D_P_Flags ;AN038; to reference first byte flags 422 <2> labelsize D_P_Flags2, byte, D_P_Flags+1 ;AN038; to reference second byte flags only 423 <2> 424 <2> ;in second byte of D_P_Flags, referenced as D_P_Flags2: 425 <2> D_P_equ equ 01h ;AN000; "=" packed in string buffet 426 <2> D_P_Neg equ 02h ;AN000; Negative value 427 <2> D_P_Time12 equ 04h ;AN000; set when PM is specified 428 <2> D_P_Key_Cmp equ 08h ;AN000; set when keyword compare 429 <2> D_P_SW_Cmp equ 10h ;AN000; set when switch compare 430 <2> D_P_Extra equ 20h ;AN000; set when extra delimiter found 431 <2> D_P_SW equ 40h ;AN000; set when switch found (tm08) 432 <2> D_P_Signed equ 80h ;AN000; signed numeric specified 433 <2> 434 <2> ;in first byte of D_P_Flags, referenced as D_P_Flags1: 435 <2> D_P_time12am equ 01h ;AN038; set when AM is specified on time 436 <2> D_P_TIME_AGAIN EQU 02H ;AN039; SET WHEN READY TO RE-PARSE TIME 437 <2> 0 00002A58 0000 D_P_SaveSI_Cmpx dw 0 ;AN000; save si for later use by complex 0 00002A5A 0000 D_P_KEYorSW_Ptr dw 0 ;AN000; points next to "=" or ":" code 0 00002A5C 0000 D_P_Save_EOB dw 0 ;AN000; save pointer to EOB 0 00002A5E 0000 D_P_Found_SYNONYM dw 0 ;AN000; es:@ points to found synonym 442 <2> 0 00002A60 000000000000000000 D_P_STRING_BUF db 128 dup(0) ;AN000; Pick a operand from command line 0 00002A69 000000000000000000 0 00002A72 000000000000000000 0 00002A7B 000000000000000000 0 00002A84 000000000000000000 0 00002A8D 000000000000000000 0 00002A96 000000000000000000 0 00002A9F 000000000000000000 0 00002AA8 000000000000000000 0 00002AB1 000000000000000000 0 00002ABA 000000000000000000 0 00002AC3 000000000000000000 0 00002ACC 000000000000000000 0 00002AD5 000000000000000000 0 00002ADE 0000 444 <2> D_P_STRING_BUF_END equ $ ;AN000; 445 <2> %IF TimeSw ;AN039; For TIME only 446 <2> D_P_ORIG_ORD DW 0 ;AN039; ORIGINAL ORDINAL FROM CX 447 <2> D_P_ORIG_STACK DW 0 ;AN039; ORIGINAL VALUE OF STACK FROM SP 448 <2> D_P_ORIG_SI DW 0 ;AN039; ORIGINAL START PARSE POINTER FROM SI 449 <2> %endif ;AN039; 450 <2> %IF DateSw+TimeSw ;AN000;(Check if date or time format is supported) 451 <2> ;------------------------------ 452 <2> ; 453 <2> D_P_Got_Time db 0 ;AN023; if 1, use Time delimiters 454 <2> D_P_NeedToBeRead equ 0ffffh ;AN000; 455 <2> 456 <2> D_P_COUNTRY_INFO: ; NASM structure instance 457 <2> D_P_CDI_size equ D_P_CDI_struc_size ; NASM port equate 458 <2> istruc D_P_CDI 459 <2> at D_P_CDI_DateF 460 <2> dw D_P_NeedToBeRead 461 <2> iend 462 <2> ; 463 <2> D_P_1st_Val dw 0 ;AN000; used when process date or time 464 <2> D_P_2nd_Val dw 0 ;AN000; used when process date or time 465 <2> D_P_3rd_Val dw 0 ;AN000; used when process date or time 466 <2> D_P_4th_Val dw 0 ;AN000; used when process date or time 467 <2> ;------------------------------ 468 <2> %endif ;AN000;(of DateSW+TimeSW) 0 00002AE0 FF D_P_Char_CAP_Ptr db 0ffh ;AN000; info id 0 00002AE1 0000 dw 0 ;AN000; offset of char case map table 0 00002AE3 0000 dw 0 ;AN000; segment of char case map table 472 <2> %IF CAPSW ;AN000;(Check if uppercase conversion is supported) 473 <2> D_P_File_CAP_Ptr db 0ffh ;AN000; info id 474 <2> dw 0 ;AN000; offset of file case map table 475 <2> dw 0 ;AN000; segment of file case map table 476 <2> %endif ;AN000;(of CAPSW) 477 <2> ; (tm06) IF FileSW ;AN000;(Check if file spec is supported) 478 <2> %IF FileSW+DrvSW ;AN000;(Check if file spec is supported) 0 00002AE5 5B5D7C3C3E2B3D3B22 D_P_FileSp_Char db '[]|<>+=;"' ;AN000; delimitter of file spec 480 <2> D_P_FileSp_Len equ $-D_P_FileSp_Char ;AN000; 481 <2> %endif ;AN000;(of FileSW) 482 <2> ; (tm05) IF QusSW ;AN000;(Check if quoted string is supported) 483 <2> ;(deleted ;AN025;) IF QusSW+CmpxSW ; (tm05) ;AN000;(Check if quoted string is supported) 484 <2> ;(deleted ;AN025;) D_P_SorD_Quote db 0 ;AN000; keep double or single quote 485 <2> ;(deleted ;AN025;) %endif ;AN000;(of QueSW) 486 <2> %IF KeySW ;AN029; if keywords supported 487 <2> D_P_count_to_eol dw 0 ;AN029; count of chars not including EOL 488 <2> ; REGISTER EQUATES - SPECIAL USAGE FOR REGISTERS 489 <2> %idefine D_P_REG_BH_CG_SW BH ;AN029;0="NO CHANGES MADE", FF=CHANGES MADE 490 <2> %idefine D_P_REG_BL_DQ_SW BL ;AN029;0=NOT IN QUOTES,FF=IN QUOTES 491 <2> 492 <2> D_P_DOUBLE_QUOTE EQU '"' ;AN029; 493 <2> D_P_BL_EQ EQU "= " ;AN029; 494 <2> D_P_EQ_BL EQU " =" ;AN029; 495 <2> D_P_TB_EQ EQU 093DH ;AN029; ;"=" 496 <2> D_P_EQ_TB EQU 3D09H ;AN029; ;"=" 497 <2> %endif ;AN029; IF KeySW Supported 498 <2> 499 <2> ; delimiter parsing 500 <2> D_P_colon_period equ 01 ;AN032; check for colon & period 501 <2> D_P_period_only equ 02 ;AN032; check only for period 502 <2> 503 <2> ;filespec error flag 0 00002AEE 00 D_P_err_flag db 00 ;AN033; flag set if filespec parsing error 505 <2> ;AN033; was detected. 506 <2> D_P_error_filespec equ 01 ;AN033; mask to set flag 507 <2> ;*********************************************************************** 30 <1> %endif ;AN000; endif (tm03) 31 <1> ; PAGE ;AN000; 32 <1> %warning out: INCLUDING COMP=COMMON DSN=PARSE.ASM...;AN000; 32 ****************** <1> warning: out: INCLUDING COMP=COMMON DSN=PARSE.ASM... [-w+user] 33 <1> ;*********************************************************************** 34 <1> ; SysParse; 35 <1> ; 36 <1> ; Function : Parser Entry 37 <1> ; 38 <1> ; Input: DS:SI -> command line 39 <1> ; ES:DI -> parameter block 40 <1> ; psdata_seg -> psdata.inc 41 <1> ; CX = operand ordinal 42 <1> ; 43 <1> ; Note: ES is the segment containing all the control blocks defined 44 <1> ; by the caller, except for the DOS COMMAND line parms, which 45 <1> ; is in DS. 46 <1> ; 47 <1> ; Output: CY = 1 error of caller, means invalid parameter block or 48 <1> ; invalid value list. But this parser does NOT implement 49 <1> ; this feature. Therefore CY always zero. 50 <1> ; 51 <1> ; CY = 0 AX = return code 52 <1> ; BL = terminated delimiter code 53 <1> ; CX = new operand ordinal 54 <1> ; SI = set past scaned operand 55 <1> ; DX = selected result buffer 56 <1> ; 57 <1> ; Use: D_P_Skip_Delim, D_P_Chk_EOL, D_P_Chk_Delim, D_P_Chk_DBCS 58 <1> ; D_P_Chk_Swtch, D_P_Chk_Pos_Control, D_P_Chk_Key_Control 59 <1> ; D_P_Chk_Sw_Control, D_P_Fill_Result 60 <1> ; 61 <1> ; Vars: D_P_Ordinal(RW), D_P_RC(RW), D_P_SI_Save(RW), D_P_DX(R), D_P_Terminator(R) 62 <1> ; D_P_SaveSI_Cmpx(W), D_P_Flags(RW), D_P_Found_SYNONYM(R), D_P_Save_EOB(W) 63 <1> ; 64 <1> ;-------- Modification History ----------------------------------------- 65 <1> ; 66 <1> ; 4/04/87 : Created by K. K, 67 <1> ; 4/28/87 : D_P_Val_YH assemble error (tm01) 68 <1> ; : JMP SHORT assemble error (tm02) 69 <1> ; 5/14/87 : Someone doesn't want to include psdata (tm03) 70 <1> ; 6/12/87 : D_P_Bridge is missing when TimeSw equ 0 and (CmpxSw equ 1 or 71 <1> ; DateSW equ 1) (tm04) 72 <1> ; 6/12/87 : D_P_SorD_Quote is missing when QusSw equ 0 and CmpxSW equ 1 73 <1> ; (tm05) in PSDATA.INC 74 <1> ; 6/12/87 : D_P_FileSp_Char and D_P_FileSP_Len are missing 75 <1> ; when FileSW equ 0 and DrvSW equ 1 (tm06) in PSDATA.INC 76 <1> ; 6/18/87 : $VAL1 and $VAL3, $VAL2 and $VAL3 can be used in the same 77 <1> ; value-list block (tm07) 78 <1> ; 6/20/87 : Add D_P_SW to check if there's an omiting parameter after 79 <1> ; switch (keyword) or not. If there is, backup si for next call 80 <1> ; (tm08) 81 <1> ; 6/24/87 : Complex Item checking does not work correctly when CmpSW equ 1 82 <1> ; and DateSW equ 0 and TimeSW equ 0 (tm09) 83 <1> ; 6/24/87 : New function flag D_P_colon_is_not_necessary for switch 84 <1> ; /+15 and /+:15 are allowed for user (tm10) 85 <1> ; 6/29/87 : ECS call changes DS register but it causes the address problem 86 <1> ; in user's routines. D_P_Chk_DBCS (tm11) 87 <1> ; 7/10/87 : Switch with no_match flag (0x0000H) does not work correctly 88 <1> ; (tm12) 89 <1> ; 7/10/87 : Invalid switch/keyword does not work correctly 90 <1> ; (tm13) 91 <1> ; 7/10/87 : Drive_only breaks 3 bytes after the result buffer 92 <1> ; (tm14) 93 <1> ; 7/12/87 : Too_Many_Operands sets DX=0 as the PARSE result 94 <1> ; (tm15) 95 <1> ; 7/24/87 : Negative lower bound on numeric ranges cause trouble 96 <1> 97 <1> ; 7/24/87 : Quoted strings being returned with quotes. 98 <1> 99 <1> ; 7/28/87 : Kerry S (;AN018;) 100 <1> ; Non optional value on switch (match flags<>0 and <>1) not flagged 101 <1> ; as an error when missing. Solution: return error 2. Modules 102 <1> ; affected: D_P_Chk_SW_Control. 103 <1> 104 <1> ; 7/29/87 : Kerry S (;AN019;) 105 <1> ; Now allow the optional bit in match flags for switches. This 106 <1> ; allows the switch to be encountered with a value or without a 107 <1> ; value and no error is returned. 108 <1> ; 109 <1> 110 <1> ; 8/28/87 : Ed K, Kerry S (;AN020;) 111 <1> ; 9/14/87 In PROC D_P_Get_DecNum, when checking for field separators 112 <1> ; within a date response, instead of checking just for the one 113 <1> ; character defined by the COUNTRY DEPENDENT INFO, check for 114 <1> ; all three chars, "-", "/", and ".". Change D_P_Chk_Switch to allow 115 <1> ; slashes in date strings when DateSw (assembler switch) is set. 116 <1> 117 <1> ; 9/1/87 : Kerry S (;AN021) 118 <1> ; In PROC D_P_String_Comp, when comparing the switch or keyword on 119 <1> ; the command line with the string in the control block the 120 <1> ; comparing was stopping at a colon (switch) or equal (keyword) 121 <1> ; on the command line and assuming a match. This allowed a shorter 122 <1> ; string on the command line than in the synonym list in the control 123 <1> ; block. I put in a test for a null in the control block so the 124 <1> ; string in the control block must be the same length as the string 125 <1> ; preceeding the colon or equal on the command line. 126 <1> 127 <1> ; 8/28/87 : Kerry S (;AN022;) 128 <1> ; All references to data in PSDATA.INC had CS overrides. This caused 129 <1> ; problems for people who included it themselves in a segment other 130 <1> ; than CS. Added switch to allow including PSDATA.INC in any 131 <1> ; segment. 132 <1> 133 <1> ; 9/16/87 : Ed K (;AN023;) PTM1040 134 <1> ; in D_P_set_cdi PROC, it assumes CS points to psdata. Change Push CS 135 <1> ; into PUSH PSDATA_SEG. In D_P_Get_DecNum PROC, fix AN020 136 <1> ; forced both TIME and DATE to use the delims, "-","/",".". 137 <1> ; Created FLag, in D_P_time_Format PROC, to request the delim in 138 <1> ; BL be used if TIME is being parsed. 139 <1> 140 <1> ; 9/24/87 : Ed K 141 <1> ; Removed the include to STRUC.INC. Replaced the STRUC macro 142 <1> ; invocations with their normally expanded code; made comments 143 <1> ; out of the STRUC macro invocation statements to maintain readability. 144 <1> 145 <1> ; 9/24/87 : Ed K (;AN024;) PTM1222 146 <1> ; When no CONTROL for a keyword found, tried to fill in RESULT 147 <1> ; pointed to by non-existant CONTROL. 148 <1> 149 <1> ; 10/15/87 : Ed K (;AN025;) PTM1672 150 <1> ; A quoted text string can be framed only by double quote. Remove 151 <1> ; support to frame quoted text string with single quote. 152 <1> ; (apostrophe) D_P_SorD_Quote is removed from PSDATA.INC. 153 <1> ; D_P_SQuote EQU also removed from PSDATA.INC. Any references to 154 <1> ; single quote in PROC prologues are left as is for history reasons. 155 <1> 156 <1> ; This fixes another bug, not mentioned in p1672, in that two 157 <1> ; quote chars within a quoted string is supposed to be reported as 158 <1> ; one quote character, but is reported as two quotes. This changed 159 <1> ; two instructions in PROC D_P_Quoted_Str. 160 <1> 161 <1> ; Also fixed are several JMP that caused a NOP, these changed to 162 <1> ; have the SHORT operator to avoid the unneeded NOP. 163 <1> 164 <1> ; The code and PSDATA.INC have been aligned for ease of reading. 165 <1> 166 <1> ; 10/26/87 : Ed K (;AN026;) PTM2041, DATE within SWITCH, BX reference to 167 <1> ; psdata buffer should have psdata_seg. 168 <1> 169 <1> ; 10/27/87 : Ed K (;AN027;) PTM2042 comma between keywords implies 170 <1> ; positional missing. 171 <1> 172 <1> ; 11/06/87 : Ed K (;AN028;) PTM 2315 Parser should not use line feed 173 <1> ; as a line delimiter, should use carriage return. 174 <1> ; Define switch: LFEOLSW, if on, accept LF as end of line char. 175 <1> 176 <1> ; 11/11/87 : Ed K (;AN029;) PTM 1651 GET RID OF WHITESPACE AROUND "=". 177 <1> 178 <1> ; 11/18/87 : Ed K (;AN030;) PTM 2551 If filename is just "", then 179 <1> ; endless loop since SI is returned still pointing to start 180 <1> ; of that parm. 181 <1> 182 <1> ; 11/19/87 : Ed K (;AN031;) PTM 2585 date & time getting bad values. 183 <1> ; Vector to returned string has CS instead of Psdata_Seg, but 184 <1> ; when tried to fix it on previous version, changed similar 185 <1> ; but wrong place. 186 <1> 187 <1> ; 12/09/87 : Bill L (;AN032;) PTM 2772 colon and period are now valid 188 <1> ; delimiters between hours, minutes, seconds for time. And period 189 <1> ; and comma are valid delimiters between seconds and 100th second. 190 <1> 191 <1> ; 12/14/87 : Bill L (;AN033;) PTM 2722 if illegal delimiter characters 192 <1> ; in a filespec, then flag an error. 193 <1> 194 <1> ; 12/22/87 : Bill L (;AN034;) All local data to parser is now 195 <1> ; indexed off of the psdata_seg equate instead of the DS register. 196 <1> ; Using this method, DS can point to the segment of PSP or to psdata 197 <1> ; --> local parser data. Why were some references to local data changed 198 <1> ; to do this before, but not all ????? 199 <1> 200 <1> ; 02/02/88 : Ed K (;AC035;) INSPECT utility, suggests optimizations. 201 <1> 202 <1> ; 02/05/88 : Ed K (;AN036;) P3372-UPPERCASE TRANSLATION, PSDATA_SEG HOSED. 203 <1> ; 204 <1> ; 02/08/88 : Ed K (;AN037;) P3410-AVOID POP OF CS, CHECK BASESW FIRST. 205 <1> 206 <1> ; 02/19/88 : Ed K (;AN038;) p3524 above noon and "am" should be error 207 <1> 208 <1> ; 02/23/88 : Ed K (;AN039;) p3518 accept "comma" and "period" as decimal 209 <1> ; separator in TIME before hundredths field. 210 <1> ; 211 <1> ;*********************************************************************** 212 <1> %IF FarSW ;AN000;(Check if need far return) 213 <1> SysParse proc far ;AN000; 214 <1> %ELSE ;AN000; 215 <1> SysParse proc near ;AN000; 216 <1> %ENDIF ;AN000;(of FarSW) 217 <1> ; $SALUT (4,9,17,41) 0 00002AEF 2EC706[3600]0000 mov word [psdata_seg:D_P_Flags],0 ;AC034; Clear all internal flags 219 <1> %IF TimeSw ;AN039; FOR TIME ONLY 220 <1> MOV [PSDATA_SEG:D_P_ORIG_ORD],CX ;AN039; ORIGINAL ORDINAL FROM CX 221 <1> MOV [PSDATA_SEG:D_P_ORIG_STACK],SP ;AN039; ORIGINAL VALUE OF STACK FROM SP 222 <1> MOV [PSDATA_SEG:D_P_ORIG_SI],SI ;AN039; ORIGINAL START PARSE POINTER FROM SI 223 <1> D_P_REDO_TIME: ;AN039; try to parse time again 224 <1> %ENDIF ;AN039; FOR TIME ONLY 0 00002AF6 FC cld ;AN000; confirm forward direction 226 <1> D_P_ordinal equ D_P_ORDINAL ; NASM port label 0 00002AF7 2E890E[2900] mov [psdata_seg:D_P_ordinal],cx ;AC034; save operand ordinal 0 00002AFC 2EC706[2B00]0000 mov word [psdata_seg:D_P_RC],D_P_No_Error ;AC034; Assume no error 0 00002B03 2EC706[3E00]0000 mov word [psdata_seg:D_P_Found_SYNONYM],0 ;AC034; initalize synonym pointer 230 <1> 0 00002B0A 2EC706[2F00]0000 mov word [psdata_seg:D_P_DX],0 ;AC034; (tm15) 232 <1> %IF KeySW ;AN029; 233 <1> ;IN CASE THE USER PUT OPTIONAL WHITESPACE CHARS AROUND THE "=" USED IN 234 <1> ;KEYWORD DEFINITIONS, SCAN THE COMMAND LINE AND COMPRESS OUT ANY WHITESPACES 235 <1> ;NEXT TO "=" BEFORE STARTING THE USUAL PARSING. 236 <1> push cx ;AN029; 237 <1> push dx ;AN029; 238 <1> push di ;AN029; 239 <1> 240 <1> push si ;AN029; remember where command line starts 241 <1> mov cx,-1 ;AN029; init counter 242 <1> ; $do 243 <1> D_P_loc_eol: ;AN029; 244 <1> inc cx ;AN029; bump counter of chars up to EOL 245 <1> lodsb ;AN029; get a char from command line 246 <1> CALL D_P_Chk_EOL ;AN029; see if AL is EOL char 247 <1> 248 <1> ; enddo z 249 <1> D_P_loc_EOL equ D_P_loc_eol ; NASM port label 250 <1> jnz D_P_loc_EOL ;AN029; not found that EOL char 251 <1> 252 <1> D_P_count_to_EOL equ D_P_count_to_eol ; NASM port label 253 <1> mov [psdata_seg:D_P_count_to_EOL],cx ;AN029;AC034;; save count of chars up to EOL 254 <1> pop si ;AN029; restore start of command line 255 <1> 256 <1> ;scan command string for combinations including "=", 257 <1> ; and replace each with just the simple "=" 258 <1> 259 <1> ;REPEAT UNTIL ONE PASS IS MADE WHEREIN NO CHANGES WERE MADE 260 <1> ; $do 261 <1> D_P_DO1: ;AN029; 262 <1> push si ;AN029; remember where string started 263 <1> D_P_COUNT_TO_EOL equ D_P_count_to_eol ; NASM port label 264 <1> MOV CX,[psdata_seg:D_P_COUNT_TO_EOL] ;AN029;AC034;; set count to no. chars in string, 265 <1> ;AN029; not counting the EOL char 266 <1> XOR BX,BX ;AN029;SET D_P_REG_BL_DQ_SW TO "NOT IN QUOTES", AND... 267 <1> ;AN029;SET D_P_REG_BH_CG_SW TO "NO CHANGES MADE" 268 <1> ;MAKE ONE PASS THRU THE STRING, LOOKING AT EACH CHARACTER 269 <1> ; $do ;AN029; 270 <1> D_P_DO2: ;AN029; 271 <1> D_P_double_quote equ D_P_DOUBLE_QUOTE ; NASM port equate 272 <1> cmp BYTE PTR [SI],D_P_double_quote ;AN029; 273 <1> ; $if e ;AN029;if a double quote was found 274 <1> JNE D_P_IF3 ;AN029; 275 <1> NOT D_P_REG_BL_DQ_SW ;AN029;TOGGLE THE DOUBLE QUOTE STATE SWITCH 276 <1> ; $endif ;AN029; 277 <1> D_P_IF3: ;AN029; 278 <1> OR D_P_REG_BL_DQ_SW,D_P_REG_BL_DQ_SW ;AN029;IS THE DOUBLE QUOTE SWITCH SET? 279 <1> ; $if Z ;AN029;IF NOT IN DOUBLE QUOTES 280 <1> JNZ D_P_IF5 ;AN029; 281 <1> mov ax,word ptr [si] ;AN029; get pair to be checked out 282 <1> cmp ax,D_P_BL_EQ ;AN029;" =" 283 <1> ; $if e,or ;AN029; 284 <1> JE D_P_LL6 ;AN029; 285 <1> cmp ax,D_P_EQ_BL ;AN029;"= " 286 <1> ; $if e,or ;AN029; 287 <1> JE D_P_LL6 ;AN029; 288 <1> cmp ax,D_P_EQ_TB ;AN029; "=" 289 <1> ; $if e,or ;AN029; 290 <1> JE D_P_LL6 ;AN029; 291 <1> cmp ax,D_P_TB_EQ ;AN029;"=" 292 <1> ; $if e ;AN029;if this pair to be replaced with a single "=" 293 <1> JNE D_P_IF6 ;AN029; 294 <1> D_P_LL6: ;AN029; 295 <1> mov BYTE PTR [SI],D_P_Keyword ;AN029; "=" 296 <1> inc si ;AN029;point to next char after the new "=" 297 <1> mov di,si ;AN029;move target right after new "=" 298 <1> 299 <1> push si ;AN029;remember where i am, right after new "=" 300 <1> PUSH CX ;AN029;SAVE CURRENT COUNT 301 <1> inc si ;AN029;source is one beyond that 302 <1> push es ;AN029;remember the extra segment 303 <1> push ds ;AN029;temporarily, set source seg and 304 <1> pop es ;AN029; target seg to the command line seg 305 <1> rep movsb ;AN029;move chars left one position 306 <1> pop es ;AN029;restore the extra segment 307 <1> POP CX ;AN029;RESTORE CURRENT COUNT 308 <1> pop si ;AN029;back to where I was 309 <1> 310 <1> DEC SI ;AN029;LOOK AT FIRST CHAR JUST MOVED 311 <1> MOV D_P_REG_BH_CG_SW,-1 ;AN029;set switch to say "a change was made" 312 <1> DEC word [psdata_seg:D_P_COUNT_TO_EOL] ;AN029;AC034;;because just threw away a char 313 <1> dec CX ;AN029;DITTO 314 <1> ; $endif ;AN029;comparand pair found? 315 <1> D_P_IF6: ;AN029; 316 <1> ; $endif ;AN029;double quote switch? 317 <1> D_P_IF5: ;AN029; 318 <1> inc si ;AN029;bump index to look at next char in command string 319 <1> dec CX ;AN029;one less char to look at 320 <1> ;(deleted ;AC035;) CMP CX,0 ;AN029;is char count all gone yet? 321 <1> ; $enddo LE ;AN029;quit if no more chars 322 <1> JNLE D_P_DO2 ;AN029; 323 <1> pop si ;AN029;remember where string started 324 <1> OR D_P_REG_BH_CG_SW,D_P_REG_BH_CG_SW ;AN029;WAS "A CHANGE MADE"? 325 <1> ; $enddo Z ;AN029;QUIT when no changes were made 326 <1> JNZ D_P_DO1 ;AN029; 327 <1> pop di ;AN029; 328 <1> pop dx ;AN029; 329 <1> pop cx ;AN029; 330 <1> 331 <1> ;NOW THAT ALL WHITESPACE SURROUNDING "=" HAVE BEEN COMPRESSED OUT, 332 <1> ;RESUME NORMAL PARSING... 333 <1> %ENDIF ;AN029; KEYWORDS SUPPORTED? 0 00002B11 E8C906 call D_P_Skip_Delim ;AN000; Move si to 1st non white space 0 00002B14 7313 jnc D_P_Start ;AN000; If EOL is not encountered, do parse 336 <1> 337 <1> ;--------------------------- End of Line 0 00002B16 B8FFFF mov ax,D_P_RC_EOL ;AN000; set exit code to -1 0 00002B19 53 push bx ;AN000; 0 00002B1A 268B1D mov bx,[es:di + D_P_PARMSX_Address] ;AN000; Get the PARMSX address to 0 00002B1D 263A0F cmp cl,[es:bx + D_P_MinP] ;AN000; check ORDINAL to see if the minimum 0 00002B20 7303 jae D_P_Fin ;AN000; positional found. 343 <1> 0 00002B22 B80200 mov ax,D_P_Op_Missing ;AN000; If no, set exit code to missing operand 345 <1> D_P_Fin: ;AN000; 0 00002B25 5B pop bx ;AN000; 0 00002B26 E91D01 jmp D_P_Single_Exit ;AN000; return to the caller 348 <1> 349 <1> ;--------------------------- 350 <1> D_P_Start: ;AN000; 0 00002B29 2E8936[3800] mov [psdata_seg:D_P_SaveSI_Cmpx],si ;AN000;AC034; save ptr to command line for later use by complex, 0 00002B2E 53 push bx ;AN000; quoted string or file spec. 0 00002B2F 57 push di ;AN000; 0 00002B30 55 push bp ;AN000; 0 00002B31 8D1E[4000] lea bx,[D_P_STRING_BUF] ;AC034; set buffer to copy from command string 0 00002B35 2EF606[3700]20 test byte [psdata_seg:D_P_Flags2],D_P_Extra ;AC034; 3/9 extra delimiter encountered ? 0 00002B3B 7543 jne D_P_Pack_End ;AN000; 3/9 if yes, no need to copy 358 <1> 359 <1> D_P_Pack_Loop: ;AN000; 0 00002B3D AC lodsb ;AN000; Pick a operand from buffer 0 00002B3E E85907 call D_P_Chk_Switch ;AN000; Check switch character 0 00002B41 723C jc D_P_Pack_End_BY_EOL ;AN020; if carry set found delimiter type slash, need backup si, else continue 363 <1> 0 00002B43 E8BD06 call D_P_Chk_EOL ;AN000; Check EOL character 0 00002B46 7437 je D_P_Pack_End_BY_EOL ;AN000; need backup si 366 <1> 0 00002B48 E8EE06 call D_P_Chk_Delim ;AN000; Check delimiter 0 00002B4B 7518 jne D_P_PL01 ;AN000; If no, process next byte 369 <1> 0 00002B4D 2EF606[3700]20 test byte [psdata_seg:D_P_Flags2],D_P_Extra ;AC034; 3/9 If yes and white spec, 371 <1> ; (tm08)jne D_P_Pack_End ;AN000; 3/9 then 372 <1> D_P_Pack_End_backup_si equ D_P_PAck_End_backup_si ; NASM port label 0 00002B53 7505 jne D_P_Pack_End_backup_si ;AN000; (tm08) 374 <1> 0 00002B55 E88506 call D_P_Skip_Delim ;AN000; skip subsequent white space,too 0 00002B58 EB26 jmp short D_P_Pack_End ;AN000; finish copy by placing NUL at end 377 <1> 378 <1> D_P_PAck_End_backup_si: ;AN000; (tm08) 0 00002B5A 2EF606[3700]41 test byte [psdata_seg:D_P_Flags2],D_P_SW+D_P_equ ;AN000;AC034; (tm08) 0 00002B60 741E je D_P_Pack_End ;AN000; (tm08) 381 <1> 0 00002B62 4E dec si ;AN000; (tm08) 0 00002B63 EB1B jmp short D_P_Pack_End ;AN025; (tm08) 384 <1> 385 <1> D_P_PL01: ;AN000; 0 00002B65 2E8807 mov [psdata_seg:bx],al ;AN000; move byte to STRING_BUF 0 00002B68 3C3D cmp al,D_P_Keyword ;AN000; if it is equal character, 0 00002B6A 7506 jne D_P_PL00 ;AN000; then 389 <1> 0 00002B6C 2E800E[3700]01 or byte [psdata_seg:D_P_Flags2],D_P_equ ;AC034; remember it in flag 391 <1> D_P_PL00: ;AN000; 0 00002B72 43 inc bx ;AN000; ready to see next byte 0 00002B73 E84207 call D_P_Chk_DBCS ;AN000; was it 1st byte of DBCS ? 0 00002B76 73C5 jnc D_P_Pack_Loop ;AN000; if no, process to next byte 395 <1> 0 00002B78 AC lodsb ;AN000; if yes, store 0 00002B79 2E8807 mov [psdata_seg:bx],al ;AN000; 2nd byte of DBCS 0 00002B7C 43 inc bx ;AN000; update pointer 0 00002B7D EBBE jmp short D_P_Pack_Loop ;AN000; process to next byte 400 <1> 401 <1> D_P_Pack_End_BY_EOL: ;AN000; 0 00002B7F 4E dec si ;AN000; backup si pointer 403 <1> D_P_Pack_End: ;AN000; 0 00002B80 2E8936[2D00] mov [psdata_seg:D_P_SI_Save],si ;AC034; save next pointer, SI 0 00002B85 2EC60700 mov byte ptr [psdata_seg:bx],D_P_NULL ;AN000; put NULL at the end 0 00002B89 2E891E[3C00] mov [psdata_seg:D_P_Save_EOB],bx ;AC034; 3/17/87 keep the address for later use of complex 0 00002B8E 268B1D mov bx,[es:di + D_P_PARMSX_Address] ;AN000; get PARMSX address 0 00002B91 8D36[4000] lea si,[D_P_STRING_BUF] ;AC034; 0 00002B95 2E803C2F cmp byte ptr [psdata_seg:si],D_P_Switch ;AN000; the operand begins w/ switch char ? 0 00002B99 7430 je D_P_SW_Manager ;AN000; if yes, process as switch 411 <1> 0 00002B9B 2EF606[3700]01 test byte [psdata_seg:D_P_Flags2],D_P_equ ;AC034; the operand includes equal char ? 413 <1> D_P_Key_manager equ D_P_Key_Manager ; NASM port label 0 00002BA1 7554 jne D_P_Key_manager ;AN000; if yes, process as keyword 415 <1> 416 <1> D_P_Positional_Manager: ;AN000; else process as positional 417 <1> D_P_MaxP equ D_P_Maxp ; NASM port equate 0 00002BA3 268A4701 mov al,[es:bx + D_P_MaxP] ;AN000; get maxp 0 00002BA7 30E4 xor ah,ah ;AN000; ax = maxp 0 00002BA9 2E3906[2900] cmp [psdata_seg:D_P_ORDINAL],ax ;AC034; too many positional ? 0 00002BAE 7312 jae D_P_Too_Many_Error ;AN000; if yes, set exit code to too many 422 <1> 0 00002BB0 2EA1[2900] mov ax,[psdata_seg:D_P_ORDINAL] ;AC034; see what the current ordinal 0 00002BB4 D1E0 shl ax,1 ;AN000; ax = ax*2 0 00002BB6 43 inc bx ;AC035; add '2' to 0 00002BB7 43 inc bx ;AC035; BX reg 427 <1> ;AN000; now bx points to 1st CONTROL 428 <1> ;(changed ;AC035;) add bx,2 ;AN000; now bx points to 1st CONTROL 0 00002BB8 01C3 add bx,ax ;AN000; now bx points to specified CONTROL address 0 00002BBA 268B1F mov bx,[es:bx] ;AN000; now bx points to specified CONTROL itself 0 00002BBD E88800 call D_P_Chk_Pos_Control ;AN000; Do process for positional 0 00002BC0 EB69 jmp short D_P_Return_to_Caller ;AN000; and return to the caller 433 <1> 434 <1> D_P_Too_Many_Error: ;AN000; 0 00002BC2 2EC706[2B00]0100 mov word [psdata_seg:D_P_RC],D_P_Too_Many ;AC034; set exit code 0 00002BC9 EB60 jmp short D_P_Return_to_Caller ;AN000; and return to the caller 437 <1> ; 438 <1> D_P_SW_Manager: ;AN000; 0 00002BCB 268A4701 mov al,[es:bx + D_P_MaxP] ;AN000; get maxp 0 00002BCF 30E4 xor ah,ah ;AN000; ax = maxp 0 00002BD1 40 inc ax ;AN000; 0 00002BD2 D1E0 shl ax,1 ;AN000; ax = (ax+1)*2 0 00002BD4 01C3 add bx,ax ;AN000; now bx points to maxs 0 00002BD6 268A0F mov cl,[es:bx] ;AN000; 0 00002BD9 30ED xor ch,ch ;AN000; cx = maxs 0 00002BDB 09C9 or cx,cx ;AN000; at least one switch ? 0 00002BDD 740F je D_P_SW_Not_Found ;AN000; 448 <1> 0 00002BDF 43 inc bx ;AN000; now bx points to 1st CONTROL address 450 <1> 451 <1> D_P_SW_Mgr_Loop: ;AN000; 0 00002BE0 53 push bx ;AN000; 0 00002BE1 268B1F mov bx,[es:bx] ;AN000; bx points to Switch CONTROL itself 0 00002BE4 E8C600 call D_P_Chk_SW_Control ;AN000; do process for switch 0 00002BE7 5B pop bx ;AN000; 0 00002BE8 7341 jnc D_P_Return_to_Caller ;AN000; if the CONTROL is for the switch, exit 457 <1> 0 00002BEA 43 inc bx ;AC035; add '2' to 0 00002BEB 43 inc bx ;AC035; BX reg 460 <1> ;AN000; else bx points to the next CONTROL 461 <1> ;(changed ;AC035;) add bx,2 ;AN000; else bx points to the next CONTROL 0 00002BEC E2F2 loop D_P_SW_Mgr_Loop ;AN000; and loop 463 <1> 464 <1> D_P_SW_Not_Found: ;AN000; 0 00002BEE 2EC706[2B00]0300 mov word [psdata_seg:D_P_RC],D_P_Not_In_SW ;AC034; here no CONTROL for the switch has 0 00002BF5 EB34 jmp short D_P_Return_to_Caller0 ;AN000; not been found, means error. 467 <1> ; 468 <1> D_P_Key_Manager: ;AN000; 0 00002BF7 268A4701 mov al,[es:bx + D_P_MaxP] ;AN000; get maxp 0 00002BFB 30E4 xor ah,ah ;AN000; ax = maxp 0 00002BFD 40 inc ax ;AN000; 0 00002BFE D1E0 shl ax,1 ;AN000; ax = (ax+1)*2 0 00002C00 01C3 add bx,ax ;AN000; now bx points to maxs 0 00002C02 268A07 mov al,[es:bx] ;AN000; 0 00002C05 30E4 xor ah,ah ;AN000; ax = maxs 0 00002C07 D1E0 shl ax,1 ;AN000; 0 00002C09 40 inc ax ;AN000; ax = ax*2+1 0 00002C0A 01C3 add bx,ax ;AN000; now bx points to maxk 0 00002C0C 268A0F mov cl,[es:bx] ;AN000; 0 00002C0F 30ED xor ch,ch ;AN000; cx = maxk 0 00002C11 09C9 or cx,cx ;AN000; at least one keyword ? 0 00002C13 740F je D_P_Key_Not_Found ;AN000; 483 <1> 0 00002C15 43 inc bx ;AN000; now bx points to 1st CONTROL 485 <1> 486 <1> D_P_Key_Mgr_Loop: ;AN000; 0 00002C16 53 push bx ;AN000; 0 00002C17 268B1F mov bx,[es:bx] ;AN000; bx points to keyword CONTROL itself 0 00002C1A E85D00 call D_P_Chk_Key_Control ;AN000; do process for keyword 0 00002C1D 5B pop bx ;AN000; 0 00002C1E 730B jnc D_P_Return_to_Caller ;AN000; if the CONTROL is for the keyword, exit 492 <1> 0 00002C20 43 inc bx ;AC035; add '2' to 0 00002C21 43 inc bx ;AC035; BX reg 495 <1> ;AN000; else bx points to the next CONTROL 496 <1> ;(changed ;AC035;) add bx,2 ;AN000; else bx points to the next CONTROL 0 00002C22 E2F2 loop D_P_Key_Mgr_Loop ;AN000; and loop 498 <1> 499 <1> D_P_Key_Not_Found: ;AN000; 0 00002C24 2EC706[2B00]0400 mov word [psdata_seg:D_P_RC],D_P_Not_In_Key ;AC034; here no CONTROL for the keyword has 501 <1> D_P_Return_to_Caller0: ;AN000; not been found, means error. 502 <1> 503 <1> ;(deleted ;AN024;) mov bx,[es:bx-2] ;AN000; (tm13) backup bx 504 <1> 505 <1> ;(deleted ;AN024;) mov al,D_P_String ;AN000; Set 506 <1> ;(deleted ;AN024;) mov ah,D_P_No_Tag ;AN000; result 507 <1> ;(deleted ;AN024;) call D_P_Fill_Result ;AN000; buffer 508 <1> 509 <1> D_P_Return_to_Caller: ;AN000; 0 00002C2B 5D pop bp ;AN000; 0 00002C2C 5F pop di ;AN000; 0 00002C2D 5B pop bx ;AN000; 513 <1> D_P_Ordinal equ D_P_ORDINAL ; NASM port label 0 00002C2E 2E8B0E[2900] mov cx,[psdata_seg:D_P_Ordinal] ;AC034; return next ordinal 0 00002C33 2EA1[2B00] mov ax,[psdata_seg:D_P_RC] ;AC034; return exit code 0 00002C37 2E8B36[2D00] mov si,[psdata_seg:D_P_SI_Save] ;AC034; return next operand pointer 0 00002C3C 2E8B16[2F00] mov dx,[psdata_seg:D_P_DX] ;AC034; return result buffer address 0 00002C41 2E8A1E[3100] mov bl,[psdata_seg:D_P_Terminator] ;AC034; return delimiter code found 519 <1> D_P_Single_Exit: ;AN000; 0 00002C46 F8 clc ;AN000; 0 00002C47 C3 ret ;AN000; 522 <1> SysParse endp ;AN000; 523 <1> ;PAGE ;AN000; 524 <1> ;*********************************************************************** 525 <1> ; D_P_Chk_Pos_Control 526 <1> ; 527 <1> ; Function: Parse CONTROL block for a positional 528 <1> ; 529 <1> ; Input: ES:BX -> CONTROL block 530 <1> ; psdata_seg:SI -> D_P_STRING_BUF 531 <1> ; 532 <1> ; Output: None 533 <1> ; 534 <1> ; Use: D_P_Fill_Result, D_P_Check_Match_Flags 535 <1> ; 536 <1> ; Vars: D_P_Ordinal(W), D_P_RC(W) 537 <1> ;*********************************************************************** 538 <1> D_P_Chk_Pos_Control proc ;AN000; 0 00002C48 50 push ax ;AN000; 0 00002C49 268B07 mov ax,[es:bx + D_P_Match_Flag] ;AN000; 0 00002C4C A90200 test ax,D_P_Repeat ;AN000; repeat allowed ? 0 00002C4F 7505 jne D_P_CPC00 ;AN000; then do not increment ORDINAL 543 <1> 0 00002C51 2EFF06[2900] inc word [psdata_seg:D_P_ORDINAL] ;AC034; update the ordinal 545 <1> D_P_CPC00: ;AN000; 0 00002C56 2E803C00 cmp byte ptr [psdata_seg:si],D_P_NULL ;AN000; no data ? 0 00002C5A 7519 jne D_P_CPC01 ;AN000; 548 <1> 0 00002C5C A90100 test ax,D_P_Optional ;AN000; yes, then is it optional ? 0 00002C5F 7509 jne D_P_CPC02 ;AN000; 551 <1> 0 00002C61 2EC706[2B00]0200 mov word [psdata_seg:D_P_RC],D_P_Op_Missing ;AC034; no, then error 3/17/87 0 00002C68 EB0E jmp short D_P_CPC_Exit ;AN000; 554 <1> 555 <1> D_P_CPC02: ;AN000; 0 00002C6A 50 push ax ;AN000; 0 00002C6B B003 mov al,D_P_String ;AN000; if it is optional return NULL 0 00002C6D B4FF mov ah,D_P_No_Tag ;AN000; no item tag indication 0 00002C6F E89E00 call D_P_Fill_Result ;AN000; 0 00002C72 58 pop ax ;AN000; 0 00002C73 EB03 jmp short D_P_CPC_Exit ;AN000; 562 <1> 563 <1> D_P_CPC01: ;AN000; 0 00002C75 E81D01 call D_P_Check_Match_Flags ;AN000; 565 <1> D_P_CPC_Exit: ;AN000; 0 00002C78 58 pop ax ;AN000; 0 00002C79 C3 ret ;AN000; 568 <1> D_P_Chk_Pos_Control endp ;AN000; 569 <1> ;PAGE ;AN000; 570 <1> ;*********************************************************************** 571 <1> ; D_P_Chk_Key_Control 572 <1> ; 573 <1> ; Function: Parse CONTROL block for a keyword 574 <1> ; 575 <1> ; Input: ES:BX -> CONTROL block 576 <1> ; psdata_seg:SI -> D_P_STRING_BUF 577 <1> ; 578 <1> ; Output: CY = 1 : not match 579 <1> ; 580 <1> ; Use: D_P_Fill_Result, D_P_Search_KEYorSW, D_P_Check_Match_Flags 581 <1> ; 582 <1> ; Vars: D_P_RC(W), D_P_SaveSI_Cmpx(W), D_P_KEYorSW_Ptr(R), D_P_Flags(W) 583 <1> ;*********************************************************************** 584 <1> D_P_Chk_Key_Control proc ;AN000; 585 <1> %IF KeySW ;AN000;(Check if keyword is supported) 586 <1> or byte [psdata_seg:D_P_Flags2],D_P_Key_Cmp ;AC034; Indicate keyword for later string comparison 587 <1> call D_P_Search_KEYorSW ;AN000; Search the keyword in the CONTROL block 588 <1> jc D_P_Chk_Key_Err0 ;AN000; not found, then try next CONTROL 589 <1> 590 <1> and byte [psdata_seg:D_P_Flags2],0ffh-D_P_Key_Cmp ;AC034; reset the indicator previously set 591 <1> ; 592 <1> push ax ;AN000; keyword= 593 <1> mov ax,[psdata_seg:D_P_KEYorSW_Ptr] ;AC034; ^ ^ 594 <1> sub ax,si ;AN000; SI KEYorSW 595 <1> add [psdata_seg:D_P_SaveSI_Cmpx],ax ;AC034; update for complex, quoted or file spec. 596 <1> pop ax ;AN000; 597 <1> ; 598 <1> mov si,[psdata_seg:D_P_KEYorSW_Ptr] ;AC034; set si just after equal char 599 <1> cmp byte ptr [psdata_seg:si],D_P_NULL ;AN000; any data after equal ? 600 <1> je D_P_Chk_Key_Err1 ;AN000; if no, syntax error 601 <1> 602 <1> call D_P_Check_Match_Flags ;AN000; else, process match flags 603 <1> clc ;AN000; 604 <1> jmp short D_P_Chk_Key_Exit ;AN000; 605 <1> 606 <1> D_P_Chk_Key_Err0: ;AN000; 607 <1> stc ;AN000; not found in keyword synonym list 608 <1> jmp short D_P_Chk_Key_Exit ;AN000; 609 <1> 610 <1> D_P_Chk_Key_Err1: ;AN000; 611 <1> mov word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; no parameter is not specified after "=" 612 <1> D_P_Chk_Key_ErrExit: ;AN000; 613 <1> push ax ;AN000; 614 <1> mov al,D_P_String ;AN000; set 615 <1> mov ah,D_P_No_Tag ;AN000; result 616 <1> call D_P_Fill_Result ;AN000; buffer 617 <1> pop ax ;AN000; 618 <1> clc ;AN000; 619 <1> D_P_Chk_Key_Exit: ;AN000; 620 <1> ret ;AN000; 621 <1> %ELSE ;AN000;(of IF KeySW) 0 00002C7A F9 stc ;AN000;this logic works when the KeySW 0 00002C7B C3 ret ;AN000;is reset. 624 <1> %ENDIF ;AN000;(of KeySW) 625 <1> D_P_Chk_Key_Control endp ;AN000; 626 <1> ;PAGE ;AN000; 627 <1> ;*********************************************************************** 628 <1> %IF KeySW+SwSW ;AN000;(Check if keyword or switch is supported) 629 <1> ; D_P_Search_KEYorSW: 630 <1> ; 631 <1> ; Function: Seach specified keyword or switch from CONTROL 632 <1> ; 633 <1> ; Input: ES:BX -> CONTROL block 634 <1> ; psdata_seg:SI -> D_P_STRING_BUF 635 <1> ; 636 <1> ; Output: CY = 1 : not match 637 <1> ; 638 <1> ; Use: D_P_String_Comp, D_P_MoveBP_NUL, D_P_Found_SYNONYM 639 <1> ;*********************************************************************** 640 <1> D_P_Search_KEYorSW proc ;AN000; 0 00002C7C 55 push bp ;AN000; 0 00002C7D 51 push cx ;AN000; 0 00002C7E 268A4F08 mov cl,[es:bx + D_P_nid] ;AN000; Get synonym count 0 00002C82 30ED xor ch,ch ;AN000; and set it to cx 0 00002C84 09C9 or cx,cx ;AN000; No synonyms specified ? 0 00002C86 740D je D_P_KEYorSW_Not_Found ;AN000; then indicate not found by CY 647 <1> 648 <1> D_P_KEYorSW equ D_P_KeyorSW ; NASM port equate 0 00002C88 8D6F09 lea bp,[bx + D_P_KEYorSW] ;AN000; BP points to the 1st synonym 650 <1> D_P_KEYorSW_Loop: ;AN000; 0 00002C8B E8E203 call D_P_String_Comp ;AN000; compare string in buffer w/ the synonym 0 00002C8E 7308 jnc D_P_KEYorSW_Found ;AN000; If match, set it to synonym pointer 653 <1> 0 00002C90 E80E00 call D_P_MoveBP_NUL ;AN000; else, bp points to the next string 0 00002C93 E2F6 loop D_P_KEYorSW_Loop ;AN000; loop nid times 656 <1> D_P_KEYorSW_Not_Found: ;AN000; 0 00002C95 F9 stc ;AN000; indicate not found in synonym list 0 00002C96 EB06 jmp short D_P_KEYorSW_Exit ;AN000; and exit 659 <1> 660 <1> D_P_KEYorSW_Found: ;AN000; 0 00002C98 2E892E[3E00] mov [psdata_seg:D_P_Found_SYNONYM],bp ;AC034; set synonym pointer 0 00002C9D F8 clc ;AN000; indicate found 663 <1> D_P_KEYorSW_Exit: ;AN000; 0 00002C9E 59 pop cx ;AN000; 0 00002C9F 5D pop bp ;AN000; 0 00002CA0 C3 ret ;AN000; 667 <1> D_P_Search_KEYorSW endp ;AN000; 668 <1> ;*********************************************************************** 669 <1> ; D_P_MoveBP_NUL 670 <1> ;*********************************************************************** 671 <1> D_P_MoveBP_NUL proc ;AN000; 672 <1> D_P_MBP_Loop: ;AN000; 0 00002CA1 26807E0000 cmp byte ptr [es:bp],D_P_NULL ;AN000; Increment BP that points 0 00002CA6 7403 je D_P_MBP_Exit ;AN000; to the synomym list 675 <1> 0 00002CA8 45 inc bp ;AN000; until 0 00002CA9 EBF6 jmp short D_P_MBP_Loop ;AN000; NULL encountered. 678 <1> 679 <1> D_P_MBP_Exit: ;AN000; 0 00002CAB 45 inc bp ;AN000; bp points to next to NULL 0 00002CAC C3 ret ;AN000; 682 <1> D_P_MoveBP_NUL endp ;AN000; 683 <1> %ENDIF ;AN000;(of KeySW+SwSW) 684 <1> ;PAGE ;AN000; 685 <1> ;*********************************************************************** 686 <1> ; D_P_Chk_SW_Control 687 <1> ; 688 <1> ; Function: Parse CONTROL block for a switch 689 <1> ; 690 <1> ; Input: ES:BX -> CONTROL block 691 <1> ; psdata_seg:SI -> D_P_STRING_BUF 692 <1> ; 693 <1> ; Output: CY = 1 : not match 694 <1> ; 695 <1> ; Use: D_P_Fill_Result, D_P_Search_KEYorSW, D_P_Check_Match_Flags 696 <1> ; 697 <1> ; Vars: D_P_SaveSI_Cmpx(W), D_P_KEYorSW_Ptr(R), D_P_Flags(W) 698 <1> ;*********************************************************************** 699 <1> D_P_Chk_SW_Control proc ;AN000; 700 <1> 701 <1> 702 <1> %IF SwSW ;AN000;(Check if switch is supported) 703 <1> D_P_Sw_Cmp equ D_P_SW_Cmp ; NASM port equate 0 00002CAD 2E800E[3700]10 or byte [psdata_seg:D_P_Flags2],D_P_Sw_Cmp ;AC034; Indicate switch for later string comparison 0 00002CB3 E8C6FF call D_P_Search_KEYorSW ;AN000; Search the switch in the CONTROL block 0 00002CB6 724A jc D_P_Chk_SW_Err0 ;AN000; not found, then try next CONTROL 707 <1> 0 00002CB8 2E8026[3700]EF and byte [psdata_seg:D_P_Flags2],0ffh-D_P_Sw_Cmp ;AC034; reset the indicator previously set 709 <1> ; 0 00002CBE 50 push ax ;AN000; /switch: 0 00002CBF 2EA1[3A00] mov ax,[psdata_seg:D_P_KEYorSW_Ptr] ;AC034; ^ ^ 0 00002CC3 29F0 sub ax,si ;AN000; SI KEYorSW 0 00002CC5 2E0106[3800] add [psdata_seg:D_P_SaveSI_Cmpx],ax ;AC034; update for complex list 0 00002CCA 58 pop ax ;AN000; 715 <1> ; 0 00002CCB 2E8B36[3A00] mov si,[psdata_seg:D_P_KEYorSW_Ptr] ;AC034; set si at the end or colon 0 00002CD0 2E803C00 cmp byte ptr [psdata_seg:si],D_P_NULL ;AN000; any data after colon 0 00002CD4 7526 jne D_P_CSW00 ;AN000; if yes, process match flags 719 <1> 0 00002CD6 2E807CFF3A cmp byte ptr [psdata_seg:si-1],D_P_Colon ;AN000; if no, the switch terminated by colon ? 0 00002CDB 7509 jne D_P_Chk_if_data_required ;AN000; if yes, 722 <1> 0 00002CDD 2EC706[2B00]0900 mov word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; return syntax error 0 00002CE4 EB1F jmp short D_P_Chk_SW_Exit ;AN000; 725 <1> 726 <1> D_P_Chk_if_data_required: ;AN018; no data, no colon 0 00002CE6 26833F00 cmp word [es:bx + D_P_Match_Flag],0 ;AN018; should have data? zero match flag means switch followed by nothing is OK 0 00002CEA 7419 je D_P_Chk_SW_Exit ;AN018; match flags not zero so should have something if optional bit is not on 729 <1> 0 00002CEC 26F7070100 test word [es:bx + D_P_Match_Flag],D_P_Optional ;AN019; see if no value is valid 0 00002CF1 7512 jnz D_P_Chk_SW_Exit ;AN019; if so, then leave, else yell 732 <1> 0 00002CF3 2EC706[2B00]0200 mov word [psdata_seg:D_P_RC],D_P_Op_Missing ;AC034; return required operand missing 0 00002CFA EB09 jmp short D_P_Chk_SW_Exit ;AN018; 735 <1> 736 <1> D_P_CSW00: ;AN000; 0 00002CFC E89600 call D_P_Check_Match_Flags ;AN000; process match flag 0 00002CFF F8 clc ;AN000; indicate match 0 00002D00 EB0D jmp short D_P_Chk_SW_Single_Exit ;AN000; 740 <1> 741 <1> D_P_Chk_SW_Err0: ;AN000; 0 00002D02 F9 stc ;AN000; not found in switch synonym list 0 00002D03 EB0A jmp short D_P_Chk_SW_Single_Exit ;AN000; 744 <1> 745 <1> D_P_Chk_SW_Exit: ;AN000; 0 00002D05 50 push ax ;AN000; 0 00002D06 B003 mov al,D_P_String ;AN000; set 0 00002D08 B4FF mov ah,D_P_No_Tag ;AN000; result 0 00002D0A E80300 call D_P_Fill_Result ;AN000; buffer 0 00002D0D 58 pop ax ;AN000; 0 00002D0E F8 clc ;AN000; 752 <1> D_P_Chk_SW_Single_Exit: ;AN000; 0 00002D0F C3 ret ;AN000; 754 <1> %ELSE ;AN000;(of IF SwSW) 755 <1> stc ;AN000; this logic works when the SwSW 756 <1> ret ;AN000; is reset. 757 <1> %ENDIF ;AN000;(of SwSW) 758 <1> D_P_Chk_SW_Control endp ;AN000; 759 <1> ;PAGE ;AN000; 760 <1> ;*********************************************************************** 761 <1> ; D_P_Fill_Result 762 <1> ; 763 <1> ; Function: Fill the result buffer 764 <1> ; 765 <1> ; Input: AH = Item tag 766 <1> ; AL = type 767 <1> ; AL = 1: CX,DX has 32bit number (CX = high) 768 <1> ; AL = 2: DX has index(offset) into value list 769 <1> ; AL = 6: DL has driver # (1-A, 2-B, ... , 26 - Z) 770 <1> ; AL = 7: DX has year, CL has month and CH has date 771 <1> ; AL = 8: DL has hours, DH has minutes, CL has secondsn, 772 <1> ; amd CH has hundredths 773 <1> ; AL = else: psdata_seg:SI points to returned string buffer 774 <1> ; ES:BX -> CONTROL block 775 <1> ; 776 <1> ; Output: None 777 <1> ; 778 <1> ; Use: D_P_Do_CAPS_String, D_P_Remove_Colon, D_P_Found_SYNONYM 779 <1> ; 780 <1> ; Vars: D_P_DX(W) 781 <1> ;*********************************************************************** 782 <1> D_P_Fill_Result proc ;AN000; 0 00002D10 57 push di ;AN000; 0 00002D11 268B7F04 mov di,[es:bx + D_P_Result_Buf] ;AN000; di points to result buffer 0 00002D15 2E893E[2F00] mov [psdata_seg:D_P_DX],di ;AC034; set returned result address 0 00002D1A 268805 mov [es:di + D_P_Type],al ;AN000; store type 0 00002D1D 26886501 mov [es:di + D_P_Item_Tag],ah ;AN000; store item tag 0 00002D21 50 push ax ;AN000; 0 00002D22 2EA1[3E00] mov ax,[psdata_seg:D_P_Found_SYNONYM] ;AC034; if yes, 0 00002D26 26894502 mov [es:di + D_P_SYNONYM_Ptr],ax ;AN000; then set it to the result 0 00002D2A 58 pop ax ;AN000; 792 <1> D_P_RLT04: ;AN000; 0 00002D2B 3C01 cmp al,D_P_Number ;AN000; if number 0 00002D2D 750A jne D_P_RLT00 ;AN000; 795 <1> 796 <1> D_P_RLT02: ;AN000; 0 00002D2F 26895504 mov word ptr [es:di + D_P_Picked_Val],dx ;AN000; then store 32bit 0 00002D33 26894D06 mov word ptr [es:di+2 + D_P_Picked_Val],cx ;AN000; number 0 00002D37 EB5A jmp short D_P_RLT_Exit ;AN000; 800 <1> 801 <1> D_P_RLT00: ;AN000; 0 00002D39 3C02 cmp al,D_P_List_Idx ;AN000; if list index 0 00002D3B 7506 jne D_P_RLT01 ;AN000; 804 <1> 0 00002D3D 26895504 mov word ptr [es:di + D_P_Picked_Val],dx ;AN000; then store list index 0 00002D41 EB50 jmp short D_P_RLT_Exit ;AN000; 807 <1> 808 <1> D_P_RLT01: ;AN000; 0 00002D43 3C07 cmp al,D_P_Date_F ;AN000; Date format ? 0 00002D45 74E8 je D_P_RLT02 ;AN000; 811 <1> 0 00002D47 3C08 cmp al,D_P_Time_F ;AN000; Time format ? 0 00002D49 74E4 je D_P_RLT02 ;AN000; 814 <1> ; 0 00002D4B 3C06 cmp al,D_P_Drive ;AN000; drive format ? 0 00002D4D 7506 jne D_P_RLT03 ;AN000; 817 <1> 0 00002D4F 26885504 mov byte ptr [es:di + D_P_Picked_Val],dl ;AN000; store drive number 0 00002D53 EB3E jmp short D_P_RLT_Exit ;AN000; 820 <1> 821 <1> D_P_RLT03: ;AN000; 0 00002D55 3C04 cmp al,D_P_Complex ;AN000; complex format ? 0 00002D57 750F jne D_P_RLT05 ;AN000; 824 <1> 0 00002D59 2EA1[3800] mov ax,[psdata_seg:D_P_SaveSI_Cmpx] ;AC034; then get pointer in command buffer 0 00002D5D 40 inc ax ;AN000; skip left Parentheses 0 00002D5E 26894504 mov word ptr [es:di + D_P_Picked_Val],ax ;AN000; store offset 0 00002D62 268C5D06 mov word ptr [es:di+2 + D_P_Picked_Val],ds ;AN000; store segment 0 00002D66 EB2B jmp short D_P_RLT_Exit ;AN000; 830 <1> 831 <1> D_P_RLT05: ;AN000; 832 <1> ;------------------------ AL = 3, 5, or 9 0 00002D68 26897504 mov word ptr [es:di + D_P_Picked_Val],si ;AN000; store offset of STRING_BUF 834 <1> ;(replaced ;AN031;) mov word ptr [es:di+word].D_P_Picked_Val,cs ;AN000; store segment of STRING_BUF 0 00002D6C 268C4D06 mov word ptr [es:di+2 + D_P_Picked_Val],Psdata_Seg ;AN031; store segment of STRING_BUF 836 <1> ; 0 00002D70 50 push ax ;AN000; 0 00002D71 26F6470201 test byte ptr [es:bx + D_P_Function_Flag],D_P_CAP_File ;AN000; need CAPS by file table? 0 00002D76 7404 je D_P_RLT_CAP00 ;AN000; 840 <1> 0 00002D78 B004 mov al,D_P_DOSTBL_File ;AN000; use file upper case table 0 00002D7A EB09 jmp short D_P_RLT_CAP02 ;AN000; 843 <1> 844 <1> D_P_RLT_CAP00: ;AN000; 0 00002D7C 26F6470202 test byte ptr [es:bx + D_P_Function_Flag],D_P_CAP_Char ;AN000; need CAPS by char table ? 0 00002D81 7405 je D_P_RLT_CAP01 ;AN000; 847 <1> 0 00002D83 B002 mov al,D_P_DOSTBL_Char ;AN000; use character upper case table 849 <1> D_P_RLT_CAP02: ;AN000; 0 00002D85 E8E500 call D_P_Do_CAPS_String ;AN000; process CAPS along the table 851 <1> D_P_RLT_CAP01: ;AN000; 0 00002D88 58 pop ax ;AN000; 0 00002D89 26F6470210 test byte ptr [es:bx + D_P_Function_Flag],D_P_Rm_Colon ;AN000; removing colon at end ? 0 00002D8E 7403 je D_P_RLT_Exit ;AN000; 855 <1> 0 00002D90 E8B400 call D_P_Remove_Colon ;AN000; then process it. 857 <1> D_P_RLT_Exit: ;AN000; 0 00002D93 5F pop di ;AN000; 0 00002D94 C3 ret ;AN000; 860 <1> D_P_Fill_Result endp ;AN000; 861 <1> ;PAGE ;AN000; 862 <1> ;*********************************************************************** 863 <1> ; D_P_Check_Match_Flags 864 <1> ; 865 <1> ; Function: Check the mutch_flags and make the exit code and set the 866 <1> ; result buffer 867 <1> ; 868 <1> ; Check for types in this order: 869 <1> ; Complex 870 <1> ; Date 871 <1> ; Time 872 <1> ; Drive 873 <1> ; Filespec 874 <1> ; Quoted String 875 <1> ; Simple String 876 <1> ; 877 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 878 <1> ; ES:BX -> CONTROL block 879 <1> ; 880 <1> ; Output: None 881 <1> ; 882 <1> ; Use: D_P_Value, P$_SValue, D_P_Simple_String, D_P_Date_Format 883 <1> ; D_P_Time_Format, D_P_Complex_Format, D_P_File_Foemat 884 <1> ; D_P_Drive_Format 885 <1> ;*********************************************************************** 886 <1> D_P_Check_Match_Flags proc ;AN000; 0 00002D95 2EC606[CE00]00 mov byte [psdata_seg:D_P_err_flag],D_P_NULL ;AN033;AC034;; clear filespec error flag. 0 00002D9B 50 push ax ;AN000; 0 00002D9C 268B07 mov ax,[es:bx + D_P_Match_Flag] ;AN000; load match flag(16bit) to ax 890 <1> 0 00002D9F 09C0 or ax,ax ;AC035; test ax for zero 892 <1> ;(changed ;AC035;) cmp ax,0 ;AN000; (tm12) 0 00002DA1 7518 jne D_P_Mat ;AN000; (tm12) 894 <1> 0 00002DA3 50 push ax ;AN000; (tm12) 0 00002DA4 53 push bx ;AN000; (tm12) 0 00002DA5 52 push dx ;AN000; (tm12) 0 00002DA6 57 push di ;AN000; (tm12) 0 00002DA7 2EC706[2B00]0900 mov word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; (tm12) 0 00002DAE B4FF mov ah,D_P_No_Tag ;AN000; (tm12) 0 00002DB0 B003 mov al,D_P_String ;AN000; (tm12) 0 00002DB2 E85BFF call D_P_Fill_Result ;AN000; (tm12) 0 00002DB5 5F pop di ;AN000; (tm12) 0 00002DB6 5A pop dx ;AN000; (tm12) 0 00002DB7 5B pop bx ;AN000; (tm12) 0 00002DB8 58 pop ax ;AN000; (tm12) 0 00002DB9 EB02 jmp short D_P_Bridge ;AC035; (tm12) 908 <1> 909 <1> D_P_Mat: ;AN000; (tm12) 910 <1> 911 <1> %IF CmpxSW ;AN000;(Check if complex item is supported) 912 <1> test ax,D_P_Cmpx_S ;AN000; Complex string 913 <1> je D_P_Match01 ;AN000; 914 <1> 915 <1> mov word [psdata_seg:D_P_RC],D_P_No_Error ;AC034; assume no error 916 <1> call D_P_Complex_Format ;AN000; do process 917 <1> cmp word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; if error, examine the next type 918 <1> jne D_P_Bridge ;AN000; 919 <1> 920 <1> D_P_Match01: ;AN000; 921 <1> %ENDIF ;AN000;(of CmpxSW) 922 <1> %IF DateSW ;AN000;(Check if date format is supported) 923 <1> test ax,D_P_Date_S ;AN000; Date string 924 <1> je D_P_Match02 ;AN000; 925 <1> 926 <1> mov word [psdata_seg:D_P_RC],D_P_No_Error ;AC034; assume no error 927 <1> call D_P_Date_Format ;AN000; do process 928 <1> cmp word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; if error, examine the next type 929 <1> jne D_P_Bridge ;AN000; 930 <1> 931 <1> D_P_Match02: ;AN000; 932 <1> %ENDIF ;AN000;(of DateSW) 933 <1> %IF TimeSW ;AN000;(Check if time format is supported) 934 <1> test ax,D_P_Time_S ;AN000; Time string 935 <1> je D_P_Match03 ;AN000; 936 <1> 937 <1> mov word [psdata_seg:D_P_RC],D_P_No_Error ;AC034; assume no error 938 <1> call D_P_Time_Format ;AN000; do process 939 <1> cmp word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; if error, examine the next type 940 <1> ; je D_P_Match03 ;AN000: 941 <1> 942 <1> jne D_P_Bridge ;AN000; (tm09) 943 <1> 944 <1> %ENDIF ;AN000;(of TimeSW) (tm04) 0 00002DBB EB03 jmp short D_P_Match03 ;AN025; (tm09) 946 <1> 947 <1> D_P_Bridge: ;AN000; 948 <1> ; jmp short D_P_Match_Exit (tm02) 949 <1> 0 00002DBD EB6F jmp D_P_Match_Exit ;AN000; (tm02) 0 00002DBF 90 nop ; identicalise 952 <1> 953 <1> D_P_Match03: ;AN000; 954 <1> ; ENDIF ;AN000;(of TimeSW) (tm04) 955 <1> %IF NumSW ;AN000;(Check if numeric value is supported) 0 00002DC0 A90080 test ax,D_P_Num_Val ;AN000; Numeric value 0 00002DC3 7412 je D_P_Match04 ;AN000; 958 <1> 0 00002DC5 2EC706[2B00]0000 mov word [psdata_seg:D_P_RC],D_P_No_Error ;AC034; assume no error 0 00002DCC E82601 call D_P_Value ;AN000; do process 0 00002DCF 2E833E[2B00]09 cmp word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; if error, examine the next type 0 00002DD5 7557 jne D_P_Match_Exit ;AN000; 963 <1> 964 <1> D_P_Match04: ;AN000; 965 <1> D_P_SNUM_Val equ D_P_SNum_Val ; NASM port equate 0 00002DD7 A90040 test ax,D_P_SNUM_Val ;AN000; Signed numeric value 0 00002DDA 7412 je D_P_Match05 ;AN000; 968 <1> 0 00002DDC 2EC706[2B00]0000 mov word [psdata_seg:D_P_RC],D_P_No_Error ;AC034; assume no error 0 00002DE3 E8EB00 call D_P_SValue ;AN000; do process 0 00002DE6 2E833E[2B00]09 cmp word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; if error, examine the next type 0 00002DEC 7540 jne D_P_Match_Exit ;AN000; 973 <1> 974 <1> D_P_Match05: ;AN000; 975 <1> %ENDIF ;AN000;(of NumSW) 976 <1> %IF DrvSW ;AN000;(Check if drive only is supported) 0 00002DEE A90001 test ax,D_P_Drv_Only ;AN000; Drive only 0 00002DF1 7415 je D_P_Match06 ;AN000; 979 <1> 0 00002DF3 2EC706[2B00]0000 mov word [psdata_seg:D_P_RC],D_P_No_Error ;AC034; assume no error 0 00002DFA E81603 call D_P_File_Format ;AN000; 1st, call file format 0 00002DFD E89903 call D_P_Drive_Format ;AN000; check drive format, next 0 00002E00 2E833E[2B00]09 cmp word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; if error, examinee the next type 0 00002E06 7526 jne D_P_Match_Exit ;AN000; 985 <1> 986 <1> D_P_Match06: ;AN000; 987 <1> %ENDIF ;AN000;(of DrvSW) 988 <1> %IF FileSW ;AN000;(Check if file spec is supported) 0 00002E08 A90002 test ax,D_P_File_Spc ;AN000; File spec 0 00002E0B 7412 je D_P_Match07 ;AN000; 991 <1> 0 00002E0D 2EC706[2B00]0000 mov word [psdata_seg:D_P_RC],D_P_No_Error ;AC034; assume no error 0 00002E14 E8FC02 call D_P_File_Format ;AN000; do process 0 00002E17 2E833E[2B00]09 cmp word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; if error, examine the next type 0 00002E1D 750F jne D_P_Match_Exit ;AN000; 996 <1> 997 <1> D_P_Match07: ;AN000; 998 <1> %ENDIF ;AN000;(of FileSW) 999 <1> %IF QusSW ;AN000;(Check if quoted string is supported) 1000 <1> test ax,D_P_Qu_String ;AN000; Quoted string 1001 <1> je D_P_Match08 ;AN000; 1002 <1> 1003 <1> mov word [psdata_seg:D_P_RC],D_P_No_Error ;AC034; assume no error 1004 <1> call D_P_Quoted_Format ;AN000; do process 1005 <1> cmp word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; if error, examine the next type 1006 <1> jne D_P_Match_Exit ;AN000; 1007 <1> 1008 <1> D_P_Match08: ;AN000; 1009 <1> %ENDIF ;AN000;(of QusSW) 0 00002E1F A90020 test ax,D_P_Simple_S ;AN000; Simple string 0 00002E22 740A je D_P_Match09 ;AN000; 1012 <1> 0 00002E24 2EC706[2B00]0000 mov word [psdata_seg:D_P_RC],D_P_No_Error ;AC034; assume no error 0 00002E2B E8D901 call D_P_Simple_String ;AN000; do process 1015 <1> ;;;; cmp psdata_seg:D_P_RC,D_P_Syntax ;AC034; These two lines will be alive 1016 <1> ;;;; jne D_P_Match_Exit ;when extending the match_flags. 1017 <1> D_P_Match09: ;AN000; 1018 <1> D_P_Match_Exit: ;AN000; 0 00002E2E 2E803E[CE00]01 cmp byte [psdata_seg:D_P_err_flag],D_P_error_filespec ;AC034; bad filespec ? 0 00002E34 750F jne D_P_Match2_Exit ;AN033; no, continue 0 00002E36 2E833E[2B00]00 cmp word [psdata_seg:D_P_RC],D_P_No_Error ;AN033;AC034;; check for other errors ? 0 00002E3C 7507 jne D_P_Match2_Exit ;AN033; no, continue 0 00002E3E 2EC706[2B00]0900 mov word [psdata_seg:D_P_RC],D_P_Syntax ;AN033;AC034;; set error flag 1024 <1> D_P_Match2_Exit: ;AN033; 0 00002E45 58 pop ax ;AN000; 0 00002E46 C3 ret ;AN000; 1027 <1> D_P_Check_Match_Flags endp ;AN000; 1028 <1> ;PAGE ;AN000; 1029 <1> ;*********************************************************************** 1030 <1> ; D_P_Remove_Colon; 1031 <1> ; 1032 <1> ; Function: Remove colon at end 1033 <1> ; 1034 <1> ; Input: psdata_seg:SI points to string buffer to be examineed 1035 <1> ; 1036 <1> ; Output: None 1037 <1> ; 1038 <1> ; Use: D_P_Chk_DBCS 1039 <1> ;*********************************************************************** 1040 <1> D_P_Remove_Colon proc ;AN000; 0 00002E47 50 push ax ;AN000; 0 00002E48 56 push si ;AN000; 1043 <1> D_P_RCOL_Loop: ;AN000; 0 00002E49 2E8A04 mov al,[psdata_seg:si] ;AN000; get character 0 00002E4C 08C0 or al,al ;AN000; end of string ? 0 00002E4E 741A je D_P_RCOL_Exit ;AN000; if yes, just exit 1047 <1> 0 00002E50 3C3A cmp al,D_P_Colon ;AN000; is it colon ? 0 00002E52 750D jne D_P_RCOL00 ;AN000; 1050 <1> 0 00002E54 2E807C0100 cmp byte ptr [psdata_seg:si+1],D_P_NULL ;AN000; if so, next is NULL ? 0 00002E59 7506 jne D_P_RCOL00 ;AN000; no, then next char 1053 <1> 0 00002E5B 2EC60400 mov byte ptr [psdata_seg:si],D_P_NULL ;AN000; yes, remove colon 0 00002E5F EB09 jmp short D_P_RCOL_Exit ;AN000; and exit. 1056 <1> 1057 <1> D_P_RCOL00: ;AN000; 0 00002E61 E85404 call D_P_Chk_DBCS ;AN000; if not colon, then check if 0 00002E64 7301 jnc D_P_RCOL01 ;AN000; DBCS leading byte. 1060 <1> 0 00002E66 46 inc si ;AN000; if yes, skip trailing byte 1062 <1> D_P_RCOL01: ;AN000; 0 00002E67 46 inc si ;AN000; si points to next byte 0 00002E68 EBDF jmp short D_P_RCOL_Loop ;AN000; loop until NULL encountered 1065 <1> 1066 <1> D_P_RCOL_Exit: ;AN000; 0 00002E6A 5E pop si ;AN000; 0 00002E6B 58 pop ax ;AN000; 0 00002E6C C3 ret ;AN000; 1070 <1> D_P_Remove_Colon endp ;AN000; 1071 <1> ;PAGE ;AN000; 1072 <1> ;*********************************************************************** 1073 <1> ; D_P_Do_CAPS_String; 1074 <1> ; 1075 <1> ; Function: Perform capitalization along with the file case map table 1076 <1> ; or character case map table. 1077 <1> ; 1078 <1> ; Input: AL = 2 : Use character table 1079 <1> ; AL = 4 : Use file table 1080 <1> ; psdata_seg:SI points to string buffer to be capitalized 1081 <1> ; 1082 <1> ; Output: None 1083 <1> ; 1084 <1> ; Use: D_P_Do_CAPS_Char, D_P_Chk_DBCS 1085 <1> ;*********************************************************************** 1086 <1> D_P_Do_CAPS_String proc ;AN000; 0 00002E6D 56 push si ;AN000; 0 00002E6E 52 push dx ;AN000; 0 00002E6F 88C2 mov dl,al ;AN000; save info id 1090 <1> 1091 <1> D_P_DCS_Loop: ;AN000; 0 00002E71 2E8A04 mov al,[psdata_seg:si] ;AN000; load charater and 0 00002E74 E84104 call D_P_Chk_DBCS ;AN000; check if DBCS leading byte 0 00002E77 720C jc D_P_DCS00 ;AN000; if yes, do not need CAPS 1095 <1> 0 00002E79 08C0 or al,al ;AN000; end of string ? 0 00002E7B 740C je D_P_DCS_Exit ;AN000; then exit. 1098 <1> 0 00002E7D E80C00 call D_P_Do_CAPS_Char ;AN000; Here a SBCS char need to be CAPS 0 00002E80 2E8804 mov [psdata_seg:si],al ;AN000; stored upper case char to buffer 0 00002E83 EB01 jmp short D_P_DCS01 ;AN000; process nexit 1102 <1> D_P_DCS00: ;AN000; 0 00002E85 46 inc si ;AN000; skip DBCS leading and trailing byte 1104 <1> D_P_DCS01: ;AN000; 0 00002E86 46 inc si ;AN000; si point to next byte 0 00002E87 EBE8 jmp short D_P_DCS_Loop ;AN000; loop until NULL encountered 1107 <1> D_P_DCS_Exit: ;AN000; 0 00002E89 5A pop dx ;AN000; 0 00002E8A 5E pop si ;AN000; 0 00002E8B C3 ret ;AN000; 1111 <1> D_P_Do_CAPS_String endp ;AN000; 1112 <1> ;PAGE ;AN000; 1113 <1> ;*********************************************************************** 1114 <1> ; D_P_Do_CAPS_Char; 1115 <1> ; 1116 <1> ; Function: Perform capitalization along with the file case map table 1117 <1> ; or character case map table. 1118 <1> ; 1119 <1> ; Input: DL = 2 : Use character table 1120 <1> ; DL = 4 : Use file table 1121 <1> ; AL = character to be capitalized 1122 <1> ; 1123 <1> ; Output: None 1124 <1> ; 1125 <1> ; Use: INT 21h /w AH=65h 1126 <1> ;*********************************************************************** 1127 <1> D_P_Do_CAPS_Char proc ;AN000; 0 00002E8C 3C80 cmp al,D_P_ASCII80 ;AN000; need upper case table ? 0 00002E8E 730C jae D_P_DCC_Go ;AN000; 1130 <1> 0 00002E90 3C61 cmp al,"a" ;AN000; if no, 0 00002E92 723C jb D_P_CAPS_Ret ;AN000; check if "a" <= AL <= "z" 1133 <1> 0 00002E94 3C7A cmp al,"z" ;AN000; 0 00002E96 7738 ja D_P_CAPS_Ret ;AN000; if yes, make CAPS 1136 <1> 0 00002E98 24DF and al,D_P_Make_Upper ;AN000; else do nothing. 0 00002E9A EB34 jmp short D_P_CAPS_Ret ;AN000; 1139 <1> 1140 <1> D_P_DCC_Go: ;AN000; 0 00002E9C 53 push bx ;AN000; 0 00002E9D 06 push es ;AN000; 0 00002E9E 57 push di ;AN000; 1144 <1> %IF CAPSW ;AN000;(Check if uppercase conversion is supported) 1145 <1> lea di,[D_P_File_CAP_Ptr] ;AC034; 1146 <1> cmp dl,D_P_DOSTBL_File ;AN000; Use file CAPS table ? 1147 <1> je D_P_DCC00 ;AN000; 1148 <1> 1149 <1> %ENDIF ;AN000;(of CAPSW) 0 00002E9F 8D3E[C000] lea di,[D_P_Char_CAP_Ptr] ;AC034; or use char CAPS table ? 1151 <1> D_P_DCC00: ;AN000; 0 00002EA3 2E3815 cmp [psdata_seg:di],dl ;AN000; already got table address ? 0 00002EA6 7417 je D_P_DCC01 ;AN000; if no, 1154 <1> 1155 <1> ;In this next section, ES will be used to pass a 5 byte workarea to INT 21h, 1156 <1> ; the GET COUNTYRY INFO call. This usage of ES is required by the function 1157 <1> ; call, regardless of what base register is currently be defined as PSDATA_SEG. 1158 <1> ;BASESW EQU 0 means that ES is the psdata_seg reg. 1159 <1> 1160 <1> %IFDEF BASESW ;AN037; If BASESW has been defined, and 1161 <1> %IFN BASESW ;AN037; If ES is psdata base 1162 <1> push PSDATA_SEG ;AN037; save current base reg 1163 <1> %ENDIF ;AN037; 1164 <1> %ENDIF ;AN037; 1165 <1> 0 00002EA8 50 push ax ;AN000; get CAPS table thru DOS call 0 00002EA9 51 push cx ;AN000; 0 00002EAA 52 push dx ;AN000; 1169 <1> 1170 <1> 0 00002EAB 0E push PSDATA_SEG ;AC036; pass current base seg into 1172 <1> ;(Note: this used to push CS. BUG... 0 00002EAC 07 pop es ;AN000; ES reg, required for 1174 <1> ;get extended country information 0 00002EAD B465 mov ah,D_P_DOS_Get_TBL ;AN000; get extended CDI 0 00002EAF 88D0 mov al,dl ;AN000; upper case table 0 00002EB1 BBFFFF mov bx,D_P_DOSTBL_Def ;AN000; get active CON 0 00002EB4 B90500 mov cx,D_P_DOSTBL_BL ;AN000; buffer length 0 00002EB7 BAFFFF mov dx,D_P_DOSTBL_Def ;AN000; get for default code page 1180 <1> ;DI already set to point to buffer 0 00002EBA CD21 int 21h ;AN000; es:di point to buffer that 1182 <1> ;now has been filled in with info 0 00002EBC 5A pop dx ;AN000; 0 00002EBD 59 pop cx ;AN000; 0 00002EBE 58 pop ax ;AN000; 1186 <1> %IFDEF BASESW ;AN037; If BASESW has been defined, and 1187 <1> %IFN BASESW ;AN037; If ES is psdata base 1188 <1> pop PSDATA_SEG ;AN037; restore current base reg 1189 <1> %ENDIF ;AN037; 1190 <1> %ENDIF ;AN037; 1191 <1> D_P_DCC01: ;AN000; 1192 <1> 1193 <1> ;In this next section, ES will be used as the base of the XLAT table, provided 1194 <1> ; by the previous GET COUNTRY INFO DOS call. This usage of ES is made 1195 <1> ; regardless of which base reg is currently the PSDATA_SEG reg. 1196 <1> 1197 <1> %IFDEF BASESW ;AN037; If BASESW has been defined, and 1198 <1> %IFN BASESW ;AN037; If ES is psdata base 1199 <1> push PSDATA_SEG ;AN037; save current base reg 1200 <1> %ENDIF ;AN037; 1201 <1> %ENDIF ;AN037; 0 00002EBF 2E8B5D01 mov bx,[psdata_seg:di+D_P_DOS_TBL_Off] ;AN000; get offset of table 0 00002EC3 2E8E4503 mov es,[psdata_seg:di+D_P_DOS_TBL_Seg] ;AN000; get segment of table 0 00002EC7 43 inc bx ;AC035; add '2' to 0 00002EC8 43 inc bx ;AC035; BX reg 1206 <1> ;AN000; skip length field 1207 <1> ;(changed ;AN035;) add bx,word ;AN000; skip length field 0 00002EC9 2C80 sub al,D_P_ASCII80 ;AN000; make char to index 0 00002ECB 26D7 es xlatb ;AN000; perform case map 1210 <1> 1211 <1> %IFDEF BASESW ;AN037; If BASESW has been defined, and 1212 <1> %IFN BASESW ;AN037; If ES is psdata base 1213 <1> pop PSDATA_SEG ;AN037; restore current base reg 1214 <1> %ENDIF ;AN037; 1215 <1> %ENDIF ;AN037; 0 00002ECD 5F pop di ;AN000; 0 00002ECE 07 pop es ;AN000; 0 00002ECF 5B pop bx ;AN000; 1219 <1> D_P_CAPS_Ret: ;AN000; 0 00002ED0 C3 ret ;AN000; 1221 <1> D_P_Do_CAPS_Char endp ;AN000; 1222 <1> ;PAGE ;AN000; 1223 <1> ;*********************************************************************** 1224 <1> %IF NumSW ;AN000;(Check if numeric value is supported) 1225 <1> ; D_P_Value / D_P_SValue 1226 <1> ; 1227 <1> ; Function: Make 32bit value from psdata_seg:SI and see value list 1228 <1> ; and make result buffer. 1229 <1> ; D_P_SValue is an entry point for the signed value 1230 <1> ; and this will simply call D_P_Value after the handling 1231 <1> ; of the sign character, "+" or "-" 1232 <1> ; 1233 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 1234 <1> ; ES:BX -> CONTROL block 1235 <1> ; 1236 <1> ; Output: None 1237 <1> ; 1238 <1> ; Use: D_P_Fill_Result, D_P_Check_OVF 1239 <1> ; 1240 <1> ; Vars: D_P_RC(W), D_P_Flags(RW) 1241 <1> ;*********************************************************************** 1242 <1> D_P_SValue proc ;AN000; when signed value here 0 00002ED1 50 push ax ;AN000; 0 00002ED2 2E800E[3700]80 or byte [psdata_seg:D_P_Flags2],D_P_Signed ;AC034; indicate a signed numeric 0 00002ED8 2E8026[3700]FD and byte [psdata_seg:D_P_Flags2],0ffh-D_P_Neg ;AC034; assume positive value 0 00002EDE 2E8A04 mov al,[psdata_seg:si] ;AN000; get sign 0 00002EE1 3C2B cmp al,D_P_Plus ;AN000; "+" ? 0 00002EE3 740A je D_P_SVal00 ;AN000; 1249 <1> 0 00002EE5 3C2D cmp al,D_P_Minus ;AN000; "-" ? 0 00002EE7 7507 jne D_P_Sval01 ;AN000; else 1252 <1> 0 00002EE9 2E800E[3700]02 or byte [psdata_seg:D_P_Flags2],D_P_Neg ;AC034; set this is negative value 1254 <1> D_P_SVal00: ;AN000; 0 00002EEF 46 inc si ;AN000; skip sign char 1256 <1> D_P_Sval01: ;AN000; 0 00002EF0 E80200 call D_P_Value ;AN000; and process value 0 00002EF3 58 pop ax ;AN000; 0 00002EF4 C3 ret ;AN000; 1260 <1> D_P_SValue endp ;AN000; 1261 <1> ;*********************************************************************** 1262 <1> D_P_Value proc ;AN000; 0 00002EF5 50 push ax ;AN000; 0 00002EF6 51 push cx ;AN000; 0 00002EF7 52 push dx ;AN000; 0 00002EF8 56 push si ;AN000; 0 00002EF9 31C9 xor cx,cx ;AN000; cx = higher 16 bits 0 00002EFB 31D2 xor dx,dx ;AN000; dx = lower 16 bits 0 00002EFD 53 push bx ;AN000; save control pointer 1270 <1> D_P_Value_Loop: ;AN000; 0 00002EFE 2E8A04 mov al,[psdata_seg:si] ;AN000; get character 0 00002F01 08C0 or al,al ;AN000; end of line ? 0 00002F03 7442 je D_P_Value00 ;AN000; 1274 <1> 0 00002F05 E8F100 call D_P_0099 ;AN000; make asc(0..9) to bin(0..9) 0 00002F08 7239 jc D_P_Value_Err0 ;AN000; 1277 <1> 0 00002F0A 30E4 xor ah,ah ;AN000; 0 00002F0C 89C5 mov bp,ax ;AN000; save binary number 0 00002F0E D1E2 shl dx,1 ;AN000; to have 2*x 0 00002F10 D1D1 rcl cx,1 ;AN000; shift left w/ carry 0 00002F12 E8D200 call D_P_Check_OVF ;AN000; Overflow occurred ? 0 00002F15 722C jc D_P_Value_Err0 ;AN000; then error, exit 1284 <1> 0 00002F17 89D3 mov bx,dx ;AN000; save low(2*x) 0 00002F19 89C8 mov ax,cx ;AN000; save high(2*x) 0 00002F1B D1E2 shl dx,1 ;AN000; to have 4*x 0 00002F1D D1D1 rcl cx,1 ;AN000; shift left w/ carry 0 00002F1F E8C500 call D_P_Check_OVF ;AN000; Overflow occurred ? 0 00002F22 721F jc D_P_Value_Err0 ;AN000; then error, exit 1291 <1> 0 00002F24 D1E2 shl dx,1 ;AN000; to have 8*x 0 00002F26 D1D1 rcl cx,1 ;AN000; shift left w/ carry 0 00002F28 E8BC00 call D_P_Check_OVF ;AN000; Overflow occurred ? 0 00002F2B 7216 jc D_P_Value_Err0 ;AN000; then error, exit 1296 <1> 0 00002F2D 01DA add dx,bx ;AN000; now have 10*x 0 00002F2F 11C1 adc cx,ax ;AN000; 32bit ADD 0 00002F31 E8B300 call D_P_Check_OVF ;AN000; Overflow occurred ? 0 00002F34 720D jc D_P_Value_Err0 ;AN000; then error, exit 1301 <1> 0 00002F36 01EA add dx,bp ;AN000; Add the current one degree decimal 0 00002F38 83D100 adc cx,0 ;AN000; if carry, add 1 to high 16bit 0 00002F3B E8A900 call D_P_Check_OVF ;AN000; Overflow occurred ? 0 00002F3E 7203 jc D_P_Value_Err0 ;AN000; then error, exit 1306 <1> 0 00002F40 46 inc si ;AN000; update pointer 0 00002F41 EBBB jmp short D_P_Value_Loop ;AN000; loop until NULL encountered 1309 <1> ; 1310 <1> D_P_Value_Err0: ;AN000; 0 00002F43 5B pop bx ;AN000; 0 00002F44 E98D00 jmp D_P_Value_Err ;AN000; Bridge 1313 <1> ; 1314 <1> D_P_Value00: ;AN000; 0 00002F47 5B pop bx ;AN000; restore control pointer 0 00002F48 2EF606[3700]02 test byte [psdata_seg:D_P_Flags2],D_P_Neg ;AC034; here cx,dx = 32bit value 0 00002F4E 740A je D_P_Value01 ;AN000; was it negative ? 1318 <1> 0 00002F50 F7D1 not cx ;AN000; + 0 00002F52 F7D2 not dx ;AN000; |- Make 2's complement 0 00002F54 83C201 add dx,1 ;AN000; | 0 00002F57 83D100 adc cx,0 ;AN000; + 1323 <1> D_P_Value01: ;AN000; / nval =0 0 00002F5A 268B7706 mov si,[es:bx + D_P_Value_List] ;AN000; si points to value list 0 00002F5E 268A04 mov al,[es:si] ;AN000; get nval 0 00002F61 3C00 cmp al,D_P_nval_None ;AN000; no value list ? 0 00002F63 7507 jne D_P_Value02 ;AN000; 1328 <1> 0 00002F65 B001 mov al,D_P_Number ;AN000; Set type 0 00002F67 B4FF mov ah,D_P_No_Tag ;AN000; No ITEM_TAG set 0 00002F69 EB74 jmp D_P_Value_Exit ;AN000; 0 00002F6B 90 nop ; identicalise 1333 <1> 1334 <1> D_P_Value02: ;AN000; / nval = 1 1335 <1> %IF Val1SW ;AN000;(Check if value list id #1 is supported) 1336 <1> ;(tm07) cmp al,D_P_nval_Range ;AN000; have range list ? 1337 <1> ;(tm07) jne D_P_Value03 ;AN000; 1338 <1> 0 00002F6C 46 inc si ;AN000; 0 00002F6D 268A04 mov al,[es:si] ;AN000; al = number of range 0 00002F70 3C00 cmp al,D_P_No_nrng ;AN000; (tm07) 0 00002F72 7460 je D_P_Value03 ;AN000; (tm07) 1343 <1> 0 00002F74 46 inc si ;AN000; si points to 1st item_tag 1345 <1> D_P_Val02_Loop: ;AN000; 0 00002F75 2EF606[3700]80 test byte [psdata_seg:D_P_Flags2],D_P_Signed ;AC034; 0 00002F7B 751E jne D_P_Val02_Sign ;AN000; 1348 <1> 0 00002F7D 263B4C03 cmp cx,[es:si+D_P_Val_XH] ;AN000; comp cx with XH 0 00002F81 7236 jb D_P_Val02_Next ;AN000; 1351 <1> 0 00002F83 7706 ja D_P_Val_In ;AN000; 1353 <1> 0 00002F85 263B5401 cmp dx,[es:si+D_P_Val_XL] ;AN000; comp dx with XL 0 00002F89 722E jb D_P_Val02_Next ;AN000; 1356 <1> 1357 <1> D_P_Val_In: ;AN000; 1358 <1> ;;;;;; cmp cx,es:D_P_Val_YH] ; comp cx with YH (tm01) 0 00002F8B 263B4C07 cmp cx,[es:si+D_P_Val_YH] ;AN000; comp cx with YH (tm01) 0 00002F8F 7728 ja D_P_Val02_Next ;AN000; 1361 <1> 0 00002F91 723A jb D_P_Val_Found ;AN000; 1363 <1> 0 00002F93 263B5405 cmp dx,[es:si+D_P_Val_YL] ;AN000; comp dx with YL 0 00002F97 7720 ja D_P_Val02_Next ;AN000; 1366 <1> 0 00002F99 EB32 jmp short D_P_Val_Found ;AN000; 1368 <1> 1369 <1> D_P_Val02_Sign: ;AN000; 0 00002F9B 263B4C03 cmp cx,[es:si+D_P_Val_XH] ;AN000; comp cx with XH 0 00002F9F 7C18 jl D_P_Val02_Next ;AN000; 1372 <1> 0 00002FA1 7F06 jg D_P_SVal_In ;AN000; 1374 <1> 0 00002FA3 263B5401 cmp dx,[es:si+D_P_Val_XL] ;AN000; comp dx with XL 0 00002FA7 7C10 jl D_P_Val02_Next ;AN000; 1377 <1> 1378 <1> D_P_SVal_In: ;AN000; 0 00002FA9 263B4C07 cmp cx,[es:si+D_P_Val_YH] ;AN000; comp cx with YH 0 00002FAD 7F0A jg D_P_Val02_Next ;AN000; 1381 <1> 0 00002FAF 7C1C jl D_P_Val_Found ;AN000; 1383 <1> 0 00002FB1 263B5405 cmp dx,[es:si+D_P_Val_YL] ;AN000; comp dx with YL 0 00002FB5 7F02 jg D_P_Val02_Next ;AN000; 1386 <1> 0 00002FB7 EB14 jmp short D_P_Val_Found ;AN000; 1388 <1> 1389 <1> D_P_Val02_Next: ;AN000; 0 00002FB9 83C609 add si,D_P_Len_Range ;AN000; 0 00002FBC FEC8 dec al ;AN000; loop nrng times in AL 0 00002FBE 75B5 jne D_P_Val02_Loop ;AN000; 1393 <1> ; / Not found 1394 <1> D_P_Out_of_Range equ D_P_Out_Of_Range ; NASM port equate 0 00002FC0 2EC706[2B00]0600 mov word [psdata_seg:D_P_RC],D_P_Out_of_Range ;AC034; 0 00002FC7 B001 mov al,D_P_Number ;AN000; 0 00002FC9 B4FF mov ah,D_P_No_Tag ;AN000; No ITEM_TAG set 0 00002FCB EB12 jmp short D_P_Value_Exit ;AN000; 1399 <1> 1400 <1> %ENDIF ;AN000;(of Val1SW) 1401 <1> %IF Val1SW+Val2SW ;AN000;(Check if value list id #1 or #2 is supported) 1402 <1> D_P_Val_Found: ;AN000; 0 00002FCD B001 mov al,D_P_Number ;AN000; 0 00002FCF 268A24 mov ah,[es:si] ;AN000; found ITEM_TAG set 0 00002FD2 EB0B jmp short D_P_Value_Exit ;AN000; 1406 <1> 1407 <1> %ENDIF ;AN000;(of Val1SW+Val2SW) 1408 <1> D_P_Value03: ;AN000; / nval = 2 1409 <1> %IF Val2SW ;AN000;(Check if value list id #2 is supported) 1410 <1> ;;;; cmp al,D_P_nval_Value ; have match list ? ASSUME nval=2, 1411 <1> ;;;; jne D_P_Value04 ; even if it is 3 or more. 1412 <1> ;(tm07) inc si ;AN000; 1413 <1> ;(tm07) mov al,[es:si] ;AN000; al = nrng 1414 <1> mov ah,D_P_Len_Range ;AN000; 1415 <1> mul ah ;AN000; Skip nrng field 1416 <1> inc ax ;AN000; 1417 <1> add si,ax ;AN000; si points to nnval 1418 <1> mov al,[es:si] ;AN000; get nnval 1419 <1> inc si ;AN000; si points to 1st item_tag 1420 <1> D_P_Val03_Loop: ;AN000; 1421 <1> cmp cx,[es:si+D_P_Val_XH] ;AN000; comp cx with XH 1422 <1> jne D_P_Val03_Next ;AN000; 1423 <1> 1424 <1> cmp dx,[es:si+D_P_Val_XL] ;AN000; comp dx with XL 1425 <1> je D_P_Val_Found ;AN000; 1426 <1> 1427 <1> D_P_Val03_Next: ;AN000; 1428 <1> add si,D_P_Len_Value ;AN000; points to next value choice 1429 <1> dec al ;AN000; loop nval times in AL 1430 <1> jne D_P_Val03_Loop ;AN000; 1431 <1> ;AN000; / Not found 1432 <1> D_P_Not_in_Val equ D_P_Not_In_Val ; NASM port equate 1433 <1> mov word [psdata_seg:D_P_RC],D_P_Not_in_Val ;AC034; 1434 <1> mov al,D_P_Number ;AN000; 1435 <1> mov ah,D_P_No_Tag ;AN000; No ITEM_TAG set 1436 <1> jmp short D_P_Value_Exit ;AN000; 1437 <1> 1438 <1> %ENDIF ;AN000;(of Val2SW) 1439 <1> D_P_Value04: ;AN000; / nval = 3 or else 1440 <1> D_P_Value_Err: ;AN000; 0 00002FD4 2EC706[2B00]0900 mov word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; 0 00002FDB B003 mov al,D_P_String ;AN000; Set type 0 00002FDD B4FF mov ah,D_P_No_Tag ;AN000; No ITEM_TAG set 1444 <1> D_P_Value_Exit: ;AN000; 0 00002FDF E82EFD call D_P_Fill_Result ;AN000; 0 00002FE2 5E pop si ;AN000; 0 00002FE3 5A pop dx ;AN000; 0 00002FE4 59 pop cx ;AN000; 0 00002FE5 58 pop ax ;AN000; 0 00002FE6 C3 ret ;AN000; 1451 <1> D_P_Value endp ;AN000; 1452 <1> ;PAGE ;AN000; 1453 <1> ;*********************************************************************** 1454 <1> ; D_P_Check_OVF 1455 <1> ; 1456 <1> ; Function: Check if overflow is occurred with consideration of 1457 <1> ; signed or un-signed numeric value 1458 <1> ; 1459 <1> ; Input: Flag register 1460 <1> ; 1461 <1> ; Output: CY = 1 : Overflow 1462 <1> ; 1463 <1> ; Vars: D_P_Flags(R) 1464 <1> ;*********************************************************************** 1465 <1> D_P_Check_OVF proc ;AN000; 0 00002FE7 9C pushf ;AN000; 0 00002FE8 2EF606[3700]02 test byte [psdata_seg:D_P_Flags2],D_P_Neg ;AC034; is it negative value ? 0 00002FEE 7502 jne D_P_COVF ;AN000; if no, check overflow 1469 <1> 0 00002FF0 9D popf ;AN000; by the CY bit 0 00002FF1 C3 ret ;AN000; 1472 <1> 1473 <1> D_P_COVF: ;AN000; 0 00002FF2 9D popf ;AN000; else, 0 00002FF3 7002 jo D_P_COVF00 ;AN000; check overflow by the OF 1476 <1> 0 00002FF5 F8 clc ;AN000; indicate it with CY bit 0 00002FF6 C3 ret ;AN000; CY=0 means no overflow 1479 <1> 1480 <1> D_P_COVF00: ;AN000; 0 00002FF7 F9 stc ;AN000; and CY=1 means overflow 0 00002FF8 C3 ret ;AN000; 1483 <1> D_P_Check_OVF endp ;AN000; 1484 <1> %ENDIF ;AN000;(of FarSW) 1485 <1> ;*********************************************************************** 1486 <1> ; D_P_0099; 1487 <1> ; 1488 <1> ; Function: Make ASCII 0-9 to Binary 0-9 1489 <1> ; 1490 <1> ; Input: AL = character code 1491 <1> ; 1492 <1> ; Output: CY = 1 : AL is not number 1493 <1> ; CY = 0 : AL contains binary value 1494 <1> ;*********************************************************************** 1495 <1> D_P_0099 proc ;AN000; 0 00002FF9 3C30 cmp al,"0" ;AN000; 0 00002FFB 7208 jb D_P_0099Err ;AN000; must be 0 =< al =< 9 1498 <1> 0 00002FFD 3C39 cmp al,"9" ;AN000; 0 00002FFF 7704 ja D_P_0099Err ;AN000; must be 0 =< al =< 9 1501 <1> 0 00003001 2C30 sub al,"0" ;AN000; make char -> bin 0 00003003 F8 clc ;AN000; indicate no error 0 00003004 C3 ret ;AN000; 1505 <1> 1506 <1> D_P_0099Err: ;AN000; 0 00003005 F9 stc ;AN000; indicate error 0 00003006 C3 ret ;AN000; 1509 <1> D_P_0099 endp ;AN000; 1510 <1> ;PAGE ;AN000; 1511 <1> ;*********************************************************************** 1512 <1> ; D_P_Simple_String 1513 <1> ; 1514 <1> ; Function: See value list for the simple string 1515 <1> ; and make result buffer. 1516 <1> ; 1517 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 1518 <1> ; ES:BX -> CONTROL block 1519 <1> ; 1520 <1> ; Output: None 1521 <1> ; 1522 <1> ; Use: D_P_Fill_Result, D_P_String_Comp 1523 <1> ; 1524 <1> ; Vars: D_P_RC(W) 1525 <1> ;*********************************************************************** 1526 <1> D_P_Simple_String proc ;AN000; 0 00003007 50 push ax ;AN000; 0 00003008 53 push bx ;AN000; 0 00003009 52 push dx ;AN000; 0 0000300A 57 push di ;AN000; 0 0000300B 268B7F06 mov di,[es:bx + D_P_Value_List] ;AN000; di points to value list 0 0000300F 268A05 mov al,[es:di] ;AN000; get nval 0 00003012 08C0 or al,al ;AN000; no value list ? 0 00003014 7504 jne D_P_Sim00 ;AN000; then 1535 <1> 0 00003016 B4FF mov ah,D_P_No_Tag ;AN000; No ITEM_TAG set 0 00003018 EB4C jmp short D_P_Sim_Exit ;AN000; and set result buffer 1538 <1> 1539 <1> D_P_Sim00: ;AN000; 1540 <1> %IF Val3SW+KeySW ;AN000;(Check if keyword or value list id #3 is supported) 0 0000301A 3C03 cmp al,D_P_nval_String ;AN000; String choice list provided ? 0 0000301C 753F jne D_P_Sim01 ;AN000; if no, syntax error 1543 <1> 0 0000301E 47 inc di ;AN000; 0 0000301F 268A05 mov al,[es:di] ;AN000; al = nrng 0 00003022 B409 mov ah,D_P_Len_Range ;AN000; 0 00003024 F6E4 mul ah ;AN000; Skip nrng field 0 00003026 40 inc ax ;AN000; ax = (nrng*9)+1 0 00003027 01C7 add di,ax ;AN000; di points to nnval 0 00003029 268A05 mov al,[es:di] ;AN000; get nnval 0 0000302C B405 mov ah,D_P_Len_Value ;AN000; 0 0000302E F6E4 mul ah ;AN000; Skip nnval field 0 00003030 40 inc ax ;AN000; ax = (nnval*5)+1 0 00003031 01C7 add di,ax ;AN000; di points to nstrval 0 00003033 268A05 mov al,[es:di] ;AN000; get nstrval 0 00003036 47 inc di ;AC035; add '2' to 0 00003037 47 inc di ;AC035; DI reg 1558 <1> ;AN000; di points to 1st string in list 1559 <1> ;(replaced ;AC035;) add di,2 ;AN000; di points to 1st string in list 1560 <1> D_P_Sim_Loop: ;AN000; 0 00003038 268B2D mov bp,[es:di] ;AN000; get string pointer 0 0000303B E83200 call D_P_String_Comp ;AN000; compare it with operand 0 0000303E 7312 jnc D_P_Sim_Found ;AN000; found on list ? 1564 <1> 0 00003040 83C703 add di,D_P_Len_String ;AN000; if no, point to next choice 0 00003043 FEC8 dec al ;AN000; loop nstval times in AL 0 00003045 75F1 jne D_P_Sim_Loop ;AN000; 1568 <1> ;AN000; / Not found 0 00003047 2EC706[2B00]0800 mov word [psdata_seg:D_P_RC],D_P_Not_In_Str ;AC034; 0 0000304E B4FF mov ah,D_P_No_Tag ;AN000; No ITEM_TAG set 0 00003050 EB14 jmp short D_P_Sim_Exit ;AN000; 1572 <1> 1573 <1> D_P_Sim_Found: ;AN000; 0 00003052 268A65FF mov ah,[es:di-1] ;AN000; set item_tag 0 00003056 B002 mov al,D_P_List_Idx ;AN000; 0 00003058 268B15 mov dx,[es:di] ;AN000; get address of STRING 0 0000305B EB0B jmp short D_P_Sim_Exit0 ;AN000; 1578 <1> %ENDIF ;AN000;(of Val3SW+KeySW) 1579 <1> D_P_Sim01: ;AN000; 0 0000305D 2EC706[2B00]0900 mov word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; 0 00003064 B4FF mov ah,D_P_No_Tag ;AN000; No ITEM_TAG set 1582 <1> D_P_Sim_Exit: ;AN000; 0 00003066 B003 mov al,D_P_String ;AN000; Set type 1584 <1> D_P_Sim_Exit0: ;AN000; 0 00003068 E8A5FC call D_P_Fill_Result ;AN000; 0 0000306B 5F pop di ;AN000; 0 0000306C 5A pop dx ;AN000; 0 0000306D 5B pop bx ;AN000; 0 0000306E 58 pop ax ;AN000; 0 0000306F C3 ret ;AN000; 1591 <1> D_P_Simple_String endp ;AN000; 1592 <1> ;PAGE ;AN000; 1593 <1> ;*********************************************************************** 1594 <1> ; D_P_String_Comp: 1595 <1> ; 1596 <1> ; Function: Compare two string 1597 <1> ; 1598 <1> ; Input: psdata_seg:SI -> 1st string 1599 <1> ; ES:BP -> 2nd string (Must be upper case) 1600 <1> ; ES:BX -> CONTROL block 1601 <1> ; 1602 <1> ; Output: CY = 1 if not match 1603 <1> ; 1604 <1> ; Use: D_P_Chk_DBCS, D_P_Do_CAPS_Char 1605 <1> ; 1606 <1> ; Vars: D_P_KEYor_SW_Ptr(W), D_P_Flags(R). D_P_KEYorSW_Ptr 1607 <1> ;*********************************************************************** 1608 <1> D_P_String_Comp proc ;AN000; 0 00003070 50 push ax ;AN000; 0 00003071 55 push bp ;AN000; 0 00003072 52 push dx ;AN000; 0 00003073 56 push si ;AN000; 0 00003074 B202 mov dl,D_P_DOSTBL_Char ;AN000; use character case map table 1614 <1> D_P_SCOM_Loop: ;AN000; 0 00003076 2E8A04 mov al,[psdata_seg:si] ;AN000; get command character 0 00003079 E83C02 call D_P_Chk_DBCS ;AN000; DBCS ? 0 0000307C 723C jc D_P_SCOM00 ;AN000; yes,DBCS 1618 <1> 0 0000307E E80BFE call D_P_Do_CAPS_Char ;AN000; else, upper case map before comparison 1620 <1> %IF KeySW+SwSW ;AN000;(Check if keyword or switch is supported) 0 00003081 2EF606[3700]08 test byte [psdata_seg:D_P_Flags2],D_P_Key_Cmp ;AC034; keyword search ? 0 00003087 740D je D_P_SCOM04 ;AN000; 1623 <1> 0 00003089 3C3D cmp al,D_P_Keyword ;AN000; "=" is delimiter 0 0000308B 751F jne D_P_SCOM03 ;AN000;IF "=" on command line AND (bp+1=> char after the "=" in synonym list) 1626 <1> 0 0000308D 26807E0100 cmp byte ptr [es:bp+1],D_P_NULL ;AN021; at end of keyword string in the control block THEN 1628 <1> D_P_SCOM_DIFFER equ D_P_SCOM_Differ ; NASM port label 0 00003092 7571 jne D_P_SCOM_DIFFER ;AN021; 1630 <1> 0 00003094 EB13 jmp short D_P_SCOM05 ;AN000; keyword found in synonym list 1632 <1> 1633 <1> D_P_SCOM04: ;AN000; 0 00003096 2EF606[3700]10 test byte [psdata_seg:D_P_Flags2],D_P_SW_Cmp ;AC034; switch search ? 0 0000309C 740E je D_P_SCOM03 ;AN000; 1636 <1> 0 0000309E 3C3A cmp al,D_P_Colon ;AN000; ":" is delimiter, at end of switch on command line 0 000030A0 750A jne D_P_SCOM03 ;AN000; continue compares 1639 <1> 0 000030A2 26807E0000 cmp byte ptr [es:bp],D_P_NULL ;AN021; IF at end of switch on command AND 0 000030A7 755C jne D_P_SCOM_DIFFER ;AN021; at end of switch string in the control block THEN 1642 <1> 1643 <1> D_P_SCOM05: ;AN000; found a match 0 000030A9 46 inc si ;AN000; si points to just after "=" or ":" 0 000030AA EB5C jmp short D_P_SCOM_Same ;AN000; exit 1646 <1> 1647 <1> D_P_SCOM03: ;AN000; 1648 <1> %ENDIF ;AN000;(of KeySW+SwSW) 0 000030AC 263A4600 cmp al,[es:bp] ;AN000; compare operand w/ a synonym 0 000030B0 751D jne D_P_SCOM_Differ0 ;AN000; if different, check ignore colon option 1651 <1> 0 000030B2 08C0 or al,al ;AN000; end of line 0 000030B4 7452 je D_P_SCOM_Same ;AN000; if so, exit 1654 <1> 0 000030B6 46 inc si ;AN000; update operand pointer 0 000030B7 45 inc bp ;AN000; and synonym pointer 0 000030B8 EB13 jmp short D_P_SCOM01 ;AN000; loop until NULL or "=" or ":" found in case 1658 <1> 1659 <1> D_P_SCOM00: ;AN000; Here al is DBCS leading byte 0 000030BA 263A4600 cmp al,[es:bp] ;AN000; compare leading byte 0 000030BE 7545 jne D_P_SCOM_Differ ;AN000; if not match, say different 1662 <1> 0 000030C0 46 inc si ;AN000; else, load next byte 0 000030C1 2E8A04 mov al,[psdata_seg:si] ;AN000; and 0 000030C4 45 inc bp ;AN000; 0 000030C5 263A4600 cmp al,[es:bp] ;AN000; compare 2nd byte 0 000030C9 753A jne D_P_SCOM_Differ ;AN000; if not match, say different, too 1668 <1> 0 000030CB 46 inc si ;AN000; else update operand pointer 0 000030CC 45 inc bp ;AN000; and synonym pointer 1671 <1> D_P_SCOM01: ;AN000; 0 000030CD EBA7 jmp short D_P_SCOM_Loop ;AN000; loop until NULL or "=" or "/" found in case 1673 <1> 1674 <1> D_P_SCOM_Differ0: ;AN000; 1675 <1> 1676 <1> %IF SwSW ;AN000;(tm10) 0 000030CF 2EF606[3700]40 test byte [psdata_seg:D_P_Flags2],D_P_SW ;AC034;(tm10) 0 000030D5 740F je D_P_not_applicable ;AN000;(tm10) 1679 <1> 0 000030D7 26F747022000 test word [es:bx + D_P_Function_Flag],D_P_colon_is_not_necessary ;AN000;(tm10) 0 000030DD 7407 je D_P_not_applicable ;AN000;(tm10) 1682 <1> 0 000030DF 26807E0000 cmp byte ptr [es:bp],D_P_NULL ;AN000;(tm10) 1684 <1> ;(deleted ;AN025;) jne D_P_not_applicable ;AN000;(tm10) 0 000030E4 7422 je D_P_SCOM_Same ;AN025;(tm10) 1686 <1> 1687 <1> D_P_not_applicable: ;AN000;(tm10) 1688 <1> %ENDIF ;AN000;(tm10) 1689 <1> 0 000030E6 26F7071000 test word [es:bx + D_P_Match_Flag],D_P_Ig_Colon ;AN000; ignore colon option specified ? 0 000030EB 7418 je D_P_SCOM_Differ ;AN000; if no, say different. 1692 <1> 0 000030ED 3C3A cmp al,D_P_Colon ;AN000; End up with ":" and 0 000030EF 7509 jne D_P_SCOM02 ;AN000; subseqently 1695 <1> 0 000030F1 26807E0000 cmp byte ptr [es:bp],D_P_NULL ;AN000; NULL ? 0 000030F6 750D jne D_P_SCOM_Differ ;AN000; if no, say different 1698 <1> 0 000030F8 EB0E jmp short D_P_SCOM_Same ;AN000; else, say same 1700 <1> 1701 <1> D_P_SCOM02: ;AN000; 0 000030FA 3C00 cmp al,D_P_NULL ;AN000; end up NULL and : 0 000030FC 7507 jne D_P_SCOM_Differ ;AN000; 1704 <1> 0 000030FE 26807E003A cmp byte ptr [es:bp],D_P_Colon ;AN000; if no, say different 0 00003103 7403 je D_P_SCOM_Same ;AN000; else, say same 1707 <1> 1708 <1> D_P_SCOM_Differ: ;AN000; 0 00003105 F9 stc ;AN000; indicate not found 0 00003106 EB06 jmp short D_P_SCOM_Exit ;AN000; 1711 <1> 1712 <1> D_P_SCOM_Same: ;AN000; 0 00003108 2E8936[3A00] mov [psdata_seg:D_P_KEYorSW_Ptr],si ;AC034; for later use by keyword or switch 0 0000310D F8 clc ;AN000; indicate found 1715 <1> D_P_SCOM_Exit: ;AN000; 0 0000310E 5E pop si ;AN000; 0 0000310F 5A pop dx ;AN000; 0 00003110 5D pop bp ;AN000; 0 00003111 58 pop ax ;AN000; 0 00003112 C3 ret ;AN000; 1721 <1> D_P_String_Comp endp ;AN000; 1722 <1> ;PAGE ;AN000; 1723 <1> ;*********************************************************************** 1724 <1> %IF DateSW ;AN000;(Check if date format is supported) 1725 <1> ; D_P_Date_Format 1726 <1> ; 1727 <1> ; Function: Convert a date string to DOS date format for int 21h 1728 <1> ; with format validation. 1729 <1> ; 1730 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 1731 <1> ; ES:BX -> CONTROL block 1732 <1> ; 1733 <1> ; Output: None 1734 <1> ; 1735 <1> ; Use: D_P_Fill_Result, D_P_Set_CDI, D_P_Get_DecNum 1736 <1> ; 1737 <1> ; Vars: D_P_RC(W), D_P_1st_Val(RW), D_P_2nd_Val(RW), D_P_3rd_Val(RW) 1738 <1> ;*********************************************************************** 1739 <1> D_P_Date_Format proc ;AN000; 1740 <1> push ax ;AN000; 1741 <1> push cx ;AN000; 1742 <1> push dx ;AN000; 1743 <1> push si ;AN000; 1744 <1> push bx ;AN000; 1745 <1> push si ;AN000; 1746 <1> call D_P_Set_CDI ;AN000; set country dependent information before process 1747 <1> ; mov bl,[psdata_seg:si].D_P_CDI_DateS ;load date separator ;AN020; (deleted) 1748 <1> ; note: the country info is still needed 1749 <1> ; to determine the order of the fields, 1750 <1> ; but the separator char is no longer used. 1751 <1> pop si ;AN000; 1752 <1> mov word [psdata_seg:D_P_1st_Val],0 ;AC034; set initial value 1753 <1> mov word [psdata_seg:D_P_2nd_Val],0 ;AC034; set initial value 1754 <1> mov word [psdata_seg:D_P_3rd_Val],0 ;AC034; set initial value 1755 <1> call D_P_Get_DecNum ;AN000; get 1st number 1756 <1> jc D_P_DateF_Err0 ;AN000;-----------------------+ 1757 <1> 1758 <1> mov [psdata_seg:D_P_1st_Val],ax ;AC034; | 1759 <1> or bl,bl ;AN000; end of line ? | 1760 <1> je D_P_DateF_YMD ;AN000; | 1761 <1> 1762 <1> call D_P_Get_DecNum ;AN000; get 2nd number | 1763 <1> jc D_P_DateF_Error ;AN000; | 1764 <1> 1765 <1> mov [psdata_seg:D_P_2nd_Val],ax ;AC034; | 1766 <1> or bl,bl ;AN000; end of line ? | 1767 <1> je D_P_DateF_YMD ;AN000; | 1768 <1> 1769 <1> call D_P_Get_DecNum ;AN000; get 3rd number | 1770 <1> D_P_DateF_Err0: ;AN000; Bridge <-----------+ 1771 <1> jc D_P_DateF_Error ;AN000; 1772 <1> 1773 <1> mov [psdata_seg:D_P_3rd_Val],ax ;AC034; 1774 <1> or bl,bl ;AN000; end of line ? 1775 <1> jne D_P_DateF_Error ;AN000; 1776 <1> 1777 <1> D_P_DateF_YMD: ;AN000; 1778 <1> D_P_Country_Info equ D_P_COUNTRY_INFO ; NASM port label 1779 <1> mov bx,[psdata_seg:D_P_Country_Info + D_P_CDI_DateF] ;AC034; get date format 1780 <1> cmp bx,D_P_Date_YMD ;AN000; 1781 <1> je D_P_DateF00 ;AN000; 1782 <1> 1783 <1> mov ax,[psdata_seg:D_P_1st_Val] ;AC034; 1784 <1> or ah,ah ;AN000; 1785 <1> jne D_P_DateF_Error ;AN000; 1786 <1> 1787 <1> mov cl,al ;AN000; set month 1788 <1> mov ax,[psdata_seg:D_P_2nd_Val] ;AC034; 1789 <1> or ah,ah ;AN000; if overflow, error. 1790 <1> jne D_P_DateF_Error ;AN000; 1791 <1> 1792 <1> mov ch,al ;AN000; set date 1793 <1> mov dx,[psdata_seg:D_P_3rd_Val] ;AC034; set year 1794 <1> cmp bx,D_P_Date_DMY ;AN000; from here format = MDY 1795 <1> jne D_P_DateF01 ;AN000; if it is DMY 1796 <1> 1797 <1> xchg ch,cl ;AN000; then swap M <-> D 1798 <1> D_P_DateF01: ;AN000; 1799 <1> jmp short D_P_DateF02 ;AN000; 1800 <1> 1801 <1> D_P_DateF00: ;AN000; / here format = YMD 1802 <1> mov dx,[psdata_seg:D_P_1st_Val] ;AC034; set year 1803 <1> mov ax,[psdata_seg:D_P_2nd_Val] ;AC034; 1804 <1> or ah,ah ;AN000; if overflow, error 1805 <1> jne D_P_DateF_Error ;AN000; 1806 <1> 1807 <1> mov cl,al ;AN000; set month 1808 <1> mov ax,[psdata_seg:D_P_3rd_Val] ;AC034; 1809 <1> or ah,ah ;AN000; if overflow, error 1810 <1> jne D_P_DateF_Error ;AN000; 1811 <1> 1812 <1> mov ch,al ;AN000; set date 1813 <1> D_P_DateF02: ;AN000; 1814 <1> cmp dx,100 ;AN000; year is less that 100 ? 1815 <1> jae D_P_DateF03 ;AN000; 1816 <1> 1817 <1> add dx,1900 ;AN000; set year 19xx 1818 <1> D_P_DateF03: ;AN000; 1819 <1> pop bx ;AN000; recover CONTROL block 1820 <1> pop si ;AN000; recover string pointer 1821 <1> mov ah,D_P_No_Tag ;AN000; set 1822 <1> mov al,D_P_Date_F ;AN000; result 1823 <1> call D_P_Fill_Result ;AN000; buffer 1824 <1> jmp short D_P_Date_Format_Exit ;AN000; to Date 1825 <1> 1826 <1> D_P_DateF_Error: ;AN000; 1827 <1> pop bx ;AN000; recover CONTROL block 1828 <1> pop si ;AN000; recover string pointer 1829 <1> mov ah,D_P_No_Tag ;AN000; set 1830 <1> mov al,D_P_String ;AN000; result 1831 <1> call D_P_Fill_Result ;AN000; buffer to string 1832 <1> mov word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; indicate syntax error 1833 <1> D_P_Date_Format_Exit: ;AN000; 1834 <1> pop dx ;AN000; 1835 <1> pop cx ;AN000; 1836 <1> pop ax ;AN000; 1837 <1> ret ;AN000; 1838 <1> D_P_Date_Format endp ;AN000; 1839 <1> %ENDIF ;AN000;(of DateSW) 1840 <1> ;PAGE ;AN000; 1841 <1> ;*********************************************************************** 1842 <1> %IF TimeSW+DateSW ;AN000;(Check if time or date format is supported) 1843 <1> ; D_P_Set_CDI: 1844 <1> ; 1845 <1> ; Function: Read CDI from DOS if it has not been read yet 1846 <1> ; 1847 <1> ; Input: None 1848 <1> ; 1849 <1> ; Output: psdata_seg:SI -> CDI 1850 <1> ; 1851 <1> ; Use: INT 21h w/ AH = 38h 1852 <1> ;*********************************************************************** 1853 <1> D_P_Set_CDI proc ;AN000; 1854 <1> lea si,[D_P_Country_Info] ;AC034; 1855 <1> cmp word [psdata_seg:si + D_P_CDI_DateF],D_P_NeedToBeRead ;AN000; already read ? 1856 <1> je D_P_Read_CDI ;AN000; 1857 <1> 1858 <1> jmp short D_P_Set_CDI_Exit ;AN000; then do nothing 1859 <1> 1860 <1> D_P_Read_CDI: ;AN000; else read CDI thru DOS 1861 <1> push ds ;AN000; 1862 <1> push dx ;AN000; 1863 <1> push ax ;AN000; 1864 <1> push PSDATA_SEG ;AC023; 1865 <1> pop ds ;AN000; set segment register 1866 <1> mov ax,D_P_DOS_Get_CDI ;AN000; get country information 1867 <1> mov dx,si ;AN000; set offset of CDI in local data area 1868 <1> int 21h ;AN000; 1869 <1> pop ax ;AN000; 1870 <1> pop dx ;AN000; 1871 <1> pop ds ;AN000; 1872 <1> D_P_Set_CDI_Exit: ;AN000; 1873 <1> ret ;AN000; 1874 <1> D_P_Set_CDI endp ;AN000; 1875 <1> ;PAGE ;AN000; 1876 <1> ;*********************************************************************** 1877 <1> ; D_P_Get_DecNum: 1878 <1> ; 1879 <1> ; Function: Read a chcrater code from psdata_seg:SI until specified delimiter 1880 <1> ; or NULL encountered. And make a decimal number. 1881 <1> ; 1882 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 1883 <1> ; 1884 <1> ; Output: BL = delimiter code or NULL 1885 <1> ; AX = Decimal number 1886 <1> ; SI advanced to the next number 1887 <1> ; CY = 1 : Syntax error, AL = Latest examineed number 1888 <1> ; 1889 <1> ; Use: D_P_0099 1890 <1> ;*********************************************************************** 1891 <1> D_P_Get_DecNum proc ;AN000; 1892 <1> push cx ;AN000; 1893 <1> push dx ;AN000; 1894 <1> xor cx,cx ;AN000; cx will have final value 1895 <1> D_P_GetNum_Loop: ;AN000; 1896 <1> mov al,[psdata_seg:si] ;AN000; load character 1897 <1> or al,al ;AN000; end of line ? 1898 <1> je D_P_GetNum00 ;AN000; if yes, exit 1899 <1> 1900 <1> cmp byte [psdata_seg:D_P_Got_Time],0 ;AC034; ;is this numeric in a time field? ;AC023 1901 <1> je D_P_Do_Date_Delims ;AN000;no, go check out Date delimiters ;AC023 1902 <1> 1903 <1> ; Determine which delimiter(s) to check for. Colon & period or period only 1904 <1> cmp bl,D_P_colon_period ;AN032; ;Time 1905 <1> jne D_P_Do_Time_Delim1 ;AN032; ;only check for period 1906 <1> 1907 <1> cmp al,D_P_Colon ;AN032; ;Is this a valid delimiter ? 1908 <1> je D_P_GetNum01 ;AN032; ;yes, exit 1909 <1> 1910 <1> D_P_Do_Time_Delim1: ;AN000; 1911 <1> cmp al,D_P_Period ;;AC032;;AC023;Is this a valid delimiter ? 1912 <1> je D_P_GetNum01 ;AC023; yes, exit 1913 <1> 1914 <1> jmp short D_P_Neither_Delims ;AN023; 1915 <1> 1916 <1> D_P_Do_Date_Delims: ;AN000; 1917 <1> ;Regardless of the date delimiter character specified in the country 1918 <1> ;dependent information, check for the presence of any one of these 1919 <1> ;three field delimiters: "-", "/", or ".". 1920 <1> cmp al,D_P_Minus ;AN020;is this a date delimiter character? 1921 <1> je D_P_GetNum01 ;AN020;if yes, exit 1922 <1> 1923 <1> cmp al,D_P_Slash ;AN020;is this a date delimiter character? 1924 <1> je D_P_GetNum01 ;AN020;if yes, exit 1925 <1> 1926 <1> cmp al,D_P_Period ;AN020;is this a date delimiter character? 1927 <1> je D_P_GetNum01 ;AN000; if yes, exit 1928 <1> 1929 <1> D_P_Neither_Delims: ;AN023; 1930 <1> 1931 <1> call D_P_0099 ;AN000; convert it to binary 1932 <1> jc D_P_GetNum_Exit ;AN000; if error exit 1933 <1> 1934 <1> mov ah,0 ;AN000; 1935 <1> xchg ax,cx ;AN000; 1936 <1> mov dx,10 ;AN000; 1937 <1> mul dx ;AN000; ax = ax * 10 1938 <1> or dx,dx ;AN000; overflow 1939 <1> jne D_P_GetNum02 ;AN000; then exit 1940 <1> 1941 <1> add ax,cx ;AN000; 1942 <1> jc D_P_GetNum_Exit ;AN000; 1943 <1> 1944 <1> xchg ax,cx ;AN000; 1945 <1> inc si ;AN000; 1946 <1> jmp short D_P_GetNum_Loop ;AN000; 1947 <1> 1948 <1> D_P_GetNum00: ;AN000; 1949 <1> mov bl,al ;AN000; set bl to NULL 1950 <1> clc ;AN000; indicate no error 1951 <1> jmp short D_P_GetNum_Exit ;AN000; 1952 <1> 1953 <1> D_P_GetNum01: ;AN000; 1954 <1> inc si ;AN000; si points to next number 1955 <1> clc ;AN000; indicate no error 1956 <1> jmp short D_P_GetNum_Exit ;AN000; 1957 <1> 1958 <1> D_P_GetNum02: ;AN000; 1959 <1> stc ;AN000; indicate error 1960 <1> D_P_GetNum_Exit: ;AN000; 1961 <1> mov ax,cx ;AN000;return value 1962 <1> pop dx ;AN000; 1963 <1> pop cx ;AN000; 1964 <1> ret ;AN000; 1965 <1> D_P_Get_DecNum endp ;AN000; 1966 <1> %ENDIF ;AN000;(of TimeSW+DateSW) 1967 <1> ;PAGE ;AN000; 1968 <1> ;*********************************************************************** 1969 <1> %IF TimeSW ;AN000;(Check if time format is supported) 1970 <1> ; D_P_Time_Format 1971 <1> ; 1972 <1> ; Function: Convert a time string to DOS time format for int 21h 1973 <1> ; with format validation. 1974 <1> ; 1975 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 1976 <1> ; ES:BX -> CONTROL block 1977 <1> ; 1978 <1> ; Output: None 1979 <1> ; 1980 <1> ; Use: D_P_Fill_Result, D_P_Set_CDI, D_P_Get_DecNum, D_P_Time_2412 1981 <1> ; 1982 <1> ; Vars: D_P_RC(W), D_P_Flags(R), D_P_1st_Val(RW), D_P_2nd_Val(RW) 1983 <1> ; D_P_3rd_Val(RW), D_P_4th_Val(RW) 1984 <1> ;*********************************************************************** 1985 <1> D_P_Time_Format proc ;AN000; 1986 <1> push ax ;AN000; 1987 <1> push cx ;AN000; 1988 <1> push dx ;AN000; 1989 <1> push si ;AN000; 1990 <1> push bx ;AN000; 1991 <1> push si ;AN000; 1992 <1> call D_P_Set_CDI ;AN000; Set country independent 1993 <1> ; information before process 1994 <1> ;(AN032; deleted) mov bl,[psdata_seg:si].D_P_CDI_TimeS ;load time separator 1995 <1> ;(AN032; deleted) mov bh,[psdata_seg:si].D_P_CDI_Dec ;load decimal separator 1996 <1> test byte ptr [psdata_seg:si + D_P_CDI_TimeF],1 ;AN000; 24 hour system 1997 <1> pop si ;AN000; 1998 <1> jne D_P_TimeF00 ;AN000; if no, means 12 hour system 1999 <1> 2000 <1> call D_P_Time_2412 ;AN000; this routine handle "am" "pm" 2001 <1> D_P_TimeF00: ;AN000; 2002 <1> mov word [psdata_seg:D_P_1st_Val],0 ;AC034; set initial value 2003 <1> mov word [psdata_seg:D_P_2nd_Val],0 ;AC034; set initial value 2004 <1> mov word [psdata_seg:D_P_3rd_Val],0 ;AC034; set initial value 2005 <1> mov word [psdata_seg:D_P_4th_Val],0 ;AC034; set initial value 2006 <1> mov byte [psdata_seg:D_P_Got_Time],1 ;AN023;AC034;; use time delimiter 2007 <1> mov bl,D_P_colon_period ;AN032; flag, indicates use of 2008 <1> ; delimiters between hours, 2009 <1> ; minutes,seconds 2010 <1> call D_P_Get_DecNum ;AN000; get 1st number 2011 <1> jc D_P_TimeF_Err0 ;AN000; 2012 <1> 2013 <1> mov [psdata_seg:D_P_1st_Val],ax ;AC034; 2014 <1> or bl,bl ;AN000; end of line ? 2015 <1> D_P_TimeF_Rlt equ D_P_TimeF_RLT ; NASM port label 2016 <1> je D_P_TimeF_Rlt ;AN000; 2017 <1> 2018 <1> call D_P_Get_DecNum ;AN000; get 2nd number 2019 <1> jc D_P_TimeF_Err0 ;AC038; if OK 2020 <1> 2021 <1> mov [psdata_seg:D_P_2nd_Val],ax ;AC034; 2022 <1> or bl,bl ;AN000; end of line ? 2023 <1> je D_P_TimeF_Rlt ;AN000; 2024 <1> 2025 <1> ;(;AN032; deleted) mov bl,bh ;set decimal separator 2026 <1> mov bl,D_P_period_only ;AN032; flag, which to decimal separator 2027 <1> call D_P_Get_DecNum ;AN000; get 3rd number 2028 <1> jc D_P_TimeF_Err0 ;AC039; if problem, bridge to error 2029 <1> 2030 <1> mov [psdata_seg:D_P_3rd_Val],ax ;AC034; 2031 <1> or bl,bl ;AN000; end of line ? 2032 <1> ;(DELETED ;AN039;) je D_P_TimeF_Rlt ;AN000; 2033 <1> jne D_P_Time_4 ;AN039; NOT END OF LINE, 2034 <1> ;AN039; GO TO 4TH NUMBER 2035 <1> D_P_Time_Again equ D_P_TIME_AGAIN ; NASM port equate 2036 <1> test byte [psdata_seg:D_P_Flags1],D_P_Time_Again ;AN039; HAS TIME PARSE 2037 <1> ;AN039; BEEN REPEATED? 2038 <1> jnz D_P_TimeF_Rlt ;AN039; yes, this is really 2039 <1> ;AN039; the end of line 2040 <1> ;AN039; no, time has not been repeated 2041 <1> mov si,[psdata_seg:D_P_SI_Save] ;AN039; get where parser quit 2042 <1> ;AN039; in command line 2043 <1> cmp byte ptr [si-1],D_P_Comma ;AN039; look at delimiter 2044 <1> ;AN039; from command line 2045 <1> jne D_P_TimeF_Rlt ;AN039; was not a comma, this is 2046 <1> ;AN039; really end of line 2047 <1> ;AN039; is comma before hundredths, 2048 <1> ;AN039; redo TIME 2049 <1> mov byte ptr [si-1],D_P_Period ;AN039; change that ambiguous 2050 <1> ;AN039; comma to a decimal point 2051 <1> ;AN039; parse can understand 2052 <1> mov word [psdata_seg:D_P_Flags],0 ;AN039; Clear all internal flags 2053 <1> or byte [psdata_seg:D_P_Flags1],D_P_Time_Again ;AN039; indicate TIME 2054 <1> ;AN039; is being repeated 2055 <1> mov cx,[psdata_seg:D_P_ORIG_ORD] ;AN039; ORIGINAL ORDINAL FROM CX 2056 <1> mov sp,[psdata_seg:D_P_ORIG_STACK] ;AN039; ORIGINAL VALUE 2057 <1> ;AN039; OF STACK FROM SP 2058 <1> mov si,[psdata_seg:D_P_ORIG_SI] ;AN039; ORIGINAL START 2059 <1> ;AN039; PARSE POINTER FROM SI 2060 <1> D_P_Redo_Time equ D_P_REDO_TIME ; NASM port label 2061 <1> jmp D_P_Redo_Time ;AN039; go try TIME again 2062 <1> ; =============================================================== 2063 <1> D_P_Time_4: ;AN039; READY FOR 4TH (HUNDREDTHS) NUMBER 2064 <1> call D_P_Get_DecNum ;AN000; get 4th number 2065 <1> D_P_TimeF_Err0: ;AN000; Bridge 2066 <1> jc D_P_TimeF_Error ;AN000; 2067 <1> 2068 <1> mov [psdata_seg:D_P_4th_Val],ax ;AC034; 2069 <1> or bl,bl ;AN000; After hundredth, no data allowed 2070 <1> jne D_P_TimeF_Error ;AN000; if some, then error 2071 <1> 2072 <1> D_P_TimeF_RLT: ;AN000; 2073 <1> mov ax,[psdata_seg:D_P_1st_Val] ;AC034; 2074 <1> or ah,ah ;AN000; if overflow then error 2075 <1> jne D_P_TimeF_Err ;AN000; 2076 <1> 2077 <1> D_P_Time12am equ D_P_time12am ; NASM port equate 2078 <1> test byte [psdata_seg:D_P_Flags1],D_P_Time12am ;AN038;if "am" specified 2079 <1> jz D_P_Time_notAM ;AN038;skip if no "AM" specified 2080 <1> ;since "AM" was specified, 2081 <1> cmp al,12 ;AN038: if hour specified as later than noon 2082 <1> ja D_P_TimeF_Err ;AN038; error if "AM" on more than noon 2083 <1> jne D_P_Time_notAM ;AN038; for noon exactly, 2084 <1> 2085 <1> xor al,al ;AN038; set hour = zero 2086 <1> D_P_Time_notAM: ;AN038; 2087 <1> test byte [psdata_seg:D_P_Flags2],D_P_Time12 ;AC034; if 12 hour system and pm is specified 2088 <1> je D_P_TimeSkip00 ;AN000; then 2089 <1> 2090 <1> cmp al,12 ;AN038; if 12:00 o'clock already 2091 <1> je D_P_TimeSkip00 ;AN038; it is PM already 2092 <1> 2093 <1> add al,12 ;AN000; add 12 hours to make it afternoon 2094 <1> jc D_P_TimeF_Err ;AN000; if overflow then error 2095 <1> 2096 <1> cmp al,24 ;AN038; after adding 12, now cannot be >24 2097 <1> ja D_P_TimeF_Err ;AN038; if too big, error 2098 <1> 2099 <1> D_P_TimeSkip00: ;AN000; 2100 <1> mov dl,al ;AN000; set hour 2101 <1> mov ax,[psdata_seg:D_P_2nd_Val] ;AC034; 2102 <1> or ah,ah ;AN000; if overflow then error 2103 <1> jne D_P_TimeF_Err ;AN000; 2104 <1> 2105 <1> mov dh,al ;AN000; set minute 2106 <1> mov ax,[psdata_seg:D_P_3rd_Val] ;AC034; 2107 <1> or ah,ah ;AN000; if overflow then error 2108 <1> jne D_P_TimeF_Err ;AN000; 2109 <1> 2110 <1> mov cl,al ;AN000; set second 2111 <1> mov ax,[psdata_seg:D_P_4th_Val] ;AC034; 2112 <1> or ah,ah ;AN000; if overflow then error 2113 <1> jne D_P_TimeF_Err ;AN000; 2114 <1> 2115 <1> mov ch,al ;AN000; set hundredth 2116 <1> pop bx ;AN000; recover CONTROL block 2117 <1> pop si ;AN000; recover string pointer 2118 <1> mov ah,D_P_No_Tag ;AN000; set 2119 <1> mov al,D_P_Time_F ;AN000; result 2120 <1> call D_P_Fill_Result ;AN000; buffer 2121 <1> jmp short D_P_Time_Format_Exit ;AN000; to time 2122 <1> 2123 <1> D_P_TimeF_Error: ;AN000; 2124 <1> D_P_TimeF_Err: ;AN000; 2125 <1> pop bx ;AN000; recover CONTROL block 2126 <1> pop si ;AN000; recover string pointer 2127 <1> mov ah,D_P_No_Tag ;AN000; set 2128 <1> mov al,D_P_String ;AN000; result 2129 <1> call D_P_Fill_Result ;AN000; buffer to string 2130 <1> mov word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; return syntax error 2131 <1> D_P_Time_Format_Exit: ;AN000; 2132 <1> mov byte [psdata_seg:D_P_Got_Time],0 ;AN023;AC034;; finished with this time field 2133 <1> pop dx ;AN000; 2134 <1> pop cx ;AN000; 2135 <1> pop ax ;AN000; 2136 <1> ret ;AN000; 2137 <1> D_P_Time_Format endp ;AN000; 2138 <1> ;PAGE ;AN000; 2139 <1> ;*********************************************************************** 2140 <1> ; D_P_Time_2412: 2141 <1> ; 2142 <1> ; Function: Remove "a", "p", "am", or "pm" from the end of stinrg 2143 <1> ; 2144 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 2145 <1> ; 2146 <1> ; Output: Set D_P_Time12 flag when the string is terminated by "p" 2147 <1> ; or "pm" 2148 <1> ; 2149 <1> ; Vars: D_P_Flags(W) 2150 <1> ;*********************************************************************** 2151 <1> D_P_Time_2412 proc ;AN000; 2152 <1> push ax ;AN000; 2153 <1> push si ;AN000; 2154 <1> D_P_T12_Loop: ;AN000; 2155 <1> mov al,[psdata_seg:si] ;AN000; Move 2156 <1> inc si ;AN000; si 2157 <1> or al,al ;AN000; to 2158 <1> jne D_P_T12_Loop ;AN000; end of string 2159 <1> 2160 <1> mov al,[psdata_seg:si-2] ;AN000; get char just before NULL 2161 <1> or al,D_P_Make_Lower ;AN000; lower case map 2162 <1> cmp al,"p" ;AN000; only "p" of "pm" ? 2163 <1> je D_P_T1200 ;AN000; 2164 <1> 2165 <1> cmp al,"a" ;AN000; only "a" of "am" ? 2166 <1> je D_P_T1201 ;AN000; 2167 <1> 2168 <1> cmp al,"m" ;AN000; "m" of "am" or "pm" 2169 <1> jne D_P_T12_Exit ;AN000; 2170 <1> 2171 <1> dec si ;AN000; 2172 <1> mov al,[psdata_seg:si-2] ;AN000; 2173 <1> D_P_Make_lower equ D_P_Make_Lower ; NASM port equate 2174 <1> or al,D_P_Make_lower ;AN000; lower case map 2175 <1> cmp al,"p" ;AN000; "p" of "pm" ? 2176 <1> je D_P_T1200 ;AN000; 2177 <1> 2178 <1> cmp al,"a" ;AN000; "a" of "am" ? 2179 <1> je D_P_T1201 ;AN000; go process "a" 2180 <1> 2181 <1> jmp short D_P_T12_Exit ;AN000; no special chars found 2182 <1> 2183 <1> D_P_T1200: ;AN000; "P" found 2184 <1> or byte [psdata_seg:D_P_Flags2],D_P_Time12 ;AC034; flag "PM" found 2185 <1> jmp short D_P_Tclr_chr ;AN038; go clear the special char 2186 <1> 2187 <1> D_P_T1201: ;AN000; "A" found 2188 <1> D_P_Time12AM equ D_P_time12am ; NASM port equate 2189 <1> or byte [psdata_seg:D_P_Flags1],D_P_Time12AM ;AN038; flag "AM" found 2190 <1> D_P_Tclr_chr: ;AN038; 2191 <1> mov byte ptr [psdata_seg:si-2],D_P_NULL ;AN000; null out special char 2192 <1> D_P_T12_Exit: ;AN000; 2193 <1> pop si ;AN000; 2194 <1> pop ax ;AN000; 2195 <1> ret ;AN000; 2196 <1> D_P_Time_2412 endp ;AN000; 2197 <1> %ENDIF ;AN000;(of TimeSW) 2198 <1> ;PAGE ;AN000; 2199 <1> ;*********************************************************************** 2200 <1> %IF CmpxSW ;AN000;(Check if complex item is supported) 2201 <1> ; D_P_Complex_Format: 2202 <1> ; 2203 <1> ; Function: Check if the input string is valid complex format. 2204 <1> ; And set the result buffer. 2205 <1> ; 2206 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 2207 <1> ; ES:BX -> CONTROL block 2208 <1> ; 2209 <1> ; Output: None 2210 <1> ; 2211 <1> ; Use: D_P_Fill_Result, D_P_Chk_DBCS, D_P_Chk_EOL, D_P_Skip_Delim 2212 <1> ; D_P_Quoted_str, D_P_Chk_DSQuote 2213 <1> ; 2214 <1> ; Vars: D_P_RC(W), D_P_SI_Save(W), D_P_SaveSI_Cmpx(R), D_P_Save_EOB(R) 2215 <1> ;*********************************************************************** 2216 <1> D_P_Complex_Format proc ;AN000; 2217 <1> push ax ;AN000; 2218 <1> push bx ;AN000; 2219 <1> push si ;AN000; 2220 <1> mov bx,[psdata_seg:D_P_SaveSI_Cmpx] ;AC034; bx points to user buffer 2221 <1> cmp byte ptr [bx],D_P_Lparen ;AN000; 1st char = left parentheses 2222 <1> jne D_P_Cmpx_Err ;AN000; 2223 <1> 2224 <1> xor ah,ah ;AN000; ah = parentheses counter 2225 <1> D_P_Cmpx_Loop: ;AN000; 2226 <1> mov al,[bx] ;AN000; load character from command buffer 2227 <1> call D_P_Chk_EOL ;AN000; if it is one of EOL 2228 <1> je D_P_CmpxErr0 ;AN000; then error exit. 2229 <1> 2230 <1> cmp al,D_P_Lparen ;AN000; left parentheses ? 2231 <1> jne D_P_Cmpx00 ;AN000; then 2232 <1> 2233 <1> inc ah ;AC035; add '1' to AH reg 2234 <1> ;AN000; increment parentheses counter 2235 <1> ;(replaced ;AC035;) add ah,1 ;AN000; increment parentheses counter 2236 <1> jc D_P_CmpxErr0 ;AN000; if overflow, error 2237 <1> D_P_Cmpx00: ;AN000; 2238 <1> cmp al,D_P_Rparen ;AN000; right parentheses ? 2239 <1> jne D_P_Cmpx01 ;AN000; then 2240 <1> 2241 <1> dec ah ;AC035; subtract '1' from AH reg 2242 <1> ;AN000; decrement parentheses counter 2243 <1> ;(changed ;AC035;) sub ah,1 ;AN000; decrement parentheses counter 2244 <1> jc D_P_CmpxErr0 ;AN000; if overflow error 2245 <1> 2246 <1> je D_P_Cmpx03 ;AN000; ok, valid complex 2247 <1> 2248 <1> D_P_Cmpx01: ;AN000; 2249 <1> ;(deleted ;AN025;) call D_P_Chk_DSQuote ;AN000; double or single quotation mark ? 3/17/KK 2250 <1> cmp al,D_P_DQuote ;AN025; double quotation mark? 2251 <1> jne D_P_Cmpx04 ;AN000; 3/17/KK 2252 <1> 2253 <1> mov [psdata_seg:si],al ;AN000; here quoted string is found in the complex list. 2254 <1> inc si ;AN000; 2255 <1> inc bx ;AN000; bx points to 2nd character 2256 <1> call D_P_Quoted_Str ;AN000; skip pointers until closing of quoted string 2257 <1> jc D_P_CmpxErr0 ;AN000; if error in quoted string syntax then exit 2258 <1> 2259 <1> jmp short D_P_Cmpx05 ;AN000; 2260 <1> 2261 <1> D_P_Cmpx04: ;AN000; 2262 <1> call D_P_Chk_DBCS ;AN000; was it a lead byte of DBCS ? 2263 <1> jnc D_P_Cmpx02 ;AN000; 2264 <1> 2265 <1> mov [psdata_seg:si],al ;AN000; then store 1st byte 2266 <1> inc si ;AN000; 2267 <1> inc bx ;AN000; 2268 <1> mov al,[bx] ;AN000; load 2nd byte 2269 <1> D_P_Cmpx02: ;AN000; 2270 <1> mov [psdata_seg:si],al ;AN000; store SBCS or 2nd byte of DBCS 2271 <1> D_P_Cmpx05: ;AN000; 2272 <1> inc si ;AN000; 2273 <1> inc bx ;AN000; 2274 <1> jmp short D_P_Cmpx_Loop ;AN000; loop 2275 <1> ;---- ;AN000; 2276 <1> D_P_Cmpx03: ;AN000; 2277 <1> mov byte ptr [psdata_seg:si],al ;AN000; 2278 <1> mov byte ptr [psdata_seg:si+1],D_P_NULL ;AN000; 2279 <1> mov byte ptr [bx],D_P_NULL ;AN000; replace right parentheses with NULL 2280 <1> mov si,bx ;AN000; skip whitespaces 2281 <1> inc si ;AN000; after 2282 <1> call D_P_Skip_Delim ;AN000; right parentheses 2283 <1> mov [psdata_seg:D_P_SI_Save],si ;AC034; save next pointer, SI 2284 <1> jmp short D_P_Cmpx_Exit ;AN000; 2285 <1> 2286 <1> D_P_CmpxErr0: ;AN000; 2287 <1> mov si,[psdata_seg:D_P_Save_EOB] ;AC034; if EOF encountered, restore 2288 <1> mov byte ptr [psdata_seg:si],D_P_NULL ;AN000; EOB mark 2289 <1> D_P_Cmpx_Err: ;AN000; 2290 <1> mov word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; 2291 <1> D_P_Cmpx_Exit: ;AN000; 2292 <1> mov ah,D_P_No_Tag ;AN000; 2293 <1> mov al,D_P_Complex ;AN000; 2294 <1> pop si ;AN000; 2295 <1> pop bx ;AN000; 2296 <1> call D_P_Fill_Result ;AN000; 2297 <1> pop ax ;AN000; 2298 <1> ret ;AN000; 2299 <1> D_P_Complex_Format endp ;AN000; 2300 <1> %ENDIF ;AN000;(of CpmxSW) 2301 <1> ;PAGE ;AN000; 2302 <1> ;*********************************************************************** 2303 <1> %IF QusSW ;AN000;(Check if quoted string is supported) 2304 <1> ; D_P_Quoted_Format: 2305 <1> ; 2306 <1> ; Function: Check if the input string is valid quoted string format. 2307 <1> ; And set the result buffer. 2308 <1> ; 2309 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 2310 <1> ; ES:BX -> CONTROL block 2311 <1> ; 2312 <1> ; Output: None 2313 <1> ; 2314 <1> ; Use: D_P_Fill_Result, D_P_Chk_DBCS, D_P_Chk_EOL, D_P_Skip_Delim 2315 <1> ; D_P_Chk_DSQuote, D_P_Quoted_Str 2316 <1> ; 2317 <1> ; Vars: D_P_RC(W), D_P_SI_Save(W), D_P_SaveSI_Cmpx(R),D_P_Save_EOB(R) 2318 <1> ;*********************************************************************** 2319 <1> D_P_Quoted_Format proc ;AN000; 2320 <1> push ax ;AN000; 2321 <1> push bx ;AN000; 2322 <1> push si ;AN000; 2323 <1> mov bx,[psdata_seg:D_P_SaveSI_Cmpx] ;AC034; bx points to user buffer 2324 <1> mov al,byte ptr [bx] ;AN000; get 1st character 2325 <1> ;(deleted ;AN025;) call D_P_Chk_DSQuote ;AN000; is it single or double quote ? 2326 <1> cmp al,D_P_DQuote ;AN025; double quotation mark? 2327 <1> jne D_P_Qus_Err ;AN000; if no, error 2328 <1> 2329 <1> ; mov [psdata_seg:si],al ;AN000; move it to internal buffer 2330 <1> ; inc si ;AN000; 2331 <1> inc bx ;AN000; bx points to 2nd character 2332 <1> call D_P_Quoted_Str ;AN000; skip pointers to the closing of quoted string 2333 <1> jc D_P_Qus_Err0 ;AN000; if invali quoted string syntax, exit 2334 <1> 2335 <1> mov byte ptr [psdata_seg:si+1],D_P_NULL ;AN000; end up with NULL 2336 <1> mov si,bx ;AN000; 2337 <1> inc si ;AN000; 2338 <1> call D_P_Skip_Delim ;AN000; skip whitespaces after closing quote 2339 <1> mov [psdata_seg:D_P_SI_Save],si ;AC034; save next pointer, SI 2340 <1> jmp short D_P_Qus_Exit ;AN000; 2341 <1> 2342 <1> D_P_Qus_Err0: ;AN000; 2343 <1> mov si,[psdata_seg:D_P_Save_EOB] ;AC034; if EOF encountered, restore 2344 <1> mov byte ptr [psdata_seg:si],D_P_NULL ;AN000; EOB mark 2345 <1> D_P_Qus_Err: ;AN000;AN000 2346 <1> mov word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; indicate syntax error 2347 <1> D_P_Qus_Exit: ;AN000; 2348 <1> mov ah,D_P_No_Tag ;AN000; set 2349 <1> mov al,D_P_Quoted_String ;AN000; result 2350 <1> pop si ;AN000; buffer 2351 <1> pop bx ;AN000; to 2352 <1> call D_P_Fill_Result ;AN000; quoted string 2353 <1> pop ax ;AN000; 2354 <1> ret ;AN000; 2355 <1> D_P_Quoted_Format endp ;AN000; 2356 <1> %ENDIF ;AN000;(of QusSW) 2357 <1> ;PAGE ;AN000; 2358 <1> ;*********************************************************************** 2359 <1> ; D_P_Chk_DSQuote; 2360 <1> ; 2361 <1> ; Function: Check if AL is double quotation or single quotation 2362 <1> ; 2363 <1> ; Input: AL = byte to be examineed 2364 <1> ; 2365 <1> ; Output: ZF on if AL is single or double quotetaion 2366 <1> ; 2367 <1> ; Vars: D_P_SorD_Quote(W) 2368 <1> ;*********************************************************************** 2369 <1> %IF QusSW+CmpxSW ;AN000;(Check if quoted string or complex item is supported) 2370 <1> ;(deleted ;AN025;) D_P_Chk_DSQuote proc ; 2371 <1> ;(deleted ;AN025;) mov D_P_SorD_Quote,D_P_SQuote ; 3/17/87 assume single quote 2372 <1> ;(deleted ;AN025;) cmp al,D_P_DQuote ; 1st char = double quotation ? 2373 <1> ;(deleted ;AN025;) jne D_P_CDSQ00 ; 3/17/87 2374 <1> ;(deleted ;AN025;) mov D_P_SorD_Quote,al ; 3/17/87 set bigning w/ double quote 2375 <1> ;(deleted ;AN025;) ret ; 3/17/87 2376 <1> ;(deleted ;AN025;) D_P_CDSQ00: ; 3/17/87 2377 <1> ;(deleted ;AN025;) cmp al,D_P_SQuote ; 1st char = single quotation ? 2378 <1> ;(deleted ;AN025;) ret ; 2379 <1> ;(deleted ;AN025;) D_P_Chk_DSQuote endp ; 2380 <1> ; PAGE ;AN000; 2381 <1> ;*********************************************************************** 2382 <1> ; D_P_Quoted_Str: 2383 <1> ; 2384 <1> ; Function: Copy chracacter from ES:BX to psdata_seg:SI until closing single 2385 <1> ; (double) quotation found. 2386 <1> ; 2387 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 2388 <1> ; ES:BX -> Operand in command buffer 2389 <1> ; 2390 <1> ; Output: CY on indicates EOF encounterd before closing quotation 2391 <1> ; BX and SI 2392 <1> ; 2393 <1> ; 2394 <1> ; Vars: D_P_SorD_Quote(R) 2395 <1> ;*********************************************************************** 2396 <1> D_P_Quoted_Str proc ;AN000; 2397 <1> push ax ;AN000; 2398 <1> D_P_Qus_Loop: ;AN000; 2399 <1> mov ax,[bx] ;AN000; 3/17/87 2400 <1> call D_P_Chk_EOL ;AN000; 2401 <1> je D_P_Qustr_Err0 ;AN000; 2402 <1> 2403 <1> ;(deleted ;AN025;) cmp al,D_P_SorD_Quote ;AN000; quotation ? 3/17/87 2404 <1> cmp al,D_P_DQuote ;AN025; double quote? 2405 <1> jne D_P_Qus00 ;AN000; 2406 <1> 2407 <1> ;(deleted ;AN025;) cmp ah,D_P_SorD_Quote ;AN000; contiguous quotation 3/17/87 2408 <1> cmp ah,D_P_DQuote ;AN025; double quote? 2409 <1> jne D_P_Qus02 ;AN000; 2410 <1> 2411 <1> ;(deleted ;AN025:) mov word ptr [psdata_seg:si],ax ;AN000; 3/17/87 2412 <1> mov byte ptr [psdata_seg:si],al ;AN025; save one of the quotes 2413 <1> ;(deleted ;AN025:) add si,2 ;AN000; 2414 <1> 2415 <1> inc si ;AC035; add '1' to SI reg 2416 <1> ;AN025; adjust target index 2417 <1> ;(changed ;AC035;) add si,1 ;AN025; adjust target index 2418 <1> inc bx ;AC035; add '2' to 2419 <1> inc bx ;AC035; BX reg 2420 <1> ;AN000; adjust source index by 2 to skip extra quote 2421 <1> ;(changed ;AC035;) add bx,2 ;AN000; adjust source index by 2 to skip extra quote 2422 <1> jmp short D_P_Qus_Loop ;AN000; 2423 <1> 2424 <1> D_P_Qus00: ;AN000; 2425 <1> call D_P_Chk_DBCS ;AN000; was it a lead byte of DBCS ? 2426 <1> jnc D_P_Qus01 ;AN000; 2427 <1> 2428 <1> mov [psdata_seg:si],al ;AN000; store 1st byte 2429 <1> inc si ;AN000; 2430 <1> inc bx ;AN000; 2431 <1> mov al,[bx] ;AN000; load 2nd byte 2432 <1> D_P_Qus01: ;AN000; 2433 <1> mov [psdata_seg:si],al ;AN000; store SBCS or 2nd byte of DBCS 2434 <1> inc si ;AN000; 2435 <1> inc bx ;AN000; 2436 <1> jmp short D_P_Qus_Loop ;AN000; 2437 <1> 2438 <1> D_P_Qustr_Err0: ;AN000; 2439 <1> stc ;AN000; indicate error 2440 <1> jmp short D_P_Quoted_Str_Exit ;AN000; 2441 <1> 2442 <1> D_P_Qus02: ;AN000; 2443 <1> mov byte ptr [psdata_seg:si],0 ;AN000; 2444 <1> clc ;AN000; indicate no error 2445 <1> D_P_Quoted_Str_Exit: ;AN000; 2446 <1> pop ax ;AN000; 2447 <1> ret ;AN000; 2448 <1> D_P_Quoted_Str endp ;AN000; 2449 <1> %ENDIF ;AN000;(of QusSW+CmpxSW) 2450 <1> ;PAGE ;AN000; 2451 <1> ;*********************************************************************** 2452 <1> %IF FileSW+DrvSW ;AN000;(Check if file spec or drive only is supported) 2453 <1> ; D_P_File_Format; 2454 <1> ; 2455 <1> ; Function: Check if the input string is valid file spec format. 2456 <1> ; And set the result buffer. 2457 <1> ; 2458 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 2459 <1> ; ES:BX -> CONTROL block 2460 <1> ; 2461 <1> ; Output: None 2462 <1> ; 2463 <1> ; Use: D_P_Fill_Result, D_P_Chk_DBCS, D_P_FileSp_Chk 2464 <1> ; 2465 <1> ; Vars: D_P_RC(W), D_P_SI_Save(W), D_P_Terminator(W), D_P_SaveSI_Cmpx(R) 2466 <1> ; D_P_SaveSI_Cmpx(R) 2467 <1> ;*********************************************************************** 2468 <1> D_P_File_Format proc ;AN000; 0 00003113 50 push ax ;AN000; 0 00003114 57 push di ;AN000; 0 00003115 56 push si ;AN000; 2472 <1> D_P_SaveSI_cmpx equ D_P_SaveSI_Cmpx ; NASM port label 0 00003116 2E8B3E[3800] mov di,[psdata_seg:D_P_SaveSI_cmpx] ;AC034; get user buffer address 2474 <1> D_P_FileF_Loop0: ;AN000; / skip special characters 0 0000311B 2E8A04 mov al,[psdata_seg:si] ;AN000; load character 0 0000311E 08C0 or al,al ;AN000; end of line ? 0 00003120 7413 je D_P_FileF_Err ;AN000; if yes, error exit 2478 <1> 0 00003122 E85F00 call D_P_FileSp_Chk ;AN000; else, check if file special character 0 00003125 7524 jne D_P_FileF03 ;AN000; if yes, 2481 <1> 2482 <1> ;AN033; deleted inc di ;skip 2483 <1> ;AN033; deleted inc si ; the 2484 <1> ;AN033; deleted jmp short D_P_FileF_Loop0 ; character 0 00003127 2EC606[CE00]01 mov byte [psdata_seg:D_P_err_flag],D_P_error_filespec ;AN033;AC034;; set error flag- bad char. 0 0000312D 5E pop si ;AN033; 0 0000312E 2EC60400 mov byte ptr [psdata_seg:si],D_P_NULL ;AN033; 0 00003132 5F pop di ;AN033; 0 00003133 EB3F jmp short D_P_FileF02 ;AN033; 2490 <1> 2491 <1> 2492 <1> D_P_FileF_Err: ;AN000; 0 00003135 5E pop si ;AN000; 0 00003136 2EC60400 mov byte ptr [psdata_seg:si],D_P_NULL ;AN000; 2495 <1> ;(deleted ;AN030;) mov di,D_P_SaveSI_cmpx ;AN000; get user buffer address 2496 <1> ;(deleted ;AN030;) mov D_P_SI_Save,di ;AN000; update pointer to user buffer 0 0000313A 5F pop di ;AN000; 0 0000313B 26F7070100 test word [es:bx + D_P_Match_Flag],D_P_Optional ;AN000; is it optional ? 0 00003140 7532 jne D_P_FileF02 ;AN000; 2500 <1> 0 00003142 2EC706[2B00]0200 mov word [psdata_seg:D_P_RC],D_P_Op_Missing ;AC034; 3/17/87 0 00003149 EB29 jmp short D_P_FileF02 ;AN000; 2503 <1> 2504 <1> D_P_FileF03: ;AN000; 0 0000314B 58 pop ax ;AN000; discard save si 0 0000314C 56 push si ;AN000; save new si 2507 <1> D_P_FileF_Loop1: ;AN000; 0 0000314D 2E8A04 mov al,[psdata_seg:si] ;AN000; load character (not special char) 0 00003150 08C0 or al,al ;AN000; end of line ? 0 00003152 741E je D_P_FileF_RLT ;AN000; 2511 <1> 0 00003154 E82D00 call D_P_FileSp_Chk ;AN000; File special character ? 0 00003157 740B je D_P_FileF00 ;AN000; 2514 <1> 0 00003159 E85C01 call D_P_Chk_DBCS ;AN000; no, then DBCS ? 0 0000315C 7302 jnc D_P_FileF01 ;AN000; 0 0000315E 47 inc di ;AN000; if yes, skip next byte 0 0000315F 46 inc si ;AN000; 2519 <1> D_P_FileF01: ;AN000; 0 00003160 47 inc di ;AN000; 0 00003161 46 inc si ;AN000; 0 00003162 EBE9 jmp short D_P_FileF_Loop1 ;AN000; 2523 <1> ; 2524 <1> D_P_FileF00: ;AN000; 0 00003164 2EA2[3100] mov [psdata_seg:D_P_Terminator],al ;AC034; 0 00003168 2EC60400 mov byte ptr [psdata_seg:si],D_P_NULL ;AN000; update end of string 0 0000316C 47 inc di ;AN000; 0 0000316D 2E893E[2D00] mov [psdata_seg:D_P_SI_Save],di ;AC034; update next pointer in command line 2529 <1> D_P_FileF_RLT: ;AN000; 0 00003172 5E pop si ;AN000; 0 00003173 5F pop di ;AN000; 2532 <1> D_P_FileF02: ;AN000; 2533 <1> 0 00003174 58 pop ax ;AN000; (tm14) 0 00003175 A90002 test ax,D_P_File_Spc ;AN000; (tm14) 0 00003178 7409 je D_P_Drv_Only_Exit ;AN000; (tm14) 2537 <1> 0 0000317A 50 push ax ;AN000; (tm14) 2539 <1> 0 0000317B B4FF mov ah,D_P_No_Tag ;AN000; set 0 0000317D B005 mov al,D_P_File_Spec ;AN000; result 0 0000317F E88EFB call D_P_Fill_Result ;AN000; buffer to file spec 0 00003182 58 pop ax ;AN000; 2544 <1> 2545 <1> D_P_Drv_Only_Exit: ;AN000; (tm14) 2546 <1> 0 00003183 C3 ret ;AN000; 2548 <1> D_P_File_Format endp ;AN000; 2549 <1> ;PAGE ;AN000; 2550 <1> ;*********************************************************************** 2551 <1> ; D_P_FileSp_Chk 2552 <1> ; 2553 <1> ; Function: Check if the input byte is one of file special characters 2554 <1> ; 2555 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 2556 <1> ; AL = character code to be examineed 2557 <1> ; 2558 <1> ; Output: ZF = 1 , AL is one of special characters 2559 <1> ;*********************************************************************** 2560 <1> D_P_FileSp_Chk proc ;AN000; 0 00003184 53 push bx ;AN000; 0 00003185 51 push cx ;AN000; 0 00003186 8D1E[C500] lea bx,[D_P_FileSp_Char] ;AC034; special character table 0 0000318A B90900 mov cx,D_P_FileSp_Len ;AN000; load length of it 2565 <1> D_P_FileSp_Loop: ;AN000; 0 0000318D 2E3A07 cmp al,[psdata_seg:bx] ;AN000; is it one of special character ? 0 00003190 7404 je D_P_FileSp_Exit ;AN000; 2568 <1> 0 00003192 43 inc bx ;AN000; 0 00003193 E2F8 loop D_P_FileSp_Loop ;AN000; 2571 <1> 0 00003195 41 inc cx ;AN000; reset ZF 2573 <1> D_P_FileSp_Exit: ;AN000; 0 00003196 59 pop cx ;AN000; 0 00003197 5B pop bx ;AN000; 0 00003198 C3 ret ;AN000; 2577 <1> D_P_FileSp_Chk endp ;AN000; 2578 <1> %ENDIF ;AN000;(of FileSW+DrvSW) 2579 <1> ;PAGE ;AN000; 2580 <1> ;*********************************************************************** 2581 <1> %IF DrvSW ;AN000;(Check if drive only is supported) 2582 <1> ; D_P_Drive_Format; 2583 <1> ; 2584 <1> ; Function: Check if the input string is valid drive only format. 2585 <1> ; And set the result buffer. 2586 <1> ; 2587 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 2588 <1> ; ES:BX -> CONTROL block 2589 <1> ; 2590 <1> ; Output: None 2591 <1> ; 2592 <1> ; Use: D_P_Fill_Result, D_P_Chk_DBCS 2593 <1> ; 2594 <1> ; Vars: D_P_RC(W) 2595 <1> ;*********************************************************************** 2596 <1> D_P_Drive_Format proc ;AN000; 0 00003199 50 push ax ;AN000; 0 0000319A 52 push dx ;AN000; 0 0000319B 2E8A04 mov al,[psdata_seg:si] ;AN000; 0 0000319E 08C0 or al,al ;AN000; if null string 0 000031A0 7438 je D_P_Drv_Exit ;AN000; do nothing 2602 <1> 0 000031A2 E81301 call D_P_Chk_DBCS ;AN000; is it leading byte ? 0 000031A5 722C jc D_P_Drv_Err ;AN000; 2605 <1> 0 000031A7 2E837C013A cmp word ptr [psdata_seg:si+1],D_P_Colon ;AN000; "d", ":", 0 ? 0 000031AC 740E je D_P_DrvF00 ;AN000; 2608 <1> 0 000031AE 26F7071000 test word [es:bx + D_P_Match_Flag],D_P_Ig_Colon ;AN000; colon can be ignored? 0 000031B3 741E je D_P_Drv_Err ;AN000; 2611 <1> 0 000031B5 2E807C0100 cmp byte ptr [psdata_seg:si+1],D_P_NULL ;AN000; "d", 0 ? 0 000031BA 7517 jne D_P_Drv_Err ;AN000; 2614 <1> 2615 <1> D_P_DrvF00: ;AN000; 0 000031BC 0C20 or al,D_P_Make_Lower ;AN000; lower case 0 000031BE 3C61 cmp al,"a" ;AN000; drive letter must 0 000031C0 7211 jb D_P_Drv_Err ;AN000; in range of 2619 <1> 0 000031C2 3C7A cmp al,"z" ;AN000; "a" - "z" 0 000031C4 770D ja D_P_Drv_Err ;AN000; if no, error 2622 <1> 0 000031C6 2C60 sub al,"a"-1 ;AN000; make text drive to binary drive 0 000031C8 88C2 mov dl,al ;AN000; set 0 000031CA B4FF mov ah,D_P_No_Tag ;AN000; result 0 000031CC B006 mov al,D_P_Drive ;AN000; buffer 0 000031CE E83FFB call D_P_Fill_Result ;AN000; to drive 0 000031D1 EB07 jmp short D_P_Drv_Exit ;AN000; 2629 <1> 2630 <1> D_P_Drv_Err: ;AN000; 0 000031D3 2EC706[2B00]0900 mov word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; 2632 <1> D_P_Drv_Exit: ;AN000; 0 000031DA 5A pop dx ;AN000; 0 000031DB 58 pop ax ;AN000; 0 000031DC C3 ret ;AN000; 2636 <1> D_P_Drive_Format endp ;AN000; 2637 <1> %ENDIF ;AN000;(of DrvSW) 2638 <1> ;PAGE ;AN000; 2639 <1> ;*********************************************************************** 2640 <1> ; D_P_Skip_Delim; 2641 <1> ; 2642 <1> ; Function: Skip delimiters specified in the PARMS list, white space 2643 <1> ; and comma. 2644 <1> ; 2645 <1> ; Input: DS:SI -> Command String 2646 <1> ; ES:DI -> Parameter List 2647 <1> ; 2648 <1> ; Output: CY = 1 if the end of line encounterd 2649 <1> ; CY = 0 then SI move to 1st non-delimiter character 2650 <1> ; AL = Last examineed character 2651 <1> ; 2652 <1> ; Use: D_P_Chk_EOL, D_P_Chk_Delim, 2653 <1> ; 2654 <1> ; Vars: D_P_Flags(R) 2655 <1> ;*********************************************************************** 2656 <1> D_P_Skip_Delim proc ;AN000; 2657 <1> D_P_Skip_Delim_Loop: ;AN000; 0 000031DD AC LODSB ;AN000; 0 000031DE E82200 call D_P_Chk_EOL ;AN000; is it EOL character ? 0 000031E1 7418 je D_P_Skip_Delim_CY ;AN000; if yes, exit w/ CY on 2661 <1> 0 000031E3 E85300 call D_P_Chk_Delim ;AN000; is it one of delimiters ? 0 000031E6 7516 jne D_P_Skip_Delim_NCY ;AN000; if no, exit w/ CY off 2664 <1> 0 000031E8 2EF606[3700]20 test byte [psdata_seg:D_P_Flags2],D_P_Extra ;AC034; extra delim or comma found ? 0 000031EE 74ED je D_P_Skip_Delim_Loop ;AN000; if no, loop 2667 <1> 0 000031F0 2EF606[3700]41 test byte [psdata_seg:D_P_Flags2],D_P_SW+D_P_equ ;AC034; /x , or xxx=zzz , (tm08) 0 000031F6 7409 je short D_P_Exit_At_Extra ;AN000; no switch, no keyword (tm08) 2670 <1> 0 000031F8 4E dec si ;AN000; backup si for next call (tm08) 0 000031F9 EB06 jmp short D_P_Exit_At_Extra ;AN000; else exit w/ CY off 2673 <1> 2674 <1> D_P_Skip_Delim_CY: ;AN000; 0 000031FB F9 stc ;AN000; indicate EOL 0 000031FC EB01 jmp short D_P_Skip_Delim_Exit ;AN000; 2677 <1> 2678 <1> D_P_Skip_Delim_NCY: ;AN000; 0 000031FE F8 clc ;AN000; indicate non delim 2680 <1> D_P_Skip_Delim_Exit: ;AN000; in this case, need 0 000031FF 4E dec si ;AN000; backup index pointer 0 00003200 C3 ret ;AN000; 2683 <1> 2684 <1> D_P_Exit_At_Extra: ;AN000; 0 00003201 F8 clc ;AN000; indicate extra delim 0 00003202 C3 ret ;AN000; 2687 <1> D_P_Skip_Delim endp ;AN000; 2688 <1> ;PAGE ;AN000; 2689 <1> ;*********************************************************************** 2690 <1> ; D_P_Chk_EOL; 2691 <1> ; 2692 <1> ; Function: Check if AL is one of End of Line characters. 2693 <1> ; 2694 <1> ; Input: AL = character code 2695 <1> ; ES:DI -> Parameter List 2696 <1> ; 2697 <1> ; Output: ZF = 1 if one of End of Line characters 2698 <1> ;********************************************************************** 2699 <1> D_P_Chk_EOL proc ;AN000; 0 00003203 53 push bx ;AN000; 0 00003204 51 push cx ;AN000; 0 00003205 3C0D cmp al,D_P_CR ;AN000; Carriage return ? 0 00003207 742D je D_P_Chk_EOL_Exit ;AN000; 2704 <1> 0 00003209 3C00 cmp al,D_P_NULL ;AN000; zero ? 0 0000320B 7429 je D_P_Chk_EOL_Exit ;AN000; 2707 <1> 2708 <1> %IF LFEOLSW ;AN028; IF LF TO BE ACCEPTED AS EOL 0 0000320D 3C0A cmp al,D_P_LF ;AN000; Line feed ? 0 0000320F 7425 je D_P_Chk_EOL_Exit ;AN000; 2711 <1> %ENDIF ;AN028; 2712 <1> 0 00003211 26807D0202 cmp byte ptr [es:di + D_P_Num_Extra],D_P_I_Have_EOL ;AN000; EOL character specified ? 0 00003216 721E jb D_P_Chk_EOL_Exit ;AN000; 2715 <1> 0 00003218 31DB xor bx,bx ;AN000; 0 0000321A 268A5D03 mov bl,[es:di + D_P_Len_Extra_Delim] ;AN000; get length of delimiter list 0 0000321E 83C304 add bx,D_P_Len_PARMS ;AN000; skip it 0 00003221 26803900 cmp byte ptr [es:bx+di],D_P_I_Use_Default ;AN000; No extra EOL character ? 0 00003225 740D je D_P_Chk_EOL_NZ ;AN000; 2721 <1> 0 00003227 31C9 xor cx,cx ;AN000; Get number of extra chcracter 0 00003229 268A09 mov cl,[es:bx+di] ;AN000; 2724 <1> D_P_Chk_EOL_Loop: ;AN000; 0 0000322C 43 inc bx ;AN000; 0 0000322D 263A01 cmp al,[es:bx+di] ;AN000; Check extra EOL character 0 00003230 7404 je D_P_Chk_EOL_Exit ;AN000; 2728 <1> 0 00003232 E2F8 loop D_P_Chk_EOL_Loop ;AN000; 2730 <1> 2731 <1> D_P_Chk_EOL_NZ: ;AN000; 0 00003234 3C0D cmp al,D_P_CR ;AN000; reset ZF 2733 <1> D_P_Chk_EOL_Exit: ;AN000; 0 00003236 59 pop cx ;AN000; 0 00003237 5B pop bx ;AN000; 0 00003238 C3 ret ;AN000; 2737 <1> D_P_Chk_EOL endp ;AN000; 2738 <1> ;PAGE ;AN000; 2739 <1> ;*********************************************************************** 2740 <1> ; D_P_Chk_Delim; 2741 <1> ; 2742 <1> ; Function: Check if AL is one of delimiter characters. 2743 <1> ; if AL+[si] is DBCS blank, it is replaced with two SBCS 2744 <1> ; blanks. 2745 <1> ; 2746 <1> ; Input: AL = character code 2747 <1> ; DS:SI -> Next Character 2748 <1> ; ES:DI -> Parameter List 2749 <1> ; 2750 <1> ; Output: ZF = 1 if one of delimiter characters 2751 <1> ; SI points to the next character 2752 <1> ; Vars: D_P_Terminator(W), D_P_Flags(W) 2753 <1> ;*********************************************************************** 2754 <1> D_P_Chk_Delim proc ;AN000; 0 00003239 53 push bx ;AN000; 0 0000323A 51 push cx ;AN000; 0 0000323B 2EC606[3100]20 mov byte [psdata_seg:D_P_Terminator],D_P_Space ;AC034; Assume terminated by space 0 00003241 2E8026[3700]DF and byte [psdata_seg:D_P_Flags2],0ffh-D_P_Extra ;AC034; 0 00003247 3C20 cmp al,D_P_Space ;AN000; Space ? 0 00003249 7436 je D_P_Chk_Delim_Exit ;AN000; 2761 <1> 0 0000324B 3C09 cmp al,D_P_TAB ;AN000; TAB ? 0 0000324D 7432 je D_P_Chk_Delim_Exit ;AN000; 2764 <1> 0 0000324F 3C2C cmp al,D_P_Comma ;AN000; Comma ? 0 00003251 7431 je D_P_Chk_Delim_Exit0 ;AN000; 2767 <1> 2768 <1> D_P_Chk_Delim00: ;AN000; 0 00003253 3C81 cmp al,D_P_DBSP1 ;AN000; 1st byte of DBCS Space ? 0 00003255 750C jne D_P_Chk_Delim01 ;AN000; 2771 <1> 0 00003257 803C40 cmp byte ptr [si],D_P_DBSP2 ;AN000; 2nd byte of DBCS Space ? 0 0000325A 7507 jne D_P_Chk_Delim01 ;AN000; 2774 <1> 0 0000325C B020 mov al,D_P_Space ;AN000; 0 0000325E 46 inc si ;AN000; make si point to next character 0 0000325F 38C0 cmp al,al ;AN000; Set ZF 0 00003261 EB1E jmp short D_P_Chk_Delim_Exit ;AN000; 2779 <1> 2780 <1> D_P_Chk_Delim01: ;AN000; 0 00003263 26807D0201 cmp byte ptr [es:di + D_P_Num_Extra],D_P_I_Have_Delim ;AN000; delimiter character specified ? 0 00003268 7217 jb D_P_Chk_Delim_Exit ;AN000; 2783 <1> 0 0000326A 31C9 xor cx,cx ;AN000; 0 0000326C 268A4D03 mov cl,[es:di + D_P_Len_Extra_Delim] ;AN000; get length of delimiter list 0 00003270 09C9 or cx,cx ;AN000; No extra Delim character ? 0 00003272 740B je D_P_Chk_Delim_NZ ;AN000; 2788 <1> 0 00003274 BB0300 mov bx,D_P_Len_PARMS-1 ;AN000; set bx to 1st extra delimiter 2790 <1> D_P_Chk_Delim_Loop: ;AN000; 0 00003277 43 inc bx ;AN000; 0 00003278 263A01 cmp al,[es:bx+di] ;AN000; Check extra Delim character 0 0000327B 7407 je D_P_Chk_Delim_Exit0 ;AN000; 2794 <1> 0 0000327D E2F8 loop D_P_Chk_Delim_Loop ;AN000; examine all extra delimiter 2796 <1> 2797 <1> D_P_Chk_Delim_NZ: ;AN000; 0 0000327F 3C20 cmp al,D_P_Space ;AN000; reset ZF 2799 <1> D_P_Chk_Delim_Exit: ;AN000; 2800 <1> ;;;; jne D_P_ChkDfin 2801 <1> ;;;; mov psdata_seg:D_P_Terminator,al ;AN034; 2802 <1> D_P_ChkDfin: ;AN000; 0 00003281 59 pop cx ;AN000; 0 00003282 5B pop bx ;AN000; 0 00003283 C3 ret ;AN000; 2806 <1> 2807 <1> D_P_Chk_Delim_Exit0: ;AN000; 0 00003284 2EA2[3100] mov [psdata_seg:D_P_Terminator],al ;AC034; keep terminated delimiter 2809 <1> D_P_Equ equ D_P_equ ; NASM port equate 0 00003288 2EF606[3700]01 test byte [psdata_seg:D_P_Flags2],D_P_Equ ;AN027;AC034;; if terminating a key= 0 0000328E 7506 jnz D_P_No_Set_Extra ;AN027; then do not set the EXTRA bit 2812 <1> 0 00003290 2E800E[3700]20 or byte [psdata_seg:D_P_Flags2],D_P_Extra ;AC034; flag terminated extra delimiter or comma 2814 <1> D_P_No_Set_Extra: ;AN027; 0 00003296 38C0 cmp al,al ;AN000; set ZF 0 00003298 EBE7 jmp short D_P_Chk_Delim_Exit ;AN000; 2817 <1> 2818 <1> D_P_Chk_Delim endp ;AN000; 2819 <1> ;PAGE ;AN000; 2820 <1> ;*********************************************************************** 2821 <1> ; D_P_Chk_Switch; 2822 <1> ; 2823 <1> ; Function: Check if AL is the switch character not in first position of 2824 <1> ; D_P_STRING_BUF 2825 <1> ; 2826 <1> ; Input: AL = character code 2827 <1> ; BX = current pointer within D_P_String_Buf 2828 <1> ; SI =>next char on command line (following the one in AL) 2829 <1> ; 2830 <1> ; Output: CF = 1 (set)if AL is switch character, and not in first 2831 <1> ; position, and has no chance of being part of a date string, 2832 <1> ; i.e. should be treated as a delimiter. 2833 <1> 2834 <1> ; CF = 0 (reset, cleared) if AL is not a switch char, is in the first 2835 <1> ; position, or is a slash but may be part of a date string, i.e. 2836 <1> ; should not be treated as a delimiter. 2837 <1> ; 2838 <1> ; Vars: D_P_Terminator(W) 2839 <1> 2840 <1> ; Use: D_P_0099 2841 <1> ;*********************************************************************** 2842 <1> D_P_Chk_Switch proc ;AN000; 2843 <1> 2844 <1> ;AN020;; Function: Check if AL is the switch character from 2nd position of D_P_STRING_BUF 2845 <1> ;AN020;; Output: ZF = 1 if switch character 2846 <1> ;AN020;; lea bp,D_P_STRING_BUF ;AN000; 2847 <1> ;AN020;; cmp bx,bp ;AN000; 1st position ? 2848 <1> ;AN020;; je D_P_Chk_S_Exit_1 ;AN000; 2849 <1> ;AN020;; cmp al,D_P_Switch ;AN000; 2850 <1> ;AN020;; jmp short D_P_Chk_S_Exit_0 ;AN000; 2851 <1> ;AN020;;D_P_Chk_S_Exit_1: ;AN000; 2852 <1> ;AN020;; cmp al,D_P_Switch ;AN000; (tm08) 2853 <1> ;AN020;; jne D_P_Nop ;AN000; (tm08) 2854 <1> ;AN020;; or D_P_Flags2,D_P_SW ;AN000; (tm08) It could be valid switch 2855 <1> ;AN020;;D_P_Nop: ;AN000; (tm08) 2856 <1> ;AN020;; inc bp ;AN000; 2857 <1> ;AN020;; cmp bx,bp ;AN000; reset ZF 2858 <1> ;AN020;;D_P_Chk_S_Exit_0: ;AN000; 2859 <1> ;AN020;; jne D_P_Chk_S_Exit ;AN000; 2860 <1> ;AN020;; mov D_P_Terminator,al ;AN000; store switch character 2861 <1> ;AN020;;D_P_Chk_S_Exit: ;AN000; 2862 <1> 2863 <1> D_P_String_Buf equ D_P_STRING_BUF ; NASM port label 0 0000329A 8D2E[4000] LEA BP,[D_P_String_Buf] ;AN020;AC034; BP=OFFSET of D_P_String_Buf even in group addressing 2865 <1> ; .IF THEN ;AN020;IF not first char THEN 0 0000329E 39EB cmp BX,BP ;AN000; 0 000032A0 740A je D_P_STRUC_L2 ;AN000; 2868 <1> 2869 <1> ; .IF THEN ;AN020;otherwise see if a slash 0 000032A2 3C2F cmp AL,D_P_Switch ;AN000; 0 000032A4 7503 jne D_P_STRUC_L5 ;AN000; 2872 <1> 0 000032A6 F9 STC ;AN020;not in first position and is slash, now see if might be in date string 2874 <1> %IF DateSw ;AN020;caller looking for date, see if this may be part of one 2875 <1> PUSH AX ;AN020;save input char 2876 <1> MOV AL,[PSDATA_SEG:BX-1] ;AN026;AL=char before the current char 2877 <1> CALL D_P_0099 ;AN020;return carry set if not numeric 2878 <1> ; .IF NC ;AND ;AN020;IF previous char numeric AND 2879 <1> jc D_P_STRUC_L7 ;AN000; 2880 <1> 2881 <1> MOV AL,[SI] ;AN020;AL=char after the current char 2882 <1> CALL D_P_0099 ;AN020;return carry set if not numeric 2883 <1> ;(deleted) .IF NC THEN ;AN020;IF next char numeric THEN could be a date 2884 <1> ;(deleted) CLC ;AN020;reset CF so "/" not treated as a delimiter 2885 <1> ;(deleted) .ENDIF ;AN026; 2886 <1> ; .ENDIF ;AN020;ENDIF looks like date (number/number) 2887 <1> D_P_STRUC_L7: ;AN000; 2888 <1> POP AX ;AN020;restore AL to input char 2889 <1> %ENDIF ;AN020;DateSw 2890 <1> ; .ELSE ;AN020; 0 000032A7 EB0E jmp short D_P_STRUC_L1 ;AN000; 2892 <1> 2893 <1> D_P_STRUC_L5: ;AN000; 0 000032A9 F8 CLC ;AN020;not a slash 2895 <1> ; .ENDIF ;AN020; 2896 <1> ; .ELSE ;AN020;is first char in the buffer, ZF=0 0 000032AA EB0B jmp short D_P_STRUC_L1 ;AN000; 2898 <1> 2899 <1> D_P_STRUC_L2: ;AN000; 2900 <1> ; .IF THEN ;AN020; 0 000032AC 3C2F cmp AL,D_P_Switch ;AN000; 0 000032AE 7506 jne D_P_STRUC_L12 ;AN000; 2903 <1> 0 000032B0 2E800E[3700]40 OR byte [psdata_seg:D_P_Flags2],D_P_SW ;AN020;AC034;;could be valid switch, first char and is slash 2905 <1> ; .ENDIF ;AN020; 2906 <1> D_P_STRUC_L12: ;AN000; 0 000032B6 F8 CLC ;AN020;CF=0 indicating first char 2908 <1> ; .ENDIF ;AN020; 2909 <1> D_P_STRUC_L1: ;AN000; 2910 <1> 0 000032B7 C3 ret ;AN000; 2912 <1> D_P_Chk_Switch endp ;AN000; 2913 <1> ; PAGE ;AN000; 2914 <1> ;************************************************************************** 2915 <1> ; D_P_Chk_DBCS: 2916 <1> ; 2917 <1> ; Function: Check if a specified byte is in ranges of the DBCS lead bytes 2918 <1> ; 2919 <1> ; Input: 2920 <1> ; AL = Code to be examineed 2921 <1> ; 2922 <1> ; Output: 2923 <1> ; If CF is on then a lead byte of DBCS 2924 <1> ; 2925 <1> ; Use: INT 21h w/AH=63 2926 <1> ; 2927 <1> ; Vars: D_P_DBCSEV_Seg(RW), D_P_DBCSEV_Off(RW) 2928 <1> ;*************************************************************************** 2929 <1> D_P_Chk_DBCS PROC ;AN000; 2930 <1> ; 0 000032B8 1E PUSH DS ;AN000; 0 000032B9 56 PUSH SI ;AN000; 0 000032BA 53 PUSH bx ;AN000; (tm11) 0 000032BB 2E833E[3400]00 CMP word [psdata_seg:D_P_DBCSEV_SEG],0 ;AC034; ALREADY SET ? 0 000032C1 7527 JNE D_P_DBCS00 ;AN000; 2936 <1> 0 000032C3 50 PUSH AX ;AN000; 2938 <1> ; PUSH BX ;AN000; (tm11) 0 000032C4 1E PUSH ds ;AN000; (tm11) 0 000032C5 51 PUSH CX ;AN000; 0 000032C6 52 PUSH DX ;AN000; 0 000032C7 57 PUSH DI ;AN000; 0 000032C8 55 PUSH BP ;AN000; 0 000032C9 06 PUSH ES ;AN000; 0 000032CA 31F6 XOR SI,SI ;AN000; 0 000032CC 8EDE MOV DS,SI ;AN000; 0 000032CE B80063 MOV AX,D_P_DOS_GetEV ;AN000; GET DBCS EV CALL 0 000032D1 CD21 INT 21H ;AN000; 2949 <1> 2950 <1> ; MOV AX,DS ;AN000; (tm11) 2951 <1> ; OR AX,AX ;AN000; (tm11) 0 000032D3 8CDB MOV bx,DS ;AN000; (tm11) 0 000032D5 09DB OR bx,bx ;AN000; (tm11) 0 000032D7 07 POP ES ;AN000; 0 000032D8 5D POP BP ;AN000; 0 000032D9 5F POP DI ;AN000; 0 000032DA 5A POP DX ;AN000; 0 000032DB 59 POP CX ;AN000; 2959 <1> ; POP BX ;AN000; (tm11) 0 000032DC 1F POP ds ;AN000; (tm11) 0 000032DD 58 POP AX ;AN000; 0 000032DE 7429 JE D_P_NON_DBCS ;AN000; 2963 <1> 2964 <1> D_P_DBCS02: ;AN000; 0 000032E0 2E8936[3200] MOV [psdata_seg:D_P_DBCSEV_OFF],SI ;AC034; save EV offset 2966 <1> ; MOV psdata_seg:D_P_DBCSEV_SEG,DS ;AC034; save EV segment 0 000032E5 2E891E[3400] MOV [psdata_seg:D_P_DBCSEV_SEG],bx ;AC034; save EV segment (tm11) 2968 <1> D_P_DBCS00: ;AN000; 0 000032EA 2E8B36[3200] MOV SI,[psdata_seg:D_P_DBCSEV_OFF] ;AC034; load EV offset 0 000032EF 2E8E1E[3400] MOV DS,[psdata_seg:D_P_DBCSEV_SEG] ;AC034; and segment 2971 <1> 2972 <1> D_P_DBCS_LOOP: ;AN000; 0 000032F4 833C00 CMP WORD PTR [SI],0 ;AN000; zero vector ? 0 000032F7 7410 JE D_P_NON_DBCS ;AN000; then exit 2975 <1> 0 000032F9 3A04 CMP AL,[SI] ;AN000; 0 000032FB 7208 JB D_P_DBCS01 ;AN000; Check if AL is in 2978 <1> 0 000032FD 3A4401 CMP AL,[SI+1] ;AN000; range of 0 00003300 7703 JA D_P_DBCS01 ;AN000; the vector 2981 <1> 0 00003302 F9 STC ;AN000; if yes, indicate DBCS and exit 0 00003303 EB05 JMP short D_P_DBCS_EXIT ;AN000; 2984 <1> 2985 <1> D_P_DBCS01: ;AN000; 0 00003305 46 INC SI ;AC035; add '2' to 0 00003306 46 INC SI ;AC035; SI reg 2988 <1> ;AN000; get next vector 2989 <1> ;(changed ;AC035;) ADD SI,2 ;AN000; get next vector 0 00003307 EBEB JMP short D_P_DBCS_LOOP ;AN000; loop until zero vector found 2991 <1> 2992 <1> D_P_NON_DBCS: ;AN000; 0 00003309 F8 CLC ;AN000; indicate SBCS 2994 <1> D_P_DBCS_EXIT: ;AN000; 0 0000330A 5B POP bx ;AN000; (tm11) 0 0000330B 5E POP SI ;AN000; 0 0000330C 1F POP DS ;AN000; 0 0000330D C3 RET ;AN000; 2999 <1> D_P_Chk_DBCS ENDP ;AN000; 247 ;=== Pop trace listing source 248 ;Control block definitions for PARSER. 249 ;--------------------------------------------------- 250 ; BUFFER = [n | n,m] {/E} 251 252 Buf_Parms label byte ;AN000; 0 0000330E [F308] dw Buf_Parmsx ;AN000; 0 00003310 01 db 1 ;AN000; An extra delimeter list 0 00003311 01 db 1 ;AN000; length is 1 0 00003312 3B db SEMICOLON ;AN000; 257 258 Buf_Parmsx label byte ;AN000; 0 00003313 0102 db 1,2 ;AN000; Min 1, Max 2 positional 0 00003315 [FD08] dw Buf_Pos1 ;AN000; 0 00003317 [1109] dw Buf_Pos2 ;AN000; 0 00003319 01 db 1 ;AN000; 1 switch 0 0000331A [2509] dw SW_X_Ctrl ;AN000;AN025; /X control 0 0000331C 00 db 0 ;AN000; no keywords 265 266 Buf_Pos1 label word ;AN000; 0 0000331D 0080 dw 8000h ;AN000; Numeric value 0 0000331F 0000 dw 0 ;AN000; no function 0 00003321 [3809] dw Result_Val ;AN000; Result value buffer 0 00003323 [0609] dw Buf_Range_1 ;AN000; value list 0 00003325 00 db 0 ;AN000; no switches/keywords 272 273 Buf_Range_1 label byte ;AN000; value definition 0 00003326 01 db 1 ;AN000; range definition 0 00003327 01 db 1 ;AN000; 1 definition of range 0 00003328 01 db 1 ;AN000; item tag for this range 0 00003329 0100000010270000 dd 1,10000 ;AN000; from 1 to 10000 278 279 Buf_Pos2 label word ;AN000; 0 00003331 0180 dw 8001h ;AN000; Numeric value, Optional 0 00003333 0000 dw 0 ;AN000; no function 0 00003335 [3809] dw Result_Val ;AN000; Result value buffer 0 00003337 [1A09] dw Buf_Range_2 ;AN000; value list 0 00003339 00 db 0 ;AN000; no switches/keywords 285 286 Buf_Range_2 label byte ;AN000; value definition 0 0000333A 01 db 1 ;AN000; range definition 0 0000333B 01 db 1 ;AN000; 1 definition of range 0 0000333C 01 db 1 ;AN000; item tag for this range 0 0000333D 0000000008000000 dd 0,8 ;AN000; from 0 to 8. 291 292 SW_X_Ctrl label word ;AN000;AN025; 0 00003345 0000 dw 0 ;AN000; no matching flag 0 00003347 0000 dw 0 ;AN000; no function 0 00003349 [3809] dw Result_Val ;AN000; return value 0 0000334B [3709] dw NoVal ;AN000; no value definition 0 0000334D 01 db 1 ;AN000; # of switches 298 Switch_X label byte ;AN000;AN025; 0 0000334E 2F5800 db '/X',0 ;AN000;AN025; 300 ;local variables 0 00003351 0000 P_Buffers dw 0 ;AN000; 0 00003353 0000 P_H_Buffers dw 0 ;AN000; 0 00003355 00 P_Buffer_Slash_X db 0 ;AN000;AN025; 0 00003356 00 Buffer_Pre_Scan db 0 ;AN030; 305 306 ;Common definitions ------------- 0 00003357 00 NoVal db 0 ;AN000; 308 309 Result_Val label byte ;AN000; 0 00003358 ?? db ? ;AN000; type returned 0 00003359 ?? db ? ;AN000; item tag returned 0 0000335A ???? dw ? ;AN000; ES:offset of the switch defined 313 RV_Byte label byte ;AN000; 314 RV_Dword label dword ;AN000; 0 0000335C ???????? dd ? ;AN000; value if number, or seg:offset to string. 316 ;-------------------------------- 317 318 ; BREAK = [ ON | OFF ] 319 320 Brk_Parms label byte ;AN000; 0 00003360 [4509] dw Brk_Parmsx ;AN000; 0 00003362 01 db 1 ;AN000; An extra delimeter list 0 00003363 01 db 1 ;AN000; length is 1 0 00003364 3B db SEMICOLON ;AN000; 325 326 Brk_Parmsx label byte ;AN000; 0 00003365 0101 db 1,1 ;AN000; Min 1, Max 1 positional 0 00003367 [4B09] dw Brk_Pos ;AN000; 0 00003369 00 db 0 ;AN000; no switches 0 0000336A 00 db 0 ;AN000; no keywords 331 332 Brk_Pos label word ;AN000; 0 0000336B 0020 dw 2000h ;AN000; Simple string 0 0000336D 0000 dw 0 ;AN000; No functions 0 0000336F [3809] dw Result_Val ;AN000; 0 00003371 [5409] dw On_Off_String ;AN000; ON,OFF string descriptions 0 00003373 00 db 0 ;AN000; no keyword/switch synonyms 338 339 On_Off_String label byte ;AN000; 0 00003374 03 db 3 ;AN000; signals that there is a string choice 0 00003375 00 db 0 ;AN000; no range definition 0 00003376 00 db 0 ;AN000; no numeric values choice 0 00003377 02 db 2 ;AN000; 2 strings for choice 0 00003378 01 db 1 ;AN000; the 1st string tag 0 00003379 [5E09] dw On_String ;AN000; 0 0000337B 02 db 2 ;AN000; the 2nd string tag 0 0000337C [6109] dw Off_String ;AN000; 348 0 0000337E 4F4E00 On_String db "ON",0 ;AN000; 0 00003381 4F464600 Off_String db "OFF",0 ;AN000; 351 ;local variable 0 00003385 00 P_Ctrl_Break db 0 ;AN000; local variable 353 354 ;-------------------------------- 355 356 ; COUNTRY = n {m {path}} 357 ; or 358 ; COUNTRY = n,,path 359 360 Cntry_Parms label byte ;AN000; 0 00003386 [6B09] dw Cntry_Parmsx ;AN000; 0 00003388 01 db 1 ;AN000; An extra delimeter list 0 00003389 01 db 1 ;AN000; length is 1 0 0000338A 3B db SEMICOLON ;AN000; 365 366 Cntry_Parmsx label byte ;AN000; 0 0000338B 0103 db 1,3 ;AN000; Min 1, Max 3 positional 0 0000338D [7509] dw Cntry_Pos1 ;AN000; 0 0000338F [8909] dw Cntry_Pos2 ;AN000; 0 00003391 [9209] dw Cntry_Pos3 ;AN000; 0 00003393 00 db 0 ;AN000; no switches 0 00003394 00 db 0 ;AN000; no keywords 373 374 Cntry_Pos1 label word ;AN000; control definition for positional 1 0 00003395 0080 dw 8000h ;AN000; Numeric value 0 00003397 0000 dw 0 ;AN000; no functions 0 00003399 [3809] dw Result_Val ;AN000; 0 0000339B [7E09] dw Cntry_Codepage_Range ;AN000; country id code range description 0 0000339D 00 db 0 ;AN000; no switch/keyword synonyms 380 381 Cntry_Codepage_Range label byte ;AN000; 0 0000339E 01 db 1 ;AN000; # of value definitions 0 0000339F 01 db 1 ;AN000; # of ranges 0 000033A0 01 db 1 ;AN000; Tag for this range 0 000033A1 01000000E7030000 dd 1,999 ;AN000; 386 387 Cntry_Pos2 label word ;AN000; control definition for positional 2 0 000033A9 0180 dw 8001h ;AN000; Numeric value, optional 0 000033AB 0000 dw 0 ;AN000; no functions 0 000033AD [3809] dw Result_Val ;AN000; 0 000033AF [7E09] dw Cntry_Codepage_Range ;AN000; code page range descriptions. 0 000033B1 00 db 0 ;AN000; no switch/keyword synonyms 393 394 Cntry_Pos3 label word ;AN000; control definition for positional 3 0 000033B2 0102 dw 0201h ;AN000; File spec, optional 0 000033B4 0000 dw 0 ;AN000; No functions. Don't need to CAP. 0 000033B6 [3809] dw Result_Val ;AN000; 0 000033B8 [3709] dw NoVal ;AN000; no value list 0 000033BA 00 db 0 ;AN000; no switch/keyword synonyms 400 401 ;Local variables 0 000033BB 0000 P_Cntry_Code dw 0 ;AN000; 0 000033BD 0000 P_Code_Page dw 0 ;AN000; 404 405 ;-------------------------------- 406 407 ; FILES = n 408 409 Files_Parms label byte ;AN000; 0 000033BF [A409] dw Files_Parmsx ;AN000; 0 000033C1 01 db 1 ;AN000; An extra delimeter list 0 000033C2 01 db 1 ;AN000; length is 1 0 000033C3 3B db SEMICOLON ;AN000; 414 415 Files_Parmsx label byte ;AN000; 0 000033C4 0101 db 1,1 ;AN000; Min 1, Max 1 positional 0 000033C6 [AA09] dw Files_Pos ;AN000; 0 000033C8 00 db 0 ;AN000; no switches 0 000033C9 00 db 0 ;AN000; no keywords 420 421 Files_Pos label byte ;AN000; 0 000033CA 0080 dw 8000h ;AN000; Numeric value 0 000033CC 0000 dw 0 ;AN000; no functions 0 000033CE [3809] dw Result_Val ;AN000; 0 000033D0 [B309] dw Files_Range ;AN000; Files range description 0 000033D2 00 db 0 ;AN000; no switch/keyword synonyms 427 428 Files_Range label byte ;AN000; 0 000033D3 01 db 1 ;AN000; # of value definitions 0 000033D4 01 db 1 ;AN000; # of ranges 0 000033D5 01 db 1 ;AN000; Tag for this range 0 000033D6 08000000FF000000 dd 8,255 ;AN000; 433 ;local variable 0 000033DE 00 P_Files db 0 ;AN000; 435 436 ;-------------------------------- 437 438 ; FCBS = n,m 439 440 FCBS_Parms label byte ;AN000; 0 000033DF [C409] dw FCBS_Parmsx ;AN000; 0 000033E1 01 db 1 ;AN000; An extra delimeter list 0 000033E2 01 db 1 ;AN000; length is 1 0 000033E3 3B db SEMICOLON ;AN000; 445 446 FCBS_Parmsx label byte ;AN000; 0 000033E4 0202 db 2,2 ;AN000; Min 2, Max 2 positional 0 000033E6 [CC09] dw FCBS_Pos_1 ;AN000; 0 000033E8 [E009] dw FCBS_Pos_2 ;AN000; 0 000033EA 00 db 0 ;AN000; no switches 0 000033EB 00 db 0 ;AN000; no keywords 452 453 FCBS_Pos_1 label byte ;AN000; 0 000033EC 0080 dw 8000h ;AN000; Numeric value 0 000033EE 0000 dw 0 ;AN000; no functions 0 000033F0 [3809] dw Result_Val ;AN000; 0 000033F2 [D509] dw FCBS_Range ;AN000; FCBS range descriptions 0 000033F4 00 db 0 ;AN000; no switch/keyword synonyms 459 460 FCBS_Range label byte ;AN000; 0 000033F5 01 db 1 ;AN000; # of value definitions 0 000033F6 01 db 1 ;AN000; # of ranges 0 000033F7 01 db 1 ;AN000; Tag for this range 0 000033F8 01000000FF000000 dd 1,255 ;AN000; 465 466 FCBS_Pos_2 label byte ;AN000; 0 00003400 0080 dw 8000h ;AN000; Numeric value 0 00003402 0000 dw 0 ;AN000; no functions 0 00003404 [3809] dw Result_Val ;AN000; 0 00003406 [E909] dw FCBS_Keep_Range ;AN000; FCBS KEEP range descriptions 0 00003408 00 db 0 ;AN000; no switch/keyword synonyms 472 473 FCBS_Keep_Range label byte ;AN000; 0 00003409 01 db 1 ;AN000; # of value definitions 0 0000340A 01 db 1 ;AN000; # of ranges 0 0000340B 01 db 1 ;AN000; Tag for this range 0 0000340C 00000000FF000000 dd 0,255 ;AN000; 478 479 ;local variable 0 00003414 00 P_Fcbs db 0 ;AN000; 0 00003415 00 P_Keep db 0 ;AN000; 482 ;-------------------------------- 483 484 ; LASTDRIVE = x 485 486 LDRV_Parms label byte ;AN000; 0 00003416 [FB09] dw LDRV_Parmsx ;AN000; 0 00003418 01 db 1 ;AN000; An extra delimeter list 0 00003419 01 db 1 ;AN000; length is 1 0 0000341A 3B db SEMICOLON ;AN000; 491 492 LDRV_Parmsx label byte ;AN000; 0 0000341B 0101 db 1,1 ;AN000; Min 1, Max 1 positional 0 0000341D [010A] dw LDRV_Pos ;AN000; 0 0000341F 00 db 0 ;AN000; no switches 0 00003420 00 db 0 ;AN000; no keywords 497 498 LDRV_Pos label byte ;AN000; 0 00003421 1001 dw 0110h ;AN000; Drive only, Ignore colon. 0 00003423 1000 dw 0010h ;AN000; Remove colon at end 0 00003425 [3809] dw Result_Val ;AN000; 0 00003427 [3709] dw NoVal ;AN000; No value list 0 00003429 00 db 0 ;AN000; no switch/keyword synonyms 504 505 ;local variable 0 0000342A 00 P_Ldrv db 0 ;AN000; 507 ;-------------------------------- 508 509 ; STACKS = n,m 510 511 STKS_Parms label byte ;AN000; 0 0000342B [100A] dw STKS_Parmsx ;AN000; 0 0000342D 01 db 1 ;AN000; An extra delimeter list 0 0000342E 01 db 1 ;AN000; length is 1 0 0000342F 3B db SEMICOLON ;AN000; 516 517 STKS_Parmsx label byte ;AN000; 0 00003430 0202 db 2,2 ;AN000; Min 2, Max 2 positional 0 00003432 [180A] dw STKS_Pos_1 ;AN000; 0 00003434 [2C0A] dw STKS_Pos_2 ;AN000; 0 00003436 00 db 0 ;AN000; no switches 0 00003437 00 db 0 ;AN000; no keywords 523 524 STKS_Pos_1 label byte ;AN000; 0 00003438 0080 dw 8000h ;AN000; Numeric value 0 0000343A 0000 dw 0 ;AN000; no functions 0 0000343C [3809] dw Result_Val ;AN000; 0 0000343E [210A] dw STKS_Range ;AN000; number of stack range descriptions 0 00003440 00 db 0 ;AN000; no switch/keyword synonyms 530 531 STKS_Range label byte ;AN000; 0 00003441 01 db 1 ;AN000; # of value definitions 0 00003442 01 db 1 ;AN000; # of ranges 0 00003443 01 db 1 ;AN000; Tag for this range 0 00003444 0000000040000000 dd 0,64 ;AN000; 536 537 STKS_Pos_2 label byte ;AN000; 0 0000344C 0080 dw 8000h ;AN000; Numeric value 0 0000344E 0000 dw 0 ;AN000; no functions 0 00003450 [3809] dw Result_Val ;AN000; 0 00003452 [350A] dw STK_SIZE_Range ;AN000; stack size range descriptions 0 00003454 00 db 0 ;AN000; no switch/keyword synonyms 543 544 STK_SIZE_Range label byte ;AN000; 0 00003455 01 db 1 ;AN000; # of value definitions 0 00003456 01 db 1 ;AN000; # of ranges 0 00003457 01 db 1 ;AN000; Tag for this range 0 00003458 0000000000020000 dd 0,512 ;AN000; 549 ;local variables 0 00003460 0000 P_Stack_Count dw 0 ;AN000; 0 00003462 0000 P_Stack_Size dw 0 ;AN000; 552 553 ;-------------------------------- 554 555 ; MULTITRACK = [ ON | OFF ] 556 557 MTrk_Parms label byte ;AN002; 0 00003464 [490A] dw MTrk_Parmsx ;AN002; 0 00003466 01 db 1 ;AN002; An extra delimeter list 0 00003467 01 db 1 ;AN002; length is 1 0 00003468 3B db SEMICOLON ;AN002; 562 563 MTrk_Parmsx label byte ;AN002; 0 00003469 0101 db 1,1 ;AN002; Min 1, Max 1 positional 0 0000346B [4F0A] dw MTrk_Pos ;AN002; 0 0000346D 00 db 0 ;AN002; no switches 0 0000346E 00 db 0 ;AN002; no keywords 568 569 MTrk_Pos label word ;AN002; 0 0000346F 0020 dw 2000h ;AN002; Simple string 0 00003471 0000 dw 0 ;AN002; No functions 0 00003473 [3809] dw Result_Val ;AN002; 0 00003475 [5409] dw On_Off_String ;AN002; ON,OFF string descriptions 0 00003477 00 db 0 ;AN002; no keyword/switch synonyms 575 576 ;local variables 0 00003478 00 P_Mtrk db 0 ;AN002; 578 ;-------------------------------- 579 580 ; CPSW = [ ON | OFF ] 581 582 CPSW_Parms label byte ;AN002; 0 00003479 [5E0A] dw CPSW_Parmsx ;AN002; 0 0000347B 01 db 1 ;AN002; An extra delimeter list 0 0000347C 01 db 1 ;AN002; length is 1 0 0000347D 3B db SEMICOLON ;AN002; 587 588 CPSW_Parmsx label byte ;AN002; 0 0000347E 0101 db 1,1 ;AN002; Min 1, Max 1 positional 0 00003480 [640A] dw CPSW_Pos ;AN002; 0 00003482 00 db 0 ;AN002; no switches 0 00003483 00 db 0 ;AN002; no keywords 593 594 CPSW_Pos label word ;AN002; 0 00003484 0020 dw 2000h ;AN002; Simple string 0 00003486 0000 dw 0 ;AN002; No functions 0 00003488 [3809] dw Result_Val ;AN002; 0 0000348A [5409] dw On_Off_String ;AN002; ON,OFF string descriptions 0 0000348C 00 db 0 ;AN002; no keyword/switch synonyms 600 601 ;local variables 0 0000348D 00 P_CPSW db 0 ;AN002; 603 604 ;-------------------------------- 605 ; SWITCHES=/K 606 607 Swit_Parms label byte ;AN019; 0 0000348E [730A] dw Swit_Parmsx ;AN019; 0 00003490 01 db 1 ;AN019; An extra delimeter list 0 00003491 01 db 1 ;AN019; length is 1 0 00003492 3B db SEMICOLON ;AN019; 612 613 Swit_Parmsx label byte ;AN019; 0 00003493 0000 db 0,0 ;AN019; No positionals 0 00003495 01 db 1 ;AN019; 1 switch for now. 0 00003496 [790A] dw Swit_K_Ctrl ;AN019; /K control 0 00003498 00 db 0 ;AN019; no keywords 618 619 Swit_K_Ctrl label word ;AN019; 0 00003499 0000 dw 0 ;AN019; no matching flag 0 0000349B 0000 dw 0 ;AN019; no function 0 0000349D [3809] dw Result_Val ;AN019; return value 0 0000349F [3709] dw NoVal ;AN019; no value definition 0 000034A1 01 db 1 ;AN019; # of switches 625 Swit_K label byte ;AN019; 0 000034A2 2F4B00 db '/K',0 ;AN019; 627 ;local variables 0 000034A5 00 P_Swit_K db 0 ;AN019; 629 0 000034A6 00 no_config_file: db 0 631 632 ;****************************************************************************** 633 634 %if 0 635 %macro debugnumber 1 636 push ax 637 mov ax, %1 638 call display_debugnumber 639 pop ax 640 %endmacro 641 642 display_debugnumber: 643 pushf 644 push bx 645 push bp 646 push ax 647 mov ah, 0Eh 648 mov bx, 7 649 int 10h 650 pop ax 651 push ax 652 xchg al, ah 653 test al, al 654 jz .nohigh 655 mov ah, 0Eh 656 mov bx, 7 657 int 10h 658 .nohigh: 659 pop ax 660 pop bp 661 pop bx 662 popf 663 retn 664 %else 665 %macro debugnumber 1 666 %endmacro 667 %endif 668 669 DOCONF: 670 debugnumber '0' 0 000034A7 0E PUSH CS 0 000034A8 1F POP DS 673 ASSUME DS:SYSINITSEG 674 675 CHAR_OPER equ Char_Oper ; NASM port equate 0 000034A9 B80037 MOV AX,(CHAR_OPER << 8) ;GET SWITCH CHARACTER 0 000034AC CD21 INT 21H 0 000034AE 8816[0100] MOV [COMMAND_LINE+1],DL ; Set in default command line 679 680 extern CONFIG_pointers 0 000034B2 BE[FEFF] mov si, CONFIG_pointers - 2 682 .loop: 0 000034B5 AD lodsw ; skip command line name 0 000034B6 AD lodsw 0 000034B7 83F8FF cmp ax, -1 0 000034BA 741A je No_Config_sys 0 000034BC 85C0 test ax, ax 0 000034BE 74F5 jz .loop 0 000034C0 89C3 mov bx, ax 0 000034C2 803F00 cmp byte [bx], 0 0 000034C5 74EE je .loop 0 000034C7 92 xchg dx, ax 693 OPEN equ Open ; NASM port equate 0 000034C8 B8003D MOV AX,OPEN << 8 ;OPEN FILE "CONFIG.SYS" 0 000034CB F9 STC ;IN CASE OF INT 24 0 000034CC CD21 int 21h 0 000034CE 72E5 jc .loop 0 000034D0 8916[0A00] mov word [CONFIG_used], dx 0 000034D4 EB55 JMP NOPROB ;PROBLEM WITH OPEN 700 701 No_Config_sys: ;AN028; 0 000034D6 F616[860A] not byte [no_config_file] 0 000034DA 31C0 xor ax, ax 0 000034DC 31D2 xor dx, dx ; = empty config 0 000034DE EB56 jmp continue_no_file 706 707 ENDCONF: 0 000034E0 C3 return 709 710 0 000034E1 BA[0000] BADOP: MOV DX,OFFSET BADOPM ;WANT TO PRINT COMMAND ERROR "Unrecognized command..." 0 000034E4 E8[0000] invoke PRINT 0 000034E7 E87D0C call Error_Line ;show "Error in CONFIG.SYS ..." . 0 000034EA E90C02 JMP COFF 715 716 Badop_p proc near ;AN000; 717 ;Same thing as BADOP, but will make sure to set DS register back to SYSINITSEG 718 ;and return back to the calller. 0 000034ED 0E push cs 0 000034EE 1F pop ds ;set ds to CONFIGSYS seg. 721 badopm equ BADOPM ; NASM port label 0 000034EF BA[0000] mov dx, offset badopm 0 000034F2 E8[0000] invoke PRINT 0 000034F5 E86F0C call Error_Line 0 000034F8 C3 ret 726 Badop_p endp 727 728 Badparm_p proc near ;AN007; 729 ;Show "Bad command or parameters - xxxxxx" 730 ;In Badparm_seg, Badparm_off -> xxxxx 731 ; 0 000034F9 2E803E[3609]01 cmp byte [cs:Buffer_Pre_Scan], 1 ;AN030; Pre scanning Buffers ... /X? 0 000034FF 7429 je BadParmp_Ret ;AN030; then do not show any message. 0 00003501 1E push ds ;AN007; 0 00003502 52 push dx ;AN007; 0 00003503 56 push si ;AN007; 737 0 00003504 0E push cs ;AN007; 0 00003505 1F pop ds ;AN007; 0 00003506 BA[0000] mov dx, offset Badparm ;AN007; 0 00003509 E8[0000] invoke PRINT ;AN007;"Bad command or parameters - " 742 Badparm_ptr equ Badparm_Ptr ; NASM port label 0 0000350C C536[0400] lds si, [Badparm_ptr] ;AN007; 744 Badparm_Prt: ;AN007;print "xxxx" until CR. 0 00003510 8A14 mov dl, byte ptr [si] ;AN007; 746 STD_CON_OUTPUT equ Std_Con_Output ; NASM port equate 0 00003512 B402 mov ah,STD_CON_OUTPUT ;AN007; 0 00003514 CD21 int 21h ;AN007; 0 00003516 46 inc si ;AN007; 0 00003517 80FA0D cmp dl, CR ;AN007; 0 0000351A 75F4 jne Badparm_Prt ;AN007; 0 0000351C 0E push cs ;AN007; 0 0000351D 1F pop ds ;AN007; 0 0000351E BA[0000] mov dx, offset CRLFM ;AN007; 0 00003521 E8[0000] invoke PRINT ;AN007; 0 00003524 E8400C call Error_Line ;AN007; 0 00003527 5E pop si ;AN007; 0 00003528 5A pop dx ;AN007; 0 00003529 1F pop ds ;AN007; 760 BadParmp_Ret: ;AN030; 0 0000352A C3 ret ;AN007; 762 Badparm_p endp 763 764 NOPROB: ;GET FILE SIZE (NOTE < 64K!!) 0 0000352B 89C3 MOV BX,AX 0 0000352D 31C9 XOR CX,CX 0 0000352F 31D2 XOR DX,DX 768 LSEEK equ LSeek ; NASM port equate 0 00003531 B80242 MOV AX,(LSEEK << 8) | 2 0 00003534 CD21 INT 21H 771 772 continue_no_file: 0 00003536 BEFEFE mov si, 64 * 1024 - 1 - 1 - 256 ; maximum size 774 ; 1 = offset of end <= 0FFFFh 775 ; 1 = linebreak we'll append 776 ; 256 = maximum length of APPEND/PREPEND kernel command line names 0 00003539 85D2 test dx, dx ; >= 64 KiB ? 0 0000353B 7504 jnz .overflow ; yes --> 0 0000353D 39F0 cmp ax, si 0 0000353F 7608 jbe .fine 781 .overflow: 0 00003541 BA[0000] mov dx, config_overflow 0 00003544 E8[0000] invoke PRINT 0 00003547 89F0 mov ax, si 785 .fine: 0 00003549 A3[0000] MOV [COUNT],AX ; true file size to read 787 0 0000354C 83C001 add ax, 1 789 config_size equ Config_Size ; NASM port label 0 0000354F A3[0000] mov [config_size], ax ;save the size of config.sys file. 791 0 00003552 D006[860A] rol byte [no_config_file], 1 0 00003556 7207 jc @F 794 0 00003558 31D2 XOR DX,DX 0 0000355A B80042 MOV AX,LSEEK << 8 ;Reset pointer to beginning of file 0 0000355D CD21 INT 21H 798 799 @@: 0 0000355F 57 push di 0 00003560 53 push bx 0 00003561 BB[490B] mov bx, .add 0 00003564 E8B000 call parse_configuration_command_line 0 00003567 EB05 jmp @F 805 806 .add: 0 00003569 010E[0000] add [config_size], cx ; add in PREPEND= / APPEND= line length 0 0000356D C3 retn 809 810 @@: 0 0000356E 5B pop bx 0 0000356F 5F pop di 813 0 00003570 57 push di 0 00003571 53 push bx 816 0 00003572 A1[0000] MOV AX,[config_size] 0 00003575 BE[0000] mov si, alloc_initconfig 0 00003578 E8[0000] call allocate_temporary_block 0 0000357B 8C06[0000] MOV [config_block], es ; Config starts here. New CONBOT value. 821 ; CALL TEMPCDS ; Finally get CDS to "safe" location 822 ASSUME DS:NOTHING,ES:NOTHING 823 0 0000357F 0E push cs 0 00003580 1F pop ds 0 00003581 8B16[0000] MOV DX,[config_block] 0 00003585 8EC2 MOV ES,DX 0 00003587 31D2 XOR DX,DX ; es:dx -> config buffer 829 0 00003589 BB[710B] mov bx, .prepend 0 0000358C E88800 call parse_configuration_command_line 0 0000358F EB14 jmp @F 833 834 .prepend: 0 00003591 81FF[0000] cmp di, nameprepend 0 00003595 750D jne .retn 0 00003597 29CE sub si, cx 0 00003599 87D7 xchg dx, di 0 0000359B F3A4 rep movsb 0 0000359D 26C645FF0A mov byte [es:di - 1], 10 ; LF 0 000035A2 87D7 xchg dx, di 842 .retn: 0 000035A4 C3 retn 844 845 @@: 0 000035A5 5B pop bx 0 000035A6 5F pop di 848 0 000035A7 06 push es 0 000035A8 1F pop ds ; ds:dx -> where to read config file 0 000035A9 2E8B0E[0000] MOV CX,[cs:COUNT] 0 000035AE 31C0 xor ax, ax ; NC, ax = 0 0 000035B0 E305 jcxz @F 854 READ equ Read ; NASM port equate 0 000035B2 B43F MOV AH,READ 0 000035B4 F9 STC ;IN CASE OF INT 24 0 000035B5 CD21 INT 21H ;Function request 858 @@: 0 000035B7 9C PUSHF 860 ; 861 ; Find the EOF mark in the file. If present, then trim length. 862 0 000035B8 505751 SaveReg 0 000035BB 91 xchg cx, ax ; cx = length actually read 0 000035BC B01A MOV AL,1Ah ; eof mark 0 000035BE 89D7 MOV DI,DX ; point ro buffer 0 000035C0 E305 JCXZ PutEOL ; no chars 0 000035C2 F2AE REPNZ SCASB ; find end 0 000035C4 7501 JNZ PutEOL ; none found and count exahusted 870 ; 871 ; We found a 1A. Back up 872 ; 0 000035C6 4F DEC DI ; backup past 1A 874 ; 875 ; Just for the halibut, stick in an extra EOL 876 ; 877 PutEOL: 0 000035C7 B00A MOV AL,LF 0 000035C9 AA STOSB ; ! LF only 880 0 000035CA 0E push cs 0 000035CB 1F pop ds 0 000035CC 89FA mov dx, di 0 000035CE 53 push bx 0 000035CF BB[B70B] mov bx, .append 0 000035D2 E84200 call parse_configuration_command_line 0 000035D5 EB14 jmp @F 888 889 .append: 0 000035D7 81FF[0000] cmp di, nameappend 0 000035DB 750D jne .retn 0 000035DD 29CE sub si, cx ; -> content 0 000035DF 87D7 xchg dx, di 0 000035E1 F3A4 rep movsb ; store in buffer 0 000035E3 26C645FF0A mov byte [es:di - 1], 10 ; LF 0 000035E8 87D7 xchg dx, di 897 .retn: 0 000035EA C3 retn 899 900 @@: 0 000035EB 5B pop bx 0 000035EC 87D7 xchg dx, di ; di = size of configuration 903 904 Count equ COUNT ; NASM port label 0 000035EE 893E[0000] MOV [Count],DI ; new count 906 ; 907 ; Restore registers 908 ; 0 000035F2 595F58 RestoreReg 910 911 ASSUME DS:SYSINITSEG 0 000035F5 50 PUSH AX 0 000035F6 2ED006[860A] rol byte [cs:no_config_file], 1 0 000035FB 7204 jc @F 915 CLOSE equ Close ; NASM port equate 0 000035FD B43E MOV AH,CLOSE 0 000035FF CD21 INT 21H 918 @@: 0 00003601 58 POP AX 0 00003602 9D POPF 0 00003603 7207 JC CONFERR ;IF NOT WE'VE GOT A PROBLEM 0 00003605 39C1 CMP CX,AX 0 00003607 7503E9B400 JZ GETCOM ;COULDN'T READ THE FILE 924 CONFERR: 0 0000360C 2E8B16[0A00] MOV DX,[cs:CONFIG_used] ;WANT TO PRINT CONFIG ERROR 0 00003611 E8[0000] CALL BADFIL 0 00003614 E9C9FE ENDCONV:JMP ENDCONF 928 929 extern nameprepend, nameappend, kernelcommandline, kernelcommandline.end 930 931 ; INP: ds = cs 932 ; ds:kernelcommandline -> contents 933 ; word [kernelcommandline.end] -> end 934 ; nameprepend, nameappend 935 ; bx = callback near function 936 ; CHG: ax. si, cx, di 937 ; Callback called with: 938 ; INP: ds:si -> past name's content terminator 939 ; cx = length of content including terminator 940 ; es = unchanged 941 ; dx = unchanged 942 ; di = nameprepend or nameappend, whichever matched 943 ; CHG: cx, ax 944 ; REM: changes of dx passed back to caller 945 parse_configuration_command_line: 0 00003617 BE[0000] mov si, kernelcommandline 947 .loopcommand: 0 0000361A A8 db __TEST_IMM8 ; skip inc 949 @@: 0 0000361B 46 inc si 0 0000361C 803C20 cmp byte [si], 32 0 0000361F 74FA je @B 0 00003621 803C09 cmp byte [si], 9 0 00003624 74F5 je @B 955 0 00003626 BF[0000] mov di, nameprepend ; -> first name 957 .loopname: 0 00003629 57 push di 0 0000362A 56 push si 960 .comparename: 0 0000362B AC lodsb 0 0000362C 3C00 cmp al, 0 0 0000362E 7427 je .next 0 00003630 3C61 cmp al, 'a' 0 00003632 7206 jb @F 0 00003634 3C7A cmp al, 'z' 0 00003636 7702 ja @F 0 00003638 2C20 sub al, 20h 969 @@: 0 0000363A 06 push es 0 0000363B 0E push cs 0 0000363C 07 pop es 0 0000363D AE scasb 0 0000363E 07 pop es 0 0000363F 7516 jne .next 0 00003641 803D00 cmp byte [di], 0 0 00003644 75E5 jne .comparename 0 00003646 AC lodsb 0 00003647 3C00 cmp al, 0 0 00003649 741A je .found 0 0000364B 3C20 cmp al, 32 0 0000364D 7416 je .found 0 0000364F 3C09 cmp al, 9 0 00003651 7412 je .found 0 00003653 3C3D cmp al, '=' 0 00003655 740E je .found 987 .next: 0 00003657 5E pop si 0 00003658 5F pop di 0 00003659 81FF[0000] cmp di, nameprepend 0 0000365D 752D jne .donename 0 0000365F BF[0000] mov di, nameappend 0 00003662 EBC5 jmp .loopname 994 995 @@: 0 00003664 AC lodsb 997 .found: 0 00003665 3C20 cmp al, 32 0 00003667 74FB je @B 0 00003669 3C09 cmp al, 9 0 0000366B 74F7 je @B 0 0000366D 3C3D cmp al, '=' 0 0000366F 7501 jne @FF 1004 @@: 0 00003671 AC lodsb 1006 @@: 0 00003672 3C20 cmp al, 32 0 00003674 74FB je @BB 0 00003676 3C09 cmp al, 9 0 00003678 74F7 je @BB 1011 0 0000367A 4E dec si ; -> content 0 0000367B 89F1 mov cx, si 1014 .findlen: 0 0000367D AC lodsb 0 0000367E 84C0 test al, al 0 00003680 75FB jnz .findlen 0 00003682 F7D9 neg cx 0 00003684 01F1 add cx, si ; = length, including terminator 0 00003686 5F pop di ; discard si 0 00003687 5F pop di ; restore di 0 00003688 FFD3 call bx 0 0000368A EB05 jmp .nextcommand 1024 .donename: 1025 @@: 0 0000368C AC lodsb 0 0000368D 3C00 cmp al, 0 0 0000368F 75FB jne @B 1029 .nextcommand: 0 00003691 3B36[0000] cmp si, word [kernelcommandline.end] 0 00003695 7283 jb .loopcommand 0 00003697 C3 retn 1033 1034 1035 Multi_Pass: ;AN018;AN026; called to execute IFS=, INSTALL= commands 0 00003698 0E push cs ;AN018; 0 00003699 1F pop ds ;AN018; 1038 Multi_Pass_id equ Multi_Pass_Id ; NASM port label 0 0000369A 803E[0000]0A cmp byte [Multi_Pass_id], 10 ;J.K. 1040 Endconv equ ENDCONV ; NASM port label 0 0000369F 7203E970FF jae Endconv ;J.K. Do nothing. Just return. 0 000036A4 8E06[0000] mov es, word [config_block] ; => config 0 000036A8 8B36[0000] mov si, [Org_Count] ;AN018; 0 000036AC 8936[0000] mov [Count], si ;AN018; set Count 0 000036B0 31F6 xor si,si ;AN018; 1046 Chrptr equ CHRPTR ; NASM port label 0 000036B2 8936[0000] mov [Chrptr], si ;AN018; reset Chrptr, LineCount 0 000036B6 8936[0000] mov [LineCount], si ;AN018; 1049 GetChr equ GETCHR ; NASM port label 0 000036BA E8840A call GetChr ;AN018; 1051 Conflp equ CONFLP ; NASM port label 0 000036BD EB07 jmp Conflp ;AN018; 0 000036BF 90 nop ; identicalise 1054 GETCOM: 0 000036C0 E8[0000] invoke ORGANIZE ;ORGANIZE THE FILE 0 000036C3 E87B0A CALL GETCHR 1057 0 000036C6 7303E949FF CONFLP: JC ENDCONV 0 000036CB E86E0B call Reset_DOS_Version ;AN024;AN026; Still need to reset version even IBMDOS handles this through 1060 ; function 4Bh call, since IBMDOS does not know when Load/Overlay call finishes. 1061 1062 %ifndef BUF2 1063 %IFN BUFFERFLAG 1064 EMS_Stub_handler equ EMS_Stub_Handler ; NASM port label 1065 call EMS_Stub_handler ;AN030; 1066 %ENDIF 1067 %endif 1068 0 000036CE FF06[0000] inc word [LineCount] ;AN000; Increase LineCount. 0 000036D2 C606[3609]00 mov byte [Buffer_Pre_Scan], 0 ;AN030; Reset Buffer_Pre_Scan. 0 000036D7 C606[0000]00 mov byte [MultDeviceFlag],0 ;AN001; Reset MultDeviceFlag. 0 000036DC C606[0300]00 mov byte [SetDevMarkFlag],0 ;AN004; Reset SetDevMarkFlag. 0 000036E1 3C0A cmp al, LF ;AN000; LineFeed? 0 000036E3 741B je Blank_Line ;AN000; then ignore this line. 0 000036E5 88C4 MOV AH,AL 0 000036E7 E8570A CALL GETCHR 1077 TryI equ TRYI ; NASM port label 0 000036EA 731B jnc TryI ;AN000; 1079 Multi_Pass_ID equ Multi_Pass_Id ; NASM port label 0 000036EC 803E[0000]02 cmp byte [Multi_Pass_ID], 2 ;AN026; 0 000036F1 7203E91EFF jae Endconv ;AN026;Do not show Badop again for multi_pass. 0 000036F6 E9E8FD JMP BADOP 1083 0 000036F9 0E COFF: PUSH CS 0 000036FA 1F POP DS 0 000036FB E8[0000] invoke NEWLINE 0 000036FE EBC6 JMP CONFLP 1088 Blank_Line: ;AN000; 1089 Getchr equ GETCHR ; NASM port label 0 00003700 E83E0A call Getchr ;AN000; 0 00003703 EBC1 jmp CONFLP ;AN000; 1092 1093 COFF_P: 0 00003705 0E push cs 0 00003706 1F pop ds 1096 1097 1098 ;J.K. 1/27/88 ;;;;;;;;;;;;;;;;;; 1099 ;To handle INSTALL= commands, we are going to use multi-pass. 1100 ;The first pass handles the other commands and only set Install_Flag when 1101 ;it finds any INSTALL command. The second pass will only handle the 1102 ;INSTALL= command. 1103 1104 ;------------------------------------------------------------------------------ 1105 ;INSTALL command 1106 ;------------------------------------------------------------------------------ 1107 TRYI: 0 00003707 803E[0000]00 cmp byte [Multi_Pass_Id], 0 ;AN029; the initial pass for XMAEM.SYS 0 0000370C 7422 je Multi_Try_XMAEM ;AN029; and BUFFERS= ... /X pre scan. 0 0000370E 803E[0000]02 cmp byte [Multi_Pass_Id], 2 ;AN026; the second pass for IFS= ? 0 00003713 743F je Multi_Try_J ;AN026; 0 00003715 803E[0000]03 cmp byte [Multi_Pass_Id], 3 ;AN026; the third pass for INSTALL= ? 0 0000371A 7440 je Multi_Try_I ;AN026; 0 0000371C 80FC69 cmp ah, 'i' 0 0000371F 7408 je .install 0 00003721 80FC49 cmp ah, 'I' ;AN018; INSTALL= command? 0 00003724 7403E99900 jne TryB ;AN018; the first pass is for normal operation. 1118 .install: 0 00003729 830E[0000]01 or word [Install_Flag], HAVE_INSTALL_CMD ;AN018; Set the flag 1120 coff equ COFF ; NASM port label 0 0000372E EBC9 jmp coff ;AN018; and handles the next command 1122 1123 Multi_Try_XMAEM: ;AN029; 0 00003730 80FC64 cmp ah, 'd' 0 00003733 7405 je .devicehigh 0 00003735 80FC44 cmp ah, 'D' ;AN029; device= command? 0 00003738 750D jne Multi_Try_Buff ;AN029; no skip it. 1128 .devicehigh: 0 0000373A E8C90A call Chk_XMAEM ;AN029; is it for XMAEM.SYS? 1130 Multi_Pass_FIlter equ Multi_Pass_Filter ; NASM port label 0 0000373D 7542 jnz Multi_Pass_FIlter ;AN029; no skip it. 0 0000373F 26C644FFFF mov byte ptr [es:si-1], 0FFh ;AN029; mark this command as a Null command for the next pass. 1133 TryDJ equ TRYDJ ; NASM port label 0 00003744 E9BA01 jmp TryDJ ;AN029; execute this command. 1135 Multi_Try_Buff: ;AN030; 0 00003747 80FC42 cmp ah, 'B' ;AN030; Buffers= command? 0 0000374A 7535 jne Multi_Pass_Filter ;AN030; 0 0000374C C606[3609]01 mov byte [Buffer_Pre_Scan], 1 ;AN030; Set Buffer_Pre_Scan 0 00003751 EB6F jmp TryB ;AN030; TryB will set P_Buffer_Slash_X to non-zero value. 0 00003753 90 nop ; identicalise 1141 1142 Multi_Try_J: ;AN026; 0 00003754 80FC4A cmp ah, 'J' ;AN026; IFS= command? 0 00003757 7528 jne Multi_Pass_Filter ;AN026; No. Ignore this. 1145 GotJ equ GOTJ ; NASM port label 0 00003759 E9C401 jmp GotJ ;AN026; Handles IFS= command. 1147 1148 Multi_Try_I: ;AN026; 0 0000375C 2EC606[1C00]00 mov byte [cs:devicehighflag], 0 0 00003762 80FC69 cmp ah, 'i' 0 00003765 7507 jne @F 0 00003767 2EF616[1C00] not byte [cs:devicehighflag] 0 0000376C B449 mov ah, 'I' 1154 @@: 0 0000376E 80FC49 cmp ah, 'I' ;AN026; INSTALL= command? 0 00003771 750E jne Multi_Pass_Filter ;AN026; No. Ignore this. 0 00003773 E8[0000] call Do_Install_Exec ;Install it. 1158 1159 extern init2_relocate_device 1160 0 00003776 06 push es 0 00003777 B8FFFF mov ax, -1 0 0000377A E8[0000] call init2_relocate_device 0 0000377D 07 pop es 1165 1166 Coff equ COFF ; NASM port label 0 0000377E E978FF jmp Coff ;to handle next Install= command. 1168 1169 Multi_Pass_Filter: ;AN023;AN026; 0 00003781 80FC59 cmp ah, 'Y' ;AN023; Comment? 0 00003784 740A je Multi_Pass_Adjust ;AN023; 0 00003786 80FC5A cmp ah, 'Z' ;AN023; Bad command? 0 00003789 7405 je Multi_Pass_Adjust ;AN023; 0 0000378B 80FC30 cmp ah, '0' ;AN023; REM? 0 0000378E 7508 jne Multi_Pass_Coff ;AN023; ignore the rest of the commands. 1176 Multi_Pass_Adjust: ;AN023; These commands need to 0 00003790 FF0E[0000] dec word [Chrptr] ;AN023; adjust chrptr, count 0 00003794 FF06[0000] inc word [Count] ;AN023; for NEWLINE proc. 1179 Multi_Pass_Coff: ;AN023; 0 00003798 E95EFF jmp Coff ;AN018; To handle next INSTALL= commands. 1181 1182 ;------------------------------------------------------------------------------ 1183 1184 Sysinit_Parse proc 1185 ;Set up registers for SysParse 1186 ;In) ES:SI -> command line in CONFBOT 1187 ; DI -> offset of the parse control defintion. 1188 ; 1189 ;Out) Calls SYSPARSE. 1190 ; Carry will set if Parse error. 1191 ; *** The caller should check the EOL condition by looking at AX 1192 ; *** after each call. 1193 ; *** If no parameters are found, then AX will contain a error code. 1194 ; *** If the caller needs to look at the SYNOMYM@ of the result, 1195 ; *** the caller should use CS:@ instead of ES:@. 1196 ; CX register should be set to 0 at the first time the caller calls this 1197 ; procedure. 1198 ; AX - exit code 1199 ; BL - TErminated delimeter code 1200 ; CX - new positional ordinal 1201 ; SI - set to pase scanned operand 1202 ; DX - selected result buffer 1203 0 0000379B 06 push es ;save es,ds 0 0000379C 1E push ds 1206 0 0000379D 06 push es 0 0000379E 1F pop ds ;now DS:SI -> command line 0 0000379F 0E push cs 0 000037A0 07 pop es ;now ES:DI -> control definition 1211 0 000037A1 2E8C1E[0600] mov [cs:Badparm_Seg],ds ;AN007;Save the pointer to the parm 0 000037A6 2E8936[0400] mov [cs:Badparm_Off],si ;AN007; we are about to parse for Badparm msg. 0 000037AB BA0000 mov dx, 0 0 000037AE E83EF3 call SysParse 1216 D_P_NO_ERROR equ D_P_No_Error ; NASM port equate 0 000037B1 83F800 cmp ax, D_P_NO_ERROR ;no error 1218 ; $IF E,OR 0 000037B4 7405 JE DD_LL1 0 000037B6 83F8FF cmp ax, D_P_RC_EOL ;or the end of line? 1221 ; $IF E 0 000037B9 7503 JNE DD_IF1 1223 DD_LL1: 0 000037BB F8 clc 1225 ; $ELSE 0 000037BC EB01 JMP SHORT DD_EN1 1227 DD_IF1: 0 000037BE F9 stc 1229 ; $ENDIF 1230 DD_EN1: 0 000037BF 1F pop ds 0 000037C0 07 pop es ;restore es,ds 0 000037C1 C3 ret 1234 Sysinit_Parse endp 1235 1236 ;------------------------------------------------------------------------------ 1237 ; Buffer command 1238 ;------------------------------------------------------------------------------ 1239 ;******************************************************************************* 1240 ; * 1241 ; Function: Parse the parameters of buffers= command. * 1242 ; * 1243 ; Input : * 1244 ; ES:SI -> parameters in command line. * 1245 ; Output: * 1246 ; Buffers set * 1247 ; Buffer_Slash_X flag set if /X option chosen. * 1248 ; H_Buffers set if secondary buffer cache specified. * 1249 ; * 1250 ; Subroutines to be called: * 1251 ; Sysinit_Parse * 1252 ; Logic: * 1253 ; { * 1254 ; Set DI points to Buf_Parms; /*Parse control definition*/ * 1255 ; Set DX,CX to 0; * 1256 ; Reset Buffer_Slash_X; * 1257 ; While (End of command line) * 1258 ; { Sysinit_parse; * 1259 ; if (no error) then * 1260 ; if (Result_Val.D_P_SYNONYM_ptr == Slash_E) then /*Not a switch * 1261 ; Buffer_Slash_X = 1 * 1262 ; else if (CX == 1) then /* first positional */ * 1263 ; Buffers = Result_Val.D_P_Picked_Val; * 1264 ; else H_Buffers = Result_Val.D_P_Picked_Val; * 1265 ; else {Show Error message;Error Exit} * 1266 ; }; * 1267 ; If (Buffer_Slash_X is off & Buffers > 99) then Show_Error; * 1268 ; }; * 1269 ; * 1270 ;******************************************************************************* 1271 ;TryB: CMP AH,'B' ;BUFFER COMMAND? 1272 ; JNZ TRYC 1273 ; invoke GETNUM 1274 ; JZ TryBBad ; Gotta have at least one 1275 ; CMP AX,100 ; check for max number 1276 ; JB SaveBuf 1277 ;TryBBad:JMP BadOp 1278 ;SaveBuf: 1279 ; MOV [BUFFERS],AX 1280 ;CoffJ1: JMP COFF 1281 1282 TryB: 0 000037C2 80FC42 CMP AH,'B' 0 000037C5 7570 JNZ TryC 0 000037C7 C606[3509]00 mov byte [P_Buffer_Slash_X], 0 ;AN000;AN025; 0 000037CC BF[EE08] mov di, offset Buf_Parms ;AN000; 0 000037CF 31C9 xor cx, cx ;AN000; 0 000037D1 89CA mov dx, cx ;AN000; 1289 1290 ; $SEARCH ;AN000; 1291 DD_DO4: 0 000037D3 E8C5FF call Sysinit_Parse ;AN000; 1293 ; $EXITIF C ;AN000; Parse Error, 0 000037D6 7305 JNC DD_IF4 0 000037D8 E81EFD call Badparm_p ;AN007; and Show messages and end the search loop. 1296 ; $ORELSE ;AN000; 0 000037DB EB57 JMP SHORT DD_SR4 1298 DD_IF4: 0 000037DD 83F8FF cmp ax, D_P_RC_EOL ;AN000; End of Line? 1300 ; $LEAVE E ;AN000; then jmp to $Endloop for semantic check. 0 000037E0 7421 JE DD_EN4 1302 D_P_SYNONYM_PTR equ D_P_SYNONYM_Ptr ; NASM port equate 0 000037E2 813E[3A09][2E09] cmp word [Result_Val + D_P_SYNONYM_PTR], offset Switch_X ;AN000;AN025; 1304 ; $IF E ;AN000; 0 000037E8 7507 JNE DD_IF8 0 000037EA C606[3509]01 mov byte [P_Buffer_Slash_X], 1 ;AN000;AN025; set the flag 1307 ; $ELSE ;AN000; 0 000037EF EB10 JMP SHORT DD_EN8 1309 DD_IF8: 1310 D_P_PICKED_VAL equ D_P_Picked_Val ; NASM port equate 0 000037F1 A1[3C09] mov ax, word ptr [Result_Val + D_P_PICKED_VAL] ;AN000; 0 000037F4 83F901 cmp cx, 1 ;AN000; 1313 ; $IF E ;AN000; 0 000037F7 7505 JNE DD_IF10 0 000037F9 A3[3109] mov [P_Buffers], ax ;AN000; 1316 ; $ELSE ;AN000; 0 000037FC EB03 JMP SHORT DD_EN10 1318 DD_IF10: 0 000037FE A3[3309] mov [P_H_Buffers], ax ;AN000; 1320 ; $ENDIF ;AN000; 1321 DD_EN10: 1322 ; $ENDIF ;AN000; 1323 DD_EN8: 1324 ; $ENDLOOP ;AN000; 0 00003801 EBD0 JMP SHORT DD_DO4 1326 DD_EN4: 0 00003803 833E[3109]63 cmp word [P_Buffers], 99 ;AN000; 1328 ; $IF A,AND ;AN000; 0 00003808 7612 JNA DD_IF15 0 0000380A 803E[3509]00 cmp byte [P_Buffer_Slash_X], 0 ;AN000;AN025; 1331 ; $IF E ;AN000; 0 0000380F 750B JNE DD_IF15 0 00003811 E8E5FC call Badparm_p ;AN000; 0 00003814 C706[3309]0000 mov word [P_H_Buffers], 0 ;AN000; 1335 ; $ELSE ;AN000; 0 0000381A EB18 JMP SHORT DD_EN15 1337 DD_IF15: 0 0000381C A1[3109] mov ax, [P_Buffers] ;AN000; We don't have any problem. 1339 Buffers equ BUFFERS ; NASM port label 0 0000381F A3[0000] mov [Buffers], ax ;AN000; Now, let's set it really. 0 00003822 A1[3309] mov ax, [P_H_Buffers] ;AN000; 0 00003825 A3[0000] mov [H_Buffers], ax ;AN000; 0 00003828 A0[3509] mov al, [P_Buffer_Slash_X] ;AN000;AN025; 0 0000382B A2[0000] mov [Buffer_Slash_X], al ;AN000;AN025; 0 0000382E A1[0000] mov ax, [LineCount] ;AN000; 0 00003831 A3[0000] mov [Buffer_LineNum], ax ;AN000; Save the line number for the future use. 1347 ; $ENDIF ;AN000; 1348 DD_EN15: 1349 ; $ENDSRCH ;AN000; 1350 DD_SR4: 0 00003834 E9C2FE jmp Coff 1352 1353 ;------------------------------------------------------------------------------ 1354 ; Break command 1355 ;------------------------------------------------------------------------------ 1356 ;******************************************************************************* 1357 ; * 1358 ; Function: Parse the parameters of Break = command. * 1359 ; * 1360 ; Input : * 1361 ; ES:SI -> parameters in command line. * 1362 ; Output: * 1363 ; Turn the Control-C check on or off. * 1364 ; * 1365 ; Subroutines to be called: * 1366 ; Sysinit_Parse * 1367 ; Logic: * 1368 ; { * 1369 ; Set DI to Brk_Parms; * 1370 ; Set DX,CX to 0; * 1371 ; While (End of command line) * 1372 ; { Sysinit_Parse; * 1373 ; if (no error) then * 1374 ; if (Result_Val.D_P_Item_Tag == 1) then /*ON */ * 1375 ; Set P_Ctrl_Break, on; * 1376 ; else /*OFF */ * 1377 ; Set P_Ctrl_Break, off; * 1378 ; else {Show message;Error_Exit}; * 1379 ; }; * 1380 ; If (no error) then * 1381 ; DOS function call to set Ctrl_Break check according to * 1382 ; }; * 1383 ; * 1384 ;******************************************************************************** 1385 ;TryC: CMP AH,'C' 1386 ; JZ GOTC 1387 ; JMP TRYDJ 1388 ;GOTC: 1389 ; CMP AL,'O' ;FIRST LETTER OF "ON" or "OFF" 1390 ; JNZ TryCBad 1391 ; CALL GETCHR 1392 ; JC TryCBad 1393 ; CMP AL,'N' ;SECOND LETTER OF "ON" 1394 ; JNZ TryCoff 1395 ; MOV AH,SET_CTRL_C_TRAPPING ;TURN ON CONTROL-C CHECK 1396 ; MOV AL,1 1397 ; MOV DL,AL 1398 ; INT 21H 1399 ;CoffJ2: JMP Coff 1400 ;TryCOff:CMP AL,'F' 1401 ; JNZ TryCBad ; Check for "OFF" 1402 ; CALL GetChr 1403 ; JC TryCBad 1404 ; CMP AL,'F' 1405 ; JZ COffJ2 1406 ;TryCBad:JMP BadOp 1407 ; 1408 TryC: 0 00003837 80FC43 CMP AH,'C' 1410 TRYM equ TryM ; NASM port label 0 0000383A 7538 JNZ TRYM 0 0000383C BF[4009] mov di, offset Brk_Parms ;AN000; 0 0000383F 31C9 xor cx,cx ;AN000; 0 00003841 89CA mov dx,cx ;AN000; 1415 ; $SEARCH ;AN000; 1416 DD_DO19: 0 00003843 E855FF call Sysinit_Parse ;AN000; 1418 ; $EXITIF C ;AN000; Parse error 0 00003846 7305 JNC DD_IF19 0 00003848 E8AEFC call Badparm_p ;AN007; Show message and end the serach loop. 1421 ; $ORELSE ;AN000; 0 0000384B EB24 JMP SHORT DD_SR19 1423 DD_IF19: 0 0000384D 83F8FF cmp ax, D_P_RC_EOL ;AN000; End of Line? 1425 ; $LEAVE E ;AN000; then end the $ENDLOOP 0 00003850 7415 JE DD_EN19 1427 D_P_ITEM_TAG equ D_P_Item_Tag ; NASM port equate 0 00003852 803E[3909]01 cmp byte [Result_Val + D_P_ITEM_TAG], 1 ;AN000; 1429 ; $IF E ;AN000; 0 00003857 7507 JNE DD_IF23 0 00003859 C606[6509]01 mov byte [P_Ctrl_Break], 1 ;AN000; Turn it on 1432 ; $ELSE ;AN000; 0 0000385E EB05 JMP SHORT DD_EN23 1434 DD_IF23: 0 00003860 C606[6509]00 mov byte [P_Ctrl_Break], 0 ;AN000; Turn it off 1436 ; $ENDIF ;AN000; 1437 DD_EN23: 1438 ; $ENDLOOP ;AN000; we actually set the ctrl break 0 00003865 EBDC JMP SHORT DD_DO19 1440 DD_EN19: 1441 SET_CTRL_C_TRAPPING equ Set_CTRL_C_Trapping ; NASM port equate 0 00003867 B433 mov ah, SET_CTRL_C_TRAPPING ;AN000; if we don't have any parse error. 0 00003869 B001 mov al, 1 ;AN000; 0 0000386B 8A16[6509] mov dl, [P_Ctrl_Break] ;AN000; 0 0000386F CD21 Int 21h ;AN000; 1446 ; $ENDSRCH ;AN000; 1447 DD_SR19: 0 00003871 E985FE jmp Coff 1449 1450 ;------------------------------------------------------------------------------ 1451 ; MultiTrack command 1452 ;------------------------------------------------------------------------------ 1453 ;******************************************************************************* 1454 ; * 1455 ; Function: Parse the parameters of MultiTrack= command. * 1456 ; * 1457 ; Input : * 1458 ; ES:SI -> parameters in command line. * 1459 ; Output: * 1460 ; Turn MulTrk_Flag on or off. * 1461 ; * 1462 ; Subroutines to be called: * 1463 ; Sysinit_Parse * 1464 ; Logic: * 1465 ; { * 1466 ; Set DI to Brk_Parms; * 1467 ; Set DX,CX to 0; * 1468 ; While (End of command line) * 1469 ; { Sysinit_Parse; * 1470 ; if (no error) then * 1471 ; if (Result_Val.D_P_Item_Tag == 1) then /*ON */ * 1472 ; Set P_Mtrk, on; * 1473 ; else /*OFF */ * 1474 ; Set P_Mtrk, off; * 1475 ; else {Show message;Error_Exit}; * 1476 ; }; * 1477 ; If (no error) then * 1478 ; DOS function call to set MulTrk_Flag according to P_Mtrk. * 1479 ; * 1480 ; }; * 1481 ; * 1482 ;******************************************************************************** 1483 TryM: ;AN002; 0 00003874 80FC4D CMP AH,'M' ;AN002; 1485 TRYW equ TryW ; NASM port label 0 00003877 754B JNZ TRYW ;AN002; 1487 Mtrk_Parms equ MTrk_Parms ; NASM port label 0 00003879 BF[440A] mov di, offset Mtrk_Parms ;AN002; 0 0000387C 31C9 xor cx,cx ;AN002; 0 0000387E 89CA mov dx,cx ;AN002; 1491 ; $SEARCH ;AN002; 1492 DD_DO28: 0 00003880 E818FF call Sysinit_Parse ;AN002; 1494 ; $EXITIF C ;AN002; Parse error 0 00003883 7305 JNC DD_IF28 0 00003885 E871FC call Badparm_p ;AN007; Show message and end the serach loop. 1497 ; $ORELSE ;AN002; 0 00003888 EB37 JMP SHORT DD_SR28 1499 DD_IF28: 0 0000388A 83F8FF cmp ax, D_P_RC_EOL ;AN002; End of Line? 1501 ; $LEAVE E ;AN002; then end the $ENDLOOP 0 0000388D 7415 JE DD_EN28 0 0000388F 803E[3909]01 cmp byte [Result_Val + D_P_ITEM_TAG], 1 ;AN002; 1504 ; $IF E ;AN002; 0 00003894 7507 JNE DD_IF32 0 00003896 C606[580A]01 mov byte [P_Mtrk], 1 ;AN002; Turn it on temporarily. 1507 ; $ELSE ;AN002; 0 0000389B EB05 JMP SHORT DD_EN32 1509 DD_IF32: 0 0000389D C606[580A]00 mov byte [P_Mtrk], 0 ;AN002; Turn it off temporarily. 1511 ; $ENDIF ;AN002; 1512 DD_EN32: 1513 ; $ENDLOOP ;AN002; we actually set the MulTrk_Flag here. 0 000038A2 EBDC JMP SHORT DD_DO28 1515 DD_EN28: 0 000038A4 1E push ds ;AN002; 0 000038A5 B8[0000] mov ax, DOSENTRY ;AN002; 0 000038A8 8ED8 mov ds, ax ;AN002; 1519 assume ds:DOSENTRY 0 000038AA 2E803E[580A]00 cmp byte [cs:P_Mtrk], 0 ;AN002; 1521 ; $IF E ;AN002; 0 000038B0 7508 JNE DD_IF36 1523 MulTrk_Flag equ MulTrk_flag ; NASM port label 0 000038B2 C706[0000]0100 mov word [MulTrk_Flag], MULTRK_OFF2 ;AN002; 0001h 1525 ; $ELSE ;AN002; 0 000038B8 EB06 JMP SHORT DD_EN36 1527 DD_IF36: 0 000038BA C706[0000]8000 mov word [MulTrk_Flag], MULTRK_ON ;AN002; 8000h 1529 ; $ENDIF ;AN002; 1530 DD_EN36: 0 000038C0 1F pop ds ;AN002; 1532 assume ds:SYSINITSEG 1533 ; $ENDSRCH ;AN002; 1534 DD_SR28: 0 000038C1 E935FE jmp Coff ;AN002; 1536 1537 ;------------------------------------------------------------------------------ 1538 ; CPSW command 1539 ;------------------------------------------------------------------------------ 1540 ;******************************************************************************* 1541 ; * 1542 ; Function: Parse the parameters of CPSW= command. * 1543 ; * 1544 ; Input : * 1545 ; ES:SI -> parameters in command line. * 1546 ; Output: * 1547 ; Turn CPSW on or off. * 1548 ; * 1549 ; Subroutines to be called: * 1550 ; Sysinit_Parse * 1551 ; Logic: * 1552 ; { * 1553 ; Set DI to CPSW_Parms; * 1554 ; Set DX,CX to 0; * 1555 ; While (End of command line) * 1556 ; { Sysinit_Parse; * 1557 ; if (no error) then * 1558 ; if (Result_Val.D_P_Item_Tag == 1) then /*ON */ * 1559 ; Set P_CPSW, on; * 1560 ; else /*OFF */ * 1561 ; Set P_CPSW, off; * 1562 ; else {Show message;Error_Exit}; * 1563 ; }; * 1564 ; If (no error) then * 1565 ; DOS function call to set CPSW according to P_CPSW. * 1566 ; }; * 1567 ; * 1568 ;******************************************************************************** 1569 TryW: ;AN002; 0 000038C4 80FC57 CMP AH,'W' ;AN002; 0 000038C7 7538 JNZ TRYDJ ;AN002; 0 000038C9 BF[590A] mov di, offset CPSW_Parms ;AN002; 0 000038CC 31C9 xor cx,cx ;AN002; 0 000038CE 89CA mov dx,cx ;AN002; 1575 ; $SEARCH ;AN002; 1576 DD_DO40: 0 000038D0 E8C8FE call Sysinit_Parse ;AN002; 1578 ; $EXITIF C ;AN002; Parse error 0 000038D3 7305 JNC DD_IF40 0 000038D5 E821FC call Badparm_p ;AN007; Show message and end the serach loop. 1581 ; $ORELSE ;AN002; 0 000038D8 EB24 JMP SHORT DD_SR40 1583 DD_IF40: 0 000038DA 83F8FF cmp ax, D_P_RC_EOL ;AN002; End of Line? 1585 ; $LEAVE E ;AN002; then end the $ENDLOOP 0 000038DD 7415 JE DD_EN40 0 000038DF 803E[3909]01 cmp byte [Result_Val + D_P_ITEM_TAG], 1 ;AN002; 1588 ; $IF E ;AN002; 0 000038E4 7507 JNE DD_IF44 0 000038E6 C606[6D0A]01 mov byte [P_CPSW], 1 ;AN002; Turn it on temporarily. 1591 ; $ELSE ;AN002; 0 000038EB EB05 JMP SHORT DD_EN44 1593 DD_IF44: 0 000038ED C606[6D0A]00 mov byte [P_CPSW], 0 ;AN002; Turn it off temporarily. 1595 ; $ENDIF ;AN002; 1596 DD_EN44: 1597 ; $ENDLOOP ;AN002; we actually set the MulTrk_Flag here. 0 000038F2 EBDC JMP SHORT DD_DO40 1599 DD_EN40: 0 000038F4 B433 mov ah, SET_CTRL_C_TRAPPING ;AN000; The same function number as Ctrl_Break 0 000038F6 B004 mov al, 4 ;AN000; Set CPSW state function 0 000038F8 8A16[6D0A] mov dl, [P_CPSW] ;AN000; 0=off, 1=on 0 000038FC CD21 Int 21h ;AN000; 1604 ; $ENDSRCH ;AN002; 1605 DD_SR40: 0 000038FE E9F8FD jmp Coff ;AN002; 1607 1608 ;------------------------------------------------------------------------------ 1609 ; Device command 1610 ;------------------------------------------------------------------------------ 1611 TRYDJ: 1612 debugnumber 'DJ' 0 00003901 2EC606[1C00]00 mov byte [cs:devicehighflag], 0 0 00003907 2E8126[0000]FE00 and word [cs:IFS_Flag], NOT_IFS ;AN000; Reset the flag 0 0000390E 80FC64 cmp ah, 'd' 0 00003911 741D je GOTDJ_devicehigh 0 00003913 80FC44 CMP AH,'D' 0 00003916 741D JZ GOTDJ 0 00003918 80FC4A CMP AH,'J' 0 0000391B 7403 jz GOTJ 0 0000391D E9C904 JMP TRYQ 1622 GOTJ: ;AN000; IFS= command. 0 00003920 2E830E[0000]01 or word [cs:IFS_Flag], IS_IFS ;AN000; set the flag. 0 00003926 803E[0000]02 cmp byte [Multi_Pass_Id], 2 ;second pass? 0 0000392B 7408 je GOTDJ ;then proceed 0 0000392D E9C9FD jmp Coff ;else ignore this until the second pass. 1627 1628 ; jmp GOTDJ_Cont 1629 ;GOTD: 1630 ; test [cs:IFS_Flag], HAD_IFS ;AN000; Cannot have DEVICE= command after IFS= command. 1631 ; jz GOTDJ_Cont ;AN000; 1632 ; call Incorrect_Order ;AN000; Display "Incorrect order ..." msg. 1633 ; jmp COFF ;AN000; 1634 1635 GOTDJ_devicehigh: 0 00003930 2EF616[1C00] not byte [cs:devicehighflag] 1637 GOTDJ: 1638 debugnumber 'gt' 0 00003935 8CCB MOV BX,CS ;DEVICE= or IFS= command. 0 00003937 8EDB MOV DS,BX 1641 0 00003939 8936[0000] MOV WORD PTR [BPB_ADDR],SI 0 0000393D 8C06[0200] MOV WORD PTR [BPB_ADDR+2],ES 1644 1645 ;J.K. In case it is for IFS=, then set the parameter pointer. 1646 ifs_rh equ IFS_RH ; NASM port label 0 00003941 8936[1600] mov word ptr [ifs_rh + IFSR_PARMS@], SI ;AN000; for IFS 0 00003945 8C06[1800] mov word ptr [ifs_rh + IFSR_PARMS@+2], ES ;AN000; 1649 1650 ; We are going to open the cdevice driver and size it as is done 1651 ; in LDFIL. The reason we must do this is that EXEC does NO checking 1652 ; for us. We must make sure there is room to load the device without 1653 ; trashing SYSINIT. This code is not 1654 ; perfect (for instance .EXE device drivers are possible) because 1655 ; it does its sizing based on the assumption that the file being loaded 1656 ; is a .COM file. It is close enough to correctness to be usable. 1657 0 00003949 06 PUSH ES 0 0000394A 1F POP DS 1660 ASSUME DS:NOTHING 0 0000394B 89F2 MOV DX,SI ;DS:DX POINTS TO FILE NAME 1662 0 0000394D B8003D MOV AX,OPEN << 8 ;OPEN THE FILE 0 00003950 F9 STC ;IN CASE OF INT 24 0 00003951 CD21 INT 21H 0 00003953 7303E97601 JC BADLDRESET 0 00003958 89C3 MOV BX,AX ;Handle in BX 0 0000395A 1E push ds 0 0000395B 52 PUSH DX ; Save pointer to name 0 0000395C 31C9 XOR CX,CX 0 0000395E 31D2 XOR DX,DX 0 00003960 B80242 MOV AX,(LSEEK << 8) | 2 0 00003963 F9 STC ;IN CASE OF INT 24 0 00003964 CD21 INT 21H ; Get file size in DX:AX 0 00003966 730A JNC GO_AHEAD_LOAD 0 00003968 B43E MOV AH,CLOSE ; Close file 0 0000396A CD21 INT 21H 0 0000396C 5A POP DX ; Clean stack 0 0000396D 5A pop dx ; discard ds 0 0000396E F9 STC ; Close may clear carry 0 0000396F E95C01 JMP BADLDRESET 1682 1683 GO_AHEAD_LOAD: 1684 ; Convert size in DX:AX to para in AX 0 00003972 83C00F ADD AX,15 ; Round up size for conversion to para 0 00003975 83D200 ADC DX,0 0 00003978 7212 jc .err ; rounded up is 4 GiB ? --> 0 0000397A B90400 mov cx, 4 1689 @@: 0 0000397D D1EA shr dx, 1 0 0000397F D1D8 rcr ax, 1 0 00003981 E2FA loop @B 0 00003983 85D2 test dx, dx ; >= 1 MiB ? 0 00003985 7505 jnz .err ; --> 0 00003987 83F8F0 cmp ax, -16 ; allow for some increment 0 0000398A 7203 jb @F ; if fine --> 1697 .err: 0 0000398C E91E01 jmp MEM_ERRJY 1699 @@: 1700 0 0000398F 0E push cs 0 00003990 1F pop ds 0 00003991 A3[0C00] mov word [devicefilesizepara], ax 1704 1705 retry_devicehigh_oom: 0 00003994 8B16[0C00] mov dx, word [devicefilesizepara] 1707 ; rol byte [devicehighflag], 1 1708 ; jnc .low1 1709 .high1: 1710 0 00003998 53 push bx ; preserve handle 0 00003999 B80058 mov ax, 5800h 0 0000399C CD21 int 21h 0 0000399E 50 push ax 0 0000399F B80158 mov ax, 5801h 0 000039A2 BB4001 mov bx, 0140h ; ignore UMB link, UMA only, first fit 0 000039A5 D006[1C00] rol byte [devicehighflag], 1 0 000039A9 7203 jc @F 0 000039AB BB1001 mov bx, 0110h ; ignore UMB link, LMA only, first fit 1720 @@: 0 000039AE CD21 int 21h 1722 0 000039B0 89D3 mov bx, dx 0 000039B2 43 inc bx ; space for SD sub-MCB 0 000039B3 B448 mov ah, 48h 0 000039B5 CD21 int 21h 0 000039B7 7316 jnc @F 1728 0 000039B9 5B pop bx 0 000039BA B80158 mov ax, 5801h 0 000039BD CD21 int 21h 0 000039BF 5B pop bx ; handle 1733 0 000039C0 D006[1C00] rol byte [devicehighflag], 1 ; already tried LMA ? 0 000039C4 7306 jnc .oom ; yes --> 0 000039C6 F616[1C00] not byte [devicehighflag] ; toggle back to try LMA 0 000039CA EBC8 jmp retry_devicehigh_oom 1738 1739 .oom: 0 000039CC E9[0000] jmp MEM_ERR 1741 1742 @@: 0 000039CF 89C2 mov dx, ax 0 000039D1 5B pop bx 0 000039D2 B80158 mov ax, 5801h 0 000039D5 CD21 int 21h 1747 0 000039D7 06 push es 0 000039D8 56 push si 1750 0 000039D9 8EC2 mov es, dx 0 000039DB B44A mov ah, 4Ah 0 000039DD BBFFFF mov bx, -1 0 000039E0 CD21 int 21h ; grow to largest size 1755 1756 ; recreate stack frame of init2_relocate_device 1757 lframe 0 1758 lvar word, umb_first_umcb 1759 lvar word, umb_last_umcb 1760 lvar word, last_mcb 0 000039E2 5589E58D66FA lenter 1762 lvar word, flags 0 000039E8 50 push ax 1764 lvar word, first_mcb 0 000039E9 B452 mov ah, 52h 0 000039EB CD21 int 21h 0 000039ED 26FF77FE push word [es:bx - 2] 1768 lvar word, first_umcb 0 000039F1 B86112 mov ax, 1261h 0 000039F4 CD2F int 2Fh 0 000039F6 50 push ax 1772 0 000039F7 4A dec dx 1774 0 000039F8 31F6 xor si, si 0 000039FA 56 push si ; loop detection counter word 0 000039FB BE2000 mov si, 20h ; "LMA then UMA" (+ first fit) 0 000039FE 56 push si 0 000039FF 89E6 mov si, sp ; ss:si -> area flags and strategy word 1780 0 00003A01 31C0 xor ax, ax ; = 0 = get first UMCB 1782 .search_umb: 0 00003A03 8946FA mov word [bp + ?last_mcb], ax 0 00003A06 E8[0000] call init2_SNextMCB 0 00003A09 722A jc .no_sd_merge ; chain corrupted 0 00003A0B 7528 jnz .no_sd_merge ; end reached 1787 0 00003A0D 39D0 cmp ax, dx 0 00003A0F 75F2 jne .search_umb 1790 0 00003A11 8B46FA mov ax, word [bp + ?last_mcb] 0 00003A14 8ED8 mov ds, ax 0 00003A16 837D0108 cmp word [di + mcbOwner], 8 0 00003A1A 7519 jne .no_sd_merge 0 00003A1C 817D085344 cmp word [di + mcbName], "SD" 0 00003A21 7512 jne .no_sd_merge 0 00003A23 807D0A00 cmp byte [di + mcbName + 2], 0 0 00003A27 750C jne .no_sd_merge 1799 1800 ; ax => SD MCB immediately before ours 1801 .sd_merge: 0 00003A29 8EC2 mov es, dx ; => new MCB (to become sub MCB) 0 00003A2B 268B5D03 mov bx, [es:di + mcbSize] 1804 ; get size 0 00003A2F 43 inc bx ; count MCB itself 0 00003A30 015D03 add word [di + mcbSize], bx 1807 ; grow SD MCB 0 00003A33 EB24 jmp .merge_common 1809 1810 .no_sd_merge: 0 00003A35 8EDA mov ds, dx ; => new MCB (to become SD MCB) 0 00003A37 89D0 mov ax, dx 0 00003A39 C745010800 mov word [di + mcbOwner], 8 0 00003A3E C745085344 mov word [di + mcbName], "SD" 0 00003A43 897D0A mov word [di + mcbName + 2], di 0 00003A46 42 inc dx 0 00003A47 8EC2 mov es, dx ; => new sub MCB 0 00003A49 8B5D03 mov bx, [di + mcbSize] 0 00003A4C 4B dec bx 0 00003A4D 26895D03 mov word [es:di + mcbSize], bx 0 00003A51 26897D05 mov word [es:di + mcbReserved], di 0 00003A55 26897D07 mov word [es:di + mcbReserved + 2], di 1823 ; clear reserved fields 1824 .merge_common: 1825 ; ax => SD MCB, we are at the tail end 1826 ; es => sub-MCB we're creating 1827 ; di = 0 1828 ; dx = es 0 00003A59 26C60544 mov byte [es:di + mcbSignature], DEVMARK_DEVICE 1830 ; set devmark 0 00003A5D 42 inc dx 0 00003A5E 26895501 mov word [es:di + mcbOwner], dx 1833 ; set owner 0 00003A62 26897D08 mov word [es:di + mcbName], di 0 00003A66 26897D0A mov word [es:di + mcbName + 2], di 0 00003A6A 26897D0C mov word [es:di + mcbName + 4], di 0 00003A6E 26897D0E mov word [es:di + mcbName + 6], di 1838 ; clear name for a bit 0 00003A72 268B5D03 mov bx, word [es:di + mcbSize] 1840 ; bx = size 1841 ; ax => SD MCB, we are at the tail end 1842 ; es => sub-MCB we've created 1843 ; di = 0 1844 ; dx => data block to use 1845 ; bx = size of sub-MCB 1846 0 00003A76 89EC5D lleave 0 00003A79 0E push cs 0 00003A7A 1F pop ds 0 00003A7B A3[0E00] mov word [devicehighsd], ax 0 00003A7E 8916[1000] mov word [devicehighdata], dx 0 00003A82 891E[1200] mov word [devicehighsize], bx 0 00003A86 01D3 add bx, dx 0 00003A88 891E[1400] mov word [devicehighafter], bx 1855 0 00003A8C 06 push es 0 00003A8D 1F pop ds ; ds => sub-MCB 1858 0 00003A8E 5E pop si 0 00003A8F 07 pop es ; es:si -> filename 1861 0 00003A90 06 push es 0 00003A91 56 push si 0 00003A92 E83207 call get_device_mcb_name 0 00003A95 5E pop si 0 00003A96 07 pop es 1867 0 00003A97 92 xchg ax, dx ; ax => memory block 0 00003A98 5B pop bx ; handle 0 00003A99 EB00 jmp .common1 1871 1872 %if 0 1873 .low1: 1874 CALL ROUND 1875 ;J.K. Set up the DEVMARK entries here for MEM command. 1876 ;J.K. Only the DEVMARK_ID and DEVMARK_FILENAME will be set. 1877 ;J.K. DEVMARK_SIZE should be set after a successful process of this file. 1878 call Set_DevMark ;AN004; 1879 inc word [MEMHI] ;AN004;Size of DEVMARK is a paragraph!! 1880 ;Don't forget decrease MEMHI 1881 ; with an unsuccessful process of this file!!. 1882 MOV AX,[MEMHI] 1883 %endif 1884 1885 .common1: 0 00003A9B 0E push cs 0 00003A9C 1F pop ds 0 00003A9D 8326[0000]00 and WORD PTR [ENTRY_POINT], 0 0 00003AA2 A3[0200] MOV WORD PTR [ENTRY_POINT+2],AX ;SET ENTRY POINT 1890 0 00003AA5 A3[0000] MOV [PRMBLK],AX ;SET LOAD OFFSET 0 00003AA8 A3[0200] MOV [PRMBLK + 2],AX ;SET LOAD OFFSET 1893 1894 %if 1 0 00003AAB EB03 jmp OKLDX 1896 %else 1897 rol byte [devicehighflag], 1 1898 jc OKLDX ; already know for devicehigh --> 1899 MOV CX,ax ; CX:0 is xaddr 1900 ADD CX, [devicefilesizepara]; New device will take up to here 1901 JC MEM_ERRJY ; WOW!!!! 1902 CMP CX, [ALLOCLIM] 1903 JB OKLDX 1904 %endif 1905 1906 MEM_ERRJY: 0 00003AAD E9[0000] JMP MEM_ERR 1908 1909 OKLDX: 0 00003AB0 5A POP DX ; Recover name pointer 0 00003AB1 1F pop ds 0 00003AB2 B43E MOV AH,CLOSE ; Close file 0 00003AB4 CD21 INT 21H 0 00003AB6 0E push cs 0 00003AB7 07 pop es 0 00003AB8 BB[0000] MOV BX,OFFSET PRMBLK ;ES:BX POINTS TO PARAMETERS 0 00003ABB B003 MOV AL,3 1918 EXEC equ Exec ; NASM port equate 0 00003ABD B44B MOV AH,EXEC 0 00003ABF F9 STC ;IN CASE OF INT 24 0 00003AC0 CD21 INT 21H ;LOAD IN THE DEVICE DRIVER 0 00003AC2 2EC606[1D00]FF mov byte [cs:device_init_first_dpb], -1 0 00003AC8 2E830E[1800]FF or word [cs:devicelastdpb], -1 1924 1925 BADLDRESET: 0 00003ACE 1E PUSH DS 0 00003ACF 07 POP ES ;ES:SI BACK TO CONFIG.SYS 0 00003AD0 0E PUSH CS 0 00003AD1 1F POP DS ;DS BACK TO SYSINIT 1930 ASSUME DS:SYSINITSEG 0 00003AD2 731A JNC GOODLD 1932 BADBRK: 0 00003AD4 2EF606[0300]01 test byte [cs:SetDevMarkFlag],SETBRKDONE ;AN004;If already Set_Break is done, 0 00003ADA 7503 jnz Skip0_ResetMEMHI ;AN004; then do not 1935 ; dec word [cs:MEMHI] ;AN004;Adjust MEMHI by a paragrah of DEVMARK. 0 00003ADC E81C01 call release_device_memory 1937 Skip0_ResetMEMHI: 0 00003ADF 26803C0D cmp byte ptr [es:si], CR ;file name is CR? (Somebody entered "device=" without filename) 0 00003AE3 7503 jne BADBRK_1 0 00003AE5 E9F9F9 jmp BADOP ;show "Unrecognized command in CONFIG.SYS" 1941 BADBRK_1: 0 00003AE8 E8[0000] invoke BADLOAD 0 00003AEB E90BFC JMP COFF 1944 1945 GOODLD: 1946 ;J.K. If it is IFS=, then we should set IFS_DOSCALL@ field in IFSHEADER. 0 00003AEE 2EF706[0000]0100 test word [cs:IFS_Flag], IS_IFS ;AN000; 0 00003AF5 7422 jz Skip_IFSHEADER_Set ;AN000; 0 00003AF7 06 push es ;AN000; 0 00003AF8 57 push di ;AN000; 0 00003AF9 1E push ds ;AN000; 0 00003AFA 2E8B1E[0200] mov bx, word ptr [cs:ENTRY_POINT+2] ;AN000; 0 00003AFF 8EDB mov ds, bx ;AN000; DS:0 will be the header 1954 DosInfo equ DOSINFO ; NASM port label 0 00003B01 2EC43E[0000] les di, [cs:DosInfo] ;AN000; 0 00003B06 268B5D37 mov bx, word ptr [es:di + SYSI_IFS_DOSCALL@] ;AN000; 0 00003B0A 891E1000 mov word ptr [IFS_DOSCALL@], bx ;AN000; 0 00003B0E 268B5D39 mov bx, word ptr [es:di + SYSI_IFS_DOSCALL@ + 2] ;AN000; 0 00003B12 891E1200 mov word ptr [IFS_DOSCALL@ + 2], bx ;AN000; 0 00003B16 1F pop ds ;AN000; 0 00003B17 5F pop di ;AN000; 0 00003B18 07 pop es ;AN000; 1963 Skip_IFSHEADER_Set: ;AN000; 0 00003B19 0656 SaveReg ;INITIALIZE THE DEVICE 1965 ; call Chk_IBMCACHE ;AN024 IBMCACHE.SYS problem.;AN026;IBMDOS will handles this thru 4Bh call. 0 00003B1B 268A1C Restore:MOV BL,[ES:SI] ; while ((c=*p) != 0) 0 00003B1E 84DB test BL,BL 0 00003B20 7403 JZ Got 0 00003B22 46 INC SI ; p++; 0 00003B23 EBF6 JMP Restore 0 00003B25 26C60420 Got: MOV BYTE PTR [ES:SI],' ' ; *p = ' '; 0 00003B29 0656 SaveReg 0 00003B2B 0E PUSH CS 0 00003B2C 07 POP ES 1975 0 00003B2D 2EF706[0000]0100 test word [cs:IFS_Flag], IS_IFS ;AN000; 0 00003B34 7408 jz Got_Device_Com ;AN000; 0 00003B36 BB1400 mov bx, IFS_CALL@ ;AN000; offset from the start of IFSHEADER 0 00003B39 E86606 call CallIFS ;AN000; 0 00003B3C EB47 jmp short End_Init_Call 1981 Got_Device_Com: 0 00003B3E 1E push ds ;AN017; 0 00003B3F 56 push si ;AN017; 0 00003B40 2EC536[0000] lds si, [cs:ENTRY_POINT] ;AN017; Peeks the header attribute 0 00003B45 F744040080 test word ptr [si + SDEVATT], DEVTYP ;AN017;Block device driver? 0 00003B4A 7512 jnz Got_Device_Com_Cont ;AN017;No. 0 00003B4C 2EC536[0000] lds si, [cs:DOSINFO] ;AN017; DS:SI -> SYS_VAR 0 00003B51 807C201A cmp byte [si + SYSI_NUMIO], 26 ;AN017; No more than 26 drive number 0 00003B55 7207 jb Got_Device_Com_Cont ;AN017; 0 00003B57 5E pop si ;AN017; 0 00003B58 1F pop ds ;AN017; 0 00003B59 5E pop si ;AN017;clear the stack 0 00003B5A 07 pop es ;AN017; 0 00003B5B E93F01 jmp BadNumBlock ;AN017; 1995 Got_Device_Com_Cont: ;AN017; 0 00003B5E 5E pop si ;AN017; 0 00003B5F 1F pop ds ;AN017; 1998 0 00003B60 2ED006[0000] rol byte [cs:MultDeviceFlag], 1 0 00003B65 7212 jc .keepbreak 0 00003B67 2EA1[1400] mov ax, word [cs:devicehighafter] 2002 %if 0 2003 rol byte [cs:devicehighflag], 1 2004 jc .common3 2005 .low3: 2006 alloclim equ ALLOCLIM ; NASM port label 2007 mov ax, [cs:alloclim] 2008 %endif 2009 .common3: 2010 Break_addr equ BREAK_ADDR ; NASM port label 0 00003B6B 2E8326[0000]00 and word ptr [cs:Break_addr], 0 0 00003B71 2EA3[0200] mov word ptr [cs:Break_addr+2], ax 0 00003B75 2EA3[1600] mov word [cs:deviceafter], ax 2014 .keepbreak: 0 00003B79 BB0600 MOV BX,SDEVSTRAT 0 00003B7C E8[0000] invoke CALLDEV ; CallDev (SDevStrat); 0 00003B7F BB0800 MOV BX,SDEVINT 0 00003B82 E8[0000] invoke CALLDEV ; CallDev (SDevInt); 2019 debugnumber 'rt' 2020 End_Init_Call: 0 00003B85 5E1F RestoreReg 0 00003B87 C60400 MOV BYTE PTR [SI],0 ; *p = 0; 2023 0 00003B8A 0E PUSH CS 0 00003B8B 1F POP DS 2026 0 00003B8C F706[0000]0100 test word [IFS_Flag], IS_IFS ;AN000; 0 00003B92 7503E99400 jz Was_Device_Com ;AN000; 0 00003B97 803E[0300]00 cmp byte [ifs_rh + IFSR_RETCODE], 0 ;AN000; Was a success ? 2030 Erase_Dev_do equ ERASE_DEV_do ; NASM port label 0 00003B9C 753C jne Erase_Dev_do ;AN000; 0 00003B9E 5E pop si ;AN000; restore es:si to clean up the 0 00003B9F 07 pop es ;AN000; stack for Set_Break call. 2034 Entry_Point equ ENTRY_POINT ; NASM port label 0 00003BA0 A1[0200] mov ax, word ptr [Entry_Point+2] ;AN000; Get the loaded segment 0 00003BA3 0306[1A00] add ax, word ptr [ifs_rh + IFSR_RESSIZE] ;AN000; 0 00003BA7 8326[0000]00 and word ptr [Break_addr], 0 ;AN000; 0 00003BAC A3[0200] mov word ptr [Break_addr+2], ax ;AN000; 0 00003BAF E8[0000] invoke Set_Break ;AN000; Will also check the memory size too. 0 00003BB2 06 push es ;AN000; Save it again, in case, for Erase_Dev_Do. 0 00003BB3 56 push si ;AN000; 0 00003BB4 7224 jc Erase_Dev_do ;AN000; 2043 Link_IFS: ;AN000; 2044 dosinfo equ DOSINFO ; NASM port label 0 00003BB6 2EC43E[0000] les di, [cs:dosinfo] ;AN000; 0 00003BBB 268B4D3B mov cx, word ptr [es:di + SYSI_IFS] ;AN000; save old pointer 0 00003BBF 268B553D mov dx, word ptr [es:di + SYSI_IFS+2] ;AN000; 0 00003BC3 2EC536[0000] lds si, [cs:Entry_Point] ;AN000; 0 00003BC8 2689753B mov word ptr [es:di + SYSI_IFS],si ;AN000; 0 00003BCC 268C5D3D mov word ptr [es:di + SYSI_IFS+2], ds ;AN000; 0 00003BD0 890C mov word ptr [si], cx ;AN000; We don't permit multiple IFSs. 0 00003BD2 895402 mov word ptr [si+2], dx ;AN000; 0 00003BD5 5E pop si ;AN000; Restore es:si for the next command. 0 00003BD6 07 pop es ;AN000; 2055 ; mov [cs:IFS_Flag], HAD_IFS ;AN014; Set the flag. 0 00003BD7 E91FFB jmp COFF ;AN000; 2057 2058 ERASE_DEV_do: ;AC000;; Modified to show message "Error in CONFIG.SYS..." 0 00003BDA 5E pop si 0 00003BDB 07 pop es 0 00003BDC 0E push cs 0 00003BDD 1F pop ds 2063 0 00003BDE F606[0300]01 test byte [SetDevMarkFlag],SETBRKDONE ;AN004;If already Set_Break is done, 0 00003BE3 7503 jnz Skip1_ResetMEMHI ;AN004; then do not 2066 ; dec word [MEMHI] ;AN004;Adjust MEMHI by a paragrah of DEVMARK. 0 00003BE5 E81300 call release_device_memory 2068 Skip1_ResetMEMHI: 0 00003BE8 833E[0000]00 cmp word [ConfigMsgFlag], 0 ;AN015; 0 00003BED 7409 je No_Error_Line_Msg ;AN015; 0 00003BEF E87505 call Error_Line ;AN021; No "Error in CONFIG.SYS" msg for device driver. DCR D493 0 00003BF2 C706[0000]0000 mov word [ConfigMsgFlag], 0 ;AN015;AN021;Set the default value again. 2073 No_Error_Line_Msg: ;AN015; 0 00003BF8 E9D501 JMP COFF_relocate 2075 2076 release_device_memory: 0 00003BFB 1E push ds 0 00003BFC 0E push cs 0 00003BFD 1F pop ds 2080 ; rol byte [devicehighflag], 1 2081 ; jnc .low2 2082 .high2: 0 00003BFE 06 push es 0 00003BFF 50 push ax 0 00003C00 53 push bx 2086 0 00003C01 A1[0E00] mov ax, word [devicehighsd] 0 00003C04 40 inc ax ; => SD MCB's data 0 00003C05 8B1E[1000] mov bx, word [devicehighdata] 0 00003C09 4B dec bx ; => sub-MCB 0 00003C0A 8EC0 mov es, ax 0 00003C0C 29C3 sub bx, ax ; = size of SD to keep 0 00003C0E 7412 jz @F ; if to free --> 0 00003C10 B44A mov ah, 4Ah 0 00003C12 CD21 int 21h ; shrink SD MCB, cannot fail 0 00003C14 8CC0 mov ax, es 0 00003C16 48 dec ax 0 00003C17 8EC0 mov es, ax ; => SD MCB 0 00003C19 26C70601000800 mov word [es:mcbOwner], 8 ; reset owner changed by 21.4A 0 00003C20 EB04 jmp @FF 2101 @@: 0 00003C22 B449 mov ah, 49h 0 00003C24 CD21 int 21h ; free SD MCB 2104 @@: 0 00003C26 5B pop bx 0 00003C27 58 pop ax 0 00003C28 07 pop es 0 00003C29 1F pop ds 0 00003C2A C3 retn 2110 %if 0 2111 .low2: 2112 dec word [MEMHI] ; Adjust MEMHI by a paragraph of DEVMARK. 2113 pop ds 2114 retn 2115 %endif 2116 2117 Was_Device_Com: ;AN000; 2118 break_addr equ BREAK_ADDR ; NASM port label 0 00003C2B A1[0000] mov ax, word ptr [break_addr] 0 00003C2E E8[0000] call ParaRound 0 00003C31 0306[0200] add ax, word ptr [break_addr + 2] 0 00003C35 7206 jc .bad 0 00003C37 3B06[1600] cmp ax, word [deviceafter] 0 00003C3B 7605 jbe BREAKOK 2125 .bad: 0 00003C3D 5E POP SI 0 00003C3E 07 POP ES 0 00003C3F E992FE JMP BADBRK 2129 2130 BREAKOK: 0 00003C42 A3[1600] mov word [deviceafter], ax ; for multi device drivers 0 00003C45 C516[0000] LDS DX,[ENTRY_POINT] ;SET DS:DX TO HEADER 0 00003C49 89D6 MOV SI,DX 0 00003C4B 83C604 ADD SI,SDEVATT ;DS:SI POINTS TO ATTRIBUTES 0 00003C4E 2EC43E[0000] LES DI,[CS:DOSINFO] ;ES:DI POINT TO DOS INFO 0 00003C53 8B04 MOV AX,[SI] ;GET ATTRIBUTES 0 00003C55 A90080 TEST AX,DEVTYP ;TEST IF BLOCK DEV 0 00003C58 7425 JZ ISBLOCK 0 00003C5A E8[0000] invoke Set_Break ; Go ahead and alloc mem for device 0 00003C5D 7303E978FF jc Erase_Dev_do ;device driver's Init routien failed. 0 00003C62 A90100 TEST AX,ISCIN ;IS IT A CONSOLE IN? 0 00003C65 7408 JZ TRYCLK 0 00003C67 2689550C MOV WORD PTR [ES:DI + SYSI_CON],DX 0 00003C6B 268C5D0E MOV WORD PTR [ES:DI + SYSI_CON+2],DS 2145 0 00003C6F A90800 TRYCLK: TEST AX,ISCLOCK ;IS IT A CLOCK DEVICE? 0 00003C72 7408 JZ GOLINK 0 00003C74 26895508 MOV WORD PTR [ES:DI+SYSI_CLOCK],DX 0 00003C78 268C5D0A MOV WORD PTR [ES:DI+SYSI_CLOCK+2],DS 0 00003C7C E91801 GOLINK: JMP LINKIT 2151 2152 ISBLOCK: 0 00003C7F 2EA0[0000] MOV AL,[CS:UNITCOUNT] ;IF NO UNITS FOUND, erase the device 0 00003C83 08C0 OR AL,AL 0 00003C85 7503E950FF jz Erase_Dev_do 2156 ; JNZ PERDRV 2157 ; MOV AX, -1 2158 ; JMP ENDDEV 2159 2160 PERDRV: 0 00003C8A B400 mov ah, 0 0 00003C8C 89C1 MOV CX,AX 0 00003C8E 88E6 MOV DH,AH 0 00003C90 268A5520 MOV DL,[ES:DI + SYSI_NUMIO] ;GET NUMBER OF DEVICES 0 00003C94 88D4 MOV AH,DL 0 00003C96 00C4 ADD AH,AL ; Check for too many devices 0 00003C98 80FC1A CMP AH,26 ; 'A' - 'Z' is 26 devices 0 00003C9B 760B JBE OK_BLOCK 2169 BadNumBlock: ;AN017; 0 00003C9D 0E PUSH CS 0 00003C9E 1F POP DS 0 00003C9F BA[0000] MOV DX,OFFSET BADBLOCK 0 00003CA2 E8[0000] invoke PRINT 0 00003CA5 E932FF JMP ERASE_DEV_do 2175 2176 OK_BLOCK: 0 00003CA8 E8[0000] invoke SET_BREAK ; Alloc the device 0 00003CAB 26004520 ADD [ES:DI + SYSI_NUMIO],AL ;UPDATE THE AMOUNT 2179 DriveNumber equ DRIVENUMBER ; NASM port label 0 00003CAF 2E0006[0000] ADD [CS:DriveNumber],AL ; remember amount for next device 0 00003CB4 2EC51E[0000] LDS BX,[CS:BPB_ADDR] ;POINT TO BPB ARRAY 2182 PERUNIT: 0 00003CB9 2EC42E[0000] LES BP,[CS:DOSINFO] 0 00003CBE 26C46E00 LES BP,[ES:BP + SYSI_DPB] ;GET FIRST DPB 2185 2186 DPB_NEXT_DPB equ dpb_next_dpb ; NASM port equate 0 00003CC2 26837E19FF SCANDPB:CMP WORD PTR [ES:BP + DPB_NEXT_DPB],-1 0 00003CC7 7406 JZ FOUNDPB 0 00003CC9 26C46E19 LES BP,[ES:BP + DPB_NEXT_DPB] 0 00003CCD EBF3 JMP SCANDPB 2191 FOUNDPB: 0 00003CCF 52 push dx 0 00003CD0 53 push bx 0 00003CD1 51 push cx 2195 0 00003CD2 1E push ds 0 00003CD3 56 push si 0 00003CD4 06 push es 0 00003CD5 57 push di 2200 0 00003CD6 2EC43E[1800] les di, [cs:devicelastdpb] 0 00003CDB 83FFFF cmp di, -1 0 00003CDE 750B jne .try_extend 2204 .alloc: 0 00003CE0 B82100 mov ax, DPBSIZ 0 00003CE3 BE[0000] mov si, alloc_dpb_no_hma 0 00003CE6 E8[0000] call allocate_relocate_block 0 00003CE9 EB03 jmp @F 2209 2210 .try_extend: 0 00003CEB 83C721 add di, DPBSIZ 2212 @@: 0 00003CEE 2E893E[1800] mov word [cs:devicelastdpb], di 0 00003CF3 2E8C06[1A00] mov word [cs:devicelastdpb + 2], es 0 00003CF8 8D4D0F lea cx, [di + 15] 0 00003CFB D1E9 shr cx, 1 0 00003CFD D1E9 shr cx, 1 0 00003CFF D1E9 shr cx, 1 0 00003D01 D1E9 shr cx, 1 ; old size (must succeed) 2220 0 00003D03 8D5D30 lea bx, [di + DPBSIZ + 15] 0 00003D06 D1EB shr bx, 1 0 00003D08 D1EB shr bx, 1 0 00003D0A D1EB shr bx, 1 0 00003D0C D1EB shr bx, 1 ; new size 0 00003D0E B44A mov ah, 4Ah 0 00003D10 CD21 int 21h ; can we have it ? 0 00003D12 7314 jnc .extended ; yes --> 0 00003D14 89CB mov bx, cx 0 00003D16 B44A mov ah, 4Ah 0 00003D18 CD21 int 21h ; restore to old size 0 00003D1A 8CC0 mov ax, es 0 00003D1C 48 dec ax 0 00003D1D 8EC0 mov es, ax 0 00003D1F 26C70601000800 mov word [es:mcbOwner], 8 ; reset owner 0 00003D26 EBB8 jmp .alloc 2237 2238 .extended: 0 00003D28 8CC0 mov ax, es 0 00003D2A 48 dec ax 0 00003D2B 8EC0 mov es, ax 0 00003D2D 26C70601000800 mov word [es:mcbOwner], 8 ; reset owner 2243 0 00003D34 5F pop di ;AN004; 0 00003D35 07 pop es ;AN004; 0 00003D36 5E pop si ;AN004; 0 00003D37 1F pop ds ;AN004; 2248 0 00003D38 59 pop cx 0 00003D39 5B pop bx 0 00003D3A 5A pop dx 2252 0 00003D3B 2EA1[1800] MOV AX,[cs:devicelastdpb] 0 00003D3F 26894619 MOV WORD PTR [ES:BP + DPB_NEXT_DPB],AX 0 00003D43 2EA1[1A00] MOV AX,[cs:devicelastdpb + 2] 0 00003D47 2689461B MOV WORD PTR [ES:BP + DPB_NEXT_DPB+2],AX 0 00003D4B 2EC42E[1800] LES BP,[cs:devicelastdpb] 0 00003D50 26834E19FF or WORD PTR [ES:BP + DPB_NEXT_DPB],-1 2259 DPB_FIRST_ACCESS equ dpb_first_access ; NASM port equate 0 00003D55 26C64618FF MOV byte [ES:BP + DPB_FIRST_ACCESS],-1 2261 0 00003D5A 8B37 MOV SI,[BX] ;DS:SI POINTS TO BPB 0 00003D5C 43 INC BX 0 00003D5D 43 INC BX ;POINT TO NEXT GUY 2265 DPB_DRIVE equ dpb_drive ; NASM port equate 0 00003D5E 26895600 MOV WORD PTR [ES:BP + DPB_DRIVE],DX 2267 SETDPB equ SetDPB ; NASM port equate 0 00003D62 B453 MOV AH,SETDPB ;HIDDEN SYSTEM CALL 0 00003D64 CD21 INT 21H 2270 DPB_SECTOR_SIZE equ dpb_sector_size ; NASM port equate 0 00003D66 268B4602 MOV AX,[ES:BP + DPB_SECTOR_SIZE] 0 00003D6A 06 PUSH ES 0 00003D6B 2EC43E[0000] LES DI,[CS:DOSINFO] ;ES:DI POINT TO DOS INFO 0 00003D70 263B4510 CMP AX,[ES:DI + SYSI_MAXSEC] 0 00003D74 07 POP ES 0 00003D75 7764 ja Bad_BPB_Size_Sector 0 00003D77 1E PUSH DS 0 00003D78 52 PUSH DX 0 00003D79 2EC516[0000] LDS DX,[CS:ENTRY_POINT] 2280 DPB_DRIVER_ADDR equ dpb_driver_addr ; NASM port equate 0 00003D7E 26895613 MOV WORD PTR [ES:BP + DPB_DRIVER_ADDR],DX 0 00003D82 268C5E15 MOV WORD PTR [ES:BP + DPB_DRIVER_ADDR+2],DS 0 00003D86 5A POP DX 0 00003D87 1F POP DS 0 00003D88 42 INC DX 0 00003D89 FEC6 INC DH 0 00003D8B E207 LOOP j_PERUNIT 0 00003D8D 0E PUSH CS 0 00003D8E 1F POP DS 0 00003D8F E8[0000] CALL TEMPCDS ; Set CDS for new drives 0 00003D92 EB03 jmp LINKIT 2292 2293 j_PERUNIT: 0 00003D94 E922FF jmp PERUNIT 2295 2296 LINKIT: 0 00003D97 2EC43E[0000] LES DI,[CS:DOSINFO] ;ES:DI = DOS TABLE 0 00003D9C 268B4D22 MOV CX,WORD PTR [ES:DI + SYSI_DEV] ;DX:CX = HEAD OF LIST 0 00003DA0 268B5524 MOV DX,WORD PTR [ES:DI + SYSI_DEV+2] 2300 0 00003DA4 2EC536[0000] LDS SI,[CS:ENTRY_POINT] ;DS:SI = DEVICE LOCATION 0 00003DA9 26897522 MOV WORD PTR [ES:DI + SYSI_DEV],SI ;SET HEAD OF LIST IN DOS 0 00003DAD 268C5D24 MOV WORD PTR [ES:DI + SYSI_DEV+2],DS 0 00003DB1 8B04 MOV AX,[SI] ;GET POINTER TO NEXT DEVICE 0 00003DB3 2EA3[0000] MOV WORD PTR [CS:ENTRY_POINT],AX ;AND SAVE IT 2306 0 00003DB7 890C MOV WORD PTR [SI],CX ;LINK IN THE DRIVER 0 00003DB9 895402 MOV WORD PTR [SI+2],DX 2309 ENDDEV: 0 00003DBC 5E POP SI 0 00003DBD 07 POP ES 0 00003DBE 40 INC AX ;AX = FFFF (no more devs if YES)? 0 00003DBF 7409 JZ COFFJ3 0 00003DC1 2EC606[0000]FF mov byte [cs:MultDeviceFlag], -1 ;AN001; Possibly multiple device driver. 0 00003DC7 E924FD JMP GOODLD ;OTHERWISE PRETEND WE LOADED IT IN 2316 COFFJ3: 0 00003DCA 2EC606[0000]00 mov byte [cs:MultDeviceFlag], 0 ;AN001; Reset the flag 2318 2319 COFF_relocate: 0 00003DD0 06 push es 0 00003DD1 B8FFFF mov ax, -1 0 00003DD4 E8[0000] call init2_relocate_device 0 00003DD7 07 pop es 0 00003DD8 E91EF9 JMP COFF 2325 2326 Bad_BPB_Size_Sector: 0 00003DDB 5E POP SI 0 00003DDC 07 POP ES 0 00003DDD BA[0000] MOV DX,OFFSET BADSIZ_PRE 2330 ; MOV BX,OFFSET BADSIZ_POST 0 00003DE0 BB[0000] mov bx, offset CRLFM ;AN???; 0 00003DE3 E8[0000] invoke PRNERR 2333 %if 0 ; flag is never clear here 2334 test byte [SetDevMarkFlag],SETBRKDONE ;AN004;If already Set_Break is done, 2335 jnz Skip2_ResetMEMHI ;AN004; then do not 2336 ; dec word [MEMHI] ;AN004;Adjust MEMHI by a paragrah of DEVMARK. 2337 call release_device_memory 2338 Skip2_ResetMEMHI: 2339 %endif 0 00003DE6 E910F9 JMP COFF 2341 2342 2343 ;------------------------------------------------------------------------------ 2344 ; Country command 2345 ; J.K. The syntax is: 2346 ; COUNTRY=country id {,codepage {,path}} 2347 ; COUNTRY=country id {,,path} :Default CODEPAGE ID in DOS 2348 ;------------------------------------------------------------------------------ 2349 TRYQ: 0 00003DE9 80FC51 CMP AH,'Q' 0 00003DEC 7403 JZ TRYQ_CONT 0 00003DEE E93A01 JMP TRYF 2353 TRYQ_CONT: 2354 2355 ; invoke GETNUM 2356 ; JZ TryQBad ; 0 is never a valid code, or number is 2357 ; ; bad 2358 ; MOV BX,AX ; Country code in BX 2359 ; 2360 ; ;J.K. 5/26/86 2361 ; MOV DX,0 ; assume no code page id 2362 ; 2363 ; invoke skip_delim ;skip the delimeters after the first num 2364 ; jc TryQ_Def_File ;no more characters left? then use default file 2365 ; cmp al, CR ; 2366 ; je TryQ_Def_File 2367 ; cmp al, LF 2368 ; jne TRYQ_YES_EXTENDED 2369 ; inc [COUNT] ;This is for NEWLINE routine in COFF. 2370 ; dec [CHRPTR] 2371 ;COFFJ41: 2372 ; JMP TryQ_Def_File ;O.K. no code page, no path specified. Use default path. 2373 ; 2374 ;TRYQ_YES_EXTENDED: 2375 ; cmp al, ',' ;was the second comma? 2376 ; jne TryQ_GETNUM 2377 ; invoke skip_delim ;Yes, skip ',' and other possible delim 2378 ; jmp short TRYQ_PATH ;and No code page id entered. 2379 ;TRYQ_GETNUM: 2380 ; invoke GETNUM 2381 ; jc TryQBadCOM ;"Country=xxx,path" will not be accepted. 2382 ;; jc TRYQ_PATH ;Codepage is not specified. No code page. 2383 ;; ;At this point, AL already contain the 2384 ;; ;first char of the PATH. 2385 ; jz TryQBad ;codepage=0 entered. Error 2386 ; mov DX, AX ;save code page in DX 2387 ; invoke skip_delim ;move CHRPTR to the path string 2388 ; jc TryQ_Def_File ;no more char? then use default filename 2389 ; cmp al, CR 2390 ; je TryQ_Def_File 2391 ; cmp al, LF 2392 ; jne TryQ_PATH ;path entered. 2393 ; inc [COUNT] 2394 ; dec [CHRPTR] 2395 ;TryQ_Def_File: 2396 ; push dx ;save code page 2397 ; mov cs:CNTRY_DRV, 0 ;flag that the default path has been used!!! 2398 ; mov dx, offset CNTRY_ROOT ;the default path 2399 ; jmp TRYQ_OPEN 2400 ; 2401 ;TryQBad: ;"Invalid country code or code page" 2402 ; STC 2403 ; MOV DX,OFFSET BADCOUNTRY 2404 ; jmp TryQChkErr 2405 ; 2406 ;TryQBadCOM: ;Error in COUNTRY command 2407 ; STC 2408 ; MOV DX,OFFSET BADCOUNTRYCOM 2409 ; jmp TryQChkErr 2410 ; 2411 ;TRYQ_PATH: ;DS - sysinitseg, ES - CONFBOT, 2412 ; mov CX, [COUNT] ;AL - the first char of path 2413 ; inc CX ;BX - country id, DX - codepage id, 0 = No code page 2414 ; mov DI, SI 2415 ;TRYQ_PATH_LOOP: ;find the end of path to put 0 after that. 2416 ; mov AL, byte ptr [ES:DI] 2417 ; call delim 2418 ; jz TRYQ_PATH_END 2419 ; cmp al, 13 2420 ; jz TRYQ_PATH_END 2421 ; inc DI 2422 ; jmp short TRYQ_PATH_LOOP 2423 ;TryQBad_Brg:jmp short TryQBad 2424 ;TRYQ_PATH_END: 2425 ; mov byte ptr [es:di], 0 ;make it a ASCIIZ string. (Organize did not handle this string) 2426 ; push ds ;switch ds,es 2427 ; push es 2428 ; pop ds 2429 ; pop es 2430 ; 2431 ; mov di, offset CNTRY_DRV ;move the user specified path to CNTRY_DRV 2432 ; call Move_ASCIIZ 2433 ; 2434 ; push ds ;restore ds,es 2435 ; push es 2436 ; pop ds 2437 ; pop es 2438 ; 2439 ;; call Set_Country_Path ;set CNTRY_DRV 2440 ; 2441 ; push dx ;save DX 2442 ; mov dx, offset CNTRY_DRV ;Now DS:DX -> CNTRY_DRV 2443 0 00003DF1 C606[0000]00 mov byte [Cntry_Drv], 0 ;AN000; Reset the drive,path to default value. 0 00003DF6 C706[9D09]0000 mov word [P_Code_Page],0 ;AN000; 0 00003DFC BF[6609] mov di, offset Cntry_Parms ;AN000; 0 00003DFF 31C9 xor cx,cx ;AN000; 0 00003E01 89CA mov dx,cx ;AN000; 2449 ; $SEARCH ;AN000; 2450 DD_DO49: 0 00003E03 E895F9 call Sysinit_Parse ;AN000; 2452 ; $EXITIF C ;AN000; Parse error, check the error code and 0 00003E06 730B JNC DD_IF49 0 00003E08 E80C01 call Cntry_Error ;AN000; Show message and end the serach loop. 0 00003E0B C706[9B09]FFFF mov word [P_Cntry_Code], -1 ;AN000; Signals that parse error. 2456 ; $ORELSE ;AN000; 0 00003E11 EB34 JMP SHORT DD_SR49 2458 DD_IF49: 0 00003E13 83F8FF cmp ax, D_P_RC_EOL ;AN000; End of Line? 2460 ; $LEAVE E ;AN000; then end the $SEARCH LOOP 0 00003E16 742F JE DD_EN49 2462 D_P_NUMBER equ D_P_Number ; NASM port equate 2463 D_P_TYPE equ D_P_Type ; NASM port equate 0 00003E18 803E[3809]01 cmp byte [Result_Val + D_P_TYPE], D_P_NUMBER ;AN000; Numeric? 2465 ; $IF E ;AN000; 0 00003E1D 7512 JNE DD_IF53 0 00003E1F A1[3C09] mov ax, word ptr [Result_Val + D_P_PICKED_VAL] ;AN000; 0 00003E22 83F901 cmp cx, 1 ;AN000; 2469 ; $IF E ;AN000; 0 00003E25 7505 JNE DD_IF54 0 00003E27 A3[9B09] mov [P_Cntry_Code], ax ;AN000; 2472 ; $ELSE ;AN000; 0 00003E2A EB03 JMP SHORT DD_EN54 2474 DD_IF54: 0 00003E2C A3[9D09] mov [P_Code_Page], ax ;AN000; 2476 ; $ENDIF ;AN000; 2477 DD_EN54: 2478 ; $ELSE ;AN000; Path entered. 0 00003E2F EB14 JMP SHORT DD_EN53 2480 DD_IF53: 0 00003E31 1E push ds ;AN000; 0 00003E32 06 push es ;AN000; 0 00003E33 56 push si ;AN000; 0 00003E34 57 push di ;AN000; 0 00003E35 0E push cs ;AN000; 0 00003E36 07 pop es ;AN000; 0 00003E37 C536[3C09] lds si, [RV_Dword] ;AN000; Move the path to known place. 2488 CNTRY_Drv equ Cntry_Drv ; NASM port label 0 00003E3B BF[0000] mov di, offset CNTRY_Drv ;AN000; 0 00003E3E E8[0000] call Move_ASCIIZ ;AN000; 0 00003E41 5F pop di ;AN000; 0 00003E42 5E pop si ;AN000; 0 00003E43 07 pop es ;AN000; 0 00003E44 1F pop ds ;AN000; 2495 ; $ENDIF ;AN000; 2496 DD_EN53: 2497 ; $ENDLOOP 0 00003E45 EBBC JMP SHORT DD_DO49 2499 DD_EN49: 2500 ; $ENDSRCH ;AN000; 2501 DD_SR49: 0 00003E47 833E[9B09]FF cmp word [P_Cntry_Code], -1 ;AN000; Had a parse error? 0 00003E4C 750A jne TRYQ_OPEN ;AN000; 0 00003E4E E9A8F8 jmp Coff ;AN000; 2505 2506 TryQBad: ;"Invalid country code or code page" 0 00003E51 F9 STC 0 00003E52 BA[0000] MOV DX,OFFSET BADCOUNTRY 0 00003E55 E99100 jmp TryQChkErr 2510 2511 TRYQ_OPEN: 0 00003E58 803E[0000]00 cmp byte [CNTRY_Drv], 0 ;AC000; 0 00003E5D 7406 je TRYQ_Def ;AC000; 0 00003E5F BA[0000] mov dx, offset CNTRY_Drv ;AC000; 0 00003E62 EB04 jmp TryQ_Openit ;AC000; 0 00003E64 90 nop ; identicalise 2517 TRYQ_Def: ;AC000; 2518 CNTRY_Root equ Cntry_Root ; NASM port label 0 00003E65 BA[0000] mov dx, offset CNTRY_Root ;AC000; 2520 TryQ_Openit: 0 00003E68 B8003D mov ax, 3d00h ;open a file 0 00003E6B F9 stc 0 00003E6C CD21 int 21h 0 00003E6E 7257 jc TryQFileBad ;open failure 2525 2526 CntryFileHandle equ CNTRYFILEHANDLE ; NASM port label 0 00003E70 2EA3[0000] mov [cs:CntryFileHandle], ax ;save file handle 0 00003E74 89C3 mov bx, ax 0 00003E76 2EA1[9B09] mov ax, [cs:P_Cntry_Code] ;AN000; 0 00003E7A 2E8B16[9D09] mov dx, [cs:P_Code_Page] ;AN000; Now, AX=country id, bx=filehandle 2531 ; xchg ax, bx ;now, AX = country id, BX = file handle 2532 0 00003E7F 50 push ax 0 00003E80 53 push bx 0 00003E81 52 push dx 0 00003E82 1E push ds 0 00003E83 06 push es 0 00003E84 BE[0000] mov si, alloc_init 0 00003E87 B80008 mov ax, 2048 ;I need 2K buffer to handle COUNTRY.SYS 0 00003E8A 31D2 xor dx, dx 0 00003E8C E8[0000] call allocate_temporary_block.large_allow_error 0 00003E8F 8CC1 mov cx, es 0 00003E91 07 pop es 0 00003E92 1F pop ds 0 00003E93 5A pop dx 0 00003E94 5B pop bx 0 00003E95 58 pop ax 0 00003E96 724D jc TryQMemory ;cannot allocate the buffer for country.sys 0 00003E98 2E890E[0800] mov word [cs:country_block], cx 2550 2551 CNTRY_DRV equ Cntry_Drv ; NASM port label 0 00003E9D BE[0000] mov si, offset CNTRY_DRV ;DS:SI -> CNTRY_DRV 0 00003EA0 803C00 cmp byte ptr [si],0 ;default path? 0 00003EA3 7502 jne TRYQ_Set_for_DOS 0 00003EA5 46 inc si 0 00003EA6 46 inc si ;DS:SI -> CNTRY_ROOT 2557 TRYQ_Set_for_DOS: 2558 SYSI_Country equ SYSI_COUNTRY ; NASM port label 0 00003EA7 2EC43E[0000] les di, [cs:SYSI_Country] ;ES:DI -> country info tab in DOS 0 00003EAC 57 push di ;save di 0 00003EAD 83C708 add di, ccPath_CountrySys 2562 MOVE_ASCIIZ equ Move_ASCIIZ ; NASM port label 0 00003EB0 E8[0000] call MOVE_ASCIIZ ;Set the path to COUNTRY.SYS in DOS. 0 00003EB3 5F pop di ;ES:DI -> country info tab again. 0 00003EB4 2E8B0E[0800] mov cx, word [cs:country_block] 0 00003EB9 8ED9 mov ds, cx 0 00003EBB 31F6 xor si, si ;DS:SI -> 2K buffer to be used. 0 00003EBD E8[0000] call SetDOSCountryInfo ;now do the job!!! 2569 TryQchkERR equ TryQChkErr ; NASM port label 0 00003EC0 7327 jnc TryQchkERR ;read error or could not find country,code page combination 0 00003EC2 83F9FF cmp cx, -1 ;Could not find matching country_id,code page? 0 00003EC5 748A je TryQBad ;then "Invalid country code or code page" 2573 TryQFileBad: 0 00003EC7 0E push cs ;AN000; 0 00003EC8 07 pop es ;AN000; 0 00003EC9 2E803E[0000]00 cmp byte [cs:CNTRY_DRV],0 ;Is the default file used? 0 00003ECF 7405 je TryQDefBad 2578 ; mov si, [cs:CONFBOT] 2579 ; mov es, si 2580 ; mov si, [cs:CHRPTR] 2581 ; dec si ;ES:SI -> path in CONFBOT 0 00003ED1 BE[0000] mov si, offset CNTRY_Drv 0 00003ED4 EB03 jmp short TryQBADLOAD 2584 TryQDefBad: ;Default file has been used. 2585 ; push cs 2586 ; pop es 2587 CNTRY_ROOT equ Cntry_Root ; NASM port label 0 00003ED6 BE[0000] mov si, offset CNTRY_ROOT ;ES:SI -> \COUNTRY.SYS in SYSINIT_SEG 2589 TryQBADLOAD: 0 00003ED9 E8[0000] call BADLOAD ;DS will be restored to SYSINIT_SEG 0 00003EDC 2E8B0E[0000] mov cx, [cs:config_block] 0 00003EE1 8EC1 mov es, cx ;Restore ES -> CONFBOT. 0 00003EE3 EB15 jmp short CoffJ4 2594 TryQMemory: 0 00003EE5 F9 stc 0 00003EE6 BA[0000] MOV DX,OFFSET INSUFMEMORY 2597 TryQChkErr: 0 00003EE9 2E8B0E[0000] mov cx, [cs:config_block] 0 00003EEE 8EC1 mov es, cx ;restore ES -> CONFBOT seg 0 00003EF0 0E push cs 0 00003EF1 1F pop ds ;retore DS to SYSINIT_SEG 0 00003EF2 7306 jnc CoffJ4 ;if no error, then exit 0 00003EF4 E8[0000] invoke PRINT ;else show error message 0 00003EF7 E86D02 call Error_Line ;AN000; 2605 CoffJ4: 0 00003EFA 31C0 xor ax, ax 0 00003EFC 8706[0800] xchg ax, word [country_block] 0 00003F00 85C0 test ax, ax 0 00003F02 7408 jz @F 0 00003F04 06 push es 0 00003F05 8EC0 mov es, ax 0 00003F07 B449 mov ah, 49h 0 00003F09 CD21 int 21h 0 00003F0B 07 pop es 2615 @@: 0 00003F0C 8B1E[0000] mov bx, [CntryFileHandle] 0 00003F10 B43E mov ah, 3eh 0 00003F12 CD21 int 21h ;close a file. Don't care even if it fails. 0 00003F14 E9E2F7 JMP COFF 2620 2621 Cntry_Error proc near 2622 ;Function: Show "Invalid country code or code page" messages, or 2623 ; "Error in COUNTRY command" depending on the error code 2624 ; in AX returned by SYSPARSE; 2625 ;In: AX - error code 2626 ; DS - Sysinitseg 2627 ; ES - CONFBOT 2628 ;Out: Show message. DX destroyed. 2629 2630 D_P_OUT_OF_RANGE equ D_P_Out_Of_Range ; NASM port equate 0 00003F17 83F806 cmp ax, D_P_OUT_OF_RANGE 2632 ; $IF E 0 00003F1A 7505 JNE DD_IF61 2634 BadCountry equ BADCOUNTRY ; NASM port label 0 00003F1C BA[0000] mov dx, offset BadCountry ;"Invalid country code or code page" 2636 ; $ELSE 0 00003F1F EB03 JMP SHORT DD_EN61 2638 DD_IF61: 2639 BadCountryCom equ BADCOUNTRYCOM ; NASM port label 0 00003F21 BA[0000] mov dx, offset BadCountryCom ;"Error in CONTRY command" 2641 ; $ENDIF 2642 DD_EN61: 0 00003F24 E8[0000] invoke Print 0 00003F27 E83D02 call Error_Line 0 00003F2A C3 ret 2646 Cntry_Error endp 2647 2648 ;------------------------------------------------------------------------------ 2649 ; Files command 2650 ;------------------------------------------------------------------------------ 2651 ;******************************************************************************* 2652 ; Function: Parse the parameters of FILES= command. * 2653 ; * 2654 ; Input : * 2655 ; ES:SI -> parameters in command line. * 2656 ; Output: * 2657 ; Variable FILES set. * 2658 ; * 2659 ; Subroutines to be called: * 2660 ; Sysinit_Parse * 2661 ; Logic: * 2662 ; { * 2663 ; Set DI points to FILES_Parms; * 2664 ; Set DX,CX to 0; * 2665 ; While (End of command line) * 2666 ; { Sysinit_parse; * 2667 ; if (no error) then * 2668 ; Files = Result_Val.D_P_Picked_Val * 2669 ; else * 2670 ; Error Exit; * 2671 ; }; * 2672 ; }; * 2673 ; * 2674 ;******************************************************************************* 2675 TRYF: 0 00003F2B 80FC46 CMP AH,'F' 0 00003F2E 7527 JNZ TRYL 2678 2679 ; invoke GETNUM 2680 ; CMP AX,5 ;j.k. change it to 8!!!!!!!! 2681 ; JB TryFBad ; Gotta have at least 5 2682 ; CMP AX,256 2683 ; JAE TryFBad ; Has to be a byte 2684 ; MOV [FILES],AL 2685 ;CoffJ5: JMP COFF 2686 ;TryFBad:JMP BadOp 2687 0 00003F30 BF[9F09] mov di, offset Files_Parms ;AN000; 0 00003F33 31C9 xor cx, cx ;AN000; 0 00003F35 89CA mov dx, cx ;AN000; 2691 2692 ; $SEARCH ;AN000; 2693 DD_DO64: 0 00003F37 E861F8 call Sysinit_Parse ;AN000; 2695 ; $EXITIF C ;AN000; Parse Error, 0 00003F3A 7305 JNC DD_IF64 0 00003F3C E8BAF5 call Badparm_p ;AN007; and Show messages and end the search loop. 2698 ; $ORELSE ;AN000; 0 00003F3F EB13 JMP SHORT DD_SR64 2700 DD_IF64: 0 00003F41 83F8FF cmp ax, D_P_RC_EOL ;AN000; End of Line? 2702 ; $LEAVE E ;AN000; then end the $ENDLOOP 0 00003F44 7408 JE DD_EN64 0 00003F46 A0[3C09] mov al, byte ptr [Result_Val + D_P_PICKED_VAL] ;AN000; 0 00003F49 A2[BE09] mov [P_Files], al ;AN000; Save it temporarily 2706 ; $ENDLOOP ;AN000; 0 00003F4C EBE9 JMP SHORT DD_DO64 2708 DD_EN64: 0 00003F4E A0[BE09] mov al, [P_Files] ;AN000; 2710 Files equ FILES ; NASM port label 0 00003F51 A2[0000] mov [Files], al ;AN000; No error. Really set the value now. 2712 ; $ENDSRCH ;AN000; 2713 DD_SR64: 0 00003F54 E9A2F7 jmp Coff 2715 2716 ;------------------------------------------------------------------------------ 2717 ; LastDrive command 2718 ;------------------------------------------------------------------------------ 2719 ;******************************************************************************* 2720 ; Function: Parse the parameters of LASTDRIVE= command. * 2721 ; * 2722 ; Input : * 2723 ; ES:SI -> parameters in command line. * 2724 ; Output: * 2725 ; Set the variable NUM_CDS. * 2726 ; * 2727 ; Subroutines to be called: * 2728 ; Sysinit_Parse * 2729 ; Logic: * 2730 ; { * 2731 ; Set DI points to LDRV_Parms; * 2732 ; Set DX,CX to 0; * 2733 ; While (End of command line) * 2734 ; { Sysinit_Parse; * 2735 ; if (no error) then * 2736 ; Set NUM_CDS to the returned value; * 2737 ; else /*Error exit*/ * 2738 ; Error Exit; * 2739 ; }; * 2740 ; }; * 2741 ; * 2742 ;******************************************************************************* 2743 TRYL: 0 00003F57 80FC4C CMP AH,'L' 0 00003F5A 7527 JNZ TRYP 2746 2747 ; OR AL,020h 2748 ; SUB AL,'a' 2749 ; JB TryLBad 2750 ; INC AL 2751 ; CMP AL,26 ; a-z are allowed 2752 ; JA TryLBad 2753 ; MOV [NUM_CDS],AL 2754 ;CoffJ6: JMP COFF 2755 ;TryLBad:JMP BadOp 2756 0 00003F5C BF[F609] mov di, offset LDRV_Parms ;AN000; 0 00003F5F 31C9 xor cx, cx ;AN000; 0 00003F61 89CA mov dx, cx ;AN000; 2760 2761 ; $SEARCH ;AN000; 2762 DD_DO70: 0 00003F63 E835F8 call Sysinit_Parse ;AN000; 2764 ; $EXITIF C ;AN000; Parse Error, 0 00003F66 7305 JNC DD_IF70 0 00003F68 E88EF5 call Badparm_p ;AN007; and Show messages and end the search loop. 2767 ; $ORELSE ;AN000; 0 00003F6B EB13 JMP SHORT DD_SR70 2769 DD_IF70: 0 00003F6D 83F8FF cmp ax, D_P_RC_EOL ;AN000; End of Line? 2771 ; $LEAVE E ;AN000; then end the $ENDLOOP 0 00003F70 7408 JE DD_EN70 0 00003F72 A0[3C09] mov al, [RV_Byte] ;AN000; Pick up the drive number 0 00003F75 A2[0A0A] mov [P_Ldrv], al ;AN000; Save it temporarily 2775 ; $ENDLOOP ;AN000; 0 00003F78 EBE9 JMP SHORT DD_DO70 2777 DD_EN70: 0 00003F7A A0[0A0A] mov al, [P_Ldrv] ;AN000; 2779 ; sub al, 'A' ;AN000; Convert it to drive number 2780 ; inc al ;AN000; make it to be a number of drives. 2781 Num_CDS equ NUM_CDS ; NASM port label 0 00003F7D A2[0000] mov [Num_CDS], al ;AN000; No error. Really set the value now. 2783 ; $ENDSRCH ;AN000; 2784 DD_SR70: 0 00003F80 E976F7 jmp Coff 2786 2787 2788 ;------------------------------------------------------------------------------- 2789 ; Setting Drive Parameters 2790 ;------------------------------------------------------------------------------- 2791 TRYP: 0 00003F83 80FC50 CMP AH,'P' 0 00003F86 7513 JNZ TRYK 0 00003F88 E8[0000] invoke PARSELINE 0 00003F8B 720B JC TryPBad 0 00003F8D E8[0000] invoke SETPARMS 0 00003F90 E8[0000] INVOKE DIDDLEBACK 0 00003F93 7203 jc TryPBad 0 00003F95 E961F7 JMP COFF 2800 Badop equ BADOP ; NASM port label 0 00003F98 E946F5 TryPBad:jmp Badop 2802 ;------------------------------------------------------------------------------- 2803 ; Setting Internal Stack Parameters 2804 ; STACKS=M,N where 2805 ; M is the number of stacks (range 8 to 64, default 9) 2806 ; N is the stack size (range 32 to 512 bytes, default 128) 2807 ; J.K. 5/5/86: STACKS=0,0 implies no stack installation. 2808 ; Any combinations that are not within the specified limits will 2809 ; result in "Unrecognized command" error. 2810 ;------------------------------------------------------------------------------- 2811 ;******************************************************************************* 2812 ; * 2813 ; Function: Parse the parameters of STACKS= command. * 2814 ; The minimum value for "number of stacks" and "stack size" is * 2815 ; 8 and 32 each. In the definition of SYSPARSE value list, they * 2816 ; are set to 0. This is for accepting the exceptional case of * 2817 ; STACKS=0,0 case (,which means do not install the stack.) * 2818 ; So, after SYSPARSE is done, we have to check if the entered * 2819 ; values (STACK_COUNT, STACK_SIZE) are within the actual range, * 2820 ; (or if "0,0" pair has been entered.) * 2821 ; Input : * 2822 ; ES:SI -> parameters in command line. * 2823 ; Output: * 2824 ; Set the variables STACK_COUNT, STACK_SIZE. * 2825 ; * 2826 ; Subroutines to be called: * 2827 ; Sysinit_Parse * 2828 ; Logic: * 2829 ; { * 2830 ; Set DI points to STKS_Parms; * 2831 ; Set DX,CX to 0; * 2832 ; While (End of command line) * 2833 ; { Sysinit_Parse; * 2834 ; if (no error) then * 2835 ; { if (CX == 1) then /* first positional = stack count */ * 2836 ; P_Stack_Count = Result_Val.D_P_Picked_Val; * 2837 ; if (CX == 2) then /* second positional = stack size */ * 2838 ; P_Stack_Size = Result_Val.D_P_Picked_Val; * 2839 ; } * 2840 ; else /*Error exit*/ * 2841 ; Error Exit; * 2842 ; }; * 2843 ; Here check P_STACK_COUNT,P_STACK_SIZE if it meets the condition; * 2844 ; If O.K., then set Stack_Count, Stack_Size; * 2845 ; else Error_Exit; * 2846 ; }; * 2847 ;******************************************************************************* 2848 TRYK: 0 00003F9B 80FC4B CMP AH,'K' 0 00003F9E 7403 JE Do_TryK 0 00003FA0 E99100 jmp TRYS 2852 2853 %IF STACKSW 2854 2855 ; MOV SepChr,',' 2856 ; INVOKE GetNum ; Get number of stacks 2857 ; MOV SepChr,0 2858 ; cmp ax, 0 ;J.K. 5/5/86 2859 ; je TRYK_0 ;J.K. Let's accept 0. 2860 ; CMP AX, MinCount ; 8 <= Number of Stacks <= 64 2861 ; JB TryKBad 2862 ; CMP AX, MaxCount 2863 ; JA TryKBad 2864 ;TRYK_0: 2865 ; MOV [STACK_COUNT], AX 2866 ; 2867 ; Skip delimiters after the first number. 2868 ; 2869 ; invoke Skip_delim ;J.K. 2870 ; JC TryKBad 2871 ; 2872 ; INVOKE GetNum ; Get size of individual stack 2873 ; JC TryKBad ; Number bad 2874 ; 2875 ; cmp ax, 0 ;J.K. 5/5/86 2876 ; je TRYK_SIZE0 ;J.K. 5/5/86. Accept 0 2877 ; 2878 ; CMP AX, MinSize ; 32 <= Stack Size <= 512 2879 ; JB TryKBad 2880 ; CMP AX, MaxSize 2881 ; JA TryKBad 2882 ;TRYK_SIZE0: 2883 ; MOV [STACK_SIZE], AX 2884 ; cmp ax,0 2885 ; je TRYK_BOTH0 2886 ;TRYK_OK: 2887 ; mov word ptr [stack_addr], -1 ;set the flag that the user entered stacks= command. 2888 ; JMP COFF 2889 ;TRYK_BOTH0: 2890 ; cmp [STACK_COUNT],0 ;stack_size = 0. Stack_Count = 0 too? 2891 ; je TRYK_OK ;yes. accepted. 2892 ;TryKBad: 2893 ; MOV DX, OFFSET BADSTACK ;J.K. 5/26/86 "Invalid stack parameter" 2894 ; invoke PRINT 2895 ; JMP COFF 2896 2897 Do_TryK: 0 00003FA3 BF[0B0A] mov di, offset STKS_Parms ;AN000; 0 00003FA6 31C9 xor cx, cx ;AN000; 0 00003FA8 89CA mov dx, cx ;AN000; 2901 2902 ; $SEARCH ;AN000; 2903 DD_DO76: 0 00003FAA E8EEF7 call Sysinit_Parse ;AN000; 2905 ; $EXITIF C ;AN000; Parse Error, 0 00003FAD 730B JNC DD_IF76 2907 BadStack equ BADSTACK ; NASM port label 0 00003FAF BA[0000] mov dx, offset BadStack ;AN000; "Invalid stack parameter" 0 00003FB2 E8[0000] call Print ;AN000; and Show messages and end the search loop. 0 00003FB5 E8AF01 call Error_Line ;AN006; 2911 ; $ORELSE ;AN000; 0 00003FB8 EB77 JMP SHORT DD_SR76 2913 DD_IF76: 0 00003FBA 83F8FF cmp ax, D_P_RC_EOL ;AN000; End of Line? 2915 ; $LEAVE E ;AN000; then end the $ENDLOOP 0 00003FBD 7412 JE DD_EN76 0 00003FBF A1[3C09] mov ax, word ptr [Result_Val + D_P_PICKED_VAL] ;AN000; 0 00003FC2 83F901 cmp cx, 1 ;AN000; 2919 ; $IF E ;AN000; 0 00003FC5 7505 JNE DD_IF80 0 00003FC7 A3[400A] mov [P_Stack_Count], ax ;AN000; 2922 ; $ELSE ;AN000; 0 00003FCA EB03 JMP SHORT DD_EN80 2924 DD_IF80: 0 00003FCC A3[420A] mov [P_Stack_Size], ax ;AN000; 2926 ; $ENDIF ;AN000; 2927 DD_EN80: 2928 ; $ENDLOOP ;AN000; 0 00003FCF EBD9 JMP SHORT DD_DO76 2930 DD_EN76: 0 00003FD1 833E[400A]00 cmp word [P_Stack_Count], 0 ;AN000; 2932 ; $IF NE ;AN000; 0 00003FD6 7416 JE DD_IF84 2934 MINCOUNT equ MinCount ; NASM port equate 0 00003FD8 833E[400A]08 cmp word [P_Stack_Count], MINCOUNT ;AN000; 2936 ; $IF B,OR ;AN000; 0 00003FDD 7207 JB DD_LL85 2938 MINSIZE equ MinSize ; NASM port equate 0 00003FDF 833E[420A]20 cmp word [P_Stack_Size], MINSIZE ;AN000; 2940 ; $IF B ;AN000; 0 00003FE4 7306 JNB DD_IF85 2942 DD_LL85: 0 00003FE6 C706[400A]FFFF mov word [P_Stack_Count], -1 ;AN000; Invalid 2944 ; $ENDIF ;AN000; 2945 DD_IF85: 2946 ; $ELSE ;AN000; 0 00003FEC EB0D JMP SHORT DD_EN84 2948 DD_IF84: 0 00003FEE 833E[420A]00 cmp word [P_Stack_Size], 0 ;AN000; 2950 ; $IF NE ;AN000; 0 00003FF3 7406 JE DD_IF88 0 00003FF5 C706[400A]FFFF mov word [P_Stack_Count], -1 ;AN000; Invalid 2953 ; $ENDIF ;AN000; 2954 DD_IF88: 2955 ; $ENDIF ;AN000; 2956 DD_EN84: 0 00003FFB 833E[400A]FF cmp word [P_Stack_Count], -1 ;AN000; Invalid? 2958 ; $IF E ;AN000; 0 00004000 751D JNE DD_IF91 2960 Stack_Count equ stack_count ; NASM port label 2961 DEFAULTCOUNT equ DefaultCount ; NASM port equate 0 00004002 C706[0000]0900 mov word [Stack_Count], DEFAULTCOUNT ;AN000;Reset to default value. 2963 Stack_Size equ stack_size ; NASM port label 2964 DEFAULTSIZE equ DefaultSize ; NASM port equate 0 00004008 C706[0000]8000 mov word [Stack_Size], DEFAULTSIZE ;AN000; 2966 STACK_ADDR equ stack_addr ; NASM port label 0 0000400E C706[0000]0000 mov word [STACK_ADDR], 0 ;AN000; 0 00004014 BA[0000] mov dx, offset BadStack ;AN000; 0 00004017 E8[0000] call Print ;AN000; 0 0000401A E84A01 call Error_Line ;AN006; 2971 ; $ELSE ;AN000; 0 0000401D EB12 JMP SHORT DD_EN91 2973 DD_IF91: 0 0000401F A1[400A] mov ax, [P_Stack_Count] ;AN000; 0 00004022 A3[0000] mov [Stack_Count], ax ;AN000; 0 00004025 A1[420A] mov ax, [P_Stack_Size] ;AN000; 0 00004028 A3[0000] mov [Stack_Size], ax ;AN000; 2978 Stack_Addr equ stack_addr ; NASM port label 0 0000402B C706[0000]FFFF mov word [Stack_Addr], -1 ;AN000;STACKS= been accepted. 2980 ; $ENDIF ;AN000; 2981 DD_EN91: 2982 ; $ENDSRCH ;AN000; 2983 DD_SR76: 0 00004031 E9C5F6 jmp Coff 2985 %ENDIF 2986 ;------------------------------------------------------------------------------ 2987 ; Switch command ;No longer supported. 2988 ;------------------------------------------------------------------------------ 2989 ;TRYW: 2990 ; CMP AH,'W' 2991 ; JNZ TRYA 2992 ; JMP BadOp ; no longer implemented 2993 ; MOV DL,AL 2994 ; MOV AX,(CHAR_OPER SHL 8) OR 1 ;SET SWITCH CHARACTER 2995 ; MOV [COMMAND_LINE+1],DL 2996 ; INT 21H 2997 ; JMP COFF 2998 ;------------------------------------------------------------------------------ 2999 ; Availdev command ;No longer supported. 3000 ;------------------------------------------------------------------------------ 3001 ;TRYA: 3002 ; CMP AH,'A' 3003 ; JNZ TRYS 3004 ; JMP BadOp ; NO LONGER IMPLEMENTED 3005 ; CMP AL,'F' ;FIRST LETTER OF "FALSE" 3006 ; JNZ COFFJ7 3007 ; MOV AX,(CHAR_OPER SHL 8) OR 3 ;TURN ON "/DEV" PREFIX 3008 ; XOR DL,DL 3009 ; INT 21H 3010 ;COFFJ7: JMP COFF 3011 3012 ;------------------------------------------------------------------------------ 3013 ; shell command 3014 ;------------------------------------------------------------------------------ 3015 TRYS: 0 00004034 80FC73 cmp ah, 's' 0 00004037 7508 jne @F 0 00004039 2EC606[1E00]FF mov byte [cs:shellhighflag], -1 0 0000403F EB0B jmp .shell 3020 @@: 0 00004041 80FC53 CMP AH,'S' 0 00004044 7543 JNZ TRYX 0 00004046 2EC606[1E00]00 mov byte [cs:shellhighflag], 0 3024 .shell: 0 0000404C C606[0100]00 MOV byte [COMMAND_LINE+1],0 0 00004051 BF[0100] MOV DI,OFFSET COMMND + 1 0 00004054 8845FF MOV [DI-1],AL 3028 STORESHELL: 0 00004057 E8E700 CALL GETCHR 0 0000405A 08C0 OR AL,AL 0 0000405C 7419 JZ GETSHPARMS 0 0000405E 3C20 CMP AL," " 0 00004060 7205 JB ENDSH 0 00004062 8805 MOV [DI],AL 0 00004064 47 INC DI 0 00004065 EBF0 JMP STORESHELL 3037 3038 ENDSH: 0 00004067 C60500 MOV BYTE PTR [DI],0 0 0000406A E8D400 CALL GETCHR 0 0000406D 3C0A CMP AL,LF 0 0000406F 7503 JNZ CONV 0 00004071 E8CD00 CALL GETCHR 0 00004074 E94FF6 CONV: JMP CONFLP 3045 3046 GETSHPARMS: 0 00004077 C60500 MOV BYTE PTR [DI],0 0 0000407A BF[0100] MOV DI,OFFSET COMMAND_LINE+1 3049 PARMLOOP: 0 0000407D E8C100 CALL GETCHR 0 00004080 3C20 CMP AL," " 0 00004082 72E3 JB ENDSH 0 00004084 8805 MOV [DI],AL 0 00004086 47 INC DI 0 00004087 EBF4 JMP PARMLOOP 3056 3057 ;------------------------------------------------------------------------------ 3058 ; FCBS Command 3059 ;------------------------------------------------------------------------------ 3060 ;******************************************************************************* 3061 ; Function: Parse the parameters of FCBS= command. * 3062 ; * 3063 ; Input : * 3064 ; ES:SI -> parameters in command line. * 3065 ; Output: * 3066 ; Set the variables FCBS, KEEP. * 3067 ; * 3068 ; Subroutines to be called: * 3069 ; Sysinit_Parse * 3070 ; Logic: * 3071 ; { * 3072 ; Set DI points to FCBS_Parms; * 3073 ; Set DX,CX to 0; * 3074 ; While (End of command line) * 3075 ; { SYSPARSE; * 3076 ; if (no error) then * 3077 ; { if (CX == 1) then /* first positional = FCBS */ * 3078 ; FCBS = Result_Val.D_P_Picked_Val; * 3079 ; if (CX == 2) then /* second positional = KEEP */ * 3080 ; KEEP = Result_Val.D_P_Picked_Val; * 3081 ; } * 3082 ; else /*Error exit*/ * 3083 ; Error Exit; * 3084 ; }; * 3085 ; }; * 3086 ;******************************************************************************* 3087 TRYX: 0 00004089 80FC58 CMP AH,'X' 0 0000408C 7547 JNZ TRYY 3090 ; invoke GETNUM 3091 ; JZ TryXBad ; gotta have at least one 3092 ; CMP AX,256 3093 ; JAE TryXBad ; Can't be more than 8 bits worth 3094 ; MOV [FCBS],AL 3095 ; 3096 ; Skip delimiters after the first number including "," 3097 ; 3098 ; invoke Skip_delim ;J.K. 3099 ; jc tryxbad 3100 ; invoke GetNum 3101 ; JC TryXBad ; Number bad (Zero is OK here) 3102 ; CMP AX,256 3103 ; JAE TryXBad 3104 ; CMP AL,FCBS 3105 ; JA TryXBad 3106 ; MOV Keep,AL 3107 ; JMP COFF 3108 ;TryXBad:JMP BadOp 3109 0 0000408E BF[BF09] mov di, offset FCBS_Parms ;AN000; 0 00004091 31C9 xor cx, cx ;AN000; 0 00004093 89CA mov dx, cx ;AN000; 3113 3114 ; $SEARCH ;AN000; 3115 DD_DO95: 0 00004095 E803F7 call Sysinit_Parse ;AN000; 3117 ; $EXITIF C ;AN000; Parse Error, 0 00004098 7305 JNC DD_IF95 0 0000409A E85CF4 call Badparm_p ;AN007; and Show messages and end the search loop. 3120 ; $ORELSE ;AN000; 0 0000409D EB33 JMP SHORT DD_SR95 3122 DD_IF95: 0 0000409F 83F8FF cmp ax, D_P_RC_EOL ;AN000; End of Line? 3124 ; $LEAVE E ;AN000; then end the $ENDLOOP 0 000040A2 7412 JE DD_EN95 0 000040A4 A0[3C09] mov al, byte ptr [Result_Val + D_P_PICKED_VAL] ;AN000; 0 000040A7 83F901 cmp cx, 1 ;AN000; The first positional? 3128 ; $IF E ;AN000; 0 000040AA 7505 JNE DD_IF99 0 000040AC A2[F409] mov [P_Fcbs], al ;AN000; 3131 ; $ELSE ;AN000; 0 000040AF EB03 JMP SHORT DD_EN99 3133 DD_IF99: 0 000040B1 A2[F509] mov [P_Keep], al ;AN000; 3135 ; $ENDIF ;AN000; 3136 DD_EN99: 3137 ; $ENDLOOP ;AN000; 0 000040B4 EBDF JMP SHORT DD_DO95 3139 DD_EN95: 0 000040B6 A0[F409] mov al, [P_Fcbs] ;AN005;make sure P_Fcbs >= P_Keep 0 000040B9 3A06[F509] cmp al, [P_Keep] ;AN005; 3142 ; $IF B ;AN005; 0 000040BD 730A JNB DD_IF103 3144 ; call Badop_p ;AN005; 0 000040BF E837F4 call Badparm_p ;AN011;show "Bad parameter -" msg. 0 000040C2 C606[F509]00 mov byte [P_Keep], 0 ;AN005; 3147 ; $ELSE ;AN005; 0 000040C7 EB09 JMP SHORT DD_EN103 3149 DD_IF103: 3150 Fcbs equ FCBS ; NASM port label 0 000040C9 A2[0000] mov [Fcbs], al ;AN000; No error. Really set the value now. 0 000040CC A0[F509] mov al, [P_Keep] ;AN000; 3153 Keep equ KEEP ; NASM port label 0 000040CF A2[0000] mov [Keep], al ;AN000; 3155 ; $ENDIF ;AN005; 3156 DD_EN103: 3157 ; $ENDSRCH ;AN000; 3158 DD_SR95: 0 000040D2 E924F6 jmp Coff 3160 3161 ;------------------------------------------------------------------------------ 3162 ; Comment= Do nothing. Just decrese CHRPTR, and increase COUNT for correct 3163 ; line number 3164 ;------------------------------------------------------------------------------ 3165 TRYY: ;AN000; 0 000040D5 80FC59 cmp ah, 'Y' ;AN000; 0 000040D8 750B jne Try0 ;AN000; 3168 DoNothing: 0 000040DA FF0E[0000] dec word [CHRPTR] ;AN000; 0 000040DE FF06[0000] inc word [COUNT] ;AN000; 0 000040E2 E914F6 jmp COFF ;AN000; 3172 3173 ;------------------------------------------------------------------------------ 3174 ; REM command 3175 ;------------------------------------------------------------------------------ 3176 Try0: ;AN003;do nothing with this line. 0 000040E5 80FC30 cmp ah, '0' ;AN003; 0 000040E8 74F0 je DoNothing ;AN003; 3179 3180 ;------------------------------------------------------------------------------ 3181 ; SWITCHES command 3182 ;------------------------------------------------------------------------------ 3183 ;******************************************************************************* 3184 ; * 3185 ; Function: Parse the option switches specified. * 3186 ; Note - This command is intended for the future use also. When we need to * 3187 ; to set system data flag, use this command. * 3188 ; * 3189 ; Input : * 3190 ; ES:SI -> parameters in command line. * 3191 ; Output: * 3192 ; P_Swit_K set if /K option chosen. * 3193 ; * 3194 ; Subroutines to be called: * 3195 ; Sysinit_Parse * 3196 ; Logic: * 3197 ; { * 3198 ; Set DI points to Swit_Parms; /*Parse control definition*/ * 3199 ; Set DX,CX to 0; * 3200 ; While (End of command line) * 3201 ; { Sysinit_parse; * 3202 ; if (no error) then * 3203 ; if (Result_Val.D_P_SYNONYM_ptr == Swit_K) then * 3204 ; P_Swit_K = 1 * 3205 ; endif * 3206 ; else {Show Error message;Error Exit} * 3207 ; }; * 3208 ; }; * 3209 ; * 3210 ;******************************************************************************* 3211 0 000040EA 80FC31 cmp ah, '1' ;AN019;Switches= command entered? 3213 Tryz equ TRYZ ; NASM port label 0 000040ED 7540 jne Tryz ;AN019; 3215 0 000040EF BF[6E0A] mov di, offset Swit_Parms ;AN019; 0 000040F2 31C9 xor cx, cx ;AN019; 0 000040F4 89CA mov dx, cx ;AN019; 3219 3220 ; $SEARCH ;AN019; 3221 DD_DO107: 0 000040F6 E8A2F6 call Sysinit_Parse ;AN019; 3223 ; $EXITIF C ;AN019; Parse Error, 0 000040F9 7305 JNC DD_IF107 0 000040FB E8FBF3 call Badparm_p ;AN019; and Show messages and end the search loop. 3226 ; $ORELSE ;AN019; 0 000040FE EB2C JMP SHORT DD_SR107 3228 DD_IF107: 0 00004100 83F8FF cmp ax, D_P_RC_EOL ;AN019; End of Line? 3230 ; $LEAVE E ;AN019; then jmp to $Endloop for semantic check. 0 00004103 740F JE DD_EN107 0 00004105 813E[3A09][820A] cmp word [Result_Val + D_P_SYNONYM_PTR], offset Swit_K ;AN019; 3233 ; $IF E ;AN019; 0 0000410B 7505 JNE DD_IF111 0 0000410D C606[850A]01 mov byte [P_Swit_K], 1 ;AN019; set the flag 3236 ; $ENDIF ;AN019; 3237 DD_IF111: 3238 ; $ENDLOOP ;AN019; 0 00004112 EBE2 JMP SHORT DD_DO107 3240 DD_EN107: 0 00004114 803E[850A]01 cmp byte [P_Swit_K], 1 ;AN019;If /K entered, 0 00004119 1E push ds ;AN019; 0 0000411A B8[0000] mov ax, DOSENTRY ;AN019; 0 0000411D 8ED8 mov ds, ax ;AN019; 3245 assume ds:DOSENTRY ;AN019; 3246 ; $IF E ;AN019; 0 0000411F 750A JNE DD_IF114 0 00004121 C606[0000]00 mov byte [KEYRD_Func], 0 ;AN019;Use the conventional keyboard functions 0 00004126 C606[0000]01 mov byte [KEYSTS_Func], 1 ;AN019; 3250 ; $ENDIF ;AN019; 3251 DD_IF114: 0 0000412B 1F pop ds ;AN019; 3253 assume ds:SYSINITSEG ;AN019; 3254 ; $ENDSRCH ;AN019; 3255 DD_SR107: 0 0000412C E9CAF5 jmp Coff ;AN019; 3257 3258 ;------------------------------------------------------------------------------ 3259 ; Bogus command 3260 ;------------------------------------------------------------------------------ 3261 TRYZ: 0 0000412F 80FCFF cmp ah, 0FFh ;AN029; 0 00004132 740B je TryFF ;AN029; 0 00004134 FF0E[0000] dec word [CHRPTR] 0 00004138 FF06[0000] inc word [COUNT] 0 0000413C E9A2F3 JMP BADOP 3267 3268 ;------------------------------------------------------------------------------ 3269 ; Null command 3270 ;------------------------------------------------------------------------------ 3271 TryFF: ;AN029;Skip this command. 0 0000413F EB99 jmp DoNothing ;AN029; 3273 3274 GETCHR: 0 00004141 51 PUSH CX 0 00004142 8B0E[0000] MOV CX,[COUNT] 0 00004146 E312 JCXZ NOCHAR 0 00004148 8B36[0000] MOV SI,[CHRPTR] 0 0000414C 268A04 MOV AL,[ES:SI] 0 0000414F FF0E[0000] DEC word [COUNT] 0 00004153 FF06[0000] INC word [CHRPTR] 0 00004157 F8 CLC 3283 GET_RET: 0 00004158 59 POP CX 0 00004159 C3 return 0 0000415A F9 NOCHAR: STC 0 0000415B EBFB JMP SHORT GET_RET 3288 3289 Incorrect_Order proc near ;AN000; 3290 ;Show "Incorrect order in CONFIG.SYS ..." message. 3291 BADORDER equ BadOrder ; NASM port label 0 0000415D BA[0000] mov dx, offset BADORDER ;AN000; 3293 print equ Print ; NASM port label 0 00004160 E8[0000] call print ;AN000; 0 00004163 E80D00 call ShowLineNum ;AN000; 0 00004166 C3 ret ;AN000; 3297 Incorrect_Order endp ;AN000; 3298 ; 3299 public Error_Line 3300 Error_Line proc near ;AN000; 3301 ;Show "Error in CONFIG.SYS ..." message. 0 00004167 0E push cs ;AN000; 0 00004168 1F pop ds ;AN000; 3304 ErrorCmd equ Errorcmd ; NASM port label 0 00004169 BA[0000] mov dx, offset ErrorCmd ;AN000; 0 0000416C E8[0000] call print ;AN000; 0 0000416F E80100 call ShowLineNum ;AN000; 0 00004172 C3 ret ;AN000; 3309 Error_Line endp ;AN000; 3310 ; 3311 ShowLineNum proc near ;AN000; 3312 ;J.K. Convert the binary LineCount to Decimal ASCII string in ShowCount 3313 ;and Display Showcount at the current curser position. 3314 ;In.) LineCount 3315 ; 3316 ;Out) the number is printed. 0 00004173 06 push es ;AN000; 0 00004174 1E push ds ;AN000; 0 00004175 57 push di ;AN000; 3320 0 00004176 0E push cs ;AN000; 0 00004177 07 pop es ;AN000; es=cs 0 00004178 0E push cs ;AN000; 0 00004179 1F pop ds ;AN000; 3325 3326 ; mov ax, ' ' 3327 ; mov di, offset ShowCount ;clean it up. 3328 ; stosw 3329 ; stosw 3330 ; stosb ;lenght of ShowCount is 5. 3331 ; dec di ;let DI points to the least significant ASCII field. 3332 0 0000417A BF[0400] mov di, offset ShowCount+4 ;AN000; DI -> the least significant decimal field. 0 0000417D B90A00 mov cx, 10 ;AN000; decimal devide factor 0 00004180 2EA1[0000] mov ax, [cs:LineCount] ;AN000; 3336 SLN_Loop: ;AN000; 0 00004184 83F80A cmp ax, 10 ;AN000; < 10? 0 00004187 720C jb SLN_Last ;AN000; 0 00004189 31D2 xor dx,dx ;AN000; 0 0000418B F7F1 div cx ;AN000; 0 0000418D 80CA30 or dl, 30h ;AN000; add "0" (= 30h) to make it an ascii. 0 00004190 8815 mov [di],dl ;AN000; 0 00004192 4F dec di ;AN000; 0 00004193 EBEF jmp SLN_Loop ;AN000; 3345 SLN_Last: ;AN000; 0 00004195 0C30 or al, 30h ;AN000; 0 00004197 8805 mov [di],al ;AN000; 0 00004199 89FA mov dx, di ;AN000; 0 0000419B E8[0000] call print ;AN000; show it. 0 0000419E 5F pop di ;AN000; 0 0000419F 1F pop ds ;AN000; 0 000041A0 07 pop es ;AN000; 0 000041A1 C3 ret ;AN000; 3354 ShowLineNum endp ;AN000; 3355 3356 3357 CallIFS proc near ;AN000; 3358 ;******************************************************************************* 3359 ; Function: Interface to IFS call. This procedure will call IFS_CALL@ * 3360 ; * 3361 ; Input : * 3362 ; Entry_Point - Segment:Offset of loaded IFS. * 3363 ; BX = IFS_CALL@ (offset of IFS_CALL@ from the IFS header) * 3364 ; ES = Segment of IFS request header * 3365 ; IFS_Packet - IFS Request packet * 3366 ; * 3367 ; Output: Nothing * 3368 ;******************************************************************************* 0 000041A2 50 push ax ;AN000; 0 000041A3 2E8E1E[0200] mov ds, word ptr [cs:Entry_Point+2] ;AN000; 0 000041A8 2E031E[0000] add bx, word ptr [cs:Entry_Point] ;AN000; [DS:BX] = Real IFS_CALL@ addr. 0 000041AD 8B07 mov ax, [bx] ;AN000; save it 0 000041AF 2EFF36[0000] push word ptr [cs:Entry_Point] ;AN000; save Entry point offset 0 000041B4 2EA3[0000] mov word ptr [cs:Entry_Point], ax ;AN000; set for the call 0 000041B8 BB[0000] mov bx, offset IFS_RH ;AN000; Now, ES:BX -> Request packet 0 000041BB 2EFF1E[0000] call far [cs:Entry_Point] ;AN000; Far call 0 000041C0 2E8F06[0000] pop word ptr [cs:Entry_Point] ;AN000; Restore Entry point offset 0 000041C5 58 pop ax ;AN000; 0 000041C6 C3 ret ;AN000; 3380 CallIFS endp ;AN000; 3381 3382 3383 %if 0 3384 Set_DevMark proc near ;AN004; 3385 ;******************************************************************************* 3386 ; Function: Set a paragraph of informations infront of a Device file or * 3387 ; an IFS file to be loaded for MEM command. * 3388 ; The structure is: * 3389 ; DEVMARK_ID byte "D" for device, "I" for IFS * 3390 ; DEVMARK_SIZE size in para for the device loaded * 3391 ; DEVMARK_FILENAME 11 bytes. Filename * 3392 ; * 3393 ; Input : * 3394 ; [MEMHI] = address to set up DEVMARK. * 3395 ; [MEMLO] = 0 * 3396 ; ES:SI -> pointer to [drive][path]filename,0 * 3397 ; [IFS_Flag] = IS_IFS bit set if IFS= command. * 3398 ; * 3399 ; Output: DEVMARK_ID, DEVMARK_FILENAME set * 3400 ; [cs:DevMark_addr] set. * 3401 ; AX, CX register destroyed. * 3402 ;******************************************************************************* 3403 push ds ;AN004; 3404 push si ;AN004; 3405 push es ;AN004; 3406 push di ;AN004; 3407 3408 mov di, [cs:MEMHI] ;AN004; 3409 mov ds, di ;AN004; 3410 assume ds:nothing ;AN004; 3411 mov [cs:DevMark_Addr], di ;AN004; save the DEVMARK address for the future. 3412 test word [cs:IFS_Flag], IS_IFS ;AN004; 3413 jnz SDVMK_IFS ;AN004; 3414 mov al, DEVMARK_DEVICE ;AN004; ='D' 3415 jmp short SDVMK_ID ;AN004; 3416 SDVMK_IFS: 3417 mov al, DEVMARK_IFS ;AN004; ='I' 3418 SDVMK_ID: ;AN004; 3419 mov [DEVMARK_ID], al ;AN004; 3420 inc di ;AN008; 3421 mov [DEVMARK_SEG], di ;AN008; 3422 call get_device_mcb_name 3423 pop di ;AN004; 3424 pop es ;AN004; 3425 pop si ;AN004; 3426 pop ds ;AN004; 3427 ret ;AN004; 3428 Set_DevMark endp ;AN004; 3429 %endif 3430 3431 ; INP: es:si -> pathname 3432 ; ds => sub-MCB 3433 ; CHG: si, di, ds, es, cx, ax 3434 get_device_mcb_name: 0 000041C7 30C0 xor al,al ;AN004; 0 000041C9 56 push si ;AN004; 0 000041CA 5F pop di ;AN004; now es:si = es:di = [path]filename,0 0 000041CB B98000 mov cx, 128 ;AN004; Maximum 128 char 0 000041CE F2AE repnz scasb ;AN004; find 0 0 000041D0 4F dec di ;AN020; Now es:di-> 0 3441 SDVMK_Backward: ;AN004; find the pointer to the start of the filename. 0 000041D1 268A05 mov al, byte ptr [es:di] ;AN004;;AN020;We do this by check es:di backward until 0 000041D4 3C5C cmp al, '\' ;AN004;;AN020; DI = SI or DI -> '\' or DI -> ':'. 0 000041D6 740B je SDVMK_GotFile ;AN004;;AN020; 0 000041D8 3C3A cmp al, ':' ;AN004; 0 000041DA 7407 je SDVMK_GotFile ;AN004; 0 000041DC 39F7 cmp di, si ;AN004; 0 000041DE 7404 je SDVMK_FilePtr ;AN004; 0 000041E0 4F dec di ;AN004; 3450 SDVMK_BackWard equ SDVMK_Backward ; NASM port label 0 000041E1 EBEE jmp SDVMK_BackWard ;AN004; 3452 SDVMK_GotFile: ;AN004; 0 000041E3 47 inc di ;AN004; 3454 SDVMK_FilePtr: ;AN004; now es:di -> start of file name 0 000041E4 57 push di ;AN004; 0 000041E5 5E pop si ;AN004; save di to si. 0 000041E6 1E push ds ;AN004; switch es, ds 0 000041E7 06 push es ;AN004; 0 000041E8 1F pop ds ;AN004; 0 000041E9 07 pop es ;AN004; now, ds:si -> start of filename 0 000041EA BF0800 mov di, DEVMARK_FILENAME ;AN004; 0 000041ED 57 push di ;AN004; 0 000041EE B020 mov al, ' ' ;AN004; 0 000041F0 B90800 mov cx, 8 ;AN004; 0 000041F3 F3AA rep stosb ;AN004; Clean up Memory. 0 000041F5 5F pop di ;AN004; 0 000041F6 B90800 mov cx, 8 ;AN004; Max 8 char. only 3468 SDVMK_Loop: ;AN004; 0 000041F9 AC lodsb ;AN004; 0 000041FA 3C2E cmp al, '.' ;AN004; 0 000041FC 7407 je SDVMK_Done ;AN004; 0 000041FE 3C00 cmp al, 0 ;AN004; 0 00004200 7403 je SDVMK_Done ;AN004; 0 00004202 AA stosb ;AN004; 0 00004203 E2F4 loop SDVMK_Loop ;AN004; 3476 SDVMK_Done: ;AN004; 0 00004205 C3 retn 3478 3479 Chk_XMAEM proc near ;AN029; 3480 ;Function: Check XMAEM.SYS file name. 3481 ;In: ES:SI -> path, filename, 0 3482 ;out: if XMAEM.SYS, then zero flag set. 3483 0 00004206 06 push es ;AN029; 0 00004207 56 push si ;AN029; 0 00004208 1E push ds ;AN029; 0 00004209 57 push di ;AN029; 0 0000420A 51 push cx ;AN029; 0 0000420B 89F7 mov di, si ;AN029;save current starting pointer 3490 CX_Cmp: ;AN029; 0 0000420D 26803C00 cmp byte ptr [es:si], 0 ;AN029; 0 00004211 7403 je CX_Endfile ;AN029; 0 00004213 46 inc si ;AN029; 0 00004214 EBF7 jmp CX_Cmp ;AN029; 3495 CX_Endfile: ;AN029; 0 00004216 4E dec si ;AN029; 0 00004217 26803C5C cmp byte ptr [es:si], '\' ;AN029; 0 0000421B 740C je CX_Got_Tail ;AN029; 0 0000421D 26803C3A cmp byte ptr [es:si], ':' ;AN029; 0 00004221 7406 je CX_Got_Tail ;AN029; 0 00004223 39F7 cmp di, si ;AN029; 0 00004225 7403 je CX_Got_Tail0 ;AN029; 0 00004227 EBED jmp CX_Endfile ;AN029; 3504 CX_Got_Tail: ;AN029; 0 00004229 46 inc si ;AN029; 3506 CX_Got_Tail0: ;AN029; 0 0000422A 0E push cs ;AN029; 0 0000422B 1F pop ds ;AN029; 0 0000422C 56 push si ;AN029; 0 0000422D 5F pop di ;AN029;now es:di -> filename,0 0 0000422E B90900 mov cx, 9 ;AN029; 3512 XMAEM_File equ XMAEM_file ; NASM port label 0 00004231 BE[1F00] mov si, offset XMAEM_File ;AN029;ds:si -> XMAEM.SYS,0 0 00004234 F3A6 repe cmpsb ;AN029; 3515 CX_Ret: ;AN029; 0 00004236 59 pop cx ;AN029; 0 00004237 5F pop di ;AN029; 0 00004238 1F pop ds ;AN029; 0 00004239 5E pop si ;AN029; 0 0000423A 07 pop es ;AN029; 0 0000423B C3 ret ;AN029; 3522 Chk_XMAEM endp 3523 3524 ;Chk_IBMCACHE proc near ;AN024;AN026; Don't need this any more. 3525 ; IBMDOS is going to handle this through 4Bh call. 3526 ;Function: IBMCACHE.SYS does not handle a DOS version 4.0 or above. 3527 ; So, this procedure will check if the device driver is IBMCACHE.SYS. 3528 ; If it is, through new INT 2fh interface "Set/Restore DOS version" 3529 ; AX=122Fh 3530 ; DX= 0 ; reset 3531 ; otherwise ; DH = minor version, DL = major version 3532 ; INT 2fh 3533 ;In: ES:SI -> path, filename, 0 3534 ;out: if IBMCACHE.SYS, then DOS version changed to 4.00 temporarily. 3535 ; Reset_Dos_Version proc will later reset it back to current DOS version 4.0. 3536 3537 ; push es ;AN024; 3538 ; push si ;AN024; 3539 ; push ds ;AN024; 3540 ; push di ;AN024; 3541 ; push cx ;AN024; 3542 ; mov di, si ;AN024;save current starting pointer 3543 ;CIC_Cmp: ;AN024; 3544 ; cmp byte ptr [es:si], 0 ;AN024; 3545 ; je CIC_Endfile ;AN024; 3546 ; inc si ;AN024; 3547 ; jmp CIC_Cmp ;AN024; 3548 ;CIC_Endfile: ;AN024; 3549 ; dec si ;AN024; 3550 ; cmp byte ptr [es:si], '\' ;AN024; 3551 ; je CIC_Got_Tail ;AN024; 3552 ; cmp byte ptr [es:si], ':' ;AN024; 3553 ; je CIC_Got_Tail ;AN024; 3554 ; cmp di, si ;AN024; 3555 ; je CIC_Got_Tail0 ;AN024; 3556 ; jmp CIC_Endfile ;AN024; 3557 ;CIC_Got_Tail: ;AN024; 3558 ; inc si ;AN024; 3559 ;CIC_Got_Tail0: ;AN024; 3560 ; push cs ;AN024; 3561 ; pop ds ;AN024; 3562 ; push si ;AN024; 3563 ; pop di ;AN024;now es:di -> filename,0 3564 ; mov cx, 12 ;AN024; 3565 ; mov si, offset IBMCACHE_File ;AN024;ds:si -> IBMCACHE.SYS,0 3566 ; repe cmpsb ;AN024; 3567 ; jnz CIC_ret ;AN024; 3568 ; mov ax, 122Fh ;AN024;Change DOS version to 3569 ; mov dx, 2803h ;AN024; DOS 3.4 temporarily. 3570 ; int 2fh ;AN024; 3571 ;CIC_Ret: ;AN024; 3572 ; pop cx ;AN024; 3573 ; pop di ;AN024; 3574 ; pop ds ;AN024; 3575 ; pop si ;AN024; 3576 ; pop es ;AN024; 3577 ; ret ;AN024; 3578 ;Chk_IBMCACHE endp 3579 ; 3580 3581 Reset_DOS_Version proc near ;AN024; 3582 ;Function: issue AX=122Fh, DX=0, INT 2fh to restore the DOS version. 0 0000423C 50 push ax ;AN024; 0 0000423D 52 push dx ;AN024; 0 0000423E B82F12 mov ax, 122Fh ;AN024; 0 00004241 BA0000 mov dx, 0 ;AN024; 0 00004244 CD2F int 2fh ;AN024; 0 00004246 5A pop dx ;AN024; 0 00004247 58 pop ax ;AN024; 0 00004248 C3 ret ;AN024; 3591 Reset_DOS_Version endp 3592 3593 3594 %ifndef BUF2 3595 ;Int 2F EMS handler + Int 67h handler for EMS 3596 ;========================================================================= 3597 ; Int_2F_EMS - This routine provides support for VDISK, 3598 ; FASTOPEN, and BUFFERS to determine the physical 3599 ; EMS pages available for their usage. 3600 ; 3601 ; Inputs : AH - Function code (18h) to return available phys. page 3602 ; DI - FEh (Signals to return useable page for VDISK & FASTOPEN) 3603 ; FFh (Signals to return useable page for BUFFERS) 3604 ; 3605 ; AL = 0 is for installation check. - J.K. 3606 ; 3607 ; Outputs : ES - Segment value for physical page 3608 ; DI - Physical Page number 3609 ; AH - Non-zero (physical page not available) 3610 ; Zero (valid physical page data returned) 3611 ; 3612 ; For installation check, AL = 0FFh for being present. - J.K. 3613 ; For the other functions, AX = 0 for successful op. 3614 ; AX = -1 for an error. 3615 ; 3616 ; Date : 5/5/88 3617 ; Release : DOS 4.0 3618 ;========================================================================= 3619 3620 ;Int_2F_Handler proc ;traps Int_2f and checks for EMS ;an000; dms; 3621 3622 EMS_STUB_START label byte ;AN030;J.K. 3623 ;Dummy DEVICE HEADER for other dummy ;AN031; Symphony assumes int 67h handler seg as a device driver! 3624 DD -1 ;AN031;becomes pointer to next device header 3625 DW 0C040H ;AN031;attribute (character device) 3626 DW 0000 ;AN031;pointer to harzard area. System will hang. 3627 DW 0000 ;AN031;pointer to harzard area. System will hang. 3628 DB 'EMMXXXX0' ;AN031;device name 3629 3630 INTV2F equ $-EMS_STUB_START ;AN030;J.K.pointer to old 2Fh handler ;an000; dms; 3631 IntV2FO DW ? ;AN030;;offset ;an000; dms; 3632 IntV2FS DW ? ;AN030;;segment ;an000; dms; 3633 3634 OLDINT67_VECTOR equ $-EMS_STUB_START ;AN030;J.K. 3635 OldInt67 dd ? ;AN030;; save pointer to old INT 67 handler here 3636 3637 %IF BUFFERFLAG 3638 3639 LOCKFLAG equ $-EMS_STUB_START 3640 LOCK_FLAG db ? 3641 3642 %ELSE 3643 3644 EMSPAGE_CNT equ $-EMS_STUB_START ;AN030;J.K. 3645 EMSPageCount dw ? ;AN030;; save count of EMS mappable pages here 3646 3647 EMSReservedArray_X label word ;AN030;;J.K. For initialization routine 3648 EMSRESERVEDARRAY equ $-EMS_STUB_START ;AN030;;J.K. 3649 dw 0ffffh,0ffffh ;AN030;; array of reserved pages 3650 dw 0ffffh,0ffffh ;AN030;; phys_page_segment, phys_page_number * 2 entries 3651 MappableArray_X label word ;AN030;;J.K. for initialization routine 3652 MAPPABLEARRAY equ $-EMS_STUB_START ;AN030;;J.K. 3653 dw 64 dup (0,0) ;AN030;; table to get addresses from old INT 67 handler 3654 3655 %ENDIF 3656 ; 64 entries * 2 words 3657 NEWEMS2F_OFF equ $-EMS_STUB_START;AN030; 3658 Int_2F_EMS: ;AN030;;J.K. Name changed. 3659 cmp ah,1Bh ;AN030;;AN032;2Fh trap for Mappable Phys. Add. Array ;an000; dms; 3660 je Int_2F_EMS_MINE ;AN030;;This one we want ;an000; dms; 3661 3662 IntV2F equ INTV2F ; NASM port equate 3663 jmp far [cs:IntV2F] ;AN030;;go to old interrupt handler ;an000; dms; 3664 3665 Int_2F_EMS_MINE: ;AN030; 3666 or al, al ;AN030;;J.K. Installation check? 3667 jnz Int_2F_5800_Func ;AN030;;J.K. 3668 mov al, 0FFh ;AN030;;J.K. Yes, I am here! 3669 iret ;AN030;;J.K. 3670 3671 Int_2F_5800_Func: ;AN030; 3672 3673 %IF BUFFERFLAG 3674 ; int 3 3675 cmp di, 80h 3676 jne st_flag 3677 mov byte [cs:LOCKFLAG], 0 3678 Int_2f_5800_Good_Exit equ Int_2F_5800_Good_Exit ; NASM port label 3679 jmp Int_2f_5800_Good_Exit 3680 nop ; identicalise 3681 st_flag: 3682 cmp di, 81h 3683 Int_2f_5800_Err_Exit equ Int_2F_5800_Err_Exit ; NASM port label 3684 jne Int_2f_5800_Err_Exit 3685 mov byte [cs:LOCKFLAG], 1 3686 jmp Int_2f_5800_Good_Exit 3687 nop ; identicalise 3688 %ELSE 3689 3690 push si ;AN030;; ;an000; dms; 3691 3692 ; mov si,offset EMSReservedArray ;point to array containing pages ;an000; dms; 3693 mov si, EMSRESERVEDARRAY ;AN030;;J.K. 3694 3695 cmp di,0feh ;AN030;;VDISK or FASTOPEN request? ;an000; dms; 3696 jne Int_2F_5800_Buff_Ck ;AN030;;no - check for buffers ;an000; dms; 3697 3698 cmp word ptr [cs:si],0ffffh ;AN030;;valid entry? ;an000; dms; 3699 je Int_2F_5800_Err_Exit ;AN030;;no - exit ;an000; dms; 3700 3701 mov es,word ptr [cs:si] ;AN030;;get segment value ;an000; dms; 3702 mov di,word ptr [cs:si+2] ;AN030;;get physical page value ;an000; dms; 3703 jmp Int_2F_5800_Good_Exit ;AN030;;exit routine ;an000; dms; 3704 3705 Int_2F_5800_Buff_Ck: ;AN030; 3706 3707 cmp di,0ffh ;AN030;;BUFFERS request? ;an000; dms; 3708 jne Int_2F_5800_Err_Exit ;AN030;;no - exit with error ;an000; dms; 3709 3710 add si,4 ;AN030;;point to second element in array ;an000; dms; 3711 3712 cmp word ptr [cs:si],0ffffh ;AN034;;valid entry? ;an000; dms; 3713 je Int_2F_5800_Err_Exit ;AN034;;no - exit ;an000; dms; 3714 3715 mov es,word ptr [cs:si] ;AN030;;get segment value ;an000; dms; 3716 mov di,word ptr [cs:si+2] ;AN030;;get physical page value ;an000; dms; 3717 3718 %ENDIF 3719 3720 Int_2F_5800_Good_Exit: ;AN030; 3721 3722 xor ax,ax ;AN030;;signal good return ;an000; dms; 3723 jmp Int_2F_Exit ;AN030;;exit routine ;an000; dms; 3724 nop ; identicalise 3725 3726 Int_2F_5800_Err_Exit: ;AN030; 3727 3728 mov ax,0ffffh ;AN030;;signal error ;an000; dms; 3729 3730 Int_2F_Exit: ;AN030; 3731 3732 3733 %IFN BUFFERFLAG 3734 pop si ;AN030;;restore regs ;an000; dms; 3735 %ENDIF 3736 iret ;AN030;;return to caller ;an000; dms; 3737 3738 3739 3740 ;------------------------------------------------------------------- 3741 ; 3742 ; INT 67h Filter 3743 ; 3744 ; This routine filters INT 67's looking for AH=58h. When initialized, 3745 ; the original INT 67 handler is called and the mappable address array 3746 ; is changed to "reserve" two pages for DOS use. This new array is 3747 ; then returned to the calling program when INT 67 AH=58h is found. 3748 ; 3749 ; Information about the two pages "reserved" for DOS is returned 3750 ; via an unpublished INT 2Fh interface. 3751 ; 3752 ; 5/10/88 for DOS 4.0. 3753 ;------------------------------------------------------------------- 3754 3755 %IFN BUFFERFLAG 3756 3757 GetMappableArray equ 58h ; INT 67 function code for Get Mappable Array 3758 GetPageFrame equ 41h ; function code for getting the page frame address 3759 null equ 0 ; zero value 3760 I67Error8F equ 8fh ;AN031;; invalid sub-function error 3761 3762 %ENDIF 3763 3764 ;------------------------------------------------------------------- 3765 NEW67_OFFSET equ $-EMS_STUB_START ;J.K. 3766 Int67Filter: ;AN030; 3767 3768 %IF BUFFERFLAG 3769 ; int 3 3770 cmp byte [cs:LOCKFLAG], 1 3771 jne PassThru 3772 mov ah, 80h 3773 stc 3774 iret 3775 %ELSE 3776 GETMAPPABLEARRAY equ GetMappableArray ; NASM port equate 3777 cmp ah,GETMAPPABLEARRAY ;AN030;; is this the INT 67 call we are interested in? 3778 jne PassThru ;AN030;; no, pass it to old INT 67 handler 3779 ;AN030;; yes ... 3780 cmp al,0 ;AN031;; AL=0 return count and table 3781 je I67Fcn0 3782 3783 cmp al,1 ;AN031;; AL=1 return count only 3784 jne I67Error ;AN031;; otherwise, error 3785 3786 3787 ; return count of mappable pages 3788 3789 sti ;AN031;; turn interrupts on 3790 3791 mov cx,word ptr [cs:EMSPAGE_CNT] ;AN031;J.K. get number of mappable pages in fake table 3792 xor ah,ah ;AN031;; good return code 3793 iret 3794 3795 ; return invalid sub-function code 3796 3797 I67Error: 3798 sti ;AN031;; turn interrupts on 3799 mov ah,I67Error8F ;AN031;; invalid sub-function error 3800 iret 3801 3802 3803 I67Fcn0: ;AN031 3804 3805 ; copy the fake table to user's buffer 3806 3807 sti ;AN030;; turn interrupts on 3808 3809 push ds ;AN030; save some regs 3810 push di ;AN030; 3811 push si ;AN030; 3812 3813 mov cx,word ptr [cs:EMSPAGE_CNT] ;AN030;J.K. get number of mappable pages in fake table 3814 shl cx,1 ;AN030;; count * 2 = number of words to copy 3815 3816 push cs ;AN030;; point DS:SI to fake table 3817 pop ds ;AN030; 3818 ; lea si,MappableArray 3819 mov si, MAPPABLEARRAY ;AN030;;J.K. 3820 3821 rep movsw ;AN030;; copy CX words from DS:SI to ES:DI 3822 3823 xor ah,ah ;AN030;; good return code 3824 mov cx,word ptr [cs:EMSPAGE_CNT] ;AN030;; page count returned to user in CX 3825 3826 3827 pop si ;AN030;; restore some regs 3828 pop di ;AN030; 3829 pop ds ;AN030; 3830 3831 iret ;AN030;; end of INT 67 filter routine 3832 3833 %ENDIF 3834 3835 ;------------------------------------------------------------------- 3836 ; 3837 ; PassThru - send request to old INT 67 handler 3838 ; 3839 ;------------------------------------------------------------------- 3840 3841 PassThru: 3842 OldINT67_VECTOR equ OLDINT67_VECTOR ; NASM port equate 3843 jmp far [cs:OldINT67_VECTOR] ;AN030;;J.K. jump to old INT 67 handler 3844 ; (IRET will return to calling program) 3845 3846 3847 EMS_STUB_END label byte ;AN030; 3848 ;------------------------------------------------------------------- 3849 3850 %IFN BUFFERFLAG 3851 ;------------------------------------------------------------------- 3852 ; 3853 ; Int67FilterInit - This routine is called to initialize the INT 67 3854 ; filter. It should be called as soon as possible after installation. 3855 ; 3856 ;------------------------------------------------------------------- 3857 3858 Int67FilterInit: ;AN030; 3859 push es ;AN030;; save caller's ES:DI 3860 push di ;AN030; 3861 3862 push cs ;AN030;; make ES:DI point to our array 3863 pop es ;AN030; 3864 mov di,offset MappableArray_X ;AN030; 3865 3866 ; call dword ptr cs:OldInt67 ; get mappable array from EMS DD 3867 3868 mov ah, GetMappableArray ;AN030; 3869 xor al,al ;AN030; 3870 int 67h ;AN030;;J.K. 3871 3872 3873 ;------------------------ 3874 ; scan table looking for highest phys_page_number 3875 3876 xor ax,ax ;AN030;; 3877 3878 cmp cx,0 ;AN033;; are the any pages left? 3879 je NoMoreEMSPages ;AN033;; no, don't bother looking any more 3880 3881 call GetHighestPage ;AN030;; get highest entry from table 3882 3883 mov [cs:EMSReservedArray_X+4],bx ;AN030;; phys_page_segment 3884 mov [cs:EMSReservedArray_X+6],ax ;AN030;; phys_page_number 3885 3886 cmp cx,0 ;AN033;; are the any pages left? 3887 je NoMoreEMSPages ;AN033;; no, don't bother looking any more 3888 3889 call GetHighestPage ;AN030;; get next highest entry from table 3890 3891 mov [cs:EMSReservedArray_X+0],bx ;AN030;; phys_page_segment 3892 mov [cs:EMSReservedArray_X+2],ax ;AN030;; phys_page_number 3893 3894 NoMoreEMSPages: ;AN033;; 3895 mov [cs:EMSPageCount],cx ;AN030;; save new page count for INT 67 filter 3896 3897 pop di 3898 pop es 3899 ret ;AN030;; return to calling program 3900 3901 3902 ; page 3903 ;------------------------------------------------------------------- 3904 ; 3905 ; GetHighestPage - returns highest physical page number in AX 3906 ; and segment for it in BX. A -1 means no valid page found. 3907 ; 3908 ;------------------------------------------------------------------- 3909 GetHighestPage: 3910 3911 xor ax,ax ;AN030;; zero candidate register 3912 mov bx,ax ;AN030;; zero pointer to candidate page 3913 3914 push cx ;AN030;; save count 3915 push dx ;AN030; 3916 push di ;AN030;; save pointer 3917 3918 PageScanLoop: ;AN030; 3919 cmp ax,[ES:di+2] ;AN030;; get phys_page_number 3920 ja LookAtNextPage ;AN030;; this one is lower than the one we are holding 3921 3922 cmp word [es:di], 0a000h ; Only reserve pages in memory above 640K.. 3923 jb LookAtNextPage ; fix for ps2emm and m20emm with motherboard 3924 ; disabled. 7/25/88. HKN. 3925 3926 mov ax,[ES:di+2] ;AN030;; this one is higher, make it new candidate 3927 mov bx,di ;AN030;; pointer to new candidate page, used to zero 3928 ; it later so we don't get the same one again 3929 mov dx,cx ;AN030;; save count where we found candidate 3930 3931 LookAtNextPage: ;AN030; 3932 add di,4 ;AN030;; point to next entry in mappable table 3933 3934 loop PageScanLoop ;AN030;; look at next entry 3935 3936 cmp bx,null ;AN030;; did we find any pages? 3937 jne FoundOne ;AN030;; yes, exit 3938 3939 jmp ReturnError ;AN030; 3940 3941 ;------------------------ 3942 FoundOne: ;AN030; 3943 cmp ax,3 ;AN030;; could the one we found be part of a page frame 3944 NotFrame equ Notframe ; NASM port label 3945 ja NotFrame ;AN030;; no, carry on 3946 3947 ; yes, find out if it is part of frame 3948 3949 push ax ;AN030;; save physical page number 3950 push bx ;an030;; dms; bx destroyed by call 3951 mov ah,GetPageFrame ;AN030;; function code to get page frame ... 3952 ; call dword ptr cs:OldInt67 ; ... from the EMS DD 3953 int 67h ;AN030;;J.K. 3954 or ah,ah ;an030;;dms; error? 3955 pop bx ;an030;;dms; restore bx 3956 pop ax ;AN030;; restore phys page number 3957 jnz NotFrame ;AN030;; no frame available, carry on 3958 3959 ; there is a frame, this page is part of frame, so return -1's 3960 3961 ReturnError: ;AN030; 3962 mov ax,0ffffh ;AN030;; indicate failure 3963 mov bx,ax ;AN030;; ax and bx = -1 3964 3965 pop di ;AN030;; restore pointer 3966 pop dx 3967 pop cx ;AN030;; restore count 3968 3969 jmp GHPExit ;AN030; 3970 3971 3972 3973 3974 ;------------------------ 3975 ; Found a page, and it is not part of a page frame, so re-pack table 3976 ; and return info. The entry we "reserve" for DOS must be removed 3977 ; from the table and the other entries moved up to repack the table. 3978 ; The count must be reduced by 1 to reflect this change. 3979 3980 Notframe: ;AN030; 3981 3982 mov di,bx ;AN030;; make ES:DI point to highest page table entry 3983 3984 mov bx,[ES:di] ;AN030;; get segment address of page 3985 3986 mov cx,dx ;AN030;; get count from candidate page 3987 3988 push ax ;AN030; 3989 PackLoop: ;AN030; 3990 mov ax, [es:di+4] ;AN030; 3991 mov [es:di+0], ax ;AN030; 3992 mov ax, [es:di+6] ;AN030; 3993 mov [es:di+2], ax ;AN030; 3994 add di, 4 ;AN030; 3995 loop PackLoop ;AN030;; do it until done 3996 pop ax ;AN030; 3997 3998 pop di ;AN030;; restore pointer 3999 pop dx ;AN030; 4000 pop cx ;AN030;; restore count 4001 4002 sub cx,1 ;AN030;; reduce count by one, one less page in table now 4003 4004 GHPExit: ;AN030; 4005 4006 ret ;AN030;; return to caller 4007 4008 %ENDIF 4009 4010 ;========================================================================= 4011 ; EMS_Install_Check : THIS MODULE DETERMINES WHETHER OR NOT EMS IS 4012 ; INSTALLED FOR THIS SESSION. 4013 ; 4014 ; INPUTS : NONE 4015 ; 4016 ; OUTPUTS : ES:BX - FRAME ARRAY 4017 ; CY - EMS NOT AVAILABLE 4018 ; NC - EMS AVAILABLE 4019 ; 4020 ; Date : 5/6/88 4021 ;========================================================================= 4022 4023 EMS_Install_Check proc near ;AN030;; check if EMS is installed ;an000; dms; 4024 4025 push ax ;AN030;; save regs ;an000; dms; 4026 4027 push ds ;AN030;; save ds ;an000; dms; 4028 xor ax,ax ;AN030;; set ax to 0 ;an000; dms; 4029 mov ds,ax ;AN030;; set ds to 0 ;an000; dms; 4030 cmp word ptr [067h*4+0],0 ;AN030;; see if int 67h is there ;an000; dms; 4031 pop ds ;AN030;; restore ds ;an000; dms; 4032 je EMS_Install_Ck_Err_Exit ;AN030;; exit routine - EMS not loaded ;an000; dms; 4033 4034 mov ah,40h ;AN030;; Get Status function ;an000; dms; 4035 xor al,al ;AN030;; clear al ;an000; dms; 4036 int 67h ;AN030;; ;an000; dms; 4037 or ah,ah ;AN030;; EMS installed? ;an000; dms; 4038 jnz EMS_Install_Ck_Err_Exit ;AN030;; exit routine - EMS not loaded ;an000; dms; 4039 4040 mov ah,46h ;AN030;; Get Version number ;an000; dms; 4041 xor al,al ;AN030;; clear al ;an000; dms; 4042 int 67h ;AN030;; ;an000; dms; 4043 cmp al,40h ;AN030;; Version 4.0? ;an000; dms; 4044 jb EMS_Install_Ck_Err_Exit ;AN030;; exit routine - wrong EMS loaded ;an000; dms; 4045 4046 clc ;AN030;; signal EMS loaded ;an000; dms; 4047 jmp EMS_Install_Ck_Exit ;AN030;; exit routine ;an000; dms; 4048 nop ; identicalise 4049 4050 EMS_Install_Ck_Err_Exit: ;AN030; 4051 4052 stc ;AN030;; signal EMS not loaded ;an000; dms; 4053 4054 EMS_Install_Ck_Exit: ;AN030; 4055 4056 pop ax ;AN030;; restore regs ;an000; dms; 4057 4058 ret ;AN030;; return to caller ;an000; dms; 4059 4060 EMS_Install_Check endp ; ;an000; dms; 4061 4062 EMS_Stub_Handler proc near ;AN030; 4063 ;At the request of Architecture Group, this logic is implemented. 4064 ;Function: If (Buffer_Slash_X <> 0 and EMS_Stub_Installed == 0), 4065 ; then { call Chk_EMS; 4066 ; if EMS is there, then install EMS_Stub dynamically 4067 ; and initialize it.} 4068 ; Note: EMS_Stub consists of INT 2fh EMS handler and INT 67h handler. 4069 ; When EMS_Stub is installed, EMS_Stub_Installed will be set to 1. 4070 4071 push es ;AN030; 4072 push si ;AN030; 4073 push ds ;AN030; 4074 push di ;AN030; 4075 push ax ;AN030; 4076 push cx ;AN030; 4077 cmp byte [cs:EMS_Stub_Installed], 0 ;AN030; 4078 je EMS_Stub_X ;AN030; 4079 jmp short EMS_SH_Ret ;AN030; 4080 nop ; identicalise 4081 EMS_Stub_X: ;AN030; 4082 cmp byte [cs:Buffer_Slash_X], 0 ;AN030; 4083 je EMS_SH_Ret ;AN030; 4084 call EMS_Install_Check ;AN030; 4085 jc EMS_SH_Ret ;AN030; 4086 ;Install EMS_Stub. ;AN030; 4087 EMS_Stub_Do: 4088 push es ;AN030; 4089 xor ax,ax ;AN030;save current Int 2fh, 67h vectors. 4090 mov es, ax ;AN030; 4091 mov ax, word ptr [es:2fh*4] ;AN030; 4092 mov [cs:IntV2FO], ax ;AN030; 4093 mov ax, word ptr [es:2fh*4+2] ;AN030; 4094 mov [cs:IntV2FS], ax ;AN030; 4095 mov ax, word ptr [es:67h*4] ;AN030; 4096 mov word ptr [cs:OldInt67], ax ;AN030; 4097 mov ax, word ptr [es:67h*4+2] ;AN030; 4098 mov word ptr [cs:OldInt67+2], ax ;AN030; 4099 pop es ;AN030; 4100 4101 %IFN BUFFERFLAG 4102 ;initalize tables in INT 67h handler 4103 call Int67FilterInit ;AN030; 4104 cmp ax, 0ffffh ; if the page found was part of a lim 4.0 page frame 4105 EMS_SH_ret equ EMS_SH_Ret ; NASM port label 4106 je EMS_SH_ret ; do not install stub. 7/24/88. HKN 4107 %ENDIF 4108 Round equ ROUND ; NASM port label 4109 call Round ;AN030; 4110 mov ax, DEVMARK_EMS_STUB ;AN030; 4111 call SetDevMark ;AN030; 4112 memhi equ MEMHI ; NASM port label 4113 mov ax, [cs:memhi] ;AN030; 4114 mov es, ax ;AN030; 4115 assume es:nothing ;AN030; 4116 xor di, di ;AN030; 4117 push cs ;AN030; 4118 pop ds ;AN030; 4119 mov cx, offset EMS_STUB_END ;AN030; 4120 mov si, offset EMS_STUB_START ;AN030; 4121 sub cx, si ;AN030;cx = size in byte 4122 memlo equ MEMLO ; NASM port label 4123 mov [cs:memlo], cx ;AN030; 4124 rep movsb ;AN030; 4125 or byte [cs:SetDevMarkFlag], FOR_DEVMARK ;AN030;set the devmark_size for MEM command. 4126 call Round ;AN030;and get the next [memhi] avaiable. 4127 mov byte [cs:EMS_Stub_Installed], 1 ;AN030; 4128 4129 xor ax, ax ;AN030; 4130 mov ds, ax ;AN030; 4131 cli ;AN030; 4132 mov word ptr [2Fh*4],NEWEMS2F_OFF;AN030;set the new int 2fh, 67h vectors. 4133 mov word ptr [2Fh*4+2], es ;AN030; 4134 mov word ptr [67h*4],NEW67_OFFSET;AN030; 4135 mov word ptr [67h*4+2], es ;AN030; 4136 sti ;AN030; 4137 EMS_SH_Ret: ;AN030; 4138 pop cx ;AN030; 4139 pop ax ;AN030; 4140 pop di ;AN030; 4141 pop ds ;AN030; 4142 pop si ;AN030; 4143 pop es ;AN030; 4144 ret ;AN030; 4145 4146 EMS_Stub_Handler endp ;AN030; 4147 %endif ; BUF2 4148 4149 4150 ; (no prior section) ; SYSINITSEG ENDS 4151 END 4152 4153 === Trace listing source: sysinit2.lst 1 ; PAGE ,132 ; 2 ; SCCSID = @(#)sysinit2.asm 1.13 85/10/15 3 ;TITLE BIOS SYSTEM INITIALIZATION 4 %warning out: ...SYSINIT2 4 ****************** warning: out: ...SYSINIT2 [-w+user] 5 6 ;============================================================================== 7 ;REVISION HISTORY: 8 ;AN000 - New for DOS Version 4.00 - J.K. 9 ;AC000 - Changed for DOS Version 4.00 - J.K. 10 ;AN00x - PTM number for DOS Version 4.00 - J.K. 11 ;============================================================================== 12 ;AN001; p132 Multiple character device installation problem. 6/27/87 J.K. 13 ;AN002; d24 MultiTrack= command added. 6/29/87 J.K. 14 ;AN003; p29 Extra space character in parameters passed. 15 ; (Modification on ORGANIZE routine for COMMENT= fixed this 16 ; problem too) 6/29/87 J.K. 17 ;AN004; d41 REM command in CONFIG.SYS 7/7/87 J.K. 18 ;AN005; d184 Set DEVMARK for MEM command 8/25/87 J.K. 19 ;AN006; p1820 New Message SKL file 10/20/87 J.K. 20 ;AN007; p1821 Include the COPYRIGH.INC file 10/22/87 J.K. 21 ;AN008; p2210 IBMDOS returns incorrect DBCS vector table length 11/02/87 J.K. 22 ;AN009; p2667 ccMono_Ptr problem 11/30/87 J.K. 23 ;AN010; p2792 Device?driver.sys /d:2 command should not work 12/09/87 J.K. 24 ;AN011; p3120 REM followed by CR, LF causes problem 01/13/88 J.K. 25 ;AN012; p3111 Take out the order dependency of the INSTALL= 01/25/88 J.K. 26 ;AN013; d479 New option to disable extended INT 16h function call 02/12/88 J.K. 27 ;AN014; D486 SHARE installation for big media 02/23/88 J.K. 28 ;AN015; D526 Add /NC parameter when installing SHARE.EXE 04/28/88 J.K. 29 ;============================================================================== 30 31 TRUE EQU 0FFFFh 32 FALSE EQU 0 33 LF equ 10 34 CR equ 13 35 TAB equ 9 36 37 IBMVER EQU TRUE 38 IBM EQU IBMVER 39 STACKSW EQU TRUE ;Include Switchable Hardware Stacks 40 IBMJAPVER EQU FALSE ;If TRUE set KANJI true also 41 %iassign MSVER FALSE 42 ALTVECT EQU FALSE ;Switch to build ALTVECT version 43 KANJI EQU FALSE 44 45 %IF IBMJAPVER 46 NOEXEC EQU TRUE 47 %ELSE 48 NOEXEC EQU FALSE 49 %ENDIF 50 51 ;DOSSIZE EQU 0A000H 52 53 54 [list -] 54 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 54 ****************** warning: out: BPB.INC... [-w+user] 54 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 54 ****************** warning: out: DEVSYM.INC... [-w+user] 54 ****************** warning: out: IOCTL.INC... [-w+user] 54 ****************** warning: out: BPB.INC... [-w+user] 54 ****************** warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi] 14 <2> [list -] 13 <1> [list -] 62 %include "entryseg.nas" 1 <1> === Switch to base=000000h -> "DOSENTRY" 2 <1> section DOSENTRY class=%[DOSENTRY] === Switch to base=000000h -> "DOSENTRY" 3 <1> section DOSENTRY 63 [list +] 64 65 %IFN IBM 66 %IFN IBMJAPVER 67 EXTRN RE_INIT:FAR 68 %ENDIF 69 %ENDIF 70 71 extrn EC35_Flag: byte 72 ; (no prior section) ; code ends 73 === Switch to base=002530h -> "SYSINITSEG" 74 section SYSINITSEG PUBLIC class=INIT align=1 75 76 ASSUME CS:SYSINITSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING 77 78 EXTRN BADOPM:BYTE,CRLFM:BYTE,BADCOM:BYTE,BADMEM:BYTE,BADBLOCK:BYTE 79 EXTRN BADSIZ_PRE:BYTE,BADLD_PRE:BYTE 80 ; EXTRN BADSIZ_POST:BYTE,BADLD_POST:BYTE 81 EXTRN SYSSIZE:BYTE,BADCOUNTRY:BYTE 82 83 EXTRN dosinfo:dword,entry_point:dword 84 EXTRN MEMORY_SIZE:WORD,fcbs:byte,keep:byte 85 EXTRN DEFAULT_DRIVE:BYTE,conf_block:word 86 EXTRN BUFFERS:WORD,zero:byte,sepchr:byte 87 EXTRN FILES:BYTE 88 EXTRN count:word,chrptr:word 89 EXTRN bufptr:byte 90 EXTRN area:word,PACKET:BYTE,UNITCOUNT:BYTE 91 EXTRN BREAK_ADDR:DWORD,BPB_ADDR:DWORD,drivenumber:byte 92 extrn COM_Level:byte, CMMT:byte, CMMT1:byte, CMMT2:byte 93 extrn Cmd_Indicator:byte 94 extrn DoNotShowNum:byte 95 extrn MultDeviceFlag:byte 96 extrn DevMark_Addr:word ;AN005; 97 extrn SetDevMarkFlag:byte ;AN005; 98 extrn Org_Count:word ;AN012; 99 extern devicehighflag, devicehighdata, devicehighafter, devicehighsd 100 extern deviceafter 101 102 EXTRN Stall:near 103 EXTRN Error_Line:near 104 105 Int24 equ INT24 ; NASM port label 106 Open_Dev equ OPEN_DEV ; NASM port label 107 Organize equ ORGANIZE ; NASM port label 108 Mem_Err equ MEM_ERR ; NASM port label 109 Newline equ NEWLINE ; NASM port label 110 CallDev equ CALLDEV ; NASM port label 111 Badload equ BADLOAD ; NASM port label 112 PUBLIC Int24,Open_Dev,Organize,Mem_Err,Newline,CallDev,Badload 113 PrnDev equ PRNDEV ; NASM port label 114 AuxDev equ AUXDEV ; NASM port label 115 Commnd equ COMMND ; NASM port label 116 Condev equ CONDEV ; NASM port label 117 GetNum equ GETNUM ; NASM port label 118 BadFil equ BADFIL ; NASM port label 119 PrnErr equ PRNERR ; NASM port label 120 PUBLIC PrnDev,AuxDev,Commnd,Condev,GetNum,BadFil,PrnErr 121 Delim equ DELIM ; NASM port label 122 Print equ PRINT ; NASM port label 123 Set_Break equ SET_BREAK ; NASM port label 124 PUBLIC Delim,Print,Set_Break 125 PUBLIC SetParms, ParseLine, DiddleBack 126 Skip_delim equ SKIP_DELIM ; NASM port label 127 Set_Country_Path equ SET_COUNTRY_PATH ; NASM port label 128 Move_Asciiz equ MOVE_ASCIIZ ; NASM port label 129 PUBLIC Skip_delim,SetDOSCountryInfo,Set_Country_Path,Move_Asciiz 130 Cntry_Drv equ CNTRY_DRV ; NASM port label 131 Cntry_Root equ CNTRY_ROOT ; NASM port label 132 Cntry_Path equ CNTRY_PATH ; NASM port label 133 PUBLIC Cntry_Drv,Cntry_Root,Cntry_Path 134 PUBLIC Delim 135 public PathString ;AN014; 136 public LShare ;AN014; 137 138 ; 139 ; The following set of routines is used to parse the DRIVPARM = command in 140 ; the CONFIG.SYS file to change the default drive parameters. 141 ; 142 SetParms: 0 00004249 1E push ds 0 0000424A 50 push ax 0 0000424B 53 push bx 0 0000424C 51 push cx 0 0000424D 52 push dx 0 0000424E 0E push cs 0 0000424F 1F pop ds 150 ASSUME DS:SYSINITSEG 0 00004250 31DB xor bx,bx 0 00004252 8A1E[680A] mov bl,byte ptr [drive] 0 00004256 FEC3 inc bl ; get it correct for IOCTL call (1=A,2=B...) 0 00004258 BA[4009] mov dx,offset DeviceParameters 155 IOCTL equ IOCtl ; NASM port equate 0 0000425B B444 mov ah, IOCTL 0 0000425D B00D mov al, GENERIC_IOCTL 0 0000425F B508 mov ch, RAWIO 0 00004261 B140 mov cl, SET_DEVICE_PARAMETERS 0 00004263 CD21 int 21H 0 00004265 F706[690A]0400 test word [Switches], flagec35 0 0000426B 7411 jz Not_EC35 163 0 0000426D 8A0E[680A] mov cl, byte ptr [drive] ; which drive was this for? 0 00004271 B8[0000] mov ax, DOSENTRY ; get Code segment 0 00004274 8ED8 mov ds, ax ; set code segment 167 assume ds:DOSENTRY 0 00004276 B001 mov al, 1 ; assume drive 0 0 00004278 D2E0 shl al, cl ; set proper bit depending on drive 0 0000427A 0806[0000] or [EC35_Flag], al ; set the bit in the permanent flags 171 172 Not_EC35: 0 0000427E 5A pop dx ; fix up all the registers 0 0000427F 59 pop cx 0 00004280 5B pop bx 0 00004281 58 pop ax 0 00004282 1F pop ds 178 assume ds:nothing 0 00004283 C3 ret 180 181 ; 182 ; Replace default values for further DRIVPARM commands 183 ; 184 DiddleBack: 0 00004284 1E push ds 0 00004285 0E push cs 0 00004286 1F pop ds 188 assume ds:sysinitseg 189 DP_Cylinders equ DP_CYLINDERS ; NASM port equate 0 00004287 C706[4409]5000 mov word [DeviceParameters + DP_Cylinders],80 191 DP_DeviceType equ DP_DEVICETYPE ; NASM port equate 0 0000428D C606[4109]02 mov byte [DeviceParameters + DP_DeviceType], DEV_3INCH720KB 193 DP_DeviceAttributes equ DP_DEVICEATTRIBUTES ; NASM port equate 0 00004292 C706[4209]0000 mov word [DeviceParameters + DP_DeviceAttributes],0 195 switches equ Switches ; NASM port label 0 00004298 C706[690A]0000 mov word [switches],0 ; zero all switches 0 0000429E 1F pop ds 198 assume ds:nothing 0 0000429F C3 ret 200 201 ; 202 ; Entry point is ParseLine. AL contains the first character in command line. 203 ; 204 ParseLine: ; don't get character first time 0 000042A0 1E push ds 0 000042A1 0E push cs 0 000042A2 1F pop ds 208 ASSUME DS:SYSINITSEG 209 NextSwtch: 0 000042A3 3C0D cmp al,CR ; carriage return? 0 000042A5 7422 jz done_line 0 000042A7 3C0A cmp al,LF ; linefeed? 0 000042A9 743E jz put_back ; put it back and done 214 ; Anything less or equal to a space is ignored. 0 000042AB 3C20 cmp al,' ' ; space? 0 000042AD 7610 jbe get_next ; skip over space 0 000042AF 3C2F cmp al,'/' 0 000042B1 7403 jz getparm 0 000042B3 F9 stc ; mark error invalid-character-in-input 0 000042B4 EB31 jmp short exitpl 221 222 getparm: 0 000042B6 E83A00 call Check_Switch 0 000042B9 891E[690A] mov word ptr [Switches],BX ; save switches read so far 0 000042BD 7207 jc swterr 226 get_next: 0 000042BF E8[0000] invoke getchr 0 000042C2 7205 jc done_line 0 000042C4 EBDD jmp NextSwtch 230 swterr: 0 000042C6 EB1F jmp exitpl ; exit if error 0 000042C8 90 nop ; identicalise 233 234 done_line: 0 000042C9 F706[690A]0800 test word [Switches],flagdrive ; see if drive specified 0 000042CF 7503 jnz okay 0 000042D1 F9 stc ; mark error no-drive-specified 0 000042D2 EB13 jmp short exitpl 239 240 okay: 0 000042D4 A1[690A] mov ax,word ptr [switches] 0 000042D7 83E003 and ax,0003H ; get flag bits for changeline and non-rem 0 000042DA A3[4209] mov word ptr [DeviceParameters + DP_DeviceAttributes],ax 244 DP_TrackTableEntries equ DP_TRACKTABLEENTRIES ; NASM port equate 0 000042DD C706[6609]0000 mov word [DeviceParameters + DP_TrackTableEntries], 0 0 000042E3 F8 clc ; everything is fine 0 000042E4 E8A000 call SetDeviceParameters 248 exitpl: 0 000042E7 1F pop ds 0 000042E8 C3 ret 251 252 put_back: 0 000042E9 FF06[0000] inc word [count] ; one more char to scan 0 000042ED FF0E[0000] dec word [chrptr] ; back up over linefeed 0 000042F1 EBD6 jmp short done_line 256 ; 257 ; Processes a switch in the input. It ensures that the switch is valid, and 258 ; gets the number, if any required, following the switch. The switch and the 259 ; number *must* be separated by a colon. Carry is set if there is any kind of 260 ; error. 261 ; 262 Check_Switch: 0 000042F3 E8[0000] invoke getchr 0 000042F6 7252 jc err_check 0 000042F8 24DF and al,0DFH ; convert it to upper case 0 000042FA 3C41 cmp al,'A' 0 000042FC 724C jb err_check 0 000042FE 3C5A cmp al,'Z' 0 00004300 7748 ja err_check 0 00004302 06 push es 0 00004303 0E push cs 0 00004304 07 pop es 0 00004305 8A0E[DF0A] mov cl,byte ptr [switchlist] ; get number of valid switches 0 00004309 B500 mov ch,0 0 0000430B BF[E00A] mov di,1+offset switchlist ; point to string of valid switches 0 0000430E F2AE repne scasb 0 00004310 07 pop es 0 00004311 7537 jnz err_check 0 00004313 B80100 mov ax,1 0 00004316 D3E0 shl ax,cl ; set bit to indicate switch 0 00004318 8B1E[690A] mov bx,word ptr [switches] ; get switches so far 0 0000431C 09C3 or bx,ax ; save this with other switches 0 0000431E 89C1 mov cx,ax 0 00004320 A9F800 test ax, switchnum ; test against switches that require number to follow 0 00004323 90 nop ; identicalise 0 00004324 7420 jz done_swtch 0 00004326 E8[0000] invoke getchr 288 err_Swtch equ err_swtch ; NASM port label 0 00004329 721D jc err_Swtch 0 0000432B 3C3A cmp al,':' 0 0000432D 7519 jnz err_swtch 0 0000432F E8[0000] invoke getchr 0 00004332 53 push bx ; preserve switches 0 00004333 2EC606[0000]20 mov byte [cs:sepchr],' ' ; allow space separators 0 00004339 E8D203 call GetNum 0 0000433C 2EC606[0000]00 mov byte [cs:sepchr],0 0 00004342 5B pop bx ; restore switches 298 ; Because GetNum does not consider carriage-return or line-feed as OK, we do 299 ; not check for carry set here. If there is an error, it will be detected 300 ; further on (hopefully). 0 00004343 E80600 call Process_Num 302 303 done_swtch: 0 00004346 F8 clc 0 00004347 C3 ret 306 307 err_swtch: 0 00004348 31CB xor bx,cx ; remove this switch from the records 309 err_check: 0 0000434A F9 stc 0 0000434B C3 ret 312 313 ; 314 ; This routine takes the switch just input, and the number following (if any), 315 ; and sets the value in the appropriate variable. If the number input is zero 316 ; then it does nothing - it assumes the default value that is present in the 317 ; variable at the beginning. Zero is OK for form factor and drive, however. 318 ; 319 Process_Num: 0 0000434C 850E[690A] test word ptr [Switches],cx ; if this switch has been done before, 0 00004350 7533 jnz done_ret ; ignore this one. 0 00004352 F7C10800 test cx,flagdrive 0 00004356 7405 jz try_f 0 00004358 A2[680A] mov byte ptr [drive],al 0 0000435B EB28 jmp short done_ret 326 327 try_f: 0 0000435D F7C18000 test cx,flagff 0 00004361 7405 jz try_t 330 ; Ensure that we do not get bogus form factors that are not supported 331 ;cmp al,Max_Dev_Type 332 ;ja done_ret 0 00004363 A2[4109] mov byte ptr [DeviceParameters + DP_DeviceType],al 0 00004366 EB1D jmp short done_ret 335 336 try_t: 0 00004368 09C0 or ax,ax 0 0000436A 7419 jz done_ret ; if number entered was 0, assume default value 0 0000436C F7C11000 test cx,flagcyln 0 00004370 7405 jz try_s 0 00004372 A3[4409] mov word ptr [DeviceParameters + DP_Cylinders],ax 0 00004375 EB0E jmp short done_ret 343 344 try_s: 0 00004377 F7C12000 test cx,flagseclim 0 0000437B 7405 jz try_h 0 0000437D A3[660A] mov word ptr [slim],ax 0 00004380 EB03 jmp short done_ret 349 ; 350 ; Must be for number of heads 351 try_h: 0 00004382 A3[640A] mov word ptr [hlim],ax 353 354 done_ret: 0 00004385 F8 clc 0 00004386 C3 ret 357 358 ; 359 ; SetDeviceParameters sets up the recommended BPB in each BDS in the 360 ; system based on the form factor. It is assumed that the BPBs for the 361 ; various form factors are present in the BPBTable. For hard files, 362 ; the Recommended BPB is the same as the BPB on the drive. 363 ; No attempt is made to preserve registers since we are going to jump to 364 ; SYSINIT straight after this routine. 365 ; 366 SetDeviceParameters: 0 00004387 06 push es 0 00004388 0E push cs 0 00004389 07 pop es 370 ASSUME ES:SYSINITSEG 0 0000438A 31DB xor bx,bx 0 0000438C 8A1E[4109] mov bl,byte ptr [DeviceParameters + DP_DeviceType] 0 00004390 80FB00 cmp bl,DEV_5INCH 0 00004393 7507 jnz Got_80 0 00004395 B92800 mov cx,40 ; 48tpi has 40 cylinders 0 00004398 890E[4409] mov word ptr [DeviceParameters + DP_Cylinders],cx 377 Got_80: 0 0000439C D1E3 shl bx,1 ; get index into BPB table 0 0000439E BE[CF0A] mov si,offset BPBTable 0 000043A1 8B30 mov si,word ptr [si+bx] ; get address of BPB 381 Set_RecBPB: 0 000043A3 BF[4709] mov di,offset DeviceParameters + DP_BPB ; es:di -> BPB 383 a_BPB_struc_size equ A_BPB_struc_size ; NASM port equate 0 000043A6 B91F00 mov cx,a_BPB_struc_size 0 000043A9 FC cld 0 000043AA F3A4 repe movsb 0 000043AC 07 pop es 388 ASSUME ES:NOTHING 0 000043AD F706[690A]2000 test word [switches],flagseclim 0 000043B3 7406 jz see_heads 0 000043B5 A1[660A] mov ax,word ptr [slim] 392 BPB_SectorsPerTrack equ BPB_SECTORSPERTRACK ; NASM port equate 0 000043B8 A3[5409] mov word ptr [DeviceParameters + DP_BPB + BPB_SectorsPerTrack],ax 394 see_heads: 0 000043BB F706[690A]4000 test word [switches],flagheads 0 000043C1 743E jz Set_All_Done 0 000043C3 A1[640A] mov ax,word ptr [hlim] 398 BPB_Heads equ BPB_HEADS ; NASM port equate 0 000043C6 A3[5609] mov word ptr [DeviceParameters + DP_BPB + BPB_Heads],ax 400 ; 401 ; We need to set the media byte and the total number of sectors to reflect the 402 ; number of heads. We do this by multiplying the number of heads by the number 403 ; of 'sectors per head'. This is not a fool-proof scheme!! 404 ; 0 000043C9 89C1 mov cx,ax ; cx has number of heads 0 000043CB FEC9 dec cl ; get it 0-based 407 BPB_TotalSectors equ BPB_TOTALSECTORS ; NASM port equate 0 000043CD A1[4F09] mov ax,[DeviceParameters + DP_BPB + BPB_TotalSectors] ; this is OK for two heads 0 000043D0 D1F8 sar ax,1 ; ax contains # of sectors/head 0 000043D2 D3E0 sal ax,cl 0 000043D4 722B jc Set_All_Done ; We have too many sectors - overflow!! 0 000043D6 A3[4F09] mov [DeviceParameters + DP_BPB + BPB_TotalSectors],ax 413 ; Set up correct Media Descriptor Byte 0 000043D9 80F901 cmp cl,1 0 000043DC B3F0 mov bl,0F0H 0 000043DE B002 mov al,2 ; AL contains sectors/cluster 0 000043E0 7717 ja Got_Correct_Mediad 418 BPB_MediaDescriptor equ BPB_MEDIADESCRIPTOR ; NASM port equate 0 000043E2 8A1E[5109] mov bl,byte ptr [DeviceParameters + DP_BPB + BPB_MediaDescriptor] 0 000043E6 7411 je Got_Correct_Mediad 421 ; We have one head - OK for 48tpi medium 0 000043E8 B001 mov al,1 ; AL contains sectors/cluster 0 000043EA 8A2E[4109] mov ch,[DeviceParameters + DP_DeviceType] 0 000043EE 80FD00 cmp ch,DEV_5INCH 0 000043F1 7404 jz Dec_Mediad 0 000043F3 B3F0 mov bl,0F0H 0 000043F5 EB02 jmp short Got_Correct_Mediad 428 Dec_Mediad: 0 000043F7 FECB dec bl ; adjust for one head 430 Got_Correct_Mediad: 0 000043F9 881E[5109] mov byte ptr [DeviceParameters + DP_BPB + BPB_MediaDescriptor],bl 432 BPB_SectorsPerCluster equ BPB_SECTORSPERCLUSTER ; NASM port equate 0 000043FD A2[4909] mov byte ptr [DeviceParameters + DP_BPB + BPB_SectorsPerCluster],al 0 00004400 F8 clc 435 Set_All_Done: 0 00004401 C3 RET 437 438 ASSUME DS:NOTHING, ES:NOTHING 439 0 00004402 F9 NOCHAR1: STC 0 00004403 C3 return 442 443 ORGANIZE: 444 COUNT equ count ; NASM port label 0 00004404 2E8B0E[0000] MOV CX,[cs:COUNT] 0 00004409 E3F7 JCXZ NOCHAR1 0 0000440B E82C02 CALL MAPCASE 0 0000440E 31F6 XOR SI,SI 0 00004410 89F7 MOV DI,SI 0 00004412 31C0 xor ax,ax 0 00004414 2EC606[0000]00 mov byte [cs:COM_Level], 0 452 453 ;ORG1: CALL GET ;SKIP LEADING CONTROL CHARACTERS 454 ; CMP AL,' ' 455 ; JB ORG1 456 Org1: 0 0000441A E8A701 call Skip_Comment ;AN000; 0 0000441D 740E jz End_Commd_Line ;AN000; found a comment string and skipped. 459 Get2 equ GET2 ; NASM port label 0 0000441F E89A01 call Get2 ;AN000; Not a comment string. Then get a char. 0 00004422 3C0A cmp al, LF ;AN000; 0 00004424 7407 je End_Commd_Line ;AN000; starts with a blank line. 0 00004426 3C20 cmp al, ' ' ;AN000; 0 00004428 76F0 jbe Org1 ;AN000; skip leading control characters 0 0000442A EB0A jmp Findit ;AN000; 0 0000442C 90 nop ; identicalise 467 End_Commd_Line: ;AN000; 0 0000442D AA stosb ;AN000; store line feed char in buffer for the LineCount. 0 0000442E 2EC606[0000]00 mov byte [cs:COM_Level], 0 ;AN000; reset the command level. 0 00004434 EBE4 jmp Org1 ;AN000; 471 Findit: ;AN000; 0 00004436 51 PUSH CX 0 00004437 56 PUSH SI 0 00004438 57 PUSH DI 0 00004439 89F5 MOV BP,SI 0 0000443B 4D DEC BP 0 0000443C BE[9108] MOV SI,OFFSET COMTAB ;Prepare to search command table 0 0000443F B500 MOV CH,0 479 FINDCOM: 0 00004441 89EF MOV DI,BP 0 00004443 8A0C MOV CL,[SI] 0 00004445 46 INC SI 0 00004446 E324 JCXZ NOCOM 0 00004448 F3A6 REPE CMPSB 0 0000444A 9F LAHF 0 0000444B 01CE ADD SI,CX ;Bump to next position without affecting flags 0 0000444D 9E SAHF 0 0000444E AC LODSB ;Get indicator letter 0 0000444F 75F0 JNZ FINDCOM 0 00004451 26803D0D cmp byte ptr [es:di], CR ;AN011;The next char might be CR,LF 0 00004455 7410 je GotCom0 ;AN011; such as in "REM",CR,LF case. 0 00004457 26803D0A cmp byte ptr [es:di], LF ;AN011; 0 0000445B 740A je GotCom0 ;AN011; 0 0000445D 50 push ax ;AN010; 0 0000445E 268A05 mov al, byte ptr [es:di] ;AN010;Now the next char. should be a delim. 496 delim equ DELIM ; NASM port label 0 00004461 E89B01 call delim ;AN010; 0 00004464 58 pop ax ;AN010; 499 findcom equ FINDCOM ; NASM port label 0 00004465 75DA jnz findcom ;AN010; 501 GotCom0: 0 00004467 5F POP DI 0 00004468 5E POP SI 0 00004469 59 POP CX 0 0000446A EB0F JMP SHORT GOTCOM 506 507 NOCOM: 0 0000446C 5F POP DI 0 0000446D 5E POP SI 0 0000446E 59 POP CX 0 0000446F B05A MOV AL,'Z' 0 00004471 AA stosb ;AN000; save indicator char. 513 Skip_Line: ;AN000; 0 00004472 E84701 call Get2 ;AN000; 0 00004475 3C0A cmp al, LF ;AN000; skip this bad command line 0 00004477 75F9 jne Skip_Line ;AN000; 0 00004479 EBB2 jmp End_Commd_Line ;AN000; handle next command line 518 0 0000447B AA GOTCOM: STOSB ;SAVE INDICATOR CHAR IN BUFFER 0 0000447C 2EA2[0000] mov [cs:Cmd_Indicator], al ;AN000; save it for the future use. 521 0 00004480 E83901 ORG2: CALL GET2 ;SKIP the commad name UNTIL DELIMITER 0 00004483 3C0A cmp al, LF ;AN011; 0 00004485 740B je Org21 ;AN011; 0 00004487 3C0D cmp al, CR ;AN011; 0 00004489 7407 je Org21 ;AN011; 0 0000448B E87101 CALL DELIM ; 0 0000448E 75F0 JNZ ORG2 0 00004490 EB02 jmp short Org3 ;AN011; 530 Org21: ;AN011;if CR or LF then 0 00004492 4E dec si ;AN011; undo SI, CX register 0 00004493 41 inc cx ;AN011; and continue 533 534 ;ORG4: CALL GET2 535 ; call Delim ;J.K. 5/30/86. To permit "device=filename/p..." stuff. 536 ; jz ORG_EXT ;J.K. 5/30/86 537 ;Org4_Cont: 538 ; STOSB 539 ; CMP AL,' ' 540 ; JA ORG4 541 ; CMP AL,10 542 ; JZ ORG1 543 ; 544 ; MOV BYTE PTR [ES:DI-1],0 545 546 Org3: 0 00004494 2E803E[0000]59 cmp byte [cs:Cmd_Indicator], 'Y' ;AN000; Comment= command? 548 Get_Cmt_Token equ Get_Cmt_token ; NASM port label 0 0000449A 747B je Get_Cmt_Token ;AN000; 0 0000449C 2E803E[0000]69 cmp byte [cs:Cmd_Indicator], 'i' ; InstallHigh= command? 0 000044A2 744C je Org_file 0 000044A4 2E803E[0000]49 cmp byte [cs:Cmd_Indicator], 'I' ;AN000; Install= command? 0 000044AA 7444 je Org_file ;AN000; 0 000044AC 2E803E[0000]64 cmp byte [cs:Cmd_Indicator], 'd' ; DEVICEHIGH= command? 0 000044B2 743C je Org_file ;AN000; 0 000044B4 2E803E[0000]44 cmp byte [cs:Cmd_Indicator], 'D' ;AN000; Device= command? 0 000044BA 7434 je Org_file ;AN000; 0 000044BC 2E803E[0000]4A cmp byte [cs:Cmd_Indicator], 'J' ;AN000; IFS= command? 0 000044C2 742C je Org_file ;AN000; 0 000044C4 2E803E[0000]73 cmp byte [cs:Cmd_Indicator], 's' 0 000044CA 7424 je Org_file 0 000044CC 2E803E[0000]53 cmp byte [cs:Cmd_Indicator], 'S' ;AN000; Shell= is a special one!!! 0 000044D2 741C je Org_file ;AN000; 0 000044D4 2E803E[0000]31 cmp byte [cs:Cmd_Indicator], '1' ;AN013; SWITCHES= command? 0 000044DA 7403 je Org_Switch ;AN013; 0 000044DC E99C00 jmp Org4 ;AN000; 567 Org_Switch: 0 000044DF E8E200 call Skip_Comment ;AN013; 0 000044E2 7477 jz End_Commd_Line_Brdg ;AN013; 0 000044E4 E8D500 call Get2 ;AN013; 0 000044E7 E81D01 call Org_Delim ;AN013; 0 000044EA 74F3 jz Org_Switch ;AN013; 0 000044EC AA stosb ;AN013; 0 000044ED E99B00 jmp Org5 ;AN013; 575 Org_file: ;AN000; Get the filename and put 0 at end, 0 000044F0 E8D100 call Skip_Comment ;AN000; 0 000044F3 7469 jz Org_Put_Zero ;AN000; 0 000044F5 E8C400 call Get2 ;AN000; Not a comment 0 000044F8 E80401 call Delim ;AN000; 0 000044FB 74F3 jz Org_file ;AN000; Skip the possible delimeters 0 000044FD AA stosb ;AN000; copy the first non delim char found in buffer 582 Org_Copy_File: ;AN000; 0 000044FE E8C300 call Skip_Comment ;AN000; comment char in the filename? 0 00004501 745B jz Org_Put_Zero ;AN000; then stop copying filename at that point 0 00004503 E8B600 call Get2 ;AN000; 0 00004506 3C2F cmp al, '/' ;AN000; a switch char? (device=filename/xxx) 587 End_File_slash equ End_file_slash ; NASM port label 0 00004508 745C je End_File_slash ;AN000; this will be the special case. 0 0000450A AA stosb ;AN000; save the char. in buffer 0 0000450B E8F100 call Delim ;AN000; 0 0000450E 745F jz End_Copy_File ;AN000; 0 00004510 3C20 cmp al, ' ' ;AN000; 0 00004512 77EA ja Org_Copy_File ;AN000; keep copying 0 00004514 EB59 jmp End_Copy_File ;AN000; otherwise, assume end of the filename. 0 00004516 90 nop ; identicalise 596 Get_Cmt_token: ;AN000; get the token. Just max. 2 char. 0 00004517 E8A200 call Get2 ;AN000; 0 0000451A 3C20 cmp al, ' ' ;AN000; skip white spaces or "=" char. 0 0000451C 74F9 je Get_Cmt_Token ;AN000; (we are allowing the other special 0 0000451E 3C09 cmp al, TAB ;AN000; charaters can used for comment id. 0 00004520 74F5 je Get_Cmt_Token ;AN000; character.) 0 00004522 3C3D cmp al, '=' ;AN000; = is special in this case. 0 00004524 74F1 je Get_Cmt_Token ;AN000; 0 00004526 3C0D cmp al, CR ;AN000; 0 00004528 742A je Get_Cmt_End ;AN000; cannot accept the carridge return 0 0000452A 3C0A cmp al, LF ;AN000; 0 0000452C 7426 je Get_Cmt_End ;AN000; 0 0000452E 2EA2[0000] mov [cs:CMMT1], al ;AN000; store it 0 00004532 2EC606[0000]01 mov byte [cs:CMMT], 1 ;AN000; 1 char. so far. 0 00004538 E88100 call Get2 ;AN000; 0 0000453B 3C20 cmp al, ' ' ;AN000; 0 0000453D 7415 je Get_Cmt_End ;AN000; 0 0000453F 3C09 cmp al, TAB ;AN000; 0 00004541 7411 je Get_Cmt_End ;AN000; 0 00004543 3C0D cmp al, CR ;AN000; 0 00004545 740D je Get_Cmt_End ;AN000; 0 00004547 3C0A cmp al, LF ;AN000; 0 00004549 7410 je End_Commd_Line_Brdg ;AN000; 0 0000454B 2EA2[0000] mov [cs:CMMT2], al ;AN000; 0 0000454F 2EFE06[0000] inc byte [cs:CMMT] ;AN000; 621 Get_Cmt_End: ;AN000; 0 00004554 E86500 call Get2 ;AN000; 0 00004557 3C0A cmp al, LF ;AN000; 0 00004559 75F9 jne Get_Cmt_End ;AN000; skip it. 0 0000455B E9CFFE End_Commd_Line_Brdg: jmp End_Commd_Line ;AN000; else jmp to End_Commd_Line 626 627 Org_Put_Zero: ;AN000; Make the filename in front of 0 0000455E 26C60500 mov byte ptr [es:di], 0 ;AN000; the comment string to be an asciiz. 0 00004562 47 inc di ;AN000; 0 00004563 E9C7FE jmp End_Commd_Line ;AN000; (Maybe null if device=/*) 631 End_file_slash: ;AN000; AL = "/" option char. 0 00004566 26C60500 mov byte ptr [es:di],0 ;AN000; make a filename an asciiz 0 0000456A 47 inc di ;AN000; and 0 0000456B AA stosb ;AN000; store "/" after that. 0 0000456C EB1D jmp Org5 ;AN000; continue with the rest of the line 0 0000456E 90 nop ; identicalise 637 638 End_Copy_File: ;AN000; 0 0000456F 26C645FF00 mov byte ptr [es:di-1], 0 ;AN000; make it an asciiz and handle the next char. 0 00004574 3C0A cmp al, LF ;AN000; 641 End_Commd_Line_brdg equ End_Commd_Line_Brdg ; NASM port label 0 00004576 74E3 je End_Commd_Line_brdg ;AN000; 0 00004578 EB11 jmp Org5 ;AN000; 0 0000457A 90 nop ; identicalise 645 646 Org4: ;AN000; Org4 skips all delimiters after the command name except for '/' 0 0000457B E84600 call Skip_Comment ;AN000; 0 0000457E 74DB jz End_Commd_Line_brdg ;AN000; 0 00004580 E83900 call Get2 ;AN000; 0 00004583 E88100 call Org_Delim ;AN000; skip delimiters EXCEPT '/' (mrw 4/88) 0 00004586 74F3 jz Org4 ;AN000; 0 00004588 EB09 jmp Org51 ;AN000; 0 0000458A 90 nop ; identicalise 654 Org5: ;AN000; rest of the line 0 0000458B E83600 call Skip_Comment ;AN000; Comment? 0 0000458E 74CB jz End_Commd_Line_brdg ;AN000; 0 00004590 E82900 call Get2 ;AN000; Not a comment. 658 Org51: ;AN000; 0 00004593 AA stosb ;AN000; copy the character 0 00004594 3C22 cmp al, '"' ;AN000; a quote ? 0 00004596 740D je At_Quote ;AN000; 0 00004598 3C20 cmp al, ' ' ;AN000; 0 0000459A 77EF ja Org5 ;AN000; 0 0000459C 3C0A cmp al, LF ;AN000; line feed? 0 0000459E 7402 je Org1_brdg ;AN000; handles the next command line. 0 000045A0 EBE9 jmp Org5 ;AN000; handles next char in this line. 0 000045A2 E975FE Org1_brdg: jmp Org1 ;AN000; 668 At_Quote: ;AN000; 0 000045A5 2E803E[0000]00 cmp byte [cs:COM_Level], 0 ;AN000; 0 000045AB 7408 je Up_Level ;AN000; 0 000045AD 2EC606[0000]00 mov byte [cs:COM_Level], 0 ;AN000; reset it. 0 000045B3 EBD6 jmp Org5 ;AN000; 673 Up_Level: ;AN000; 674 COM_level equ COM_Level ; NASM port label 0 000045B5 2EFE06[0000] inc byte [cs:COM_level] ;AN000; set it. 0 000045BA EBCF jmp Org5 ;AN000; 677 678 679 ;ORG5: CALL GET2 680 ; STOSB 681 ; CMP AL,10 682 ; JNZ ORG5 683 ; JMP ORG1 684 ; 685 ;ORG_EXT: 686 ; cmp al,' ' ;space? 687 ; je Org4_Cont ;then do not make an exception. Go back. 688 ; cmp al,9 ;Tab? 689 ; je Org4_Cont 690 ; mov byte ptr [es:di], 0 ;put 0 at the current DI to make it an ASCIIZ 691 ; inc DI ; 692 ; stosb ;and copy the delimeter char. 693 ; jmp short ORG5 ;and continue as usual. 694 695 696 GET2: 0 000045BC E35C JCXZ NOGET 0 000045BE 268A04 MOV AL,[ES:SI] 0 000045C1 46 INC SI 0 000045C2 49 DEC CX 0 000045C3 C3 return 702 703 ;GET: JCXZ NOGET 704 ; MOV AL,[ES:SI] 705 ; INC SI 706 ; DEC CX 707 ; CALL Org_DELIM 708 ; JZ GET 709 ; return 710 711 Skip_Comment: 712 ;J.K.Skip the commented string until LF, if current es:si-> a comment string. 713 ;J.K.In) ES:SI-> sting 714 ;J.K. CX -> length. 715 ;J.K.Out) Zero flag not set if not found a comment string. 716 ;J.K. Zero flag set if found a comment string and skipped it. AL will contain 717 ;J.K. the line feed charater at this moment when return. 718 ;J.K. AX register destroyed. 719 ;J.K. If found, SI, CX register adjusted accordingly. 720 721 NoGet equ NOGET ; NASM port label 0 000045C4 E354 jcxz NoGet ;AN000; Get out of the Organize routine. 0 000045C6 2E803E[0000]00 cmp byte [cs:COM_Level], 0 ;AN000; only check it if parameter level is 0. 0 000045CC 7530 jne No_Commt ;AN000; (Not inside quotations) 725 0 000045CE 2E803E[0000]01 cmp byte [cs:CMMT], 1 ;AN000; 0 000045D4 7228 jb No_Commt ;AN000; 0 000045D6 268A04 mov al, [es:si] ;AN000; 0 000045D9 2E3806[0000] cmp [cs:CMMT1], al ;AN000; 0 000045DE 751E jne No_Commt ;AN000; 0 000045E0 2E803E[0000]02 cmp byte [cs:CMMT], 2 ;AN000; 0 000045E6 750B jne Skip_Cmmt ;AN000; 0 000045E8 268A4401 mov al, [es:si+1] ;AN000; 0 000045EC 2E3806[0000] cmp [cs:CMMT2], al ;AN000; 0 000045F1 750B jne No_Commt ;AN000; 736 Skip_Cmmt: ;AN000; 0 000045F3 E325 jcxz NoGet ;AN000; get out of Organize routine. 0 000045F5 268A04 mov al, [es:si] ;AN000; 0 000045F8 46 inc si ;AN000; 0 000045F9 49 dec cx ;AN000; 0 000045FA 3C0A cmp al, LF ;AN000; line feed? 0 000045FC 75F5 jne Skip_Cmmt ;AN000; 743 No_Commt: ;AN000; 0 000045FE C3 ret ;AN000; 745 746 747 DELIM: 0 000045FF 3C2F CMP AL,'/' ;J.K. 5/30/86. IBM will assume "/" as an delimeter. 0 00004601 74C0 retz 0 00004603 3C00 cmp al, 0 ;J.K. 5/23/86 Special case for sysinit!!! 0 00004605 74BC retz 752 Org_Delim: ;AN000; Used by Organize routine except for getting 0 00004607 3C20 CMP AL,' ' ;the filename. 0 00004609 74B8 retz 0 0000460B 3C09 CMP AL,9 0 0000460D 74B4 retz 0 0000460F 3C3D CMP AL,'=' 0 00004611 74B0 retz 0 00004613 3C2C CMP AL,',' 0 00004615 74AC retz 0 00004617 3C3B CMP AL,';' 0 00004619 C3 return 763 764 0 0000461A 59 NOGET: POP CX 0 0000461B 2E893E[0000] MOV [cs:COUNT],DI 0 00004620 2E893E[0000] mov [cs:Org_Count], DI ;AN012; 0 00004625 31F6 XOR SI,SI 769 CHRPTR equ chrptr ; NASM port label 0 00004627 2E8936[0000] MOV [cs:CHRPTR],SI 0 0000462C C3 return 772 773 ;Get3: jcxz NOGET ;J.K.do not consider '/',',' as a delim. 774 ; mov al, [es:si] 775 ; inc si 776 ; dec cx 777 ; call DELIM 778 ; jnz Get3_ret 779 ; cmp al,'/' 780 ; je Get3_ret 781 ; cmp al,',' 782 ; jne Get3 783 ;Get3_ret: 784 ; ret 785 786 787 788 ; 789 ; NEWLINE RETURNS WITH FIRST CHARACTER OF NEXT LINE 790 ; 0 0000462D E8[0000] NEWLINE:invoke GETCHR ;SKIP NON-CONTROL CHARACTERS 0 00004630 72FA retc 0 00004632 3C0A CMP AL,LF ;LOOK FOR LINE FEED 0 00004634 75F7 JNZ NEWLINE 0 00004636 E8[0000] invoke GETCHR 0 00004639 C3 return 797 798 MAPCASE: 0 0000463A 51 PUSH CX 0 0000463B 56 PUSH SI 0 0000463C 1E PUSH DS 0 0000463D 06 PUSH ES 0 0000463E 1F POP DS 0 0000463F 31F6 XOR SI,SI 805 CONVLOOP: 0 00004641 AC LODSB 807 808 %IF KANJI 809 CALL TESTKANJ 810 JZ NORMCONV 811 INC SI ;Skip next char 812 DEC CX 813 JCXZ CONVDONE ;Just ignore 1/2 kanji error 814 ;Fall through, know AL is not in 'a'-'z' range 815 NORMCONV: 816 %ENDIF 817 0 00004642 3C61 CMP AL,'a' 0 00004644 7209 JB NOCONV 0 00004646 3C7A CMP AL,'z' 0 00004648 7705 JA NOCONV 0 0000464A 2C20 SUB AL,20H 0 0000464C 8844FF MOV [SI-1],AL 824 NOCONV: 0 0000464F E2F0 LOOP CONVLOOP 826 CONVDONE: 0 00004651 1F POP DS 0 00004652 5E POP SI 0 00004653 59 POP CX 0 00004654 C3 return 831 832 %IF KANJI 833 TESTKANJ: 834 CMP AL,81H 835 JB NOTLEAD 836 CMP AL,9FH 837 JBE ISLEAD 838 CMP AL,0E0H 839 JB NOTLEAD 840 CMP AL,0FCH 841 JBE ISLEAD 842 NOTLEAD: 843 PUSH AX 844 XOR AX,AX ;Set zero 845 POP AX 846 return 847 848 ISLEAD: 849 PUSH AX 850 XOR AX,AX ;Set zero 851 INC AX ;Reset zero 852 POP AX 853 return 854 %ENDIF 855 856 ASSUME DS:NOTHING 857 858 Yes_Break_Failed: ;device driver Init failed and aborted. 0 00004655 F9 stc 0 00004656 58 pop ax 0 00004657 C3 return 862 863 SET_BREAK: 864 ;J.K. 8/14/86 For DOS 3.3, this routine is modified to take care of the 865 ;Device driver's initialization error and abort. 866 ;If [break_addr+2] == [memhi] && [break_addr] = 0 then assume 867 ;that the device driver's initialization has an error and wanted to 868 ;abort the device driver. In this case, this routine will set carry 869 ;and return to the caller. 870 ;J.K. 6/26/87 If MultDeviceFlag <> 0, then do not perform the check. 871 ;This is to allow the multiple character device driver which uses 872 ;the same ending address segment with the offset value 0 for each 873 ;of the drives. 874 0 00004658 50 PUSH AX 0 00004659 2EA1[0000] MOV AX, WORD PTR [cs:BREAK_ADDR] 0 0000465D 83C00F add ax, 15 ; round up 0 00004660 D1D8 rcr ax, 1 0 00004662 D1E8 shr ax, 1 0 00004664 D1E8 shr ax, 1 0 00004666 D1E8 shr ax, 1 ; = paragraphs 0 00004668 2E0306[0200] add ax, WORD PTR [cs:BREAK_ADDR+2] ;REMOVE THE INIT CODE 883 ; ax => behind keep address 0 0000466D 72E6 jc Yes_Break_Failed 0 0000466F 2E803E[0000]00 cmp byte [cs:MultDeviceFlag], 0 ;AN001; 0 00004675 7507 jne Set_Break_Continue ;AN001;Do not check it. 887 888 ; rol byte [cs:devicehighflag], 1 889 ; jnc .low1 890 .high1: 0 00004677 2E3B06[0000] cmp ax, [cs:devicehighdata] ; at start ? 892 ; jmp .common1 893 ; .low1: 894 ; MEMHI equ memhi ; NASM port label 895 ; cmp ax, [cs:MEMHI] 896 .common1: 897 Yes_Break_failed equ Yes_Break_Failed ; NASM port label 0 0000467C 76D7 jbe Yes_Break_failed ; <= start, failed 899 900 Set_Break_Continue: 0 0000467E 2E800E[0000]01 or byte [cs:SetDevMarkFlag], SETBRKDONE ;AN005; Signal the successful Set_break 902 903 ; rol byte [cs:devicehighflag], 1 904 ; jnc .low2 905 .high2: 0 00004684 2E3B06[0000] cmp ax, [cs:devicehighafter] 0 00004689 773E ja MEM_ERR 908 0 0000468B 53 push bx 0 0000468C 06 push es 0 0000468D 2E8B1E[0000] mov bx, word [cs:devicehighdata] 0 00004692 4B dec bx ; => MCB 0 00004693 8EC3 mov es, bx 0 00004695 43 inc bx ; => memory block 0 00004696 F7DB neg bx ; - memory block 0 00004698 01C3 add bx, ax ; end - memory block 0 0000469A 26891E0300 mov word [es:mcbSize], bx 0 0000469F 2E8B1E[0000] mov bx, word [cs:devicehighsd] 0 000046A4 53 push bx 0 000046A5 43 inc bx ; => SD memory block 0 000046A6 8EC3 mov es, bx ; 21.4A input 0 000046A8 F7DB neg bx ; - SD memory block 0 000046AA 01C3 add bx, ax ; end - SD memory block 0 000046AC B44A mov ah, 4Ah 0 000046AE CD21 int 21h ; shrink 0 000046B0 8CC0 mov ax, es 0 000046B2 01D8 add ax, bx 0 000046B4 2EA3[0000] mov [cs:devicehighafter], ax 0 000046B8 2EA3[0000] mov [cs:deviceafter], ax 0 000046BC 07 pop es 0 000046BD 26C70601000800 mov word [es:mcbOwner], 8 ; reset owner 0 000046C4 07 pop es 0 000046C5 5B pop bx 0 000046C6 58 pop ax 0 000046C7 F8 clc 0 000046C8 C3 retn 937 938 %if 0 939 .low2: 940 MOV AX,WORD PTR [cs:BREAK_ADDR + 2] 941 MOV [cs:MEMHI],AX 942 MOV AX,WORD PTR [cs:BREAK_ADDR] 943 MEMLO equ memlo ; NASM port label 944 MOV [cs:MEMLO],AX 945 POP AX ; NOTE FALL THROUGH 946 or byte [cs:SetDevMarkFlag], FOR_DEVMARK 947 948 ; 949 ; Round the values in MEMLO and MEMHI to paragraph boundary. 950 ; Perform bounds check. 951 ; 952 ROUND: 953 PUSH AX 954 MOV AX,[cs:MEMLO] 955 956 invoke ParaRound ; para round up 957 958 ADD [cs:MEMHI],AX 959 jc MEM_ERR 960 and word [cs:MEMLO],0 961 mov ax,[cs:memhi] ; ax = new memhi 962 ALLOCLIM equ alloclim ; NASM port label 963 CMP AX,[cs:ALLOCLIM] ; if new memhi >= alloclim, error 964 JAE MEM_ERR 965 test byte [cs:SetDevMarkFlag], FOR_DEVMARK ;AN005; 966 jz Skip_Set_DEVMARKSIZE ;AN005; 967 push es ;AN005; 968 push si ;AN005; 969 mov si, [cs:DevMark_Addr] ;AN005; 970 mov es, si ;AN005; 971 sub ax, si ;AN005; 972 dec ax ;AN005; 973 mov [es:DEVMARK_SIZE], ax ;AN005; Paragraph 974 and byte [cs:SetDevMarkFlag], NOT_FOR_DEVMARK ;AN005; 975 pop si ;AN005; 976 pop es ;AN005; 977 Skip_Set_DEVMARKSIZE: ;AN005; 978 POP AX 979 clc ;clear carry 980 return 981 %endif 982 983 MEM_ERR: 0 000046C9 BA[0000] MOV DX,OFFSET BADMEM 0 000046CC 0E PUSH CS 0 000046CD 1F POP DS 0 000046CE E88502 CALL PRINT 988 STALL equ Stall ; NASM port label 0 000046D1 E9[0000] JMP STALL 990 991 ENTRY_POINT equ entry_point ; NASM port label 0 000046D4 2E8E1E[0200] CALLDEV:MOV DS,WORD PTR [CS:ENTRY_POINT+2] 0 000046D9 2E031E[0000] ADD BX,WORD PTR [CS:ENTRY_POINT] ;Do a little relocation 0 000046DE 8B07 MOV AX,[BX] 0 000046E0 2EFF36[0000] PUSH WORD PTR [CS:ENTRY_POINT] 0 000046E5 2EA3[0000] MOV WORD PTR [CS:ENTRY_POINT],AX 0 000046E9 BB[0000] MOV BX,OFFSET PACKET 0 000046EC 2EFF1E[0000] CALL far [cs:ENTRY_POINT] 0 000046F1 2E8F06[0000] POP WORD PTR [CS:ENTRY_POINT] 0 000046F6 C3 return 1001 1002 BADNUM: 0 000046F7 2EC606[0000]00 MOV byte [cs:sepchr],0 0 000046FD 31C0 XOR AX,AX ; Set Zero flag, and AX = 0 0 000046FF 5B pop bx ; J.K. 0 00004700 F9 stc ; AND carry set 0 00004701 C3 return 1008 1009 ToDigit: 0 00004702 2C30 SUB AL,'0' 0 00004704 7206 JB NotDig 0 00004706 3C09 CMP AL,9 0 00004708 7702 JA NotDig 0 0000470A F8 CLC 0 0000470B C3 return 0 0000470C F9 NotDig: STC 0 0000470D C3 return 1018 1019 ; GetNum parses a decimal number. 1020 ; Returns it in AX, sets zero flag if AX = 0 (MAY BE considered an 1021 ; error), if number is BAD carry is set, zero is set, AX=0. 0 0000470E 53 GETNUM: push bx ; J.K. 0 0000470F 31DB XOR BX,BX ; running count is zero 0 00004711 E8EEFF B2: CALL ToDigit ; do we have a digit 1025 BadNum equ BADNUM ; NASM port label 0 00004714 72E1 JC BadNum ; no, bomb 0 00004716 93 XCHG AX,BX ; put total in AX 0 00004717 53 PUSH BX ; save digit 0 00004718 BB0A00 MOV BX,10 ; base of arithmetic 0 0000471B F7E3 MUL BX ; shift by one decimal di... 0 0000471D 5B POP BX ; get back digit 0 0000471E 00D8 ADD AL,BL ; get total 0 00004720 80D400 ADC AH,0 ; make that 16 bits 0 00004723 72D2 JC BADNUM ; too big a number 0 00004725 93 XCHG AX,BX ; stash total 1036 0 00004726 E8[0000] invoke GETCHR ;GET NEXT DIGIT 0 00004729 722F JC B1 ; no more characters 0 0000472B 3C20 cmp al, ' ' ;J.K. 5/23/86 space? 1040 B15 equ b15 ; NASM port label 0 0000472D 7421 jz B15 ;J.K. 5/23/86 then end of digits 0 0000472F 3C2C cmp al, ',' ;J.K. 5/23/86 ',' is a seperator!!! 0 00004731 741D jz B15 ;J.K. 5/23/86 then end of digits. 0 00004733 3C09 cmp al, TAB ;J.K. 5/23/86 TAB 0 00004735 7419 jz B15 ;J.K. 1046 SepChr equ sepchr ; NASM port label 0 00004737 2E3A06[0000] CMP AL,[cs:SepChr] ; allow 0 or special separators 0 0000473C 7412 JZ b15 0 0000473E 3C2F cmp al,SWTCHR ; See if another switch follows 0 00004740 90 nop ; identicalise 0 00004741 90 nop ; identicalise 0 00004742 740C JZ b15 0 00004744 3C0A cmp al,LF ; Line-feed? 0 00004746 7408 jz b15 0 00004748 3C0D cmp al,CR ; Carriage return? 0 0000474A 7404 jz b15 0 0000474C 08C0 OR AL,AL ; end of line separator? 0 0000474E 75C1 JNZ B2 ; no, try as a valid char... 0 00004750 2EFF06[0000] b15: INC word [cs:COUNT] ; one more character to s... 0 00004755 2EFF0E[0000] DEC word [cs:CHRPTR] ; back up over separator 0 0000475A 89D8 B1: MOV AX,BX ; get proper count 0 0000475C 09C0 OR AX,AX ; Clears carry, sets Zero accordingly 0 0000475E 5B pop bx 0 0000475F C3 return 1065 1066 SKIP_DELIM proc near ;J.K. 1067 ;Skip the delimeters pointed by CHRPTR. AL will contain the first non delimeter 1068 ;character encountered and CHRPTR will point to the next character. 1069 ;This rouitne will assume the second "," found as a non delimiter character. So 1070 ;in case if the string is " , , ", this routine will stop at the second ",". At 1071 ;this time, Zero flag is set. 1072 ;If COUNT is exhausted, then carry will be set. 1073 Skip_delim_char: 0 00004760 E8[0000] call getchr 0 00004763 7219 jc Skip_delim_exit 0 00004765 3C2C cmp al, ',' ;the first comma? 0 00004767 7407 je Skip_delim_next 0 00004769 E893FE call delim ;check the charater in AL. 0 0000476C 74F2 jz Skip_delim_char 0 0000476E EB0E jmp short Skip_delim_exit ;found a non delim char 1081 Skip_delim_next: 0 00004770 E8[0000] call getchr 0 00004773 7209 jc Skip_delim_exit 0 00004775 3C2C cmp al, ',' ;the second comma? 0 00004777 7405 je Skip_delim_exit ;done 0 00004779 E883FE call delim 0 0000477C 74F2 jz Skip_delim_next 1088 Skip_delim_exit: 0 0000477E C3 return 1090 SKIP_DELIM endp 1091 1092 ;J.K. 5/26/86 ***************************************************************** 1093 SetDOSCountryInfo proc near 1094 ;Input: ES:DI -> pointer to DOS_COUNTRY_CDPG_INFO 1095 ; DS:0 -> buffer. 1096 ; SI = 0 1097 ; AX = country id 1098 ; DX = code page id. (If 0, then use ccSysCodePage as a default.) 1099 ; BX = file handle 1100 ; This routine can handle maxium 72 COUNTRY_DATA entries. 1101 ;Output: DOS_country_cdpg_info set. 1102 ; Carry set if any file read failure or wrong information in the file. 1103 ; Carry set and CX = -1 if cannot find the matching COUNTRY_id, CODEPAGE 1104 ; _id in the file. 1105 0 0000477F 57 push di 0 00004780 50 push ax 0 00004781 52 push dx 1109 0 00004782 31C9 xor cx,cx 0 00004784 31D2 xor dx,dx 0 00004786 B80002 mov ax, 512 ;read 512 bytes 0 00004789 E83101 call ReadInControlBuffer ;Read the file header 0 0000478C 724C jc SetDOSData_fail 0 0000478E 06 push es 0 0000478F 56 push si 0 00004790 0E push cs 0 00004791 07 pop es 0 00004792 BF[F807] mov di, offset COUNTRY_FILE_SIGNATURE 0 00004795 B90800 mov cx, 8 ;length of the signature 0 00004798 F3A6 repz cmpsb 0 0000479A 5E pop si 0 0000479B 07 pop es 0 0000479C 753C jnz SetDOSData_fail ;signature mismatch 1125 0 0000479E 83C612 add si, 18 ;SI -> county info type 0 000047A1 803C01 cmp byte ptr [si], 1 ;Only accept type 1 (Currently only 1 header type) 0 000047A4 7534 jne SetDOSData_fail ;cannot proceed. error return 0 000047A6 46 inc si ;SI -> file offset 0 000047A7 8B14 mov dx, word ptr [si] ;Get the INFO file offset. 0 000047A9 8B4C02 mov cx, word ptr [si+2] 0 000047AC B80004 mov ax, 1024 ;read 1024 bytes. 0 000047AF E80B01 call ReadInControlBuffer ;Read INFO 0 000047B2 7226 jc SetDOSData_fail 0 000047B4 8B0C mov cx, word ptr [si] ;get the # of country, codepage combination entries 0 000047B6 83F948 cmp cx, 72 ;cannot handle more than 72 entries. 0 000047B9 771F ja SetDOSData_fail 0 000047BB 46 inc si 0 000047BC 46 inc si ;SI -> entry information packet 0 000047BD 5A pop dx ;restore code page id 0 000047BE 58 pop ax ;restore country id 0 000047BF 5F pop di 1143 1144 SetDOSCntry_find: ;Search for desired country_id,codepage_id. 0 000047C0 3B4402 cmp ax, word ptr [si+2] ;compare country_id 0 000047C3 750A jne SetDOSCntry_next 0 000047C5 83FA00 cmp dx, 0 ;No user specified code page ? 1148 SetDOSCntry_any_codepage equ SetDOSCntry_any_CodePage ; NASM port label 0 000047C8 7415 je SetDOSCntry_any_codepage;then no need to match code page id. 0 000047CA 3B5404 cmp dx, word ptr [si+4] ;compare code page id 0 000047CD 7413 je SetDOSCntry_got_it 1152 SetDOSCntry_next: 0 000047CF 0334 add si, word ptr [si] ;next entry 0 000047D1 46 inc si 0 000047D2 46 inc si ;take a word for size of entry itself 0 000047D3 E2EB loop SetDOSCntry_find 0 000047D5 B9FFFF mov cx, -1 ;signals that bad country id entered. 1158 SetDOSCntry_fail: 0 000047D8 F9 stc 0 000047D9 C3 ret 1161 1162 SetDOSData_fail: 0 000047DA 5E pop si 0 000047DB 59 pop cx 0 000047DC 5F pop di 0 000047DD EBF9 jmp short SetDOSCntry_fail 1167 1168 SetDOSCntry_any_CodePage: ;use the code_page_id of the country_id found. 0 000047DF 8B5404 mov dx, word ptr [si+4] 1170 SetDOSCntry_got_it: ;found the matching entry 0 000047E2 2E8916[0008] mov [cs:CntryCodePage_Id], dx ;save code page ID for this country. 0 000047E7 8B540A mov dx, word ptr [si+10] ;get the file offset of country data 0 000047EA 8B4C0C mov cx, word ptr [si+12] 0 000047ED B80002 mov ax, 512 ;read 512 bytes 0 000047F0 E8CA00 call ReadInControlBuffer 0 000047F3 72E3 jc SetDOSCntry_fail 0 000047F5 8B0C mov cx, word ptr [si] ;get the number of entries to handle. 0 000047F7 46 inc si 0 000047F8 46 inc si ;SI -> first entry 1180 1181 SetDOSCntry_data: 0 000047F9 57 push di ;ES:DI -> DOS_COUNTRY_CDPG_INFO 0 000047FA 51 push cx ;save # of entry left 0 000047FB 56 push si ;si -> current entry in Control buffer 1185 0 000047FC 8A4402 mov al, byte ptr [si+2] ;get data entry id 0 000047FF E88D00 call GetCountryDestination ;get the address of destination in ES:DI 0 00004802 727A jc strict short SetDOSCntry_data_next ;No matching data entry id in DOS 1189 1190 0 00004804 8B5404 mov dx, word ptr [si+4] ;get offset of data 0 00004807 8B4C06 mov cx, word ptr [si+6] 0 0000480A B80042 mov ax, 4200h 0 0000480D F9 stc 0 0000480E CD21 int 21h ;move pointer 0 00004810 72C8 jc SetDOSData_fail 0 00004812 BA0002 mov dx, 512 ;start of data buffer 1198 ; mov cx, word ptr [es:di] ;length of the corresponding data in DOS. 1199 ; add cx, 10 ;Signature + A word for the length itself 0 00004815 B91400 mov cx, 20 ;read 20 bytes only. We only need to 0 00004818 B43F mov ah, 3fh ;look at the length of the data in the file. 0 0000481A F9 stc 0 0000481B CD21 int 21h ;read the country.sys data 0 0000481D 72BB jc SetDOSData_fail ;read failure 0 0000481F 39C8 cmp ax, cx 0 00004821 75B7 jne SetDOSData_fail 1207 0 00004823 8B5404 mov dx, word ptr [si+4] ;AN008;get offset of data again. 0 00004826 8B4C06 mov cx, word ptr [si+6] ;AN008; 0 00004829 B80042 mov ax, 4200h ;AN008; 0 0000482C F9 stc ;AN008; 0 0000482D CD21 int 21h ;AN008;move pointer back again 0 0000482F 72A9 jc SetDOSData_fail ;AN008; 1214 0 00004831 56 push si ;AN008; 0 00004832 BE0802 mov si, (512+8) ;AN008;get length of the data from the file 0 00004835 8B0C mov cx, word ptr [si] ;AN008; 0 00004837 5E pop si ;AN008; 0 00004838 BA0002 mov dx, 512 ;AN008;start of data buffer 0 0000483B 83C10A add cx, 10 ;AN008;Signature + A word for the length itself 0 0000483E B43F mov ah, 3fh ;AN008;Read the data from the file. 0 00004840 F9 stc ;AN008; 0 00004841 CD21 int 21h ;AN008; 0 00004843 7295 jc SetDOSData_fail ;AN008; 0 00004845 39C8 cmp ax, cx ;AN008; 0 00004847 7591 jne SetDOSData_fail ;AN008; 1227 0 00004849 8A4402 mov al, byte ptr [si+2] ;save Data id for future use. 0 0000484C BE0802 mov si, (512+8) ;SI-> data buffer + id tag field 0 0000484F 8B0C mov cx, word ptr [si] ;get the length of the file 0 00004851 41 inc cx ;Take care of a word for lenght of tab 0 00004852 41 inc cx ;itself. 0 00004853 81F9F805 cmp cx, (2048 - 512 - 8) ;Fit into the buffer? 0 00004857 7781 ja SetDOSData_fail 0 00004859 3C01 cmp al, SetCountryInfo ;is the data for SetCountryInfo table? 0 0000485B 7512 jne SetDOSCntry_Mov ;no, don't worry 0 0000485D 26FF7518 push word ptr [es:di+ccMono_Ptr-ccCountryInfoLen] ;AN009;Cannot destroy ccMono_ptr address. Save them. 0 00004861 26FF751A push word ptr [es:di+ccMono_Ptr-ccCountryInfoLen+2] ;AN009;At this time DI -> ccCountryInfoLen 0 00004865 57 push di ;save DI 1240 0 00004866 50 push ax 0 00004867 2EA1[0008] mov ax,[cs:CntryCodePage_Id] ;Do not use the Code Page info in Country_Info 0 0000486B 894404 mov [si+4], ax ;Use the saved one for this !!!! 0 0000486E 58 pop ax 1245 1246 SetDOSCntry_Mov: 0 0000486F F3A4 rep movsb ;copy the table into DOS 0 00004871 3C01 cmp al, SetCountryInfo ;was the ccMono_ptr saved? 0 00004873 7509 jne SetDOSCntry_data_next 0 00004875 5F pop di ;restore DI 0 00004876 268F451A pop word ptr [es:di+ccMono_Ptr-ccCountryInfoLen+2] ;AN009;restore 0 0000487A 268F4518 pop word ptr [es:di+ccMono_Ptr-ccCountryInfoLen] ;AN009; 1253 1254 SetDOSCntry_data_next: 0 0000487E 5E pop si ;restore control buffer pointer 0 0000487F 59 pop cx ;restore # of entries left 0 00004880 5F pop di ;restore pointer to DSO_COUNTRY_CDPG 0 00004881 0334 add si, word ptr [si] ;try to get the next entry 0 00004883 46 inc si 0 00004884 46 inc si ;take a word of entry length itself 1261 ; loop SetDOSCntry_data 0 00004885 49 dec cx ;AN008; 0 00004886 83F900 cmp cx,0 ;AN008; 0 00004889 7403 je SetDOSCntry_OK ;AN008; 0 0000488B E96BFF jmp SetDOSCntry_data ;AN008; 1266 SetDOSCntry_OK: ;AN008; 0 0000488E C3 ret 1268 SetDOSCountryInfo endp 1269 ; 1270 1271 GetCountryDestination proc near 1272 ;Get the destination address in the DOS country info table. 1273 ;Input: AL - Data ID 1274 ; ES:DI -> DOS_COUNTRY_CDPG_INFO 1275 ;On return: 1276 ; ES:DI -> Destination address of the matching data id 1277 ; carry set if no matching data id found in DOS. 1278 0 0000488F 51 push cx 0 00004890 83C74A add di, ccNumber_of_entries ;skip the reserved area, syscodepage etc. 0 00004893 268B0D mov cx, word ptr [es:di] ;get the number of entries 0 00004896 47 inc di 0 00004897 47 inc di ;SI -> the first start entry id 1284 GetCntryDest: 0 00004898 263805 cmp byte ptr [es:di], al 0 0000489B 7413 je GetCntryDest_OK 0 0000489D 26803D01 cmp byte ptr [es:di], SetCountryInfo ;was it SetCountryInfo entry? 0 000048A1 7405 je GetCntryDest_1 0 000048A3 83C705 add di, 5 ;next data id 0 000048A6 EB03 jmp short GetCntryDest_loop 1291 GetCntryDest_1: 0 000048A8 83C729 add di, NEW_COUNTRY_SIZE + 3 ;next data id 1293 GetCntryDest_loop: 0 000048AB E2EB loop GetCntryDest 0 000048AD F9 stc 1296 GetCntryDest_exit equ GetCntryDest_Exit ; NASM port label 0 000048AE EB0B jmp short GetCntryDest_exit 1298 GetCntryDest_OK: 0 000048B0 3C01 cmp al, SetCountryInfo ;select country info? 0 000048B2 7503 jne GetCntryDest_OK1 0 000048B4 47 inc di ;now DI -> ccCountryInfoLen 0 000048B5 EB04 jmp short GetCntryDest_exit 1303 GetCntryDest_OK1: 0 000048B7 26C47D01 les di, [es:di+1] ;get the destination in ES:DI 1305 GetCntryDest_Exit: 0 000048BB 59 pop cx 0 000048BC C3 ret 1308 GetCountryDestination endp 1309 1310 ; 1311 ReadInControlBuffer proc near 1312 ;Move file pointer to CX:DX 1313 ;Read AX bytes into the control buffer. (Should be less than 2 Kb) 1314 ;SI will be set to 0 hence DS:SI points to the control buffer. 1315 ;Entry: CX,DX offset from the start of the file where the read/write pointer 1316 ; be moved. 1317 ; AX - # of bytes to read 1318 ; BX - file handle 1319 ; DS - buffer seg. 1320 ;Return: The control data information is read into DS:0 - DS:0200. 1321 ; CX,DX value destroyed. 1322 ; Carry set if error in Reading file. 1323 ; 0 000048BD 50 push ax ;# of bytes to read 0 000048BE B80042 mov ax, 4200h 0 000048C1 F9 stc 0 000048C2 CD21 int 21h ;move pointer 0 000048C4 59 pop cx ;# of bytes to read 0 000048C5 7209 jc RICB_exit 0 000048C7 31D2 xor dx,dx ;ds:dx -> control buffer 0 000048C9 31F6 xor si,si 0 000048CB B43F mov ah,3fh ;read into the buffer 0 000048CD F9 stc 0 000048CE CD21 int 21h ;should be less than 1024 bytes. 1335 RICB_exit: 0 000048D0 C3 ret 1337 ReadInControlBuffer endp 1338 1339 ; 1340 SET_COUNTRY_PATH proc near 1341 ;In: DS - SYSINITSEG, ES - CONFBOT, SI -> start of the asciiz path string 1342 ; DOSINFO_EXT, CNTRY_DRV, CNTRY_ROOT, CNTRY_PATH 1343 ; Assumes current directory is the ROOT directory. 1344 ;Out: DS:DI -> full path (CNTRY_DRV). 1345 ; Set the CNTRY_DRV string from the COUNTRY=,,path command. 1346 ; DS, ES, SI value saved. 1347 0 000048D1 56 push si 0 000048D2 1E push ds ;switch ds, es 0 000048D3 06 push es 0 000048D4 1F pop ds 0 000048D5 07 pop es ;now DS -> CONFBOT, ES -> SYSINITSEG 1353 1354 chk_drive_letter equ CHK_DRIVE_LETTER ; NASM port label 0 000048D6 E83100 call chk_drive_letter ;current [DS:SI] is a drive letter? 0 000048D9 7206 jc SCP_Default_drv ;no, use current default drive. 0 000048DB 8A04 mov al, byte ptr [SI] 0 000048DD 46 inc si 0 000048DE 46 inc si ;SI -> next char after ":" 0 000048DF EB06 jmp short SCP_SetDrv 1361 SCP_Default_drv: 0 000048E1 B419 mov ah, 19h 0 000048E3 CD21 int 21h 0 000048E5 0441 add al, "A" ;convert it to a character. 1365 SCP_SetDrv: 0 000048E7 2EA2[B507] mov [cs:CNTRY_DRV], al ;set the drive letter. 0 000048EB BF[B807] mov di, offset CNTRY_PATH 0 000048EE 8A04 mov al, byte ptr [SI] 0 000048F0 3C5C cmp al, "\" 0 000048F2 7409 je SCP_Root_Dir 0 000048F4 2E3A062F00 cmp al, [cs:SWTCHR] ;let's accept "/" as an directory delim 0 000048F9 7402 je SCP_Root_Dir 0 000048FB EB01 jmp short SCP_Path 1374 SCP_Root_Dir: 0 000048FD 4F dec di ;DI -> CNTRY_ROOT 1376 SCP_Path: 0 000048FE E81F00 call MOVE_ASCIIZ ;copy it 0 00004901 BF[B507] mov di, offset CNTRY_DRV 1379 SCPath_Exit: 0 00004904 1E push ds ;switch ds, es 0 00004905 06 push es 0 00004906 1F pop ds 0 00004907 07 pop es ;DS, ES value restored 0 00004908 5E pop si 0 00004909 C3 RET 1386 SET_COUNTRY_PATH endp 1387 1388 ; 1389 CHK_DRIVE_LETTER proc near 1390 ;Check if [DS:SI] is a drive letter followed by ":". 1391 ;Assume that every alpha charater is already converted to UPPER CASE. 1392 ;Carry set if not. 1393 ; 0 0000490A 50 push ax 0 0000490B 803C41 cmp byte ptr [si], "A" 0 0000490E 720D jb CDLetter_NO 0 00004910 803C5A cmp byte ptr [si], "Z" 0 00004913 7708 ja CDLetter_NO 0 00004915 807C013A cmp byte ptr [si+1], ":" 0 00004919 7502 jne CDLetter_NO 0 0000491B EB01 jmp short CDLetter_exit 1402 CDLetter_NO: 0 0000491D F9 stc 1404 CDLetter_exit: 0 0000491E 58 pop ax 0 0000491F C3 ret 1407 CHK_DRIVE_LETTER endp 1408 1409 ; 1410 MOVE_ASCIIZ proc near 1411 ;In: DS:SI -> source ES:DI -> target 1412 ;Out: copy the string until 0. 1413 ;Assumes there exists a 0. 1414 MASCIIZ_loop: 0 00004920 A4 movsb 0 00004921 807CFF00 cmp byte ptr [SI-1], 0 ;Was it 0? 0 00004925 75F9 jne MASCIIZ_loop 0 00004927 C3 ret 1419 MOVE_ASCIIZ endp 1420 1421 ; 1422 ; DS:DX POINTS TO STRING TO OUTPUT (ASCIZ) 1423 ; 1424 ; PRINTS 1425 ; 1426 ; 1427 ; 1428 BADFIL: 0 00004928 0E PUSH CS 0 00004929 07 POP ES 0 0000492A 89D6 MOV SI,DX 1432 BADLOAD: 0 0000492C BA[0000] MOV DX,OFFSET BADLD_PRE ;WANT TO PRINT CONFIG ERROR 1434 ; MOV BX,OFFSET BADLD_POST 0 0000492F BB[0000] mov bx, offset CRLFM ;AN006; 1436 PRNERR: 0 00004932 0E PUSH CS 0 00004933 1F POP DS 0 00004934 E81F00 call Print 0 00004937 268A14 PRN1: MOV DL,[ES:SI] 0 0000493A 08D2 OR DL,DL 0 0000493C 7407 JZ PRN2 1443 STD_CON_OUTPUT equ Std_Con_Output ; NASM port equate 0 0000493E B402 MOV AH,STD_CON_OUTPUT 0 00004940 CD21 INT 21H 0 00004942 46 INC SI 0 00004943 EBF2 JMP PRN1 0 00004945 89DA PRN2: MOV DX,BX 0 00004947 E80C00 call Print 0 0000494A 2E803E[0000]01 cmp byte [cs:DoNotShowNum], 1 ;AN000; suppress line number when handling COMMAND.COM 1451 Prnexit equ PRNEXIT ; NASM port label 0 00004950 7403 je Prnexit 0 00004952 E8[0000] call Error_Line 1454 PRNEXIT: 0 00004955 C3 return 1456 1457 STD_CON_STRING_OUTPUT equ Std_Con_String_Output ; NASM port equate 0 00004956 B409 PRINT: MOV AH,STD_CON_STRING_OUTPUT 0 00004958 CD21 INT 21H 0 0000495A C3 return 1461 1462 1463 OPEN equ Open ; NASM port equate 1464 CLOSE equ Close ; NASM port equate 1465 %IF NOEXEC 1466 ; 1467 ; LOAD NON EXE FILE CALLED [DS:DX] AT MEMORY LOCATION ES:BX 1468 ; 1469 LDFIL: 1470 PUSH AX 1471 PUSH BX 1472 PUSH CX 1473 PUSH DX 1474 PUSH SI 1475 PUSH DS 1476 PUSH BX 1477 XOR AX,AX ;OPEN THE FILE 1478 MOV AH,OPEN 1479 STC ;IN CASE OF INT 24 1480 INT 21H 1481 POP DX ;Clean stack in case jump 1482 JC LDRET 1483 PUSH DX 1484 MOV BX,AX ;Handle in BX 1485 XOR CX,CX 1486 XOR DX,DX 1487 LSEEK equ LSeek ; NASM port equate 1488 MOV AX,(LSEEK << 8) | 2 1489 STC ;IN CASE OF INT 24 1490 INT 21H ; Get file size in DX:AX 1491 JC LDCLSP 1492 OR DX,DX 1493 JNZ LDERRP ; File >64K 1494 POP DX 1495 PUSH DX 1496 MOV CX,ES ; CX:DX is xaddr 1497 ADD DX,AX ; Add file size to Xaddr 1498 JNC DOSIZE 1499 ADD CX,1000H ; ripple carry 1500 DOSIZE: 1501 mov ax,dx 1502 call ParaRound 1503 mov dx,ax 1504 1505 ADD CX,DX 1506 CMP CX,[cs:ALLOCLIM] 1507 JB OKLD 1508 JMP MEM_ERR 1509 1510 OKLD: 1511 XOR CX,CX 1512 XOR DX,DX 1513 MOV AX,LSEEK << 8 ;Reset pointer to beginning of file 1514 STC ;IN CASE OF INT 24 1515 INT 21H 1516 JC LDCLSP 1517 POP DX 1518 PUSH ES ;READ THE FILE IN 1519 POP DS ;Trans addr is DS:DX 1520 MOV CX,0FF00H ; .COM files arn't any bigger than 1521 ; 64k-100H 1522 READ equ Read ; NASM port equate 1523 MOV AH,READ 1524 STC ;IN CASE OF INT 24 1525 INT 21H 1526 JC LDCLS 1527 MOV SI,DX ;CHECK FOR EXE FILE 1528 CMP WORD PTR [SI],"MZ" ; NASM port swapped text literals 1529 CLC ; Assume OK 1530 JNZ LDCLS ; Only know how to do .COM files 1531 STC 1532 JMP SHORT LDCLS 1533 1534 LDERRP: 1535 STC 1536 LDCLSP: 1537 POP DX ;Clean stack 1538 LDCLS: 1539 PUSHF 1540 MOV AH,CLOSE ;CLOSE THE FILE 1541 STC 1542 INT 21H 1543 POPF 1544 1545 LDRET: POP DS 1546 POP SI 1547 POP DX 1548 POP CX 1549 POP BX 1550 POP AX 1551 return 1552 %ENDIF 1553 1554 ; 1555 ; OPEN DEVICE POINTED TO BY DX, AL HAS ACCESS CODE 1556 ; IF UNABLE TO OPEN DO A DEVICE OPEN NULL DEVICE INSTEAD 1557 ; 1558 OPEN_DEV: 0 0000495B E81C00 CALL OPEN_FILE 0 0000495E 7307 JNC OPEN_DEV3 1561 OPEN_DEV1: 0 00004960 BA[9907] MOV DX,OFFSET NULDEV 0 00004963 E81400 CALL OPEN_FILE 0 00004966 C3 return 1565 1566 OPEN_DEV3: 0 00004967 89C3 MOV BX,AX ; Handle from open to BX 0 00004969 31C0 XOR AX,AX ; GET DEVICE INFO 0 0000496B B444 MOV AH,IOCTL 0 0000496D CD21 INT 21H 0 0000496F F6C280 TEST DL,10000000B 0 00004972 75F2 retnz 0 00004974 B43E MOV AH,CLOSE 0 00004976 CD21 INT 21H 0 00004978 EBE6 JMP OPEN_DEV1 1576 1577 OPEN_FILE: 0 0000497A B43D MOV AH,OPEN 0 0000497C F9 STC 0 0000497D CD21 INT 21H 0 0000497F C3 return 1582 1583 ;J.K. TEST INT24. Return back to DOS with the fake user response of "FAIL" 1584 INT24: 0 00004980 B003 mov al, 3 ;AN000; Fail the system call 0 00004982 CF iret ;AN000; Return back to DOS. 1587 1588 1589 ;INT24: ADD SP,6 ;RESTORE MACHINE STATE 1590 ; POP AX 1591 ; POP BX 1592 ; POP CX 1593 ; POP DX 1594 ; POP SI 1595 ; POP DI 1596 ; POP BP 1597 ; POP DS 1598 ; POP ES 1599 ; PUSH AX 1600 ; MOV AH,GET_DEFAULT_DRIVE ;INITIALIZE DOS 1601 ; INT 21H 1602 ; POP AX 1603 ; IRET ;BACK TO USER 1604 1605 %IF ALTVECT 1606 BOOTMES DB 13,10,"MS-DOS version " 1607 DB MAJOR_VERSION + "0" 1608 DB "." 1609 DB (MINOR_VERSION / 10) + "0" 1610 DB (MINOR_VERSION MOD 10) + "0" 1611 DB 13,10 1612 DB "Copyright 1981,88 Microsoft Corp.",13,10,"$" 1613 %ENDIF 1614 1615 %include "copyrigh.mac" ;P1821; Copyright statement 0 00004983 4D5320444F53205665 DB "MS DOS Version 4.00 (C)Copyright 1988 Microsoft Corp" 0 0000498C 7273696F6E20342E30 0 00004995 3020284329436F7079 0 0000499E 726967687420313938 0 000049A7 38204D6963726F736F 0 000049B0 667420436F7270 0 000049B7 4C6963656E73656420 DB "Licensed Material - Property of Microsoft " 0 000049C0 4D6174657269616C20 0 000049C9 2D2050726F70657274 0 000049D2 79206F66204D696372 0 000049DB 6F736F66742020 1616 0 000049E2 4E554C00 NULDEV DB "NUL",0 0 000049E6 434F4E00 CONDEV DB "CON",0 0 000049EA 41555800 AUXDEV DB "AUX",0 0 000049EE 50524E00 PRNDEV DB "PRN",0 1621 1622 global OLDCONFIG_name 0 000049F2 5C434F4E4649472E53 OLDCONFIG_name: DB "\CONFIG.SYS",0 0 000049FB 595300 1624 0 000049FE 413A CNTRY_DRV DB "A:" 0 00004A00 5C CNTRY_ROOT DB "\" 0 00004A01 434F554E5452592E53 CNTRY_PATH DB "COUNTRY.SYS",0 0 00004A0A 595300 0 00004A0D 000000000000000000 DB 52 DUP (0) 0 00004A16 000000000000000000 0 00004A1F 000000000000000000 0 00004A28 000000000000000000 0 00004A31 000000000000000000 0 00004A3A 00000000000000 1629 0 00004A41 FF434F554E545259 COUNTRY_FILE_SIGNATURE db 0FFh,'COUNTRY' 1631 0 00004A49 ???? CntryCodePage_Id DW ? 1633 0 00004A4B 5C434F4D4D414E442E COMMND DB "\COMMAND.COM",0 0 00004A54 434F4D00 0 00004A58 000000000000000000 DB 51 dup (0) 0 00004A61 000000000000000000 0 00004A6A 000000000000000000 0 00004A73 000000000000000000 0 00004A7C 000000000000000000 0 00004A85 000000000000 1636 0 00004A8B 000000000000000000 PathString db 64 dup (0) ;AN014; 0 00004A94 000000000000000000 0 00004A9D 000000000000000000 0 00004AA6 000000000000000000 0 00004AAF 000000000000000000 0 00004AB8 000000000000000000 0 00004AC1 000000000000000000 0 00004ACA 00 0 00004ACB 53484152452E455845 LShare db "SHARE.EXE",0,"/NC",0Dh,0Ah ;AN014;AN015;To be used by Load/exec. 0 00004AD4 002F4E430D0A 1639 ;/NC parm will disable file sharing check. 1640 1641 COMTAB LABEL BYTE 1642 ;;;; DB 8,"AVAILDEV",'A' ; NO LONGER SUPPORTED 0 00004ADA 074255464645525342 DB 7,"BUFFERS", 'B' 0 00004AE3 05425245414B43 DB 5,"BREAK", 'C' 0 00004AEA 0A4445564943454849 DB 10,"DEVICEHIGH",'d' 0 00004AF3 474864 0 00004AF6 0644455649434544 DB 6,"DEVICE", 'D' 0 00004AFE 0546494C455346 DB 5,"FILES", 'F' 0 00004B05 044643425358 DB 4,"FCBS", 'X' 0 00004B0B 094C41535444524956 DB 9,"LASTDRIVE",'L' 0 00004B14 454C 0 00004B16 0A4D554C5449545241 db 10,"MULTITRACK", 'M' ;AN002; 0 00004B1F 434B4D 0 00004B22 08445249565041524D DB 8,"DRIVPARM", 'P' ; RS for DOS 3.2 0 00004B2B 50 1652 %IF STACKSW 0 00004B2C 06535441434B534B DB 6,"STACKS", 'K' ; BAS for DOS 3.2 1654 %ENDIF 0 00004B34 07434F554E54525951 DB 7,"COUNTRY", 'Q' 0 00004B3D 095348454C4C484947 DB 9,"SHELLHIGH",'s' 0 00004B46 4873 0 00004B48 055348454C4C53 DB 5,"SHELL", 'S' 0 00004B4F 0B494E5354414C4C48 db 11,"INSTALLHIGH",'i' 0 00004B58 49474869 0 00004B5C 07494E5354414C4C49 db 7,"INSTALL", 'I' ;AN000; 0 00004B65 034946534A db 3,"IFS", 'J' ;AN000; 0 00004B6A 044350535757 db 4,"CPSW", 'W' ;AN000; 1662 ;;;; DB 8,"SWITCHAR",'W' ; NO LONGER SUPPORTED 0 00004B70 07434F4D4D454E5459 db 7,"COMMENT", 'Y' ;AN000; 0 00004B79 0352454D30 db 3,"REM", '0' ;AN004; 0 00004B7E 085357495443484553 db 8,"SWITCHES", '1' ;AN013; 0 00004B87 31 0 00004B88 00 DB 0 1667 1668 public DeviceParameters 1669 DeviceParameters: ; NASM structure instance 1670 A_DEVICEPARAMETERS_size equ A_DEVICEPARAMETERS_struc_size ; NASM port equate 1671 istruc A_DEVICEPARAMETERS 1672 at DP_SPECIALFUNCTIONS 0 00004B89 00 db 0 1674 at DP_DEVICETYPE 0 00004B8A 02 db DEV_3INCH720KB 1676 at DP_DEVICEATTRIBUTES 0 00004B8B 0000 dw 0 1678 at DP_CYLINDERS 0 00004B8D 5000 dw 80 0 00004B8F 00 iend 1681 0 00004CAD 0200 hlim dw 2 0 00004CAF 0900 slim dw 9 1684 1685 public drive 0 00004CB1 ?? drive db ? 1687 1688 public switches 0 00004CB2 0000 Switches dw 0 1690 1691 ; 1692 ; The following are the recommended BPBs for the media that we know of so 1693 ; far. 1694 1695 ; 48 tpi diskettes 1696 0 00004CB4 0002 BPB48T DW 512 0 00004CB6 02 DB 2 0 00004CB7 0100 DW 1 0 00004CB9 02 DB 2 0 00004CBA 7000 DW 112 0 00004CBC D002 DW 2*9*40 0 00004CBE FD DB 0FDH 0 00004CBF 0200 DW 2 0 00004CC1 0900 DW 9 0 00004CC3 0200 DW 2 0 00004CC5 00000000 DD 0 0 00004CC9 00000000 DD 0 1709 1710 ; 96tpi diskettes 1711 0 00004CCD 0002 BPB96T DW 512 0 00004CCF 01 DB 1 0 00004CD0 0100 DW 1 0 00004CD2 02 DB 2 0 00004CD3 E000 DW 224 0 00004CD5 6009 DW 2*15*80 0 00004CD7 F9 DB 0F9H 0 00004CD8 0700 DW 7 0 00004CDA 0F00 DW 15 0 00004CDC 0200 DW 2 0 00004CDE 00000000 DD 0 0 00004CE2 00000000 DD 0 1724 1725 ; 3 1/2 inch diskette BPB 1726 0 00004CE6 0002 BPB35 DW 512 0 00004CE8 02 DB 2 0 00004CE9 0100 DW 1 0 00004CEB 02 DB 2 0 00004CEC 7000 DW 70h 0 00004CEE A005 DW 2*9*80 0 00004CF0 F9 DB 0F9H 0 00004CF1 0300 DW 3 0 00004CF3 0900 DW 9 0 00004CF5 0200 DW 2 0 00004CF7 00000000 DD 0 0 00004CFB 00000000 DD 0 1739 0 00004CFF 0002 BPB35H DW 0200H 0 00004D01 01 DB 01H 0 00004D02 0100 DW 0001H 0 00004D04 02 DB 02H 0 00004D05 E000 DW 0E0h 0 00004D07 400B DW 0B40H 0 00004D09 F0 DB 0F0H 0 00004D0A 0900 DW 0009H 0 00004D0C 1200 DW 0012H 0 00004D0E 0200 DW 0002H 0 00004D10 00000000 DD 0 0 00004D14 00000000 DD 0 1752 0 00004D18 [6B0A] BPBTable dw BPB48T ; 48tpi drives 0 00004D1A [840A] dw BPB96T ; 96tpi drives 0 00004D1C [9D0A] dw BPB35 ; 3.5" drives 1756 ; The following are not supported, so default to 3.5" media layout 0 00004D1E [9D0A] dw BPB35 ; Not used - 8" drives 0 00004D20 [9D0A] dw BPB35 ; Not Used - 8" drives 0 00004D22 [9D0A] dw BPB35 ; Not Used - hard files 0 00004D24 [9D0A] dw BPB35 ; Not Used - tape drives 0 00004D26 [B60A] dw BPB35H ; 3-1/2" 1.44MB drive 1762 0 00004D28 08464853544449434E switchlist db 8,"FHSTDICN" ; Preserve the positions of N and C. 1764 1765 ; The following depend on the positions of the various letters in SwitchList 1766 1767 switchnum equ 11111000B ; which switches require number 1768 1769 flagec35 equ 00000100B ; electrically compatible 3.5 inch disk drive 1770 flagdrive equ 00001000B 1771 flagcyln equ 00010000B 1772 flagseclim equ 00100000B 1773 flagheads equ 01000000B 1774 flagff equ 10000000B 1775 1776 SWTCHR EQU "/" ; switch follows this character 1777 1778 ; (no prior section) ; SYSINITSEG ENDS 1779 END === Trace listing source: sysimes.lst 1 ;SCCSID = @(#)sysimes.asm 1.2 85/07/25 2 %warning out: ...SYSIMES 2 ****************** warning: out: ...SYSIMES [-w+user] 3 4 ;============================================================================== 5 ;REVISION HISTORY: 6 ;AN000 - New for DOS Version 4.00 - J.K. 7 ;AC000 - Changed for DOS Version 4.00 - J.K. 8 ;AN00x - PTM number for DOS Version 4.00 - J.K. 9 ;============================================================================== 10 ;AN001 D246, P976 Show "Bad command or parameters - ..." msg 9/22/87 J.K. 11 ;AN002 P1820 New Message SKL file 10/20/87 J.K. 12 ;AN003 D486 Share installation for large media 02/24/88 J.K. 13 ;============================================================================== 14 === Switch to base=008400h -> "BIOCODE" 15 section BIOCODE PUBLIC align=2 class=DOSCODE === Switch to base=002530h -> "SYSINITSEG" 16 section SYSINITSEG PUBLIC align=1 class=INIT 17 18 itest equ 0 19 %include "msequ.mac" 1 <1> %warning out: MSEQU.INC... 1 ****************** <1> warning: out: MSEQU.INC... [-w+user] 2 <1> ;============================================================================== 3 <1> 4 <1> FTOOBIG EQU 80H 5 <1> FBIG EQU 40H 6 <1> ROMSTATUS EQU 1 7 <1> ROMREAD EQU 2 8 <1> ROMWRITE EQU 3 9 <1> ROMVERIFY EQU 4 10 <1> ROMFORMAT EQU 5 11 <1> VID_SIZE EQU 12 12 <1> 13 <1> %include "msbds.mac" ; VARIOUS EQUATES FOR BDS 1 <2> 2 <2> %warning out: MSBDS.INC... 2 ****************** <2> warning: out: MSBDS.INC... [-w+user] 3 <2> ; SCCSID = @(#)IBMBDS.ASM 1.9 85/09/16 4 <2> ;============================================================================== 5 <2> ;REVISION HISTORY: 6 <2> ;AN000 - New for DOS Version 4.00 - J.K. 7 <2> ;AC000 - Changed for DOS Version 4.00 - J.K. 8 <2> ;AN00x - PTM number for DOS Version 4.00 - J.K. 9 <2> ;============================================================================== 10 <2> ;AN001; D113 Disable I/O access to unformatted media 9/03/87 J.K. 11 <2> ;============================================================================== 12 <2> 13 <2> ; VALUES FOR VARIOUS FLAGS IN BDS.FLAGS. 14 <2> 15 <2> FNON_REMOVABLE EQU 01H ;FOR NON-REMOVABLE MEDIA 16 <2> FCHANGELINE EQU 02H ;IF CHANGELINE SUPPORTED ON DRIVE 17 <2> RETURN_FAKE_BPB EQU 04H ; WHEN SET, DON'T DO A BUILD BPB 18 <2> ; JUST RETURN THE FAKE ONE 19 <2> GOOD_TRACKLAYOUT EQU 08H ; THE TRACK LAYOUT HAS NO FUNNY SECTORS 20 <2> ; FCHANGED_BY_FORMAT EQU 08H 21 <2> FI_AM_MULT EQU 10H ;IF MORE THAN ONE LOGICAL FOR THIS PHYSICAL 22 <2> FI_OWN_PHYSICAL EQU 20H ;SIGNIFY LOGICAL OWNER OF THIS PHYSICAL 23 <2> FCHANGED EQU 40H ;INDICATES MEDIA CHANGED 24 <2> SET_DASD_TRUE EQU 80H ; SET DASD BEFORE NEXT FORMAT 25 <2> FCHANGED_BY_FORMAT EQU 100H ;MEDIA CHANGED BY FORMAT 26 <2> UNFORMATTED_MEDIA EQU 200H ;AN001; Fixed disk only 27 <2> F_LBA equ 400h ; LBA supported 28 <2> 29 <2> LBAPACKETSTRUC struc 0 00004D31 ???? lpSize dw ? 0 00004D33 ???? lpCount dw ? 0 00004D35 ???????? lpBuffer dd ? 0 00004D39 ???????????????? lpSector dd ?,? 34 <2> LBAPACKETSTRUC ends 34 ****************** <2> warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 35 <2> 36 <2> ; 37 <2> ; VARIOUS FORM FACTORS TO DESCRIBE MEDIA 38 <2> ; 39 <2> FF48TPI EQU 0 40 <2> FF96TPI EQU 1 41 <2> FFSMALL EQU 2 42 <2> FFHARDFILE EQU 5 43 <2> FFOTHER EQU 7 44 <2> 45 <2> BDS_TYPE STRUC 0 00004D31 ???????? LINK DD ? ; LINK TO NEXT BDS 0 00004D35 ?? DRIVENUM DB ? ; INT 13 DRIVE NUMBER 0 00004D36 ?? DRIVELET DB ? ; DOS DRIVE NUMBER 0 00004D37 ???? BYTEPERSEC DW ? ; NUMBER OF BYTES/SEC 0 00004D39 ?? SECPERCLUS DB ? ; SEC PER ALLOCATION UNIT 0 00004D3A ???? RESSEC DW ? ; NUMBER OF RESERVED SECTORS 0 00004D3C ?? CFAT DB ? ; NUMBER OF FATS 0 00004D3D ???? CDIR DW ? ; NUMBER OF DIRECTORY ENTRIES 0 00004D3F ???? DRVLIM DW ? ; NUMBER OF SECTORS ON MEDIUM 0 00004D41 ?? MEDIAD DB ? ; MEDIA DESCRIPTOR BYTE 0 00004D42 ???? CSECFAT DW ? ; NUMBER OF SECTORS/FAT 0 00004D44 ???? SECLIM DW ? ; SECTORS PER TRACK 0 00004D46 ???? HDLIM DW ? ; MAX NUMBER OF HEADS 0 00004D48 ???? HIDSEC_L DW ? ; NUMBER OF HIDDEN SECTORS 0 00004D4A ???? HIDSEC_H dw ? ;0 ;J.K.87 0 00004D4C ???? DRVLIM_L dw ? ;0 ;J.K.87 0 00004D4E ???? DRVLIM_H dw ? ;0 ;J.K.87 0 00004D50 ?? FATSIZ DB ? ; FLAGS... 0 00004D51 ???? OPCNT DW ? ; OPEN REF. COUNT 0 00004D53 ?? FORMFACTOR DB ? ; FORM FACTOR INDEX 0 00004D54 ???? FLAGS DW ? ; VARIOUS FLAGS 0 00004D56 ???? CCYLN DW ? ; MAX NUMBER OF CYLINDERS 0 00004D58 ???? RBYTEPERSEC DW ? ; RECOMMENDED BPB 0 00004D5A ?? RSECPERCLUS DB ? 0 00004D5B ???? RRESSEC DW ? 0 00004D5D ?? RCFAT DB ? 0 00004D5E ???? RCDIR DW ? 0 00004D60 ???? RDRVLIM DW ? 0 00004D62 ?? RMEDIAD DB ? 0 00004D63 ???? RCSECFAT DW ? 0 00004D65 ???? RSECLIM DW ? 0 00004D67 ???? RHDLIM DW ? 0 00004D69 ???? RHIDSEC_L DW ? 0 00004D6B ???? RHIDSEC_H DW ? ;0 ;J.K.87 0 00004D6D ???? RDRVLIM_L dw ? ;0 ;J.K.87 0 00004D6F ???? RDRVLIM_H dw ? ;0 ;J.K.87 0 00004D71 ???????????? RESERVE DB 6 DUP (?) ; RESERVED FOR FUTURE 0 00004D77 ?? TRACK DB ? ; LAST TRACK ACCESSED ON DRIVE 0 00004D78 ???? TIM_LO DW ? ; TIME OF LAST ACCESS. KEEP 0 00004D7A ???? TIM_HI DW ? ; THESE CONTIGUOUS. 86 0000004B <2> VOLID DB 12 DUP (?) ; VOLUME ID OF MEDIUM 0 00004D88 ???????? VOL_SERIAL dd ? ;0 ;J.K.87 Current volume serial number from Boot record 88 0000005B <2> FILESYS_Id db 9 dup (?) ;(0) ;J.K.87 Current file system id from Boot record 89 <2> BDS_TYPE ENDS 89 ****************** <2> warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 90 <2> 91 <2> BPBSIZE equ TRACK - RBYTEPERSEC ; SIZE IN BYTES OF RECBPB AREA IN THE BDS 92 <2> 93 <2> 94 <2> ;********************************************************************* 95 <2> ; BDS structure for mini disk - J.K. 4/7/86 96 <2> ;********************************************************************* 97 <2> 98 <2> BDSM_type struc 0 00004D31 ???? mlink DW ? ;-1 ;Link to next structure 0 00004D33 ???? DW ? 0 00004D35 ?? mdriveNum DB ? ;80 ;Int 13 Drive Number 0 00004D36 ?? mdriveLet DB ? ;3 ;Logical Drive Number 0 00004D37 ???? mBytePerSec DW ? ;512 0 00004D39 ?? mSecPerClus DB ? ;1 ;Sectors/allocation unit 0 00004D3A ???? mRESSEC DW ? ;1 ;Reserved sectors for DOS 0 00004D3C ?? mcFAT DB ? ;2 ;No. of allocation tables 0 00004D3D ???? mcDIR DW ? ;16 ;Number of directory entries 0 00004D3F ???? mDRVLIM DW ? ;0 ;Number of sectors (at 512 bytes each) 0 00004D41 ?? mMediad DB ? ;11111000B ;Media descriptor 0 00004D42 ???? mcSecFat DW ? ;1 ;Number of FAT sectors 0 00004D44 ???? mSECLIM DW ? ;0 ;Sector limit 0 00004D46 ???? mHDLIM DW ? ;0 ;Head limit 0 00004D48 ???? mHIDSEC_L DW ? ;0 ;Hidden sector count 0 00004D4A ???? mHidsec_H dw ? ;0 ;J.K.87 0 00004D4C ???? mDrvlim_L dw ? ;0 ;J.K.87 0 00004D4E ???? mDrvlim_H dw ? ;0 ;J.K.87 0 00004D50 ?? mFatSiz DB ? ;0 ;TRUE => bigfat 0 00004D51 ???? mOPCNT DW ? ;0 ;Open Ref. Count 0 00004D53 ?? mFormFactor DB ? ;3 ;Form Factor 0 00004D54 ???? mFLAGS DW ? ;0020H ;Various Flags 0 00004D56 ???? mcCyln dw ? ;40 ;max number of cylinders 122 00000027 <2> mRecBPB db 31 dup (?) ;(0) ;Recommended BPB for drive 0 00004D77 ?? mTrack db ? ;-1 0 00004D78 ???? IsMini dw ? ;1 ;Overlapping TIM_LOH 0 00004D7A ???? Hidden_Trks dw ? ;0 ;Overlapping TIM_HIH 126 0000004B <2> mVOLID DB 11 dup (?) ;"NO NAME " ;Volume ID for this disk 0 00004D87 ?? DB ? ;0 ;ASCIZII for "NO NAME " 0 00004D88 ???????? mVol_Serial dd ? ;0 ;Current volume serial number from Boot record 0 00004D8C ???????????????? mFileSys_Id db 8 dup (?) ;"FAT12 " ;Current file system id from Boot record 0 00004D94 ?? db ? ;0 131 <2> 132 <2> BDSM_type ENDS 132 ****************** <2> warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 133 <2> ;****************************************************************************** 134 <2> Max_mini_dsk_num equ 23 ;J.K. 4/7/86 - max # of mini disk ibmbio can support 135 <2> ; 136 <2> 14 <1> 15 <1> ;AN000; Extended BPB structure. 16 <1> BPB_TYPE STRUC 0 00004D31 ???? SECSIZE DW ? 0 00004D33 ?? SECALL DB ? 0 00004D34 ???? RESNUM DW ? 0 00004D36 ?? FATNUM DB ? 0 00004D37 ???? DIRNUM DW ? 0 00004D39 ???? SECNUM DW ? 0 00004D3B ?? FATID DB ? 0 00004D3C ???? FATSIZE DW ? 0 00004D3E ???? SLIM DW ? 0 00004D40 ???? HLIM DW ? 0 00004D42 ???? HIDDEN_L DW ? 0 00004D44 ???? HIDDEN_H dw ? ;0 ;J.K. 0 00004D46 ???? SECNUM_L dw ? ;0 ;J.K. 0 00004D48 ???? SECNUM_H dw ? ;0 ;J.K. 31 <1> BPB_TYPE ENDS 31 ****************** <1> warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 32 <1> 33 <1> ;;;;;;;;;;; 34 <1> BOOT_SERIAL_SIZE equ 4 ;J.K. 35 <1> BOOT_VOLUME_LABEL_SIZE equ 11 ;J.K. 36 <1> BOOT_SYSTEM_ID_SIZE equ 8 ;J.K. 37 <1> EXT_BOOT_SIGNATURE equ 41 ;J.K. 38 <1> RSINIT equ 0A3H ;RS232 INITIALIZATION 39 <1> ;9600 BAUD:NO PARITY:1 STOP:8 BIT WORD 40 <1> LF equ 10 ;LINE FEED 41 <1> CR equ 13 ;CARRIAGE RETURN 42 <1> BACKSP equ 8 ;BACKSPACE 43 <1> BRKADR equ 1BH * 4 ;006C 1BH BREAK VECTOR ADDRESS 44 <1> TIMADR equ 1CH * 4 ;0070 1CH TIMER INTERRUPT 45 <1> DSKADR equ 1EH * 4 ;ADDRESS OF PTR TO DISK PARAMETERS 46 <1> SEC9 equ 522H ;ADDRESS OF DISK PARAMETERS 47 <1> HEADSETTLE equ SEC9+9 ; ARR 2.20 ADDRESS OF HEAD SETTLE TIME 48 <1> NORMSETTLE equ 15 ; ARR 2.20 NORMAL HEAD SETTLE 49 <1> SPEEDSETTLE equ 0 ; ARR 2.20 SPEED UP SETTLE TIME 50 <1> INITSPOT equ 534H ; ARR IBM WANTS 4 ZEROS HERE 51 <1> AKPORT equ 20H 52 <1> EOI equ 20H 53 <1> CMDLEN equ 0 ;LENGTH OF THIS COMMAND 54 <1> UNIT equ 1 ;SUB UNIT SPECIFIER 55 <1> CMD equ 2 ;COMMAND CODE 56 <1> STATUS equ 3 ;STATUS 57 <1> MEDIA equ 13 ;MEDIA DESCRIPTOR 58 <1> TRANS equ 14 ;TRANSFER ADDRESS 59 <1> COUNT equ 18 ;COUNT OF BLOCKS OR CHARACTERS 60 <1> START equ 20 ;FIRST BLOCK TO TRANSFER 61 <1> EXTRA equ 22 ;USUALLY A POINTER TO VOL ID FOR ERROR 15 62 <1> CHROUT equ 29H 63 <1> MAXERR equ 5 64 <1> LSTDRV equ 504H 65 <1> 66 <1> NOTBUSYSTATUS equ 10000000B ; NOT BUSY 67 <1> ACKSTATUS equ 01000000B ; ACKNOWLEDGE (FOR WHAT?) 68 <1> NOPAPERSTATUS equ 00100000B ; NO MORE PAPER 69 <1> SELECTEDSTATUS equ 00010000B ; THE PRINTER SAID IT WAS SELECTED 70 <1> IOERRSTATUS equ 00001000B ; SOME KINDA ERROR 71 <1> RESERVED equ 00000110B ; NOPS 72 <1> TIMEOUTSTATUS equ 00000001B ; TIME OUT. 73 <1> ERROR_UNKNOWN_MEDIA equ 7 ; FOR USE IN BUILD BPB CALL 74 <1> 75 <1> PATHGEN equ 1 20 %include "msmacro.mac" 1 <1> === Switch to base=008400h -> "BIOCODE" 2 <1> section BIOCODE 3 <1> ; 4 <1> ; This file contains three macros used in debugging the system. If the 5 <1> ; variable "itest" (in msbio.asm) is nonzero code is included in the 6 <1> ; modules to print debugging messages. The level of debugging is controlled 7 <1> ; by the value of the variable fTestBits in msbio.asm. Specific bits in 8 <1> ; the variable determine which messages to print. The equ's below tell 9 <1> ; which bits control which funcitons. For example the fifth bit 10 <1> ; cooresponds to disk activity (see fTestDisk equ below). 11 <1> ; 12 <1> ; The macros in the file are: 13 <1> ; 14 <1> ; message Prints an ascii string on the screen. 15 <1> ; Example usage: 16 <1> ; 17 <1> ; message fTestDisk, <"Start Disk Write", CR, LF> 18 <1> ; message fTestINIT, <"Begin BDS initialization"> 19 <1> ; 20 <1> ; 21 <1> ; MNUM Print the value in a register or memory location on 22 <1> ; the screen. Value is displayed in hex. 23 <1> ; Usage: 24 <1> ; MNUM bitpattern, valueLocation 25 <1> ; 26 <1> ; valueLocation is typically a regester: 27 <1> ; 28 <1> ; mnum fTestCom, AX 29 <1> ; mnum fTestDisk, DX 30 <1> ; 31 <1> ; ValueLocation can also be a memory location: 32 <1> ; 33 <1> ; mnum fTestINIT, Final_Dos_Location 34 <1> ; 35 <1> ; If no valueLocation is given the macro defaults to 36 <1> ; the BX register. 37 <1> ; 38 <1> ; ZWAIT Stops the program until any key is pressed. 39 <1> ; 40 <1> ; 41 <1> ; The three macros preserve all register values. If "test" is zero 42 <1> ; defined during assembly then the marco produce no code. 43 <1> ; 44 <1> 45 <1> %IF itest ;3.30 46 <1> EXTRN MSGOUT:NEAR,MSGNUM:NEAR ;3.30 47 <1> EXTRN NUMBUF:BYTE,DIGITS:BYTE,FTESTBITS:WORD ;3.30 48 <1> EXTRN DUMPBYTES:NEAR,OUTCHAR:NEAR,HEX_TO_ASCII:NEAR ;3.30 49 <1> 50 <1> 51 <1> fTestALL equ 1111111111111111b ; watch everything 52 <1> fTestHARD equ 0000000000000001b ; watch hard disk initialization 53 <1> fTest96 equ 0000000000000010b ; watch 96 tpi activity 54 <1> FTEST13 EQU 0000000000000100B ; WATCH INT 13 ACTIVITY ;3.30 55 <1> FTESTCOM EQU 0000000000001000B ; WATCH PACKET ACTIVITY ;3.30 56 <1> FTESTINIT EQU 0000000000010000B ; WATCH INITIALIZATION MESSAGES ;3.30 57 <1> FTESTDISK EQU 0000000000100000B ; WATCH DISK DEVICE DRIVER CALLS ;3.30 58 <1> FTESTCON EQU 0000000001000000B ; WATCH SYSTEM WAIT ACTIVITY IN CO;3.30 NSOLE 59 <1> FtestClock equ 0000000010000000b ; wathc clock device 5/2/86 ;3.30 60 <1> 61 <1> ; NASM original macros 62 <1> 63 <1> ; 64 <1> ; message macro -- see above for description 65 <1> ; 66 <1> 67 <1> %unimacro stripangles 2+.nolist 68 <1> 69 <1> %imacro stripangles 2+.nolist 70 <1> %defstr %%param %2 71 <1> %rep 16 72 <1> %substr %%opening %%param 1 73 <1> %ifidn %%opening, '<' 74 <1> %substr %%param %%param 2,-1 75 <1> %endif 76 <1> %endrep 77 <1> %rep 16 78 <1> %strlen %%length %%param 79 <1> %substr %%closing %%param %%length 80 <1> %ifidn %%closing, '>' 81 <1> %substr %%param %%param 1,-2 82 <1> %endif 83 <1> %endrep 84 <1> %deftok %%token %%param 85 <1> %1 %%token 86 <1> %endmacro 87 <1> 88 <1> %imacro MESSAGE 2+ 89 <1> jmp short %%b 90 <1> %%a: 91 <1> stripangles db, %2 92 <1> db 0 93 <1> %%b: push SI 94 <1> push AX 95 <1> mov AX, %1 96 <1> mov SI, OFFSET %%a 97 <1> call MSGOUT 98 <1> pop AX 99 <1> pop SI 100 <1> %endmacro 101 <1> 102 <1> 103 <1> ; 104 <1> ; mnum macro -- see above for description 105 <1> ; 106 <1> 107 <1> %imacro MNum 1-2 108 <1> push AX 109 <1> %ifempty %2 110 <1> mov AX,%1 111 <1> call MSGNUM 112 <1> %else 113 <1> push BX 114 <1> mov BX,%2 115 <1> mov AX,%1 116 <1> call MSGNUM 117 <1> pop BX 118 <1> %endif 119 <1> pop AX 120 <1> %endmacro 121 <1> 122 <1> 123 <1> ; 124 <1> ; zwait macro -- see above for description 125 <1> ; 126 <1> 127 <1> %imacro ZWAIT 0 128 <1> Message fTestALL,<"? "> 129 <1> CALL ZWAITrtn 130 <1> %endmacro 131 <1> 132 <1> ZWAITrtn: 133 <1> pushf ; save the flags 134 <1> push AX ; preserve AX 135 <1> xor AH, AH ; set command to get character ;3.30* 136 <1> int 16h ; call rom keyboard routine ;3.30* 137 <1> pop AX ; restore AX 138 <1> popf ; restore the flags 139 <1> ret 140 <1> 141 <1> ;Dump_byte dumps the memory contents in hex. ;3.30 142 <1> ;DUMPOFFLABEL should be a label or a variable defined in DUMPSEG. ;3.30 143 <1> %imacro DUMP_BYTE 3 144 <1> push es ;3.30 145 <1> PUSH DS ;3.30 146 <1> PUSH SI ;3.30 147 <1> PUSH CX ;3.30 148 <1> ;3.30 149 <1> MOV CX, %1 ;3.30 150 <1> MOV DS, CX ;3.30 151 <1> MOV SI, OFFSET %2 ;3.30 152 <1> MOV CX, %3 ;3.30 153 <1> call dumpbytes ;3.30 154 <1> ;3.30 155 <1> POP CX ;3.30 156 <1> POP SI ;3.30 157 <1> POP DS ;3.30 158 <1> pop es ;3.30 159 <1> %endmacro ;3.30 160 <1> ;3.30 161 <1> ;Dump_Byte_Reg dumps the memory contents in hex. - 4/9/86 ;3.30 162 <1> ;DUMPOFFREG should be a register contains the offset value in DUMPSEG. ;3.30 163 <1> %imacro DUMP_BYTE_REG 3 164 <1> DUMP_BYTE_REG MACRO DUMPSEG, DUMPOFFREG, BYTELENGTH ;3.30 165 <1> push es ;3.30 166 <1> PUSH DS ;3.30 167 <1> PUSH SI ;3.30 168 <1> PUSH CX ;3.30 169 <1> ;3.30 170 <1> MOV CX, %1 ;3.30 171 <1> MOV DS, CX ;3.30 172 <1> MOV SI, %2 ;3.30 173 <1> MOV CX, %3 ;3.30 174 <1> call dumpbytes ;3.30 175 <1> ;3.30 176 <1> POP CX ;3.30 177 <1> POP SI ;3.30 178 <1> POP DS ;3.30 179 <1> pop es ;3.30 180 <1> %endmacro ;3.30 181 <1> 182 <1> %else 183 <1> ; if test is not defined then make macro into null statements 184 <1> %imacro Message 0-1+.nolist 185 <1> %endmacro 186 <1> 187 <1> %imacro MNUM 0-1+.nolist 188 <1> %endmacro 189 <1> 190 <1> %imacro ZWAIT 0-1+.nolist 191 <1> %endmacro 192 <1> 193 <1> %imacro DUMP_BYTE 0-1+.nolist 194 <1> %endmacro 195 <1> 196 <1> %imacro DUMP_BYTE_REG 0-1+.nolist 197 <1> %endmacro 198 <1> 199 <1> %endif 200 <1> 201 <1> %unimacro PATHSTART 2 202 <1> %unimacro PATHEND 2 203 <1> 204 <1> %imacro PATHSTART 2 205 <1> %IF PATHGEN ;3.30 206 <1> PUBLIC %2%1S,%2%1E ;3.30 207 <1> %2%1S LABEL BYTE ;3.30 208 <1> %ENDIF ;3.30 209 <1> %endmacro ;3.30 210 <1> ;3.30 211 <1> %imacro PATHEND 2 212 <1> %IF PATHGEN ;3.30 213 <1> %2%1E LABEL BYTE ;3.30 214 <1> %ENDIF ;3.30 215 <1> %endmacro ;3.30 21 === Switch to base=002530h -> "SYSINITSEG" 22 section SYSINITSEG 23 24 PUBLIC BADOPM,CRLFM,BADSIZ_PRE,BADLD_PRE,BADCOM,BADCOUNTRY 25 ; PUBLIC BADLD_POST,BADSIZ_POST,BADMEM,BADBLOCK,BADSTACK 26 PUBLIC BADMEM,BADBLOCK,BADSTACK 27 PUBLIC INSUFMEMORY,BADCOUNTRYCOM 28 BadOrder equ BADORDER ; NASM port label 29 Errorcmd equ ERRORCMD ; NASM port label 30 public BadOrder,Errorcmd ;AN000; 31 public BadParm ;AN001; 32 public SHAREWARNMSG ;AN003; 33 public config_overflow 34 public unknown_command 35 36 37 ;include sysimes.inc 38 ;=== Push trace listing source: msbio.cl3 39 %include "msbio.cl3" ;AN002; ; NASM included file 1 <1> ; msbio.cl3 2 <1> 3 <1> 4 <1> ;_______________________ 5 <1> 0 00004D31 0D0A556E7265636F67 BADOPM DB 13,10,"Unrecognized command in CONFIG.SYS" 0 00004D3A 6E697A656420636F6D 0 00004D43 6D616E6420696E2043 0 00004D4C 4F4E4649472E535953 7 <1> 8 <1> ;_______________________ 9 <1> 0 00004D55 0D0A24 CRLFM DB 13,10,"$" 11 <1> 12 <1> ;_______________________ 13 <1> 0 00004D58 0D0A42616420636F6D BadParm DB 13,10,"Bad command or parameters - $" 0 00004D61 6D616E64206F722070 0 00004D6A 6172616D6574657273 0 00004D73 202D2024 15 <1> 16 <1> ;_______________________ 17 <1> 0 00004D77 0D0A536563746F7220 BADSIZ_PRE DB 13,10,"Sector size too large in file $" 0 00004D80 73697A6520746F6F20 0 00004D89 6C6172676520696E20 0 00004D92 66696C652024 19 <1> 20 <1> ;_______________________ 21 <1> 0 00004D98 0D0A426164206F7220 BADLD_PRE DB 13,10,"Bad or missing $" 0 00004DA1 6D697373696E672024 23 <1> 24 <1> ;_______________________ 25 <1> 0 00004DAA 436F6D6D616E642049 BADCOM DB "Command Interpreter",0 0 00004DB3 6E7465727072657465 0 00004DBC 7200 27 <1> 28 <1> ;_______________________ 29 <1> 0 00004DBE 0D0A496E76616C6964 BADCOUNTRY DB 13,10,"Invalid country code or code page",13,10,"$" 0 00004DC7 20636F756E74727920 0 00004DD0 636F6465206F722063 0 00004DD9 6F646520706167650D 0 00004DE2 0A24 31 <1> 32 <1> ;_______________________ 33 <1> 0 00004DE4 0D0A4572726F722069 BADCOUNTRYCOM DB 13,10,"Error in COUNTRY command",13,10,"$" 0 00004DED 6E20434F554E545259 0 00004DF6 20636F6D6D616E640D 0 00004DFF 0A24 35 <1> 36 <1> ;_______________________ 37 <1> 0 00004E01 0D0A496E7375666669 INSUFMEMORY DB 13,10, "Insufficient memory for COUNTRY.SYS file",13,10,"$" 0 00004E0A 6369656E74206D656D 0 00004E13 6F727920666F722043 0 00004E1C 4F554E5452592E5359 0 00004E25 532066696C650D0A24 39 <1> 40 <1> ;_______________________ 41 <1> 0 00004E2E 0D0A436F6E66696775 BADMEM DB 13,10,"Configuration too large for memory",13,10,"$" 0 00004E37 726174696F6E20746F 0 00004E40 6F206C617267652066 0 00004E49 6F72206D656D6F7279 0 00004E52 0D0A24 43 <1> 44 <1> ;_______________________ 45 <1> 0 00004E55 0D0A546F6F206D616E BADBLOCK DB 13,10,"Too many block devices",13,10,"$" 0 00004E5E 7920626C6F636B2064 0 00004E67 6576696365730D0A24 47 <1> 48 <1> ;_______________________ 49 <1> 0 00004E70 0D0A496E76616C6964 BADSTACK DB 13,10,"Invalid STACK parameters",13,10,"$" 0 00004E79 20535441434B207061 0 00004E82 72616D65746572730D 0 00004E8B 0A24 51 <1> 52 <1> ;_______________________ 53 <1> 0 00004E8D 0D0A496E636F727265 BADORDER DB 13,10,"Incorrect order in CONFIG.SYS line ","$" 0 00004E96 6374206F7264657220 0 00004E9F 696E20434F4E464947 0 00004EA8 2E535953206C696E65 0 00004EB1 2024 55 <1> 56 <1> ;_______________________ 57 <1> 0 00004EB3 4572726F7220696E20 ERRORCMD DB "Error in CONFIG.SYS line ","$" 0 00004EBC 434F4E4649472E5359 0 00004EC5 53206C696E652024 59 <1> 60 <1> ;_______________________ 61 <1> 0 00004ECD 5741524E494E472120 SHAREWARNMSG DB "WARNING! SHARE should be loaded for large media",13,10,"$" 0 00004ED6 53484152452073686F 0 00004EDF 756C64206265206C6F 0 00004EE8 6164656420666F7220 0 00004EF1 6C61726765206D6564 0 00004EFA 69610D0A24 40 ;=== Pop trace listing source 41 0 00004EFF 0D0A436F6E66696775 config_overflow: db 13,10,"Configuration is too long! Truncating.",13,10,36 0 00004F08 726174696F6E206973 0 00004F11 20746F6F206C6F6E67 0 00004F1A 21205472756E636174 0 00004F23 696E672E0D0A24 0 00004F2A 556E6B6E6F776E2063 unknown_command: db "Unknown command in kernel command line! Ignoring:",13,10,' "',0 0 00004F33 6F6D6D616E6420696E 0 00004F3C 206B65726E656C2063 0 00004F45 6F6D6D616E64206C69 0 00004F4E 6E65212049676E6F72 0 00004F57 696E673A0D0A202200 44 45 PATHEND 001,SYSMES 212 <1> %IF PATHGEN 213 <1> %2%1E LABEL BYTE 214 <1> %ENDIF 46 47 END === Trace listing source: ../INC/nibdos.lst 1 ; SCCSID = @(#)nibdos.asm 1.1 85/04/10 2 ;TITLE NIBDOS 3 ;NAME MSDOS_3 4 5 ;=== Push trace listing source: mssw.nas 6 %include "mssw.nas" ; NASM included file 1 <1> ; SCCSID = @(#)ibmsw.asm 1.1 85/04/10 2 <1> 3 <1> %include "version.mac" 1 <2> ; Some modules really want TRUE to be 0FFH. Best to let them have their way. 2 <2> TRUE EQU 0FFFFh 3 <2> TRUEBYTE EQU 0FFh 4 <2> FALSE EQU 0 5 <2> 6 <2> ; 7 <2> ; Use the following switches to control cmacros.inc 8 <2> ; 9 <2> ?PLM equ 0 10 <2> ?WIN equ 0 11 <2> 12 <2> memS EQU 1 ; Small model 13 <2> ; 14 <2> ; Use the switches below to produce the standard Microsoft version or the IBM 15 <2> ; version of the operating system 16 <2> ; 17 <2> ; The below chart will indicate how to set the switches to build the various 18 <2> ; versions 19 <2> ; 20 <2> ; IBMVER IBMCOPYRIGHT 21 <2> ; -------------------------------------------------------- 22 <2> ; IBM Version | TRUE TRUE 23 <2> ; -------------------------------------------------------- 24 <2> ; MS Version | FALSE FALSE 25 <2> ; -------------------------------------------------------- 26 <2> ; Clone Version | TRUE FALSE 27 <2> ; 28 <2> IBMVER EQU TRUE 29 <2> IBMCOPYRIGHT EQU FALSE 30 <2> 31 <2> BUFFERFLAG EQU ~ IBMCOPYRIGHT 32 <2> 33 <2> %ifndef MSVER 34 <2> MSVER EQU ~ IBMVER 35 <2> %endif 36 <2> IBM EQU IBMVER 37 <2> ; 38 <2> ; 39 <2> %IF IBMVER 40 <2> %IF IBMCOPYRIGHT 41 <2> %warning out: ... IBM version build switch on ... 42 <2> %ELSE 43 <2> %warning out: ... CLONE version build switch on ... 43 ****************** <2> warning: out: ... CLONE version build switch on ... [-w+user] 44 <2> %ENDIF 45 <2> %ELSE 46 <2> %IFN IBMCOPYRIGHT 47 <2> %warning out: ... MS version build switch on ... 48 <2> %ELSE 49 <2> %warning out: !!!!!!!!! VERSION SWITCHES SET INCORECTLY !!!!!!!!! 50 <2> %warning out: !!!!!!!!! CHECK SETTINGS IN INC\VERSION.INC !!!!!!!!! 51 <2> %ENDIF 52 <2> %ENDIF 53 <2> ; 54 <2> ; 55 <2> ;*************************************************************************** 56 <2> ;* The following switches are for DBCS or SBCS support * 57 <2> ;* * 58 <2> ;* Set INTERNAT EQU TRUE FOR DBCS * 59 <2> ;* Set INTERNAT EQU FALSE FOR SBCS * 60 <2> ;* * 61 <2> ;*************************************************************************** 62 <2> ; 63 <2> IBMJAPVER EQU FALSE ;If TRUE set KANJI true also 64 <2> 65 <2> ; 66 <2> ; Switch INTERNAT for DBCS support 67 <2> ; 68 <2> INTERNAT EQU FALSE 69 <2> ; 70 <2> %IF INTERNAT 71 <2> %ifndef KANJI 72 <2> KANJI EQU TRUE 73 <2> %endif 74 <2> IBMJAPAN EQU TRUE 75 <2> %ELSE 76 <2> %ifndef KANJI 77 <2> KANJI EQU FALSE 78 <2> %endif 79 <2> IBMJAPAN EQU FALSE 80 <2> %ENDIF 81 <2> 82 <2> %ifndef altvect ; avoid jerking off vector.inc 83 <2> ALTVECT EQU FALSE ;Switch to build ALTVECT version 84 <2> %endif 85 <2> 86 <2> ; 87 <2> ; Country code switches 88 <2> ; The default contry code is assumed as USA. 89 <2> ; 90 <2> %IF INTERNAT 91 <2> KOREA EQU TRUE 92 <2> JAPAN EQU FALSE 93 <2> %ELSE 94 <2> KOREA EQU FALSE 95 <2> JAPAN EQU FALSE 96 <2> %ENDIF 97 <2> ; 98 <2> %IF INTERNAT 99 <2> %warning out: Internat(ECS) version build switch on 100 <2> %ENDIF 4 <1> 5 <1> ibmver equ IBMVER ; NASM port equate 6 <1> IBM EQU ibmver 7 <1> WANG EQU FALSE 8 <1> 9 <1> ; Set this switch to cause DOS to move itself to the end of memory 10 <1> HIGHMEM EQU FALSE 11 <1> 12 <1> ; Turn on switch below to allow testing disk code with DEBUG. It sets 13 <1> ; up a different stack for disk I/O (functions > 11) than that used for 14 <1> ; character I/O which effectively makes the DOS re-entrant. 15 <1> 16 <1> %IF IBM 17 <1> ESCCH EQU 0 ; character to begin escape seq. 18 <1> CANCEL EQU 27 ;Cancel with escape 19 <1> TOGLPRN EQU TRUE ;One key toggles printer echo 20 <1> ZEROEXT EQU TRUE 21 <1> %ELSE 22 <1> ESCCH EQU 1BH 23 <1> CANCEL EQU "X"-"@" ;Cancel with Ctrl-X 24 <1> TOGLPRN EQU FALSE ;Separate keys for printer echo on 25 <1> ;and off 26 <1> ZEROEXT EQU TRUE 27 <1> %ENDIF 28 <1> 7 ;=== Pop trace listing source 8 ;=== Push trace listing source: msconst.nas 9 %include "msconst.nas" ; NASM included file 1 <1> ; SCCSID = @(#)msconst.asm 1.4 85/09/12 2 <1> ; Revision history 3 <1> ; AN000 version 4.00 Jan. 1988 4 <1> ; AN007 fake version check for IBMCACHE.COM 5 <1> ;=== Push trace listing source: mshead.nas 6 <1> %include "mshead.nas" ; NASM included file 1 <2> ; SCCSID = @(#)mshead.asm 1.1 85/04/10 2 <2> ; TITLE MSHEAD.ASM -- MS-DOS DEFINITIONS 3 <2> ;PAGE 4 <2> ; MS-DOS High-performance operating system for the 8086 version 1.28 5 <2> ; by Microsoft MSDOS development group: 6 <2> ; TP (Ret.) 7 <2> ; AR 8 <2> ; NP (Parenting) 9 <2> ; MZ 10 <2> ; CP (BIOS) (ret.) 11 <2> 12 <2> ; ****************** Revision History ************************* 13 <2> ; >> EVERY change must noted below!! << 14 <2> ; 15 <2> ; 0.34 12/29/80 General release, updating all past customers 16 <2> ; 0.42 02/25/81 32-byte directory entries added 17 <2> ; 0.56 03/23/81 Variable record and sector sizes 18 <2> ; 0.60 03/27/81 Ctrl-C exit changes, including register save on user stack 19 <2> ; 0.74 04/15/81 Recognize I/O devices with file names 20 <2> ; 0.75 04/17/81 Improve and correct buffer handling 21 <2> ; 0.76 04/23/81 Correct directory size when not 2^N entries 22 <2> ; 0.80 04/27/81 Add console input without echo, Functions 7 & 8 23 <2> ; 1.00 04/28/81 Renumber for general release 24 <2> ; 1.01 05/12/81 Fix bug in `STORE' 25 <2> ; 1.10 07/21/81 Fatal error trapping, NUL device, hidden files, date & time, 26 <2> ; RENAME fix, general cleanup 27 <2> ; 1.11 09/03/81 Don't set CURRENT BLOCK to 0 on open; fix SET FILE SIZE 28 <2> ; 1.12 10/09/81 Zero high half of CURRENT BLOCK after all (CP/M programs don't) 29 <2> ; 1.13 10/29/81 Fix classic "no write-through" error in buffer handling 30 <2> ; 1.20 12/31/81 Add time to FCB; separate FAT from DPT; Kill SMALLDIR; Add 31 <2> ; FLUSH and MAPDEV calls; allow disk mapping in DSKCHG; Lots 32 <2> ; of smaller improvements 33 <2> ; 1.21 01/06/82 HIGHMEM switch to run DOS in high memory 34 <2> ; 1.22 01/12/82 Add VERIFY system call to enable/disable verify after write 35 <2> ; 1.23 02/11/82 Add defaulting to parser; use variable escape character Don't 36 <2> ; zero extent field in IBM version (back to 1.01!) 37 <2> ; 1.24 03/01/82 Restore fcn. 27 to 1.0 level; add fcn. 28 38 <2> ; 1.25 03/03/82 Put marker (00) at end of directory to speed searches 39 <2> ; 1.26 03/03/82 Directory buffers searched as a circular queue, current buffer 40 <2> ; is searched first when possible to minimize I/O 41 <2> ; 03/03/82 STORE routine optimized to tack on partial sector tail as 42 <2> ; full sector write when file is growing 43 <2> ; 03/09/82 Multiple I/O buffers 44 <2> ; 03/29/82 Two bugs: Delete all case resets search to start at beginning 45 <2> ; of directory (infinite loop possible otherwise), DSKRESET 46 <2> ; must invalidate all buffers (disk and directory). 47 <2> ; 1.27 03/31/82 Installable device drivers 48 <2> ; Function call 47 - Get pointer to device table list 49 <2> ; Function call 48 - Assign CON AUX LIST 50 <2> ; 04/01/82 Spooler interrupt (INT 28) added. 51 <2> ; 1.28 04/15/82 DOS retructured to use ASSUMEs and PROC labels around system 52 <2> ; call entries. Most CS relative references changed to SS 53 <2> ; relative with an eye toward putting a portion of the DOS in 54 <2> ; ROM. DOS source also broken into header, data and code pieces 55 <2> ; 04/15/82 GETDMA and GETVECT calls added as 24 and 32. These calls 56 <2> ; return the current values. 57 <2> ; 04/15/82 INDOS flag implemented for interrupt processing along with 58 <2> ; call to return flag location (call 29) 59 <2> ; 04/15/82 Volume ID attribute added 60 <2> ; 04/17/82 Changed ABORT return to user to a long ret from a long jump to 61 <2> ; avoid a CS relative reference. 62 <2> ; 04/17/82 Put call to STATCHK in dispatcher to catch ^C more often 63 <2> ; 04/20/82 Added INT int_upooler into loop ^S wait 64 <2> ; 04/22/82 Dynamic disk I/O buffer allocation and call to manage them 65 <2> ; call 49. 66 <2> ; 04/23/82 Added GETDSKPTDL as call 50, similar to GETFATPT(DL), returns 67 <2> ; address of DPB 68 <2> ; 04/29/82 Mod to WRTDEV to look for ^C or ^S at console input when 69 <2> ; writting to console device via file I/O. Added a console 70 <2> ; output attribute to devices. 71 <2> ; 04/30/82 Call to en/dis able ^C check in dispatcher Call 51 72 <2> ; 04/30/82 Code to allow assignment of func 1-12 to disk files as well 73 <2> ; as devices.... pipes, redirection now possible 74 <2> ; 04/30/82 Expanded GETLIST call to 2.0 standard 75 <2> ; 05/04/82 Change to INT int_fatal_abort callout int HARDERR_DOS. DOS SS 76 <2> ; (data segment) stashed in ES, INT int_fatal_abort routines must 77 <2> ; preserve ES. This mod so HARDERR_DOS can be ROMed. 78 <2> ; 1.29 06/01/82 Installable block and character devices as per 2.0 spec 79 <2> ; 06/04/82 Fixed Bug in CLOSE regarding call to CHKFATWRT. It got left 80 <2> ; out back about 1.27 or so (oops). ARR 81 <2> ; 1.30 06/07/82 Directory sector buffering added to main DOS buffer queue 82 <2> ; 1.40 06/15/82 Tree structured directories. XENIX Path Parser MKDIR CHDIR 83 <2> ; RMDIR Xenix calls 84 <2> ; 1.41 06/13/82 Made GETBUFFR call PLACEBUF 85 <2> ; 1.50 06/17/82 FATs cached in buffer pool, get FAT pointer calls disappear 86 <2> ; Frees up lots of memory. 87 <2> ; 1.51 06/24/82 BREAKDOWN Revised to do EXACT one sector read/write through 88 <2> ; system buffers 89 <2> ; 1.52 06/30/82 OPEN, CLOSE, READ, WRITE, DUP, DUP2, LSEEK implemented 90 <2> ; 1.53 07/01/82 OPEN CLOSE mod for Xenix calls, saves and gets remote dir 91 <2> ; 1.54 07/11/82 Function calls 1-12 make use of new 2.0 PDB. Init code 92 <2> ; changed to set file handle environment. 93 <2> ; 2.00 08/01/82 Number for IBM release 94 <2> ; 01/19/83 No environ bug in EXEC 95 <2> ; 01/19/83 MS-DOS OEM INT 21 extensions (SET_OEM_HANDLER) 96 <2> ; 01/19/83 Performance bug fix in cooked write to NUL 97 <2> ; 01/27/83 Growcnt fixed for 32-bits 98 <2> ; 01/27/83 Find-first problem after create 99 <2> ; 2.01 02/17/83 International DOS 100 <2> ; 2.10 03/09/83 Start of NETWORK support 101 <2> ; New Buffer structure 102 <2> ; New Sytem file table structure 103 <2> ; FCB moved to internal representation 104 <2> ; DOS re-organized 105 <2> ; 2.11 04/21/83 Continuation of 2.10, preliminary Network 106 <2> ; device interface. 107 <2> ; 2.50 09/12/83 More network stuff 108 <2> ; 109 <2> ; ************************************************************* 110 <2> 111 <2> [list -] 111 ****************** <2> warning: out: ... for DOS Version 4.00 ... [-w+user] 111 ****************** <2> warning: out: BPB.INC... [-w+user] 111 ****************** <2> warning: out: ... CLONE version build switch on ... [-w+user] 111 ****************** <2> warning: out: DEVSYM.INC... [-w+user] 126 <2> 127 <2> %ifndef Installed 128 <2> %iassign Installed 0 129 <2> %endif 130 <2> === Switch to base=001140h -> "START" 131 <2> section START 132 <2> ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING 133 <2> 134 <2> %ifndef DONOBITS 0 00000000 E9[0000] JMP near ptr DOSINIT 136 <2> %else ; DONOBITS 137 <2> db ?,?,? 138 <2> %endif ; DONOBITS 139 <2> 140 <2> ; (no prior section) ; START ENDS 141 <2> === Switch to base=001140h -> "LAST" 142 <2> section LAST 143 <2> Extrn DOSINIT:NEAR 144 <2> ; (no prior section) ; LAST ENDS 145 <2> 7 <1> ;=== Pop trace listing source 8 <1> %include "version.mac" 1 <2> ; Some modules really want TRUE to be 0FFH. Best to let them have their way. 2 <2> TRUE EQU 0FFFFh 3 <2> TRUEBYTE EQU 0FFh 4 <2> FALSE EQU 0 5 <2> 6 <2> ; 7 <2> ; Use the following switches to control cmacros.inc 8 <2> ; 9 <2> ?PLM equ 0 10 <2> ?WIN equ 0 11 <2> 12 <2> memS EQU 1 ; Small model 13 <2> ; 14 <2> ; Use the switches below to produce the standard Microsoft version or the IBM 15 <2> ; version of the operating system 16 <2> ; 17 <2> ; The below chart will indicate how to set the switches to build the various 18 <2> ; versions 19 <2> ; 20 <2> ; IBMVER IBMCOPYRIGHT 21 <2> ; -------------------------------------------------------- 22 <2> ; IBM Version | TRUE TRUE 23 <2> ; -------------------------------------------------------- 24 <2> ; MS Version | FALSE FALSE 25 <2> ; -------------------------------------------------------- 26 <2> ; Clone Version | TRUE FALSE 27 <2> ; 28 <2> IBMVER EQU TRUE 29 <2> IBMCOPYRIGHT EQU FALSE 30 <2> 31 <2> BUFFERFLAG EQU ~ IBMCOPYRIGHT 32 <2> 33 <2> %ifndef MSVER 34 <2> MSVER EQU ~ IBMVER 35 <2> %endif 36 <2> IBM EQU IBMVER 37 <2> ; 38 <2> ; 39 <2> %IF IBMVER 40 <2> %IF IBMCOPYRIGHT 41 <2> %warning out: ... IBM version build switch on ... 42 <2> %ELSE 43 <2> %warning out: ... CLONE version build switch on ... 43 ****************** <2> warning: out: ... CLONE version build switch on ... [-w+user] 44 <2> %ENDIF 45 <2> %ELSE 46 <2> %IFN IBMCOPYRIGHT 47 <2> %warning out: ... MS version build switch on ... 48 <2> %ELSE 49 <2> %warning out: !!!!!!!!! VERSION SWITCHES SET INCORECTLY !!!!!!!!! 50 <2> %warning out: !!!!!!!!! CHECK SETTINGS IN INC\VERSION.INC !!!!!!!!! 51 <2> %ENDIF 52 <2> %ENDIF 53 <2> ; 54 <2> ; 55 <2> ;*************************************************************************** 56 <2> ;* The following switches are for DBCS or SBCS support * 57 <2> ;* * 58 <2> ;* Set INTERNAT EQU TRUE FOR DBCS * 59 <2> ;* Set INTERNAT EQU FALSE FOR SBCS * 60 <2> ;* * 61 <2> ;*************************************************************************** 62 <2> ; 63 <2> IBMJAPVER EQU FALSE ;If TRUE set KANJI true also 64 <2> 65 <2> ; 66 <2> ; Switch INTERNAT for DBCS support 67 <2> ; 68 <2> INTERNAT EQU FALSE 69 <2> ; 70 <2> %IF INTERNAT 71 <2> %ifndef KANJI 72 <2> KANJI EQU TRUE 73 <2> %endif 74 <2> IBMJAPAN EQU TRUE 75 <2> %ELSE 76 <2> %ifndef KANJI 77 <2> KANJI EQU FALSE 78 <2> %endif 79 <2> IBMJAPAN EQU FALSE 80 <2> %ENDIF 81 <2> 82 <2> %ifndef altvect ; avoid jerking off vector.inc 83 <2> ALTVECT EQU FALSE ;Switch to build ALTVECT version 84 <2> %endif 85 <2> 86 <2> ; 87 <2> ; Country code switches 88 <2> ; The default contry code is assumed as USA. 89 <2> ; 90 <2> %IF INTERNAT 91 <2> KOREA EQU TRUE 92 <2> JAPAN EQU FALSE 93 <2> %ELSE 94 <2> KOREA EQU FALSE 95 <2> JAPAN EQU FALSE 96 <2> %ENDIF 97 <2> ; 98 <2> %IF INTERNAT 99 <2> %warning out: Internat(ECS) version build switch on 100 <2> %ENDIF 9 <1> %include "lmacros1.mac" 1 <2> [list -] 1 ****************** <2> warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi] 10 <1> %include "entryseg.nas" 1 <2> === Switch to base=000000h -> "DOSENTRY" 2 <2> section DOSENTRY class=%[DOSENTRY] 11 <1> 12 <1> extern okcallentry, badcallentry 13 <1> === Switch to base=008400h -> "DOSCODECODE" 14 <1> section DOSCODECODE 15 <1> Extrn LeaveDOS:NEAR 16 <1> Extrn BadCall:FAR, OKCall:FAR 17 <1> ; (no prior section) ; DOSCODECODE ENDS 18 <1> === Switch to base=001140h -> "LAST" 19 <1> section LAST 20 <1> extrn SYSBUF:byte 21 <1> ; (no prior section) ; LAST ENDS 22 <1> 23 <1> Break 24 <1> 25 <1> ; 26 <1> ; We need to identify the parts of the data area that are relevant to tasks 27 <1> ; and those that are relevant to the system as a whole. Under 3.0, the system 28 <1> ; data will be gathered with the system code. The process data under 2.x will 29 <1> ; be available for swapping and under 3.0 it will be allocated per-process. 30 <1> ; 31 <1> ; The data that is system data will be identified by [SYSTEM] in the comments 32 <1> ; describing that data item. 33 <1> ; 34 <1> 35 <1> %ifndef Kanji 36 <1> %iassign Kanji 0 37 <1> %endif 38 <1> %ifndef Debug 39 <1> %iassign Debug 0 40 <1> %endif 41 <1> %ifndef Redirector 42 <1> %iassign Redirector 0 43 <1> %endif 44 <1> %ifndef ShareF 45 <1> %iassign ShareF 0 46 <1> %endif 47 <1> === Switch to base=000000h -> "DOSENTRY" 48 <1> section DOSENTRY 49 <1> extern ifsentry 50 <1> === Switch to base=001140h -> "CONSTANTS" 51 <1> section CONSTANTS 52 <1> 53 <1> extrn sfTabl:DWORD 54 <1> 55 <1> ;ORG 0 56 <1> 57 <1> EVEN 58 <1> ; 59 <1> ; WANGO!!! The following word is used by SHARE and REDIR to determin data 60 <1> ; area compatability. This location must be incremented EACH TIME the data 61 <1> ; area here gets mucked with. 62 <1> ; 63 <1> ; Also, do NOT change this position relative to 0. wrt DOSGROUP 64 <1> ; 65 <1> Public MSCT001S,MSCT001E 66 <1> MSCT001S: 0 00000004 0100 I_am DataVersion,WORD,<1> ;AC000; [SYSTEM] version number for DOS DATA 68 <1> 69 <1> %warning "out: WARNING!!! Debug fields are being included!!!" 69 ****************** <1> warning: out: WARNING!!! Debug fields are being included!!! [-w+user] 0 00000006 42554720 DB "BUG " ; THIS FIELD MUST BE EVEN # OF BYTES 0 0000000A 0000 I_am BugTyp,WORD,<0> 0 0000000C 0000 I_am BugLev,WORD,<0> 73 <1> %include "bugtyp.nas" 1 <2> ; SCCSID = @(#)bugtyp.asm 1.1 85/04/09 2 <2> ; 3 <2> ; debugging types and levels for MSDOS 4 <2> ; 5 <2> 6 <2> TypAccess EQU 0001h 7 <2> LevSFN EQU 0000h 8 <2> LevBUSY EQU 0001h 9 <2> 10 <2> TypShare EQU 0002h 11 <2> LevShEntry EQU 0000h 12 <2> LevMFTSrch EQU 0001h 13 <2> 14 <2> TypSect EQU 0004h 15 <2> LevEnter EQU 0000h 16 <2> LevLeave EQU 0001h 17 <2> LevReq EQU 0002h 18 <2> 19 <2> TypSMB EQU 0008h 20 <2> LevSMBin EQU 0000h 21 <2> LevSMBout EQU 0001h 22 <2> LevParm EQU 0002h 23 <2> LevASCIZ EQU 0003h 24 <2> LevSDB EQU 0004h 25 <2> LevVarlen EQU 0005h 26 <2> 27 <2> TypNCB EQU 0010h 28 <2> LevNCBin EQU 0000h 29 <2> LevNCBout EQU 0001h 30 <2> 31 <2> TypSeg EQU 0020h 32 <2> LevAll EQU 0000h 33 <2> 34 <2> TypSyscall EQU 0040h 35 <2> LevLog EQU 0000h 36 <2> LevArgs EQU 0001h 37 <2> 38 <2> TypInt24 EQU 0080h 39 <2> LevLog EQU 0000h 40 <2> 41 <2> TypProlog EQU 0100h 42 <2> LevLog EQU 0000h 43 <2> 44 <2> TypInt EQU 0200h 45 <2> LevLog equ 0000h 46 <2> 47 <2> typFCB equ 0400h 48 <2> LevLog equ 0000h 49 <2> LevCheck equ 0001h 74 <1> 0 0000000E 0000 I_am MYNUM,WORD,<0> ; [SYSTEM] A number that goes with MYNAME 0 00000010 0000 I_am FCBLRU,WORD,<0> ; [SYSTEM] LRU count for FCB cache 0 00000012 0000 I_am OpenLRU,WORD,<0> ; [SYSTEM] LRU count for FCB cache opens 78 <1> ; NOTE: We include the decl of OEM_HANDLER in IBM DOS even though it is not used. 79 <1> ; This allows the REDIRector to work on either IBM or MS-DOS. 80 <1> PUBLIC OEM_HANDLER 0 00000014 FFFFFFFF OEM_HANDLER DD -1 ; [SYSTEM] Pointer to OEM handler code 82 <1> DOSGroup equ DOSGROUP ; NASM port equate 0 00000018 [0000] I_am LeaveAddr,WORD,<> ; [SYSTEM] 0 0000001A 0300 I_am RetryCount,WORD,<3> ; [SYSTEM] Share retries 0 0000001C 0100 I_am RetryLoop,WORD,<1> ; [SYSTEM] Share retries 0 0000001E FFFFFFFF I_am LastBuffer,DWORD,<-1,-1>; [SYSTEM] Buffer queue recency pointer 0 00000022 ???? I_am CONTPOS,WORD ; [SYSTEM] location in buffer of next read 0 00000024 ???? I_am arena_head,WORD ; [SYSTEM] Segment # of first arena in memory 89 <1> ; The following block of data is used by SYSINIT. Do not change the order or 90 <1> ; size of this block 91 <1> PUBLIC SYSINITVAR ; [SYSTEM] 92 <1> SYSINITVAR LABEL WORD ; [SYSTEM] 0 00000026 00000000 I_am DPBHEAD,DWORD,<0,0> ; [SYSTEM] Pointer to head of DPB-FAT list 94 <1> DosGroup equ DOSGROUP ; NASM port equate 0 0000002A [0000]???? I_am sft_addr,DWORD,<,?> ; [SYSTEM] Pointer to first SFT table 0 0000002E ???????? I_am BCLOCK,DWORD ; [SYSTEM] The CLOCK device 0 00000032 ???????? I_am BCON,DWORD ; [SYSTEM] Console device entry points 0 00000036 8000 I_am MAXSEC,WORD,<128> ; [SYSTEM] Maximum allowed sector size 99 <1> %ifdef BUF2 0 00000038 FFFFFFFF dd -1 101 <1> %else 102 <1> I_am BUFFHEAD,DWORD ; [SYSTEM] Pointer to head of buffer queue 103 <1> %endif 0 0000003C ???????? I_am CDSADDR,DWORD ; [SYSTEM] Pointer to curdir structure table 0 00000040 ???????? I_am sftFCB,DWORD ; [SYSTEM] pointer to FCB cache table 0 00000044 ???? I_am KeepCount,WORD ; [SYSTEM] count of FCB opens to keep 0 00000046 ?? I_am NUMIO,BYTE ; [SYSTEM] Number of disk tables 0 00000047 ?? I_am CDSCOUNT,BYTE ; [SYSTEM] Number of CDS structures in above 109 <1> ; A fake header for the NUL device 0 00000048 ???????? I_am NULDEV,DWORD ; [SYSTEM] Link to rest of device list 0 0000004C 0480 DW DEVTYP | ISNULL ; [SYSTEM] Null device attributes 0 0000004E [0000] short_addr SNULDEV ; [SYSTEM] Strategy entry point 0 00000050 [0000] short_addr INULDEV ; [SYSTEM] Interrupt entry point 0 00000052 4E554C2020202020 DB "NUL " ; [SYSTEM] Name of null device 0 0000005A 00 I_am Splices,BYTE,<0> ; [SYSTEM] TRUE => splices being done 0 0000005B 0000 I_am Special_Entries,WORD,<0>; [SYSTEM] address of specail entries ;AN000; 0 0000005D [0000][0000] I_am IFS_DOS_CALL,DWORD, ; [SYSTEM] entry for IFS DOS service ;AN000; 0 00000061 ???????? I_am IFS_HEADER,DWORD ; [SYSTEM] IFS header chain ;AN000; 0 00000065 0000 I_am BUFFERS_PARM1,WORD,<0> ; [SYSTEM] value of BUFFERS= ,m ;AN000; 0 00000067 0000 I_am BUFFERS_PARM2,WORD,<0> ; [SYSTEM] value of BUFFERS= ,n ;AN000; 0 00000069 ?? I_am BOOTDRIVE,BYTE ; [SYSTEM] the boot drive ;AN000; 0 0000006A 00 I_am DDMOVE,BYTE,<0> ; [SYSTEM] 1 if we need DWORD move ;AN000; 0 0000006B 0000 I_am EXT_MEM_SIZE,WORD,<0> ; [SYSTEM] extended memory size ;AN000; 124 <1> 125 <1> %ifndef BUF2 126 <1> PUBLIC HASHINITVAR ; [SYSTEM] ;AN000; 127 <1> HASHINITVAR LABEL WORD ; [SYSTEM] ;AN000; 128 <1> I_am BUF_HASH_PTR,DWORD ; [SYSTEM] buffer Hash table addr ;AN000; 129 <1> I_am BUF_HASH_COUNT,WORD,<1> ; [SYSTEM] number of Hash entries ;AN000; 130 <1> I_am SC_CACHE_PTR,DWORD ; [SYSTEM] secondary cache pointer ;AN000; 131 <1> I_am SC_CACHE_COUNT,WORD,<0> ; [SYSTEM] secondary cache count ;AN000; 132 <1> 133 <1> %IF BUFFERFLAG 134 <1> I_am BUF_EMS_SAFE_FLAG,BYTE,<1> ; indicates whether the page used by buffers is safe or not 135 <1> I_am BUF_EMS_LAST_PAGE,4,<0,0,0,0> ; holds the last page above 640k 136 <1> I_am BUF_EMS_FIRST_PAGE,4,<0,0,0,0> ; holds the first page above 640K 137 <1> I_am BUF_EMS_NPA640,WORD,<0> ; holds the number of pages above 640K 138 <1> 139 <1> %ENDIF 140 <1> 141 <1> I_am BUF_EMS_MODE,BYTE,<-1> ; [SYSTEM] EMS mode ;AN000; 142 <1> I_am BUF_EMS_HANDLE,WORD ; [SYSTEM] buffer EMS handle ;AN000; 143 <1> I_am BUF_EMS_PAGE_FRAME,WORD ,<-1>;[SYSTEM] EMS page frame number ;AN000; 144 <1> I_am BUF_EMS_SEG_CNT,WORD,<1>; [SYSTEM] EMS seg count ;AN000; 145 <1> I_am BUF_EMS_PFRAME,WORD ; [SYSTEM] EMS page frame seg address ;AN000; 146 <1> I_am BUF_EMS_RESERV,WORD,<0> ; [SYSTEM] reserved ;AN000; 147 <1> 148 <1> %IF BUFFERFLAG 149 <1> I_am BUF_EMS_MAP_BUFF,1,<0> ; this is not used to save the state of the 150 <1> ; of the buffers page. this one byte is 151 <1> ; retained to keep the size of this data 152 <1> ; block the same. 153 <1> %ELSE 154 <1> I_am BUF_EMS_MAP_BUFF,12,<0,0,0,0,0,0,0,0,0,0,0,0> ; map buufer ;AN000; 155 <1> %ENDIF 156 <1> %endif 157 <1> 158 <1> %ifdef BUF2 0 0000006D ?? align 2, db ? 0 0000006E 0000 I_am BUF2_Dirty_Count,WORD,0 0 00000070 ???????? I_am BUFFHEAD,DWORD ; [SYSTEM] Pointer to head of buffer queue 0 00000074 ???????? I_am BuffFree,DWORD 163 <1> %endif 164 <1> 165 <1> ; End of SYSINITVar block 166 <1> 0 00000078 ?? _fill 90h, ?, DataVersion - 4 168 <1> 169 <1> ; 170 <1> ; Sharer jump table 171 <1> ; 172 <1> PUBLIC JShare 173 <1> EVEN 174 <1> JShare LABEL DWORD 0 00000090 [0000][0000] DW OFFSET badcallentry, DOSENTRY 0 00000094 [0000][0000] DW OFFSET okcallentry, DOSENTRY ; 1 MFT_enter 0 00000098 [0000][0000] DW OFFSET okcallentry, DOSENTRY ; 2 MFTClose 0 0000009C [0000][0000] DW OFFSET badcallentry, DOSENTRY ; 3 MFTclU 0 000000A0 [0000][0000] DW OFFSET badcallentry, DOSENTRY ; 4 MFTCloseP 0 000000A4 [0000][0000] DW OFFSET badcallentry, DOSENTRY ; 5 MFTCloN 0 000000A8 [0000][0000] DW OFFSET badcallentry, DOSENTRY ; 6 set_block 0 000000AC [0000][0000] DW OFFSET badcallentry, DOSENTRY ; 7 clr_block 0 000000B0 [0000][0000] DW OFFSET okcallentry, DOSENTRY ; 8 chk_block 0 000000B4 [0000][0000] DW OFFSET badcallentry, DOSENTRY ; 9 MFT_get 0 000000B8 [0000][0000] DW OFFSET badcallentry, DOSENTRY ; 10 ShSave 0 000000BC [0000][0000] DW OFFSET badcallentry, DOSENTRY ; 11 ShChk 0 000000C0 [0000][0000] DW OFFSET okcallentry , DOSENTRY ; 12 ShCol 0 000000C4 [0000][0000] DW OFFSET badcallentry, DOSENTRY ; 13 ShCloseFile 0 000000C8 [0000][0000] DW OFFSET badcallentry, DOSENTRY ; 14 ShSU 190 <1> 191 <1> MSCT001E: 192 <1> ; (no prior section) ; CONSTANTS ENDS 193 <1> 194 <1> 10 ;=== Pop trace listing source 11 END === Trace listing source: ../INC/const2.lst 1 ; SCCSID = @(#)const2.asm 1.4 85/07/24 2 ;TITLE CONST2 - More constants data 3 ;NAME CONST2 4 5 [list -] 5 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 5 ****************** warning: out: BPB.INC... [-w+user] 5 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 5 ****************** warning: out: DEVSYM.INC... [-w+user] 12 13 Break 14 15 ; 16 ; We need to identify the parts of the data area that are relevant to tasks 17 ; and those that are relevant to the system as a whole. Under 3.0, the system 18 ; data will be gathered with the system code. The process data under 2.x will 19 ; be available for swapping and under 3.0 it will be allocated per-process. 20 ; 21 ; The data that is system data will be identified by [SYSTEM] in the comments 22 ; describing that data item. 23 ; 24 25 %ifndef Kanji 26 %iassign Kanji 0 27 %endif 28 %ifndef Debug 29 %iassign Debug 0 30 %endif 31 %ifndef Redirector 32 %iassign Redirector 0 33 %endif 34 %ifndef ShareF 35 %iassign ShareF 0 36 %endif 37 === Switch to base=001140h -> "CONSTANTS" 38 section CONSTANTS 39 40 ; 41 ; Table of routines for assignable devices 42 ; 43 ; MSDOS allows assignment if the following standard devices: 44 ; stdin (usually CON input) 45 ; stdout (usually CON output) 46 ; auxin (usually AUX input) 47 ; auxout (usually AUX output) 48 ; stdlpt (usually PRN output) 49 ; 50 ; SPECIAL NOTE: 51 ; Status of a file is a strange idea. We choose to handle it in this 52 ; manner: If we're not at end-of-file, then we always say that we have a 53 ; character. Otherwise, we return ^Z as the character and set the ZERO 54 ; flag. In this manner we can support program written under the old DOS 55 ; (they use ^Z as EOF on devices) and programs written under the new DOS 56 ; (they use the ZERO flag as EOF). 57 58 ; Default SFTs for boot up 59 60 CONST001S equ CONST001s ; NASM port label 61 CONST001E equ CONST001e ; NASM port label 62 Public CONST001S,CONST001E 63 CONST001s label byte 64 PUBLIC sftabl 65 sftabl LABEL DWORD ; [SYSTEM] file table 0 000000CC FFFF DW -1 ; [SYSTEM] link to next table 0 000000CE FFFF DW -1 ; [SYSTEM] link seg to next table 0 000000D0 0500 DW sf_default_number ; [SYSTEM] Number of entries in table 0 000000D2 000000000000000000 DB sf_default_number * sf_entry_struc_size DUP (0); [SYSTEM] 0 000000DB 000000000000000000 0 000000E4 000000000000000000 0 000000ED 000000000000000000 0 000000F6 000000000000000000 0 000000FF 000000000000000000 0 00000108 000000000000000000 0 00000111 000000000000000000 0 0000011A 000000000000000000 0 00000123 000000000000000000 0 0000012C 000000000000000000 0 00000135 000000000000000000 0 0000013E 000000000000000000 0 00000147 000000000000000000 0 00000150 000000000000000000 0 00000159 000000000000000000 0 00000162 000000000000000000 0 0000016B 000000000000000000 0 00000174 000000000000000000 0 0000017D 000000000000000000 0 00000186 000000000000000000 0 0000018F 000000000000000000 0 00000198 000000000000000000 0 000001A1 000000000000000000 0 000001AA 000000000000000000 0 000001B3 000000000000000000 0 000001BC 000000000000000000 0 000001C5 000000000000000000 0 000001CE 000000000000000000 0 000001D7 000000000000000000 0 000001E0 000000000000000000 0 000001E9 000000000000000000 0 000001F2 00000000000000 70 71 ; the next two variables relate to the position of the logical stdout/stdin 72 ; cursor. They are only meaningful when stdin/stdout are assigned to the 73 ; console. 0 000001F9 ?? I_am CARPOS,BYTE ; [SYSTEM] cursor position in stdin 0 000001FA ?? I_am STARTPOS,BYTE ; [SYSTEM] position of cursor at beginning of buffered input call 76 0000012F I_am INBUF,128 ; [SYSTEM] general device input buffer 77 000001AF I_am CONBUF,131 ; [SYSTEM] The rest of INBUF and console buffer 78 0 000002FE ?? I_am PFLAG,BYTE ; [SYSTEM] printer echoing flag 0 000002FF ?? I_am VERFLG,BYTE ; [SYSTEM] Initialize with verify off 0 00000300 03 I_am CharCo,BYTE,<00000011B> ; [SYSTEM] Allows statchks every 4 chars... 0 00000301 2F I_am chSwitch,BYTE,<'/'> ; [SYSTEM] current switch character 0 00000302 ?? I_am AllocMethod,BYTE ; [SYSTEM] how to alloc first(best)last 0 00000303 00 I_am fShare,BYTE,<0> ; [SYSTEM] TRUE => sharing installed 0 00000304 01 I_am DIFFNAM,BYTE,<1> ; [SYSTEM] Indicates when MYNAME has 86 ; changed 0 00000305 202020202020202020 I_am MYNAME,16,<32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32> 0 0000030E 20202020202020 88 ; [SYSTEM] My network name 89 90 91 ; 92 ; The following table is a list of addresses that the sharer patches to be 93 ; PUSH AX to enable the critical sections 94 ; 95 PUBLIC CritPatch 96 CritPatch LABEL WORD 97 %macro critpatchentry 1.nolist 98 %IF (! REDIRECTOR) && (! SHAREF) 99 Short_Addr patch_dosdata_E%1 100 Short_Addr patch_dosdata_L%1 101 %ELSE 102 DW 0 103 DW 0 104 %ENDIF 105 %endmacro 0 00000315 [0000][0000] critpatchentry critDisk 0 00000319 [0000][0000] critpatchentry critDevice 0 0000031D 0000 DW 0 109 110 ; 111 ; WARNING!!! PRINT and PSPRINT *REQUIRE* ErrorMode to precede INDOS. 112 ; Also, IBM server 1.0 requires this also. 113 ; 0 0000031F 00 EVEN ; Force swap area to start on word boundry 115 PUBLIC SWAP_START 116 SWAP_START LABEL BYTE 0 00000320 ?? I_am ErrorMode,BYTE ; Flag for INT 24 processing 0 00000321 00 I_am INDOS,BYTE,<0> ; DOS status for interrupt processing 0 00000322 FF I_am WPErr,BYTE,<-1> ; Write protect error flag 0 00000323 ?? I_am EXTERR_LOCUS,BYTE ; Extended Error Locus 0 00000324 0000 I_am EXTERR,WORD,<0> ; Extended Error code 122 123 ;WARNING Following two bytes Accessed as word in $GetExtendedError 0 00000326 ?? I_am EXTERR_ACTION,BYTE ; Extended Error Action 0 00000327 ?? I_am EXTERR_CLASS,BYTE ; Extended Error Class 126 ; end warning 127 0 00000328 ???????? I_am EXTERRPT,DWORD ; Extended Error pointer 0 0000032C 8000???? I_am DMAADD,DWORD,<80h,?> ; User's disk transfer address (disp/seg) 0 00000330 ???? I_am CurrentPDB,WORD ; Current process identifier 0 00000332 ???? I_am ConC_spsave,WORD ; saved SP before ^C 0 00000334 ???? I_am exit_code,WORD ; exit code of last proc. 0 00000336 ?? I_am CURDRV,BYTE ; Default drive (init A) 0 00000337 00 I_am CNTCFLAG,BYTE,<0> ; ^C check in dispatch disabled 135 ; F.C. 2/17/86 0 00000338 00 I_am CPSWFLAG,BYTE,<0> ; Code Page Switching Flag DOS 4.00 0 00000339 00 I_am CPSWSAVE,BYTE,<0> ; copy of above in case of ABORT 138 EVEN 139 PUBLIC Swap_Always 140 Swap_Always LABEL BYTE 0 0000033A ???? I_am USER_IN_AX,WORD ; User INPUT AX value (used for 142 ; extended error type stuff. NOTE: 143 ; does not have Correct value on 144 ; 1-12, OEM, Get/Set CurrentPDB, 145 ; GetExtendedError system calls 0 0000033C 0000 I_am PROC_ID,WORD,<0> ; PID for sharing (0 = local) 0 0000033E 0000 I_am USER_ID,WORD,<0> ; Machine for sharing (0 = local) 0 00000340 ???? I_am FirstArena,WORD ; first free block found 0 00000342 ???? I_am BestArena,WORD ; best free block found 0 00000344 ???? I_am LastArena,WORD ; last free block found 0 00000346 ???? I_am EndMem,WORD ; End of memory used in DOSINIT 0 00000348 ???? I_am LASTENT,WORD ; Last entry for directory search 153 0 0000034A 00 I_am FAILERR,BYTE,<0> ; NZ if user did FAIL on I 24 0 0000034B 00 I_am ALLOWED,BYTE,<0> ; Allowed I 24 answers (see allowed_) 0 0000034C ?? I_am NoSetDir,BYTE ; true -> do not set directory 0 0000034D ?? I_am DidCTRLC,BYTE ; true -> we did a ^C exit 0 0000034E ?? I_am SpaceFlag,BYTE ; true -> embedded spaces are allowed in FCB 159 ; Warning! The following items are accessed as a WORD in TIME.ASM 0 0000034F 00 EVEN 0 00000350 00 I_am DAY,BYTE,<0> ; Day of month 0 00000351 00 I_am MONTH,BYTE,<0> ; Month of year 0 00000352 0000 I_am YEAR,WORD,<0> ; Year (with century) 0 00000354 FFFF I_am DAYCNT_DOS,WORD,<-1> ; Day count from beginning of year 0 00000356 00 I_am WEEKDAY,BYTE,<0> ; Day of week 166 ; end warning 0 00000357 ?? I_am CONSWAP,BYTE ; TRUE => console was swapped during device read 0 00000358 01 I_am IDLEINT,BYTE,<1> ; TRUE => idle int is allowed 0 00000359 00 I_am fAborting,BYTE,<0> ; TRUE => abort in progress 170 171 ; Combination of all device call parameters 172 PUBLIC DEVCALL ; 173 DEVCALL: 174 SRHEAD_size equ SRHEAD_struc_size ; NASM port equate 175 istruc SRHEAD 0 0000035A ?? iend 177 PUBLIC CALLUNIT 178 CALLUNIT LABEL BYTE ; unit number for disk 179 CALLFLSH LABEL WORD ; 0 00000367 ?? I_am CALLMED,BYTE ; media byte 181 CALLBR LABEL DWORD ; 182 PUBLIC CALLXAD ; 183 CALLXAD LABEL DWORD ; 0 00000368 ?? I_am CALLRBYT,BYTE ; 185 PUBLIC CALLVIDM ; 186 CALLVIDM LABEL DWORD ; 0 00000369 ?????? DB 3 DUP(?) ; 188 CallBPB equ CALLBPB ; NASM port label 189 PUBLIC CallBPB ; 190 CALLBPB LABEL DWORD ; 0 0000036C ???? I_am CALLSCNT,WORD ; 192 PUBLIC CALLSSEC 193 CALLSSEC LABEL WORD ; 0 0000036E ???? DW ? ; 0 00000370 ???????? I_am CALLVIDRW,DWORD ; 196 ; 0 00000374 ???????? I_am CALLNEWSC,DWORD ; starting sector for >32mb 0 00000378 ???????? I_am CALLDEVAD,DWORD ; stash for device entry point 199 ; 200 ; Same as above for I/O calls ; 201 ; 202 IOCall equ IOCALL ; NASM port label 203 PUBLIC IOCall ; 204 IOCALL: 205 istruc SRHEAD 0 0000037C ?? iend 207 IOFLSH LABEL WORD ; 208 PUBLIC IORCHR ; 209 IORCHR LABEL BYTE ; 0 00000389 ?? I_am IOMED,BYTE ; 0 0000038A ???????? I_am IOXAD,DWORD ; 0 0000038E ???? I_am IOSCNT,WORD ; 0 00000390 ???? I_am IOSSEC,WORD ; 214 ; Call struct for DSKSTATCHK ; 0 00000392 0E00 I_am DSKSTCALL,2, ; 0 00000394 05 I_am DSKSTCOM,1, ; 0 00000395 ???? I_am DSKSTST,WORD ; 0 00000397 0000000000000000 DB 8 DUP (0) ; 0 0000039F ?? I_am DSKCHRET,BYTE ; 0 000003A0 [0000] short_addr DEVIOBUF ; 0 000003A2 ???? DW ? ; DOS segment set at Init 0 000003A4 0100 I_AM DSKSTCNT,WORD,<1> ; 0 000003A6 0000 DW 0 ; 224 0 000003A8 ?? I_am CreatePDB,BYTE ; flag for creating a process 226 PUBLIC Lock_Buffer ; 227 Lock_Buffer LABEL DWORD ;MS. DOS Lock Buffer for Ext Lock 0 000003A9 ???????? DD ? ;MS. position 0 000003AD ???????? DD ? ;MS. length 230 CONST001e label byte 231 232 ; (no prior section) ; CONSTANTS ENDS 233 END === Trace listing source: ../INC/msdata.lst 1 ; SCCSID = @(#)ibmdata.asm 1.1 85/04/10 2 ; 3 ; DATA Segment for DOS. 4 ; 5 6 ;page 255,132 7 8 [list -] 8 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 8 ****************** warning: out: DEVSYM.INC... [-w+user] 29 30 ;TITLE IBMDATA - DATA segment for DOS 31 ;NAME IBMDATA 32 33 %iassign installed TRUE 34 35 ;=== Push trace listing source: ms_data.nas 36 %include "ms_data.nas" ; NASM included file 1 <1> %include "nasmorg.mac" 1 <2> 2 <2> %if 0 3 <2> 4 <2> NASM macros to replace JWasm org directive 5 <2> 2024 by E. C. Masloch, Public Domain 6 <2> 7 <2> %endif 8 <2> 9 <2> %imacro org 1-2.nolist db 0 10 <2> times (%1) - ($ - $$) %2 11 <2> %endmacro 2 <1> 3 <1> ; SCCSID = @(#)msdata.asm 1.8 85/09/12 4 <1> %ifndef Kanji 5 <1> %iassign Kanji 0 6 <1> %endif 7 <1> %ifndef Debug 8 <1> %iassign Debug 0 9 <1> %endif 10 <1> %ifndef Redirector 11 <1> %iassign Redirector 0 12 <1> %endif 13 <1> %ifndef ShareF 14 <1> %iassign ShareF 0 15 <1> %endif 16 <1> 17 <1> Break 18 <1> 19 <1> %define RECORDED none, none 20 <1> %macro record 2.nolist 21 <1> %%before: 22 <1> %1 23 <1> %%after: 24 <1> %assign %%i 0 25 <1> %rep %%after - %%before 26 <1> %assign %%offset %%before + %%i - MSDAT001S 27 <1> %xdefine RECORDED RECORDED, %%offset, %2 28 <1> %assign %%i %%i + 1 29 <1> %endrep 30 <1> %endmacro 31 <1> === Switch to base=001140h -> "DATA" 32 <1> section DATA 33 <1> ; Init code overlaps with data area below 34 <1> 35 <1> absolute $ 36 <1> 37 <1> ORG 0, resb 1 38 <1> MSDAT001E equ MSDAT001e ; NASM port label 39 <1> PUBLIC MSDAT001S,MSDAT001E 40 <1> MSDAT001S label byte 41 <1> 0 000003B6 ???????????? I_am_nobits TIMEBUF,6 ; Time read from clock device 0 000003BC ???? I_am_nobits DEVIOBUF,2 ; Buffer for I/O under file assignment 44 <1> ; 45 <1> ; The following areas are used as temp buffer in EXEC system call 46 <1> ; 47 00000008 <1> I_am_nobits OPENBUF,128 ; buffer for name operations 48 00000088 <1> I_am_nobits RenBuf,128 ; buffer for rename destination 49 <1> ; Buffer for search calls 50 00000108 <1> I_am_nobits SEARCHBUF,53 ; internal search buffer 51 0000013D <1> I_am_nobits DummyCDS,curdirLen 52 <1> ; 53 <1> ; End of contiguous buffer 54 <1> ; 55 <1> 56 <1> ; 57 <1> ; Temporary directory entry for use by many routines. Device directory 58 <1> ; entries (bogus) are built here. 59 <1> ; 60 <1> DevFCB equ DEVFCB ; NASM port label 61 <1> PUBLIC DevFCB 62 <1> DEVFCB LABEL BYTE ; Uses NAME1, NAME2, combined 63 <1> ; WARNING.. do not alter position of NAME1 relative to DEVFCB 64 <1> ; without first examining BUILD_DEVICE_ENT. Look carefully at DOS_RENAME 65 <1> ; as well as it is the only guy who uses NAME2 and DESTSTART. 66 00000195 <1> I_am_nobits NAME1,12 ; File name buffer 67 000001A1 <1> I_am_nobits NAME2,13 ; 0 00000564 ???? I_am_nobits DESTSTART,WORD ; 69 <1> DIR_ENTRY_struc_size equ dir_entry_struc_size ; NASM port equate 0 00000566 ?????????? DB ((DIR_ENTRY_struc_size) - ($ - DEVFCB)) DUP (?) 71 <1> ; 72 <1> ; End Temporary directory entry. 73 <1> ; 0 0000056B ?? I_am_nobits ATTRIB,BYTE ; storage for file attributes 0 0000056C ?? I_am_nobits EXTFCB,BYTE ; TRUE => extended FCB in use 0 0000056D ?? I_am_nobits SATTRIB,BYTE ; Storage for search attributes 77 <1> %if EXTFCB + 1 != SATTRIB ; used in macro2.nas 78 <1> %error Unexpected layout 79 <1> %endif 0 0000056E ?? I_am_nobits open_access,BYTE ; access of open system call 0 0000056F ?? I_am_nobits FoundDel,BYTE ; true => file was deleted 0 00000570 ?? I_am_nobits Found_dev,BYTE ; true => search found a device 0 00000571 ?? I_am_nobits fSplice,BYTE ; true => do a splice in transpath 0 00000572 ?? I_am_nobits fSharing,BYTE ; TRUE => no redirection 0 00000573 ?? I_am_nobits SECCLUSPOS,BYTE ; Position of first sector within cluster 0 00000574 ?? I_am_nobits TRANS,BYTE ; 0 00000575 ?? I_am_nobits READOP,BYTE ; 0 00000576 ?? I_am_nobits THISDRV,BYTE ; 0 00000577 ?? I_am_nobits CLUSFAC,BYTE ; 0 00000578 ?? I_am_nobits CLUSSPLIT,BYTE ; 0 00000579 ?? I_am_nobits INSMODE,BYTE ; true => insert mode in buffered read 0 0000057A ?? I_am_nobits cMeta,BYTE ; count of meta'ed components found 0 0000057B ?? I_am_nobits VOLID,BYTE ; 0 0000057C ?? I_am_nobits exit_type,BYTE ; type of exit... 95 <1> 0 0000057D ?? record alignb 2, 90h 97 <1> 98 <1> ; WARNING - the following two items are accessed as a word 0 0000057E ?? I_am_nobits CREATING,BYTE ; true => creating a file 0 0000057F ?? I_am_nobits DELALL,BYTE ; true => deleting everything 101 <1> 0 00000580 ???????? I_am_nobits EXITHOLD,DWORD ; Temp location for proc terminate 0 00000584 ???? I_am_nobits user_SP,WORD ; User SP for system call 0 00000586 ???? I_am_nobits user_SS,WORD ; User SS for system call 0 00000588 ???? I_am_nobits CONTSTK,WORD ; 0 0000058A ???????? I_am_nobits THISDPB,DWORD ; 0 0000058E ???? I_am_nobits CLUSSAVE,WORD ; 0 00000590 ???????? I_am_nobits CLUSSEC,DWORD ;>32mb AC0000 0 00000594 ???? I_am_nobits PREREAD,WORD ; 0 means preread; 1 means optional 0 00000596 ???? I_am_nobits FATBYT,WORD ; Used by ALLOCATE 0 00000598 ???? I_am_nobits FATBYTE,WORD ; Used by $SLEAZEFUNC 0 0000059A ???????? I_am_nobits DEVPT,DWORD ; 0 0000059E ???????? I_am_nobits THISSFT,DWORD ; Address of user SFT 0 000005A2 ???????? I_am_nobits THISCDS,DWORD ; Address of current CDS 0 000005A6 ???????? I_am_nobits THISFCB,DWORD ; Address of user FCB 0 000005AA ???? record {I_am_nobits SFN,WORD,<-1>}, 255 ; SystemFileNumber found for accessfile 0 000005AC ???? I_am_nobits JFN,WORD ; JobFileNumber found for accessfile 0 000005AE ???????? I_am_nobits PJFN,DWORD ; PointerJobFileNumber found for accessfile 0 000005B2 ???? I_am_nobits WFP_START,WORD ; 0 000005B4 ???? I_am_nobits REN_WFP,WORD ; 0 000005B6 ???? I_am_nobits CURR_DIR_END,WORD ; 0 000005B8 ???? I_am_nobits NEXTADD,WORD ; 0 000005BA ???? I_am_nobits LASTPOS,WORD ; 0 000005BC ???? I_am_nobits CLUSNUM,WORD ; 0 000005BE ???????? I_am_nobits DIRSEC,DWORD ;>32mb AC0000 0 000005C2 ???? I_am_nobits DIRSTART,WORD ; 0 000005C4 ???????? I_am_nobits SECPOS,DWORD ;>32mb Position of first sector accessed 0 000005C8 ???????? I_am_nobits VALSEC,DWORD ;>32mb Number of valid (previously written) 129 <1> ; sectors 0 000005CC ???? I_am_nobits BYTSECPOS,WORD ; Position of first byte within sector 0 000005CE ???????? I_am_nobits BYTPOS,4 ; Byte position in file of access 0 000005D2 ???? I_am_nobits BYTCNT1,WORD ; No. of bytes in first sector 0 000005D4 ???? I_am_nobits BYTCNT2,WORD ; No. of bytes in last sector 0 000005D6 ???? I_am_nobits SECCNT_DOS,WORD ; No. of whole sectors 0 000005D8 ???? I_am_nobits ENTFREE,WORD ; 0 000005DA ???? I_am_nobits ENTLAST,WORD ; 0 000005DC ???? I_am_nobits NXTCLUSNUM,WORD ; 0 000005DE ???????? I_am_nobits GROWCNT,DWORD ; 0 000005E2 ???????? I_am_nobits CURBUF,DWORD ; 0 000005E6 ???????? I_am_nobits CONSft,DWORD ; SFT of console swapped guy. 0 000005EA ???? I_am_nobits SaveBX,WORD ; 0 000005EC ???? I_am_nobits SaveDS,WORD ; 0 000005EE ???? I_am_nobits restore_tmp,WORD ; return address for restore world 0 000005F0 ???? I_am_nobits NSS,WORD 0 000005F2 ???? I_am_nobits NSP,WORD 0 000005F4 ???? I_am_nobits EXTOPEN_FLAG,WORD,<0> ;FT. extended open input flag ;AN000; 0 000005F6 ?? I_am_nobits EXTOPEN_ON,BYTE,<0> ;FT. extended open conditional flag ;AN000; 0 000005F7 ???? I_am_nobits EXTOPEN_IO_MODE,WORD,<0>;FT. extende open io mode ;AN000; 0 000005F9 ???? I_am_nobits SAVE_DI,WORD ;FT. extende open saved DI ;AN000; 0 000005FB ???? I_am_nobits SAVE_ES,WORD ;FT. extende open saved ES ;AN000; 0 000005FD ???? I_am_nobits SAVE_DX,WORD ;FT. extende open saved DX ;AN000; 0 000005FF ???? I_am_nobits SAVE_CX,WORD ;FT. extende open saved CX ;AN000; 0 00000601 ???? I_am_nobits SAVE_BX,WORD ;FT. extende open saved BX ;AN000; 0 00000603 ???? I_am_nobits SAVE_SI,WORD ;FT. extende open saved SI ;AN000; 0 00000605 ???? I_am_nobits SAVE_DS,WORD ;FT. extende open saved DS ;AN000; 0 00000607 ???? I_am_nobits HIGH_SECTOR,WORD,<0> ;>32mb higher sector # ;AN000; 0 00000609 ???? I_am_nobits HIGH_SECTOR_TEMP,WORD,<0>;>32mb high sector # ;AN000; 0 0000060B ?? I_am_nobits DISK_FULL,BYTE ;>32mb indicating disk full when 1 ;AN000; 0 0000060C ???? I_am_nobits TEMP_VAR,WORD ; temporary variable for everyone ;AN000; 0 0000060E ???? I_am_nobits TEMP_VAR2,WORD ; temporary variable 2 for everyone ;AN000; 0 00000610 ?? I_am_nobits DrvErr,BYTE ; used to save drive error ;AN000; 0 00000611 ???? I_am_nobits DOS34_FLAG,WORD,<0> ; common flag for DOS 3.4 ;AN000; 0 00000613 ???????? I_am_nobits NO_FILTER_PATH,DWORD ; pointer to orignal path ;AN000; 0 00000617 ???????? I_am_nobits NO_FILTER_DPATH,DWORD ; pointer to orignal path of destination;AN000; 0 0000061B ???? I_am_nobits Callback_SS,WORD ;AN000; call back SS for system call 0 0000061D ???? I_am_nobits Callback_SP,WORD ;AN000; call back SP for system call 0 0000061F ?? I_am_nobits Callback_flag,BYTE,<0> ;AN000; call back flag 168 <1> 169 <1> 170 <1> ; make those pushes fast!!! 171 <1> record alignb 2, 90h 172 <1> StackSize equ 180h ; gross but effective 173 <1> ;;;StackSize = 300h ; This is a "trial" change IBM hasn't 174 <1> ;;; ; made up their minds about 175 <1> 176 <1> ; 177 <1> ; WARNING!!!! DskStack may grow into AUXSTACK due to interrupt service. 178 <1> ; This is NO problem as long as AUXSTACK comes immediately before DSKSTACK 179 <1> ; 180 <1> 181 <1> PUBLIC RENAMEDMA,AuxStack,DskStack,IOStack 182 <1> RENAMEDMA LABEL BYTE ; See DOS_RENAME 183 <1> 184 0000026A <1> DB StackSize DUP (?) ; 185 <1> AuxStack LABEL BYTE 186 <1> 187 000003EA <1> DB StackSize DUP (?) ; 188 <1> DskStack LABEL BYTE 189 <1> 190 0000056A <1> DB StackSize DUP (?) ; 191 <1> IOStack LABEL BYTE 192 <1> 193 <1> 194 <1> ; patch space for Boca folks. 195 <1> ; Say What????!!! This does NOT go into the swappable area! 196 <1> ; NOTE: We include the decl of ibmpatch in ms-dos even though it is not needed. 197 <1> ; This allows the REDIRector to work on either IBM or MS-DOS. 198 <1> 199 <1> PUBLIC IBMPATCH 200 <1> IBMPATCH label byte 0 00000AA0 ?? I_am_nobits PRINTER_FLAG,BYTE,<0> ; [SYSTEM] status of PRINT utility 0 00000AA1 ?? I_am_nobits VOLCHNG_FLAG,BYTE,<0> ; [SYSTEM] true if volume label created 0 00000AA2 ?? I_am_nobits VIRTUAL_OPEN,BYTE,<0> ; [SYSTEM] non-zero if we opened a virtual file 204 <1> 205 <1> ; Following 4 variables moved to MSDATA.asm from MSTABLE.asm (P4986) 0 00000AA3 ?? I_am_nobits FSeek_drive,BYTE ;AN000; fastseek drive # 0 00000AA4 ???? I_am_nobits FSeek_firclus,WORD ;AN000; fastseek first cluster # 0 00000AA6 ???? I_am_nobits FSeek_logclus,WORD ;AN000; fastseek logical cluster # 0 00000AA8 ???? I_am_nobits FSeek_logsave,WORD ;AN000; fastseek returned log clus # 210 <1> %ifndef BUF2 211 <1> record {I_am_nobits ACT_PAGE,WORD,<-1>}, 255 ;;;;;;; ;BL ; active EMS page ;AN000; 212 <1> %endif 213 <1> 214 <1> ; lDOS extensions 215 <1> record alignb 2, 90h 0 00000AAA ???? I_am_nobits CLUSTER_FACTOR_EDR,WORD 0 00000AAC ???? I_am_nobits CLUSTER_NEXT_EDR,WORD 0 00000AAE ???? I_am_nobits dosdata_to_doscode,WORD 219 <1> dosdata_to_doscode_segment equ dosdata_to_doscode 220 <1> global dosdata_to_doscode_segment 0 00000AB0 ???? record {I_am_nobits first_umcb, word, <-1>}, 255 0 00000AB2 ?? I_am_nobits enable_uma, byte 0 00000AB3 ?? I_am_nobits alloc_strategy_ext, byte 0 00000AB4 ???? I_am_nobits first_hmcb, word 0 00000AB6 ?? I_am_nobits doslocation3306, byte 0 00000AB7 ?? I_am_nobits doslocation3001, byte 0 00000AB8 ???? I_am_nobits backdoor_free_mcb_exec, word 228 <1> 229 <1> SWAP_END LABEL BYTE 230 <1> PUBLIC SWAP_END 231 <1> 232 <1> ; THE FOLLOWING BYTE MUST BE HERE, IMMEDIATELY FOLLOWING SWAP_END. IT CANNOT 233 <1> ; BE USED. If the size of the swap data area is ODD, it will be rounded up 234 <1> ; to include this byte. 0 00000ABA ?? DB ? 236 <1> 237 <1> ibmpatch equ IBMPATCH ; NASM port label 238 00000705 <1> DB (512+80+32-(SWAP_END-ibmpatch)) DUP (?) 239 <1> 240 <1> MSDAT001e label byte 241 <1> 242 <1> ;.xall 243 <1> 244 <1> ; (no prior section) ; DATA ENDS 245 <1> 246 <1> 37 ;=== Pop trace listing source 38 ;=== Push trace listing source: msinit.nas 39 %include "msinit.nas" ; NASM included file 1 <1> ; SCCSID = @(#)msinit.asm 1.2 85/07/23 2 <1> ; TITLE MSINIT.ASM -- MS-DOS INITIALIZATION CODE 3 <1> ; AN000 version 4.0 Jan. 1988 4 <1> ; AN007 PTM 3957 - fake version for IBMCACHE.COM 5 <1> ; AN008 PTM 4070 - fake version for MS WINDOWS 6 <1> [list -] 6 ****************** <1> warning: out: ... CLONE version build switch on ... [-w+user] 6 ****************** <1> warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi] 14 <3> [list -] 14 <2> [list -] 11 <1> %include "entrysw.mac" 1 <2> 2 <2> DOSENTRYADJUSTSEGMENT equ 70h - 26h 3 <2> DOSENTRYADJUSTOFFSET equ DOSENTRYADJUSTSEGMENT * 16 12 <1> %include "lstruct.mac" 1 <2> [list -] 13 <2> [list -] 13 <1> %include "entryseg.nas" 1 <2> === Switch to base=000000h -> "DOSENTRY" 2 <2> section DOSENTRY class=%[DOSENTRY] === Switch to base=000000h -> "DOSENTRY" 3 <2> section DOSENTRY 14 <1> [list +] 15 <1> 16 <1> extern i20, i21, i25, i26, i27, i2F, call5, i23, i24, entry_iret, i31 17 <1> 18 <1> I_need DMAAdd,DWORD ; current dma address 19 <1> I_need DPBHead,DWORD ; long pointer to DPB chain 20 <1> I_need SFT_Addr,DWORD ; pointer to open file list 21 <1> I_need NumIO,BYTE ; number of physical drives 22 <1> I_need BuffHead,DWORD ; pointer to buffer chain 23 <1> I_need EndMem,WORD ; first unavailable address in memory 24 <1> I_need CurrentPDB,WORD ; current process ID 25 <1> I_need CreatePDB,BYTE ; TRUE => create a new PDB 26 <1> I_need Arena_Head,WORD ; paragraph address of head of arena 27 <1> I_need sfTabl,BYTE ; internal file table 28 <1> I_need SysInitVar,BYTE ; label for internal structures 29 <1> I_need NulDev,DWORD ; long pointer to device chain 30 <1> I_need BCon,DWORD ; pointer to console device 31 <1> I_need BClock,DWORD ; pointer to clock device 32 <1> I_need CallUnit,BYTE ; unit field in dd packet 33 <1> I_need CallBPB,DWORD ; returned BPB from DD 34 <1> I_need Maxsec,WORD 35 <1> I_need Dskchret,BYTE 36 <1> I_need Devcall,BYTE 37 <1> i_need Header,BYTE 38 <1> I_need JShare,DWORD 39 <1> I_need COUNTRY_CDPG,BYTE ; country info table, DOS 3.3 40 <1> I_need SysInitTable,BYTE ; sys init table for SYSINIT 41 <1> I_need FastOpenTable,BYTE ; table for FASTOPEN 42 <1> I_need FETCHI_TAG,WORD ; TAG CHECK 43 <1> I_need Special_Entries,WORD ; address of special entries ;AN007; 44 <1> I_need IFS_DOS_CALL,DWORD ; IFS IBMDOS CALL entry ;AN000; 45 <1> I_need HASHINITVAR,WORD ; hash table variables ;AN000; 46 <1> I_need Packet_Temp,WORD ; used for initial Hash table;AN000; 47 <1> I_need BUF_HASH_PTR,DWORD ; used for initial Hash table;AN000; 48 <1> I_need SWAP_ALWAYS_AREA,DWORD ; swap always area addr ;AN000; 49 <1> I_need SWAP_ALWAYS_AREA_LEN,WORD; swap always area length ;AN000; 50 <1> I_need SWAP_IN_DOS,DWORD ; swap in dos area ;AN000; 51 <1> I_need SWAP_IN_DOS_LEN,WORD ; swap in dos area length ;AN000; 52 <1> I_need SWAP_AREA_LEN,WORD ; swap area length ;AN000; 53 <1> I_need SWAP_START,BYTE ; swap start addr ;AN000; 54 <1> I_need SWAP_ALWAYS,BYTE ; swap always addr ;AN000; 55 <1> I_need Hash_Temp,WORD ; temporary Hash table ;AN000; 56 <1> 57 <1> i_need CallDevAd,DWORD 58 <1> === Switch to base=001140h -> "DATA" 59 <1> section DATA 60 <1> ; ORG 0 ; reset to beginning of data segment 61 <1> 62 <1> %ifdef DONOBITS 63 <1> [list -] 64 <1> %endif 65 <1> 66 <1> %ifndef DONOBITS 67 <1> 68 <1> Public MSINI001S,MSINI001E 69 <1> MSINI001S label byte 70 <1> MSINI001E label byte 71 <1> 72 <1> ASSUME CS:DOSGROUP,SS:NOTHING 73 <1> 74 <1> === Switch to base=002530h -> "SYSINITSEG" 75 <1> section SYSINITSEG PUBLIC class=INIT align=16 === Switch to base=002530h -> "SYSINITTRAIL" 76 <1> section SYSINITTRAIL PUBLIC class=INIT 77 <1> 78 <1> group SYSINITGROUP SYSINITSEG SYSINITTRAIL 79 <1> 80 <1> extern doscode_retf 81 <1> extern dosdata_to_doscode 82 <1> 83 <1> %imacro neartransfer 1.nolist 84 <1> extern %1 85 <1> call transfer_sysinitseg_to_doscode 86 <1> jmp strict short %%skip 87 <1> dw %1 88 <1> %%skip: 89 <1> %endmacro 90 <1> 91 <1> transfer_sysinitseg_to_doscode: ; near call ip: in_ip_out_cs 0 00005A90 50 push ax ; in_ax_out_ip 0 00005A91 B8[0000] mov ax, doscode_retf 0 00005A94 50 push ax ; out_retf 0 00005A95 50 push ax ; out_destination + 2 0 00005A96 50 push ax ; out_destination + 0 97 <1> lframe 0 98 <1> lpar word, in_ip_out_cs 99 <1> lpar word, in_ax_out_ip 100 <1> lpar word, out_retf 101 <1> lpar dword, out_destination 0 00005A97 5589E5 lenter 0 00005A9A 1E push ds 0 00005A9B 56 push si 0 00005A9C 8CCE mov si, cs ; si = cs 0 00005A9E 87760A xchg si, word [bp + ?in_ip_out_cs] 107 <1> ; set cs, get ip 0 00005AA1 56 push si ; preserve ip for later 0 00005AA2 AD lodsw ; skip jmp short 0 00005AA3 2EAD cs lodsw ; get destination 0 00005AA5 894602 mov word [bp + ?out_destination + 0], ax 112 <1> ; set destination 0 00005AA8 E81000 call getdosdata 0 00005AAB 8ED8 mov ds, ax 0 00005AAD A1[F806] mov ax, word [dosdata_to_doscode] 116 <1> ; ax => DOSCODE 0 00005AB0 894604 mov word [bp + ?out_destination + 2], ax 118 <1> ; => DOSCODE 0 00005AB3 58 pop ax 0 00005AB4 874608 xchg ax, word [bp + ?in_ax_out_ip] 121 <1> ; ax = original ax, set out ip 0 00005AB7 5E pop si 0 00005AB8 1F pop ds 0 00005AB9 5D lleave 0 00005ABA CB retf 126 <1> 127 <1> 128 <1> global sysinit_getdosdata 129 <1> sysinit_getdosdata: 130 <1> getdosdata: 0 00005ABB 1E push ds 0 00005ABC B80000 mov ax, 0 0 00005ABF 8ED8 mov ds, ax ; ds => IVT 0 00005AC1 A1C600 mov ax, [31h * 4 + 2] ; ds => DOSDATA 0 00005AC4 1F pop ds 0 00005AC5 C3 retn 137 <1> 138 <1> 139 <1> MOVDPB: 140 <1> DOSAssume CS,,"MovDPB" 0 00005AC6 FC CLD 142 <1> sft_addr equ SFT_Addr ; NASM port label 0 00005AC7 8C1E[0200] MOV WORD PTR [sft_addr+2], ds 144 <1> NUMIO equ NumIO ; NASM port label 0 00005ACB 8A0E[0000] MOV CL,[NUMIO] ; Number of DPBs 0 00005ACF 30ED XOR CH,CH 147 <1> DPBHEAD equ DPBHead ; NASM port label 0 00005AD1 BEFFFF mov si, -1 0 00005AD4 E30F jcxz @F 0 00005AD6 C536[0000] lds SI, [DPBHEAD]; Address of first DPB 0 00005ADA 56 push si 152 <1> SETFINDPB: 0 00005ADB C64418FF MOV byte [SI + dpb_first_access],-1 ; Never accessed before 0 00005ADF 83C621 ADD SI, DPBSIZ ; Point to next DPB 0 00005AE2 E2F7 LOOP SETFINDPB 0 00005AE4 5E pop si 157 <1> @@: 0 00005AE5 268936[0000] mov [es:DPBHEAD], si ; Address of first DPB 159 <1> 160 <1> 161 <1> DOSGroup equ DOSGROUP ; NASM port equate 162 <1> ASSUME ES:DOSGroup 163 <1> 164 <1> sftabl equ sfTabl ; NASM port label 165 <1> 0 00005AEA C3 retn 167 <1> 168 <1> === Switch to base=001140h -> "DATA" 169 <1> section DATA 170 <1> 171 <1> %macro replayrecorded 2-*.nolist 172 <1> %rep (%0 - 2) / 2 173 <1> %rotate 2 174 <1> %assign %%offset %1 175 <1> %assign %%value %2 176 <1> %if ($ - MSINI001S) < %%offset 177 <1> org %%offset 178 <1> %endif 179 <1> %if ($ - MSINI001S) == %%offset 180 <1> db %%value 181 <1> %endif 182 <1> %endrep 183 <1> %endmacro 184 <1> 0 000003B6 009000 replayrecorded RECORDED 185 00000000 FFFF00- <1> 185 00000000 FFFF <1> 186 <1> 0 00000AB2 00 org (MSDAT001e - MSDAT001S) 188 <1> %else ; DONOBITS 189 <1> org (MSDAT001e - MSDAT001S), db ? 190 <1> %endif ; DONOBITS 191 <1> 192 <1> [list +] 193 <1> 194 <1> ; (no prior section) ; DATA ENDS 195 <1> 196 <1> ; the next segment defines a new class that MUST appear last in the link map. 197 <1> ; This defines several important locations for the initialization process that 198 <1> ; must be the first available locations of free memory. 199 <1> === Switch to base=001140h -> "LAST" 200 <1> section LAST 201 <1> 202 <1> %ifdef DONOBITS 203 <1> [list -] 204 <1> %endif 205 <1> 206 <1> %ifndef DONOBITS 207 <1> 208 <1> entry DOSINIT 209 <1> %ifndef DOPLACEHOLDER 0 00001330 EA[A004][0000] jmp DOSENTRY - DOSENTRYADJUSTSEGMENT:i31 + DOSENTRYADJUSTOFFSET 211 <1> %else 212 <1> jmp 0:0 213 <1> %endif 214 <1> 0 00001335 90 align 2, nop 216 <1> 217 <1> PUBLIC SYSBUF 218 <1> PUBLIC MEMSTRT 219 <1> 220 <1> SYSBUF LABEL WORD 221 <1> ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING 222 <1> 223 <1> === Switch to base=002530h -> "SYSINITTRAIL" 224 <1> section SYSINITTRAIL 225 <1> 226 <1> %ifndef DOPLACEHOLDER 227 <1> 228 <1> ; INP: es => DOS data segment 229 <1> ; bx => where to create PSP 230 <1> ; dx => behind usable memory (at EBDA or UMA) 231 <1> ; ss:sp -> init stack 232 <1> ; ds:si -> CON device 233 <1> ; (and subsequent device chain in msbio) 234 <1> ; cx => SYSINIT S MCB 235 <1> entry NEARDOSINIT 0 00005AEB FA CLI 0 00005AEC FC CLD 0 00005AED 26891E[0000] MOV [es:CurrentPDB], bx 0 00005AF2 268916[0000] MOV [es:ENDMEM],DX 240 <1> NULDEV equ NulDev ; NASM port label 0 00005AF7 268C1E[0200] MOV WORD PTR [es:NULDEV+2],DS 0 00005AFC 268936[0000] MOV WORD PTR [es:NULDEV],SI ; DS:SI Points to CONSOLE Device 243 <1> 0 00005B01 51 push cx 0 00005B02 1E push ds 0 00005B03 56 push si 247 <1> ; Need Crit vector inited to use DEVIOCALL 0 00005B04 31C0 XOR AX,AX 0 00005B06 8ED8 MOV DS,AX 0 00005B08 8C06C600 mov word [31h * 4 + 2], es ; RI31S => DOSDATA 0 00005B0C C706A800[A004] MOV word [addr_int_IBM], entry_iret + DOSENTRYADJUSTOFFSET 0 00005B12 C706AA00[0000] MOV word [addr_int_IBM+2], DOSENTRY - DOSENTRYADJUSTSEGMENT 253 <1> 0 00005B18 4A dec dx ; => first UMCB 0 00005B19 268916[FA06] mov word [es:first_umcb], dx 0 00005B1E 06 push es 0 00005B1F 8EC2 mov es, dx 0 00005B21 31FF xor di, di ; -> first UMCB 0 00005B23 0E push cs 0 00005B24 1F pop ds 0 00005B25 BE[A003] mov si, first_umcb_smcb ; -> template 0 00005B28 B90800 mov cx, words(MCB_size) 0 00005B2B F3A5 rep movsw ; copy the template 0 00005B2D 07 pop es 0 00005B2E 06 push es 0 00005B2F 1F pop ds 267 <1> 0 00005B30 BD[0600] MOV BP,OFFSET SYSBUF wrt DOSGROUP 0 00005B33 892E[0000] MOV [Special_Entries],BP ;MS.;AN007 save starting address of Special entries 0 00005B37 BE[1C00] MOV SI,OFFSET Version_Fake_Table wrt DOSGROUP ;MS.;AN007 0 00005B3A 89F2 MOV DX,SI ;MS.;AN007 0 00005B3C 30E4 XOR AH,AH ;MS.;AN007 273 <1> NextEntry: ;MS.;AN007 0 00005B3E AC LODSB ;MS.;AN007 get name length 0 00005B3F 84C0 test AL,AL ;MS.;AN007 end of list 0 00005B41 7407 JZ endlist ;MS.;AN007 yes 0 00005B43 01C6 ADD SI,AX ;MS.;AN007 position to 0 00005B45 83C603 ADD SI,3 ;MS.;AN007 next entry 0 00005B48 EBF4 JMP NextEntry ;MS.;AN007 280 <1> endlist: ;MS.;AN007 0 00005B4A 29D6 SUB SI,DX ;MS.;AN007 0 00005B4C 01F5 ADD BP,SI ;MS.;AN007 283 <1> 0 00005B4E 89F1 mov cx, si 0 00005B50 89D6 mov si, dx 0 00005B52 BF[0600] mov di, SYSBUF wrt DOSGROUP 0 00005B55 F3A4 rep movsb 288 <1> 0 00005B57 83C50F ADD BP,15 ; True start of free space (round up to segment) 0 00005B5A D1DD RCR BP,1 0 00005B5C B103 MOV CL,3 0 00005B5E D3ED SHR BP,CL ; Number of segments for DOS resources 293 <1> ;;;;;; MOV [IBMDOS_SIZE],BP ;MS. save it for information 0 00005B60 8CC2 MOV DX, es 0 00005B62 01EA ADD DX,BP ; First free segment 0 00005B64 BB0F00 MOV BX,0FH 0 00005B67 8B0E[0000] MOV CX,[ENDMEM] 298 <1> 299 <1> %IF HIGHMEM 300 <1> SUB CX,BP 301 <1> MOV BP,CX ; Segment of DOS 302 <1> MOV DX, es ; Program segment 303 <1> %ENDIF 304 <1> 305 <1> %IFN HIGHMEM 0 00005B6B 8CC5 MOV BP, es 307 <1> %ENDIF 308 <1> 309 <1> ; BP has segment of DOS (whether to load high or run in place) 310 <1> ; DX has program segment (whether after DOS or overlaying DOS) 311 <1> ; CX has size of memory in paragraphs (reduced by DOS size if HIGHMEM) 0 00005B6D 890E[0000] MOV [ENDMEM],CX 0 00005B71 8EC5 MOV ES,BP 314 <1> ASSUME ES:DOSGROUP 315 <1> 316 <1> %IF HIGHMEM 317 <1> XOR SI,SI 318 <1> MOV DI,SI 319 <1> MOV CX,OFFSET SYSBUF wrt DOSGROUP ;# bytes to move 320 <1> SHR CX,1 ;# words to move (carry set if odd) 321 <1> REP MOVSW ; Move DOS to high memory 322 <1> JNC NOTODD 323 <1> MOVSB 324 <1> NOTODD: 325 <1> %ENDIF 326 <1> 0 00005B73 5E pop si 0 00005B74 1F pop ds 329 <1> 0 00005B75 52 push dx 0 00005B76 55 push bp 332 <1> 0 00005B77 E80703 CALL CHARINIT 0 00005B7A 56 PUSH SI ; Save pointer to header 335 <1> ; es => DOSDATA 336 <1> ASSUME ES:DOSGROUP 0 00005B7B BF[0600] MOV DI,OFFSET sftabl + SFTable wrt DOSGROUP ; Point to sft 0 0 00005B7E B80300 MOV AX,3 0 00005B81 AB STOSW ; Refcount 0 00005B82 48 DEC ax 341 <1> errnz sf_mode-(sf_ref_count+2) 0 00005B83 AB STOSW ; Access rd/wr, compatibility 0 00005B84 30C0 XOR AL,AL 344 <1> errnz sf_attr-(sf_mode+2) 0 00005B86 AA STOSB ; attribute 0 00005B87 B0C3 MOV AL,devid_device_EOF | devid_device | ISCIN | ISCOUT 347 <1> errnz sf_flags-(sf_attr+1) 0 00005B89 AB STOSW ; Flags 0 00005B8A 89F0 MOV AX,SI 350 <1> errnz sf_devptr-(sf_flags+2) 0 00005B8C AB STOSW ; Device pointer in devptr 0 00005B8D 8CD8 MOV AX,DS 0 00005B8F AB STOSW 0 00005B90 31C0 XOR AX,AX 355 <1> errnz sf_firclus-(sf_devptr+4) 0 00005B92 AB STOSW ; firclus 357 <1> errnz sf_time-(sf_firclus+2) 0 00005B93 AB STOSW ; time 359 <1> errnz sf_date-(sf_time+2) 0 00005B94 AB STOSW ; date 0 00005B95 48 DEC AX 362 <1> errnz sf_size-(sf_date+2) 0 00005B96 AB STOSW ; size 0 00005B97 AB STOSW 0 00005B98 40 INC AX 366 <1> errnz sf_position-(sf_size+4) 0 00005B99 AB STOSW ; position 0 00005B9A AB STOSW 0 00005B9B 83C707 ADD DI,sf_name - sf_cluspos ;Point at name 0 00005B9E 83C60A ADD SI,SDEVNAME ; Point to name 0 00005BA1 B90400 MOV CX,4 0 00005BA4 F3A5 REP MOVSW ; Name 0 00005BA6 B103 MOV CL,3 0 00005BA8 B020 MOV AL," " 0 00005BAA F3AA REP STOSB ; Extension 0 00005BAC 5E POP SI ; Get back pointer to header 0 00005BAD 804C0403 OR BYTE PTR [SI + SDEVATT],ISCIN | ISCOUT 378 <1> BCON equ BCon ; NASM port label 0 00005BB1 268936[0000] MOV WORD PTR [es:BCON],SI 0 00005BB6 268C1E[0200] MOV WORD PTR [es:BCON+2],DS 381 <1> 0 00005BBB 5D pop bp 0 00005BBC 5A pop dx 384 <1> 385 <1> DSKCHRET equ Dskchret ; NASM port label 0 00005BBD 268C06[0300] MOV WORD PTR [ES:DSKCHRET+3],ES 0 00005BC2 31C0 XOR AX,AX 0 00005BC4 8ED8 MOV DS,AX 0 00005BC6 8EC0 MOV ES,AX 390 <1> ASSUME DS:NOTHING,ES:NOTHING 0 00005BC8 BF8200 MOV DI,INTBASE+2 0 00005BCB 89E8 MOV AX,BP ; Final DOS segment to AX 393 <1> 0 00005BCD 50 push ax 395 <1> 0 00005BCE B8[0000] mov ax, DOSENTRY - DOSENTRYADJUSTSEGMENT 397 <1> 398 <1> extern i00 0 00005BD1 C7060000[A004] mov word [0], i00 + DOSENTRYADJUSTOFFSET 0 00005BD7 A30200 mov word [2], ax ; Set default divide trap address 401 <1> 402 <1> ; Set vectors 20-28 and 2A-3F to point to IRET. 0 00005BDA B91100 MOV CX,17 0 00005BDD F3AB REP STOSW ; Set 9 segments 405 <1> ; Sets segs for INTs 20H-28H 0 00005BDF 83C706 ADD DI,6 ; Skip INT 29H vector (FAST CON) as it may 407 <1> ; already be set. 0 00005BE2 B12B MOV cl, 43 0 00005BE4 F3AB REP STOSW ; Set 22 segments 410 <1> ; Sets segs for vectors 2AH-3FH 0 00005BE6 8F06C600 pop word [31h * 4 + 2] ; RI31S => DOSDATA 412 <1> 0 00005BEA BF8000 MOV DI,INTBASE 0 00005BED B8[A004] MOV AX, entry_iret + DOSENTRYADJUSTOFFSET 0 00005BF0 B109 MOV cl, 9 ; Set 9 offsets (skip 2 between each) 416 <1> ; Sets offsets for INTs 20H-28H 417 <1> 418 <1> ISET1: 0 00005BF2 AB STOSW ; offset 0 00005BF3 AF scasw ; di += 2 0 00005BF4 E2FC LOOP ISET1 422 <1> 0 00005BF6 AF scasw ; di += 2 0 00005BF7 AF scasw ; di += 2 425 <1> ; Skip vector 29H 426 <1> 0 00005BF8 B116 MOV cl, 22 ; Set 22 offsets (skip 2 between each) 428 <1> ; Sets offsets for INTs 2AH-3FH 429 <1> 430 <1> ISET2: 0 00005BFA AB STOSW 0 00005BFB AF scasw ; di += 2 0 00005BFC E2FC LOOP ISET2 434 <1> 0 00005BFE 89E8 MOV AX,BP ; Final DOS segment to AX 436 <1> 437 <1> %IF installed 438 <1> ; the following two are in the Code segment, thus the CS 439 <1> ; overrides 0 00005C00 C706BC00[A004] MOV WORD PTR [02FH * 4], i2F + DOSENTRYADJUSTOFFSET 441 <1> %ENDIF 442 <1> 443 <1> ; Set up entry point call at vectors 30-31H 0 00005C06 C606C000EA MOV BYTE PTR [ENTRYPOINT],mi_Long_JMP 0 00005C0B C706C100[A004] MOV WORD PTR [ENTRYPOINT+1], call5 + DOSENTRYADJUSTOFFSET 0 00005C11 C706C300[0000] MOV WORD PTR [ENTRYPOINT+3], DOSENTRY - DOSENTRYADJUSTSEGMENT 0 00005C17 C606C50000 mov byte [ENTRYPOINT+5], 0 448 <1> ; this also happens to init int 31h to DOSDATA:0, 449 <1> ; which is equal to our legacy DOSINIT entrypoint. 450 <1> ; this is now re-used as i31, far-jumping to DOSENTRY 451 <1> ; and relocating to DOSCODE. currently this just sets 452 <1> ; ax = 1 and CY and returns (using an iret). 453 <1> 454 <1> %IF ALTVECT 455 <1> MOV DI,ALTBASE+2 456 <1> MOV CX,15 457 <1> REP STOSW ; Set 8 segments (skip 2 between each) 458 <1> %ENDIF 459 <1> 460 <1> ; all interrupt handler entrypoints 461 <1> ; => DOSENTRY - DOSENTRYADJUSTSEGMENT 0 00005C1C C7068000[A004] MOV WORD PTR [addr_int_abort], i20 + DOSENTRYADJUSTOFFSET 0 00005C22 C7068400[A004] MOV WORD PTR [addr_int_command], i21 + DOSENTRYADJUSTOFFSET 0 00005C28 C70688000001 MOV WORD PTR [addr_int_terminate],100H 0 00005C2E 89168A00 MOV WORD PTR [addr_int_terminate+2],DX 0 00005C32 C7068C00[A004] MOV WORD PTR [23h * 4], i23 + DOSENTRYADJUSTOFFSET 0 00005C38 C7069000[A004] MOV WORD PTR [24h * 4], i24 + DOSENTRYADJUSTOFFSET 0 00005C3E C7069400[A004] MOV WORD PTR [addr_int_disk_read], i25 + DOSENTRYADJUSTOFFSET 0 00005C44 C7069800[A004] MOV WORD PTR [addr_int_disk_write], i26 + DOSENTRYADJUSTOFFSET 0 00005C4A C7069C00[A004] MOV WORD PTR [addr_int_keep_process], i27 + DOSENTRYADJUSTOFFSET 471 <1> 0 00005C50 E868FE call getdosdata 0 00005C53 8ED8 mov ds, ax 0 00005C55 8EC0 mov es, ax 475 <1> ASSUME DS:DOSGROUP,ES:DOSGROUP 476 <1> 0 00005C57 89D0 mov ax, dx 478 <1> 0 00005C59 BA6000 mov dx, 60h ; new first MCB (init PSP) 480 <1> arena_head equ Arena_Head ; NASM port label 0 00005C5C 268916[0000] MOV [ES:arena_head], dx 482 <1> 0 00005C61 5B pop bx ; bx => SYSINIT S MCB 0 00005C62 1E push ds 0 00005C63 06 push es 0 00005C64 8EDA mov ds, dx ; => MCB 0 00005C66 03160300 add dx, word [arena_size] 0 00005C6A 42 inc dx 0 00005C6B 8EC2 mov es, dx ; => DOSENTRY MCB destination 0 00005C6D 0E push cs 0 00005C6E 1F pop ds 0 00005C6F BE[B003] mov si, dosentry_mcb ; -> template 0 00005C72 31FF xor di, di 0 00005C74 B90800 mov cx, words(16) 0 00005C77 F3A5 rep movsw 0 00005C79 F7DA neg dx 0 00005C7B 01C2 add dx, ax ; dx = ax - dx 0 00005C7D 4A dec dx 0 00005C7E 2689160300 mov word [es:arena_size], dx 500 <1> ; set size 0 00005C83 07 pop es 502 <1> 0 00005C84 8ED8 MOV DS,AX 0 00005C86 C60600004D MOV byte [arena_signature], 'M' 505 <1> ; The SYSINIT S MCB initially does not link to the UMCB. 506 <1> ; The free MCB does however link to the SYSINIT S MCB. 0 00005C8B C70601000000 MOV word [arena_owner],arena_owner_system 508 <1> ENDMEM equ EndMem ; NASM port label 0 00005C91 29D8 SUB AX, bx 0 00005C93 F7D0 not ax ; like neg ax, dec ax 0 00005C95 A30300 MOV [arena_size],AX 0 00005C98 1F pop ds 513 <1> 0 00005C99 8B16[0000] mov dx, [CurrentPDB] 0 00005C9D 31C0 xor ax, ax ; = 0 0 00005C9F 8EC2 mov es, dx 0 00005CA1 31FF xor di, di ; -> PSP to create 0 00005CA3 B93000 mov cx, words(60h) ; clear PSP needed part 0 00005CA6 F3AB rep stosw ; clear memory 0 00005CA8 A1[0000] mov ax, [ENDMEM] 521 <1> 0 00005CAB E8E2FDEB02[0000] neartransfer SETMEM ; Basic Header 523 <1> ; SETMEM works with ss != DOSDATA 0 00005CB2 268C061600 mov word [ES:PDB_Parent_PID], es 525 <1> ; set parent to itself (better than uninit) 526 <1> ASSUME DS:NOTHING,ES:NOTHING 0 00005CB7 E801FE call getdosdata 0 00005CBA 8ED8 mov ds, ax 529 <1> ASSUME DS:DOSGROUP 0 00005CBC BF1800 MOV DI,PDB_JFN_Table 0 00005CBF 31C0 XOR AX,AX 0 00005CC1 AB STOSW 0 00005CC2 AA STOSB ; 0,1 and 2 are CON device 0 00005CC3 B0FF MOV AL,0FFH 0 00005CC5 B91100 MOV CX,FilPerProc - 3 0 00005CC8 F3AA REP STOSB ; Rest are unused 0 00005CCA 1E PUSH ds 0 00005CCB 07 POP ES 539 <1> ASSUME ES:DOSGROUP 0 00005CCC 8C1E[0200] MOV WORD PTR [sft_addr+2],DS ; Must be set to print messages 541 <1> 542 <1> ; After this points the char device functions for CON will work for 543 <1> ; printing messages 544 <1> 545 <1> %IF (! IBM) | (DEBUG) 546 <1> %IFN ALTVECT 547 <1> HEADER equ Header ; NASM port label 548 <1> MOV SI,OFFSET HEADER wrt DOSGROUP 549 <1> OUTMES: 550 <1> call getdosdata 551 <1> mov ds, ax 552 <1> lodsb 553 <1> CMP AL,"$" 554 <1> JZ OUTDONE 555 <1> invalid function call 556 <1> invoke OUT 557 <1> JMP SHORT OUTMES 558 <1> OUTDONE: 559 <1> PUSH ds ; OUT stomps on segments 560 <1> POP es 561 <1> %ENDIF 562 <1> %ENDIF 563 <1> 564 <1> ;F.C Modification start DOS 3.3 0 00005CD0 BE[0000] MOV SI,OFFSET COUNTRY_CDPG wrt DOSGROUP ;F.C. for DOS 3.3 country info 566 <1> ; table address 0 00005CD3 268C444F MOV WORD PTR [ES:SI + ccUcase_ptr + 2],ES ; initialize double word 0 00005CD7 268C4454 MOV WORD PTR [ES:SI + ccFileUcase_ptr + 2],ES ; pointers with DOSGROUP 0 00005CDB 268C4459 MOV WORD PTR [ES:SI + ccFileChar_ptr + 2],ES 0 00005CDF 268C445E MOV WORD PTR [ES:SI + ccCollate_ptr + 2],ES 0 00005CE3 268C4463 MOV WORD PTR [ES:SI + ccDBCS_ptr + 2],ES ; 2/16/KK 572 <1> 0 00005CE7 BE[0000] MOV SI,OFFSET SysInitTable wrt DOSGROUP 0 00005CEA 268C4406 MOV WORD PTR [ES:SI + SYSI_Country_Tab + 2],ES 0 00005CEE 268C4402 MOV WORD PTR [ES:SI + SYSI_InitVars + 2],ES 576 <1> 577 <1> %ifdef BUF2 578 <1> %else 579 <1> BUFFHEAD equ BuffHead ; NASM port label 580 <1> MOV WORD PTR [ES:BUFFHEAD+2],ES ;LB. DOS 4.00 buffer head pointer ;AN000; 581 <1> MOV SI,OFFSET HASHINITVAR wrt DOSGROUP ;LB. points to Hashinitvar ;AN000; 582 <1> MOV WORD PTR [ES:BUFFHEAD],SI ;LB. ;AN000; 583 <1> MOV WORD PTR [ES:BUF_HASH_PTR+2],ES ;LB. ;AN000; 584 <1> MOV SI,OFFSET Hash_Temp wrt DOSGROUP ;LB. ;AN000; 585 <1> MOV WORD PTR [ES:BUF_HASH_PTR],SI ;LB. ;AN000; 586 <1> %endif 587 <1> 0 00005CF2 26C706[0000]7258 MOV word [ES:FETCHI_TAG],22642 ; TAG for IBM, 589 <1> ; Fetchi's serial # = 822642 590 <1> 0 00005CF9 BF[0000] MOV DI,OFFSET SWAP_START wrt DOSGROUP ;IFS. ;AN000; 0 00005CFC B9[0407] MOV CX,OFFSET SWAP_END wrt DOSGROUP ;IFS. ;AN000; 593 <1> Swap_Always equ SWAP_ALWAYS ; NASM port label 0 00005CFF BA[0000] MOV DX,OFFSET Swap_Always wrt DOSGroup ;IFS. ;AN000; 0 00005D02 89CD MOV BP,CX ;IFS. ;AN000; 0 00005D04 29FD SUB BP,DI ;IFS. ;AN000; 0 00005D06 D1ED SHR BP,1 ;IFS. div by 2, remainder in carry ;AN000; 0 00005D08 83D500 ADC BP,0 ;IFS. div by 2 + round up ;AN000; 0 00005D0B D1E5 SHL BP,1 ;IFS. round up to 2 boundary. ;AN000; 0 00005D0D 26892E[0000] MOV [ES:SWAP_AREA_LEN],BP ;IFS. ;AN000; 601 <1> 0 00005D12 29D1 SUB CX,DX ;IFS. ;AN000; 0 00005D14 29FA SUB DX,DI ;IFS. ;AN000; 0 00005D16 D1E9 SHR CX,1 ;IFS. div by 2, remainder in carry ;AN000; 0 00005D18 83D100 ADC CX,0 ;IFS. div by 2 + round up ;AN000; 0 00005D1B D1E1 SHL CX,1 ;IFS. round up to 2 boundary. ;AN000; 0 00005D1D 26890E[0000] MOV [ES:SWAP_IN_DOS_LEN],CX ;IFS. ;AN000; 0 00005D22 26893E[0000] MOV WORD PTR [ES:SWAP_ALWAYS_AREA],DI ;IFS. ;AN000; 0 00005D27 268C06[0200] MOV WORD PTR [ES:SWAP_ALWAYS_AREA+2],ES ;IFS. ;AN000; 0 00005D2C 81CA0080 OR DX,8000H ;IFS. ;AN000; 0 00005D30 268916[0000] MOV [ES:SWAP_ALWAYS_AREA_LEN],DX ;IFS. ;AN000; 0 00005D35 BF[0000] MOV DI,OFFSET Swap_Always wrt DOSGroup ;IFS. ;AN000; 0 00005D38 26893E[0000] MOV WORD PTR [ES:SWAP_IN_DOS],DI ;IFS. ;AN000; 0 00005D3D 268C06[0200] MOV WORD PTR [ES:SWAP_IN_DOS+2],ES ;IFS. ;AN000; 615 <1> 616 <1> SySInitTable equ SysInitTable ; NASM port label 0 00005D42 BF[0000] MOV DI,OFFSET SySInitTable wrt DOSGROUP 618 <1> 619 <1> %IFN Installed 620 <1> invoke NETWINIT 621 <1> ; ELSE 622 <1> ; invoke NETWINIT 623 <1> ; %OUT Random NETWINIT done at install 624 <1> %ENDIF 625 <1> 0 00005D45 268E1E[0000] mov ds, word [es:CurrentPDB] ; ds => created PSP 627 <1> DMAADD equ DMAAdd ; NASM port label 0 00005D4A 268C1E[0200] MOV WORD PTR [es:DMAADD+2], ds 0 00005D4F C3 retn 630 <1> 631 <1> 632 <1> entry INITDPB 0 00005D50 E868FD call getdosdata 0 00005D53 8EC0 mov es, ax 635 <1> 0 00005D55 26C536[0000] lds si, [es:NULDEV] 637 <1> CHAR_INIT_LOOP: 0 00005D5A C534 LDS SI,[SI] ; AUX device 0 00005D5C E82201 CALL CHARINIT 0 00005D5F F6440408 TEST BYTE PTR [SI + SDEVATT],ISCLOCK 0 00005D63 74F5 JZ CHAR_INIT_LOOP 642 <1> BCLOCK equ BClock ; NASM port label 0 00005D65 268936[0000] MOV WORD PTR [es:BCLOCK],SI 0 00005D6A 268C1E[0200] MOV WORD PTR [es:BCLOCK+2],DS 645 <1> 0 00005D6F B448 mov ah, 48h 0 00005D71 BB0500 mov bx, paras(DPBSIZ * 2) 0 00005D74 CD21 int 21h 0 00005D76 7303 jnc @F 650 <1> mem_err_j: 651 <1> extern MEM_ERR 0 00005D78 E9[0000] jmp MEM_ERR 653 <1> @@: 654 <1> lframe 0 00005D7B 5589E5 lenter 656 <1> lvar word, dosdataseg 0 00005D7E 06 push es ; => DOS data segment 658 <1> lvar dword, nextdpb 0 00005D7F 50 push ax ; => DPB allocation 0 00005D80 31C0 xor ax, ax 0 00005D82 50 push ax ; -> next DPB 662 <1> PERDRIVER: 0 00005D83 8E46FE mov es, word [bp + ?dosdataseg] 0 00005D86 C534 LDS SI,[SI] ; Next device 0 00005D88 83FEFF CMP SI,-1 0 00005D8B 7503E9CB00 JZ CONTINIT 0 00005D90 E8EE00 CALL CHARINIT 0 00005D93 F744040080 TEST word [SI + SDEVATT],DEVTYP 0 00005D98 75E9 JNZ PERDRIVER ; Skip any other character devs 670 <1> CALLUNIT equ CallUnit ; NASM port label 0 00005D9A 31C9 xor cx, cx 0 00005D9C 268A0E[0000] MOV CL,[es:CALLUNIT] 0 00005DA1 884C0A MOV [SI + SDEVNAME],CL ; Number of units in name field 0 00005DA4 E3DD jcxz PERDRIVER 0 00005DA6 1E PUSH DS 0 00005DA7 56 PUSH SI 0 00005DA8 268A16[0000] MOV DL,[es:NUMIO] 0 00005DAD 30F6 XOR DH,DH 0 00005DAF 26000E[0000] ADD [es:NUMIO],CL 680 <1> CALLBPB equ CallBPB ; NASM port label 0 00005DB4 26C51E[0000] LDS BX,[es:CALLBPB] 682 <1> PERUNIT: 0 00005DB9 8B37 MOV SI,[BX] ; DS:SI Points to BPB 0 00005DBB 43 INC BX 0 00005DBC 43 INC BX ; On to next BPB 686 <1> 0 00005DBD 55 push bp 0 00005DBE C46EFA les bp, [bp + ?nextdpb] 689 <1> 0 00005DC1 85ED test bp, bp 0 00005DC3 7408 jz @F 0 00005DC5 26896EF8 mov word [es:bp - DPBSIZ + dpb_next_dpb], bp 0 00005DC9 268C46FA mov word [es:bp - DPBSIZ + dpb_next_dpb + 2], es 694 <1> @@: 695 <1> 0 00005DCD 53 PUSH BX 0 00005DCE 51 PUSH CX 0 00005DCF 52 PUSH DX 699 <1> 700 <1> ; es => DPB allocation 0 00005DD0 B104 mov cl, 4 0 00005DD2 8D5E30 lea bx, [bp + DPBSIZ + 15] ; -> behind this DPB, round up 0 00005DD5 39EB cmp bx, bp 0 00005DD7 729F jb mem_err_j 0 00005DD9 D3EB shr bx, cl ; to paragraphs 0 00005DDB B44A mov ah, 4Ah 0 00005DDD CD21 int 21h ; resize 0 00005DDF 7297 jc mem_err_j 709 <1> 710 <1> ; ! only write the next DPB after it is allocated 0 00005DE1 5A pop dx ; = unit/drive numbers 712 <1> %if dpb_drive + 1 != dpb_UNIT 713 <1> %error Unexpected layout 714 <1> %endif 0 00005DE2 26895600 MOV [ES:BP + dpb_drive], dx 716 <1> 0 00005DE6 B8FFFF mov ax, -1 0 00005DE9 26894619 mov word [es:bp + dpb_next_dpb], ax 0 00005DED 2689461B mov word [es:bp + dpb_next_dpb + 2], ax 0 00005DF1 52 push dx ; push unit/drive numbers again 721 <1> 722 <1> ; es:bp -> DPB, ds:si -> BPB 723 <1> %if 0 724 <1> neartransfer D_SETDPB 725 <1> ; D_SETDPB works with ss != DOSDATA 726 <1> %else 0 00005DF2 B453 mov ah, 53h 0 00005DF4 CD21 int 21h 729 <1> %endif 0 00005DF6 268B4602 MOV AX,[ES:BP + dpb_sector_size] 0 00005DFA 5A POP DX 0 00005DFB 59 POP CX 0 00005DFC 5B POP BX 734 <1> 0 00005DFD 5D pop bp 0 00005DFE 8E46FE mov es, word [bp + ?dosdataseg] 737 <1> 738 <1> MAXSEC equ Maxsec ; NASM port label 0 00005E01 263B06[0000] CMP AX,[es:MAXSEC] 0 00005E06 7604 JBE NOTMAX 0 00005E08 26A3[0000] MOV [es:MAXSEC],AX 742 <1> NOTMAX: 743 <1> 744 <1> 0 00005E0C 8CD8 MOV AX,DS ; Save DS 0 00005E0E 5E POP SI 0 00005E0F 1F POP DS 748 <1> 0 00005E10 55 push bp 0 00005E11 C46EFA les bp, [bp + ?nextdpb] 751 <1> 0 00005E14 26897613 MOV WORD PTR [ES:BP + dpb_driver_addr],SI 0 00005E18 268C5E15 MOV WORD PTR [ES:BP + dpb_driver_addr+2],DS 754 <1> 0 00005E1C 5D pop bp 756 <1> 0 00005E1D 1E PUSH DS 0 00005E1E 56 PUSH SI 0 00005E1F FEC6 INC DH 0 00005E21 FEC2 INC DL 0 00005E23 8ED8 MOV DS,AX 0 00005E25 8346FA21 ADD word [bp + ?nextdpb],DPBSIZ 0 00005E29 E28E LOOP PERUNIT 0 00005E2B 5E POP SI 0 00005E2C 1F POP DS 0 00005E2D E953FF JMP PERDRIVER 767 <1> 768 <1> align 2 769 <1> first_umcb_smcb: 770 <1> istruc MCB 0 00005E30 5A at mcbSignature, db 'Z' 0 00005E31 0800 at mcbOwner, dw 8 0 00005E33 0000 at mcbSize, dw 0 0 00005E35 005300 at smcbName, db "S", 0 0 00005E3A 30 at smcbType, db S_EXCLDUMA 0 00005E3B 00 iend 777 <1> 778 <1> dosentry_mcb: 779 <1> istruc MCB 0 00005E40 4D at mcbSignature, db 'M' 0 00005E41 0800 at mcbOwner, dw 8 0 00005E43 0000 at mcbSize, dw 0 0 00005E45 005300 at smcbName, db "S", 0 0 00005E4A 01 at smcbType, db S_DOSENTRY 0 00005E4B 00 iend 786 <1> 787 <1> dpb_smcb: 0 00005E50 000000 db 0,0,0 0 00005E53 5300 db "S",0 ; name "S" 0 00005E55 08 db 8 ; type S_DPB 0 00005E56 00 times 5 db 0 792 <1> 793 <1> CONTINIT: ; es => DOSDATA 0 00005E5B 58 pop ax ; offset last DPB 0 00005E5C 58 pop ax ; => DPB allocation 0 00005E5D 26A3[0200] mov word [es:DPBHEAD + 2], ax 0 00005E61 48 dec ax 0 00005E62 8EC0 mov es, ax 0 00005E64 26C70601000800 mov word [es:arena_owner], 8 800 <1> ; init owner 0 00005E6B BF0500 mov di, arena_reserved 0 00005E6E 0E push cs 0 00005E6F 1F pop ds 0 00005E70 BE[C003] mov si, dpb_smcb 0 00005E73 B90B00 mov cx, 3 + 8 0 00005E76 F3A4 rep movsb ; init name and type 807 <1> 0 00005E78 1F pop ds ; => DOS data 0 00005E79 1E PUSH ds 0 00005E7A 07 POP es 811 <1> ASSUME DS:DOSGROUP 812 <1> 0 00005E7B 89EC5D lleave 814 <1> 0 00005E7E E945FC JMP MOVDPB 816 <1> 817 <1> CHARINIT: 818 <1> ASSUME DS:NOTHING,ES:NOTHING 819 <1> ; DS:SI Points to device header 820 <1> DEVCALL equ Devcall ; NASM port label 0 00005E81 06 PUSH ES 0 00005E82 53 PUSH BX 0 00005E83 50 PUSH AX 0 00005E84 E834FC call getdosdata 0 00005E87 8EC0 mov es, ax ; => DOSDATA 0 00005E89 58 pop ax 0 00005E8A 50 push ax 0 00005E8B BB[0000] MOV BX,OFFSET DEVCALL wrt DOSGROUP 0 00005E8E 26C6071A MOV byte [es:bx + REQLEN],DINITHL 0 00005E92 26C6470100 MOV byte [es:bx + REQUNIT],0 0 00005E97 26C6470200 MOV byte [es:bx + REQFUNC],DEVINIT 0 00005E9C 2683670300 and word [es:bx + REQSTAT],0 833 <1> %if 0 834 <1> neartransfer DEVIOCALL2 835 <1> %else 836 <1> ; device critical section is not yet enabled 0 00005EA1 8B4406 MOV AX, [SI + SDEVSTRAT] 838 <1> CALLDEVAD equ CallDevAd ; NASM port label 0 00005EA4 26A3[0000] MOV WORD PTR [es:CALLDEVAD],AX 0 00005EA8 268C1E[0200] MOV WORD PTR [es:CALLDEVAD+2],DS 0 00005EAD 26FF1E[0000] CALL far [es:CALLDEVAD] 0 00005EB2 8B4408 MOV AX,[SI + SDEVINT] 0 00005EB5 26A3[0000] MOV WORD PTR [es:CALLDEVAD],AX 0 00005EB9 26FF1E[0000] CALL far [es:CALLDEVAD] 845 <1> %endif 0 00005EBE 58 POP AX 0 00005EBF 5B POP BX 0 00005EC0 07 POP ES 0 00005EC1 C3 RET 850 <1> 851 <1> %endif ; DOPLACEHOLDER 852 <1> 0 00005EC2 90 align 16, nop 854 <1> === Switch to base=001140h -> "LAST" 855 <1> section LAST 856 <1> 857 <1> Public MSINI002S,MSINI002E 858 <1> MSINI002S label byte 859 <1> 860 <1> align 2, db ? 0 00001336 ???? DW ? 0 00001338 414444205350454349 DB "ADD SPECIAL ENTRIES",0 ;AN007 tiltle 0 00001341 414C20454E54524945 0 0000134A 5300 863 <1> ;The following entries don't expect version 4.0 864 <1> ;The entry format: name_length, name, expected version, fake count 865 <1> ;fake_count: ff means the version will be reset when Abort or Exec is encountered 866 <1> ; n means the version will be reset after n DOS version calls are issued 867 <1> ; 868 <1> Version_Fake_Table: ;AN007 starting address for special 0 0000134C 0C49424D4341434845 DB 12,"IBMCACHE.COM",3,40,255 ;AN007 ibmcache 1 0 00001355 2E434F4D0328FF 0 0000135C 0C49424D4341434845 DB 12,"IBMCACHE.SYS",3,40,255 ;AN007 ibmcache 2 0 00001365 2E5359530328FF 0 0000136C 0C44584D41304D4F44 DB 12,"DXMA0MOD.SYS",3,40,255 ;AN007 lan support 3 0 00001375 2E5359530328FF 0 0000137C 0A57494E3230302E42 DB 10,"WIN200.BIN" ,3,40,4 ;AN008 windows 4 0 00001385 494E032804 0 0000138A 0950534350472E434F DB 9,"PSCPG.COM" ,3,40,255 ;AN008 vittoria 5 0 00001393 4D0328FF 0 00001397 0B44434A535330322E DB 11,"DCJSS02.EXE" ,3,40,255 ;AN008 netview 6 0 000013A0 4558450328FF 0 000013A6 084953414D2E455845 DB 8,"ISAM.EXE" ,3,40,255 ;AN008 basic 7 0 000013AF 0328FF 0 000013B2 094953414D322E4558 DB 9,"ISAM2.EXE" ,3,40,255 ;AN008 basic 8 0 000013BB 450328FF 0 000013BF 0C44464941304D4F44 DB 12,"DFIA0MOD.SYS",3,40,255 ;AN008 lan support 9 0 000013C8 2E5359530328FF 0 000013CF 000000000000000000 DB 20 dup(0) ;AN007 0 000013D8 000000000000000000 0 000013E1 0000 879 <1> 0 000013E3 00 align 16, db 0 881 <1> 882 <1> MEMSTRT LABEL WORD 883 <1> MSINI002E label byte 884 <1> ADJFAC EQU MEMSTRT-SYSBUF 885 <1> 886 <1> %endif ; DONOBITS 887 <1> 888 <1> [list +] 889 <1> 890 <1> ; (no prior section) ; LAST ENDS 40 ;=== Pop trace listing source 41 END === Trace listing source: ../INC/mstable.lst 1 ; SCCSID = @(#)ibmtable.asm 1.1 85/04/10 2 ; 3 ; Table Segment for DOS 4 ; 5 6 [list -] 6 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 13 14 ;TITLE IBMTABLE - Table segment for DOS 15 ;NAME IBMTABLE 16 17 ;=== Push trace listing source: ms_table.nas 18 %include "ms_table.nas" ; NASM included file 1 <1> ; SCCSID = @(#)mstable.asm 1.3 85/07/25 2 <1> ; Revision history: 3 <1> ; A000 version 4.0 Jan. 1988 4 <1> ; A001 DCR 486 - Share installation for >32mb drives 5 <1> ; A006 DCR 503 - fake version for IBMCACHE 6 <1> ; A008 PTM 4070 - fake version for MS WINDOWS 7 <1> [list -] 7 ****************** <1> warning: out: ... for DOS Version 4.00 ... [-w+user] 7 ****************** <1> warning: out: BPB.INC... [-w+user] 7 ****************** <1> warning: out: ... CLONE version build switch on ... [-w+user] 16 <1> 17 <1> %ifndef Kanji 18 <1> %iassign Kanji 0 19 <1> %endif 20 <1> %ifndef Debug 21 <1> %iassign Debug 0 22 <1> %endif 23 <1> %ifndef Redirector 24 <1> %iassign Redirector 0 25 <1> %endif 26 <1> %ifndef ShareF 27 <1> %iassign ShareF 0 28 <1> %endif 29 <1> === Switch to base=001140h -> "TABLE" 30 <1> section TABLE ; in DOSDATA 31 <1> 32 <1> PUBLIC MSVERS 33 <1> MSTAB001s equ MSTAB001S ; NASM port label 34 <1> MSTAB001e equ MSTAB001E ; NASM port label 35 <1> PUBLIC MSTAB001s,MSTAB001e 36 <1> MSTAB001S label byte 37 <1> 38 <1> MSVERS: ; lDOS version in hex for $GET_VERSION 0 00000D12 05 MSMAJOR DB alt_major_version 0 00000D13 1A MSMINOR DB alt_minor_version 41 <1> 42 <1> align 2, db 0 0 00000D14 C8A6C8A5C8A5C8A5 I_am YRTAB,8,<200,166,200,165,200,165,200,165> ; [SYSTEM] 0 00000D1C 1F1C1F1E1F1E1F1F1E I_am MONTAB,12,<31,28,31,30,31,30,31,31,30,31,30,31> ; [SYSTEM] 0 00000D25 1F1E1F 45 <1> 46 <1> === Switch to base=008400h -> "DOSCODETABLE" 47 <1> section DOSCODETABLE 48 <1> 49 <1> ; 50 <1> ; This is the error code mapping table for INT 21 errors. This table defines 51 <1> ; those error codes which are "allowed" for each system call. If the error 52 <1> ; code ABOUT to be returned is not "allowed" for the call, the correct action 53 <1> ; is to return the "real" error via Extended error, and one of the allowed 54 <1> ; errors on the actual call. 55 <1> ; 56 <1> ; The table is organized as follows: 57 <1> ; 58 <1> ; Each entry in the table is of variable size, but the first 59 <1> ; two bytes are always: 60 <1> ; 61 <1> ; Call#,Cnt of bytes following this byte 62 <1> ; 63 <1> ; EXAMPLE: 64 <1> ; Call 61 (OPEN) 65 <1> ; 66 <1> ; DB 61,5,12,3,2,4,5 67 <1> ; 68 <1> ; 61 is the AH INT 21 call value for OPEN. 69 <1> ; 5 indicates that there are 5 bytes after this byte (12,3,2,4,5). 70 <1> ; Next five bytes are those error codes which are "allowed" on OPEN. 71 <1> ; The order of these values is not important EXCEPT FOR THE LAST ONE (in 72 <1> ; this case 5). The last value will be the one returned on the call if 73 <1> ; the "real" error is not one of the allowed ones. 74 <1> ; 75 <1> ; There are a number of calls (for instance all of the FCB calls) for which 76 <1> ; there is NO entry. This means that NO error codes are returned on this 77 <1> ; call, so set up an Extended error and leave the current error code alone. 78 <1> ; 79 <1> ; The table is terminated by a call value of 0FFh 80 <1> 81 <1> PUBLIC I21_MAP_E_TAB 82 <1> I21_MAP_E_TAB LABEL BYTE 0 00000232 38020102 DB International,2,error_invalid_function,error_file_not_found 0 00000236 3903030205 DB MKDir,3,error_path_not_found,error_file_not_found,error_access_denied 0 0000023B 3A041003 DB RMDir,4,error_current_directory,error_path_not_found 0 0000023F 0205 DB error_file_not_found,error_access_denied 0 00000241 3B020203 DB CHDir,2,error_file_not_found,error_path_not_found 0 00000245 3C040302 DB Creat,4,error_path_not_found,error_file_not_found 0 00000249 04 DB error_too_many_open_files 0 0000024A 05 DB error_access_denied 0 0000024B 3D0603020C DB Open,6,error_path_not_found,error_file_not_found,error_invalid_access 0 00000250 04 DB error_too_many_open_files 93 <1> error_not_dos_disk equ error_not_DOS_disk ; NASM port equate 0 00000251 1A05 DB error_not_dos_disk,error_access_denied 0 00000253 3E0106 DB Close,1,error_invalid_handle 0 00000256 3F020605 DB Read,2,error_invalid_handle,error_access_denied 0 0000025A 40020605 DB Write,2,error_invalid_handle,error_access_denied 0 0000025E 4103030205 DB Unlink,3,error_path_not_found,error_file_not_found,error_access_denied 0 00000263 42020601 DB LSeek,2,error_invalid_handle,error_invalid_function 0 00000267 4304030201 DB CHMod,4,error_path_not_found,error_file_not_found,error_invalid_function 0 0000026C 05 DB error_access_denied 0 0000026D 44050F0D01 DB IOCtl,5,error_invalid_drive,error_invalid_data,error_invalid_function 0 00000272 0605 DB error_invalid_handle,error_access_denied 0 00000274 45020604 DB XDup,2,error_invalid_handle,error_too_many_open_files 0 00000278 46020604 DB XDup2,2,error_invalid_handle,error_too_many_open_files 0 0000027C 47021A0F DB Current_Dir,2,error_not_DOS_disk,error_invalid_drive 0 00000280 48020708 DB Alloc,2,error_arena_trashed,error_not_enough_memory 0 00000284 49020709 DB Dealloc,2,error_arena_trashed,error_invalid_block 0 00000288 4A03070908 DB Setblock,3,error_arena_trashed,error_invalid_block,error_not_enough_memory 0 0000028D 4B08030102 DB Exec,8,error_path_not_found,error_invalid_function,error_file_not_found 0 00000292 040B0A DB error_too_many_open_files,error_bad_format,error_bad_environment 0 00000295 0805 DB error_not_enough_memory,error_access_denied 0 00000297 4E03030212 DB Find_First,3,error_path_not_found,error_file_not_found,error_no_more_files 0 0000029C 4F0112 DB Find_Next,1,error_no_more_files 0 0000029F 5605110302 DB Rename,5,error_not_same_device,error_path_not_found,error_file_not_found 0 000002A4 1005 DB error_current_directory,error_access_denied 0 000002A6 57040608 DB File_Times,4,error_invalid_handle,error_not_enough_memory 0 000002AA 0D01 DB error_invalid_data,error_invalid_function 0 000002AC 58020107 DB AllocOper,2,error_invalid_function, 7 0 000002B0 5A040302 DB CreateTempFile,4,error_path_not_found,error_file_not_found 0 000002B4 0405 DB error_too_many_open_files,error_access_denied 0 000002B6 5B055003 DB CreateNewFile,5,error_file_exists,error_path_not_found 0 000002BA 020405 DB error_file_not_found,error_too_many_open_files,error_access_denied 0 000002BD 5C040601 DB LockOper,4,error_invalid_handle,error_invalid_function 0 000002C1 2421 DB error_sharing_buffer_exceeded,error_lock_violation 0 000002C3 65020102 DB GetExtCntry,2,error_invalid_function,error_file_not_found ;DOS 3.3 0 000002C7 66020102 DB GetSetCdPg,2,error_invalid_function,error_file_not_found ;DOS 3.3 0 000002CB 680106 DB Commit,1,error_invalid_handle ;DOS 3.3 0 000002CE 67030408 DB ExtHandle,3,error_too_many_open_files,error_not_enough_memory 0 000002D2 01 DB error_invalid_function 0 000002D3 6C0A DB ExtOpen,10 0 000002D5 03020C DB error_path_not_found,error_file_not_found,error_invalid_access 0 000002D8 045008 DB error_too_many_open_files,error_file_exists,error_not_enough_memory 0 000002DB 1A0D DB error_not_dos_disk,error_invalid_data 0 000002DD 0105 DB error_invalid_function,error_access_denied 0 000002DF 69040F0D DB GetSetMediaID,4,error_invalid_drive,error_invalid_data 0 000002E3 0105 DB error_invalid_function,error_access_denied 0 000002E5 FF DB 0FFh 139 <1> 140 <1> ; 141 <1> ; The following table defines CLASS ACTION and LOCUS info for the INT 21H 142 <1> ; errors. Each entry is 4 bytes long: 143 <1> ; 144 <1> ; Err#,Class,Action,Locus 145 <1> ; 146 <1> ; A value of 0FFh indicates a call specific value (ie. should already 147 <1> ; be set). AN ERROR CODE NOT IN THE TABLE FALLS THROUGH TO THE CATCH ALL AT 148 <1> ; THE END, IT IS ASSUMES THAT CLASS, ACTION, LOCUS IS ALREADY SET. 149 <1> 150 <1> ;ErrTab Macro err,class,action,locus 151 <1> %imacro ErrTab 4.nolist 152 <1> %ifidni %4, 0FFh 153 <1> DB error_%1,errCLASS_%2,errACT_%3,0FFh 154 <1> %else 155 <1> DB error_%1,errCLASS_%2,errACT_%3,errLOC_%4 156 <1> %endif 157 <1> %endmacro 158 <1> === Switch to base=001140h -> "TABLE" 159 <1> section TABLE ; in DOSDATA 160 <1> 161 <1> error_Not_supported equ error_not_supported ; NASM port equate 162 <1> quuux equ error_Not_supported 163 <1> error_Invalid_Parameter equ error_invalid_parameter ; NASM port equate 164 <1> qbar equ error_Invalid_Parameter 165 <1> error_Sharing_buffer_exceeded equ error_sharing_buffer_exceeded ; NASM port equate 166 <1> qbaz equ error_Sharing_buffer_exceeded 167 <1> error_Handle_EOF equ error_handle_EOF ; NASM port equate 168 <1> qux equ error_Handle_EOF 169 <1> error_Handle_DISK_FULL equ error_handle_Disk_Full ; NASM port equate 170 <1> qxyzzy equ error_Handle_DISK_FULL 171 <1> quux equ error_Sharing_buffer_exceeded 172 <1> 173 <1> align 2, db 0 174 <1> PUBLIC ERR_TABLE_21 175 <1> ERR_TABLE_21 LABEL BYTE 0 00000D28 010704FF ErrTab invalid_function, Apperr, Abort, 0FFh 0 00000D2C 02080302 ErrTab file_not_found, NotFnd, User, Disk 0 00000D30 03080302 ErrTab path_not_found, NotFnd, User, Disk 0 00000D34 04010401 ErrTab too_many_open_files, OutRes, Abort, Unk 0 00000D38 050303FF ErrTab access_denied, Auth, User, 0FFh 0 00000D3C 06070401 ErrTab invalid_handle, Apperr, Abort, Unk 0 00000D40 07070505 ErrTab arena_trashed, Apperr, Panic, Mem 0 00000D44 08010405 ErrTab not_enough_memory, OutRes, Abort, Mem 0 00000D48 09070405 ErrTab invalid_block, Apperr, Abort, Mem 0 00000D4C 0A070405 ErrTab bad_environment, Apperr, Abort, Mem 0 00000D50 0B090301 ErrTab bad_format, BadFmt, User, Unk 0 00000D54 0C070401 ErrTab invalid_access, Apperr, Abort, Unk 0 00000D58 0D090401 ErrTab invalid_data, BadFmt, Abort, Unk 0 00000D5C 0F080302 ErrTab invalid_drive, NotFnd, User, Disk 0 00000D60 10030302 ErrTab current_directory, Auth, User, Disk 0 00000D64 110D0302 ErrTab not_same_device, Unk, User, Disk 0 00000D68 12080302 ErrTab no_more_files, NotFnd, User, Disk 0 00000D6C 500C0302 ErrTab file_exists, Already, User, Disk 0 00000D70 200A0202 ErrTab sharing_violation, Locked, DlyRet, Disk 0 00000D74 210A0202 ErrTab lock_violation, Locked, DlyRet, Disk 0 00000D78 540104FF ErrTab out_of_structures, OutRes, Abort, 0FFh 0 00000D7C 56030301 ErrTab invalid_password, Auth, User, Unk 0 00000D80 52010402 ErrTab cannot_make, OutRes, Abort, Disk 0 00000D84 32090303 ErrTab Not_supported, BadFmt, User, Net 0 00000D88 550C0303 ErrTab Already_assigned, Already, User, Net 0 00000D8C 57090301 ErrTab Invalid_Parameter, BadFmt, User, Unk 0 00000D90 530D0401 ErrTab FAIL_I24, Unk, Abort, Unk 0 00000D94 24010405 ErrTab Sharing_buffer_exceeded,OutRes, Abort, Mem 0 00000D98 26010401 ErrTab Handle_EOF, OutRes, Abort, Unk ;AN000; 0 00000D9C 27010401 ErrTab Handle_DISK_FULL, OutRes, Abort, Unk ;AN000; 0 00000DA0 5A0D0402 ErrTab sys_comp_not_loaded, Unk, Abort, Disk ;AN001; 0 00000DA4 FFFFFFFF DB 0FFh, 0FFH, 0FFH, 0FFh 208 <1> 209 <1> ; 210 <1> ; The following table defines CLASS ACTION and LOCUS info for the INT 24H 211 <1> ; errors. Each entry is 4 bytes long: 212 <1> ; 213 <1> ; Err#,Class,Action,Locus 214 <1> ; 215 <1> ; A Locus value of 0FFh indicates a call specific value (ie. should already 216 <1> ; be set). AN ERROR CODE NOT IN THE TABLE FALLS THROUGH TO THE CATCH ALL AT 217 <1> ; THE END. 218 <1> 219 <1> align 2, db 0 220 <1> PUBLIC ERR_TABLE_24 221 <1> ERR_TABLE_24 LABEL BYTE 0 00000DA8 130B0702 ErrTab write_protect, Media, IntRet, Disk 0 00000DAC 14040501 ErrTab bad_unit, Intrn, Panic, Unk 0 00000DB0 150507FF ErrTab not_ready, HrdFail, IntRet, 0FFh 0 00000DB4 16040501 ErrTab bad_command, Intrn, Panic, Unk 0 00000DB8 170B0402 ErrTab CRC, Media, Abort, Disk 0 00000DBC 18040501 ErrTab bad_length, Intrn, Panic, Unk 0 00000DC0 19050102 ErrTab Seek, HrdFail, Retry, Disk 0 00000DC4 1A0B0702 ErrTab not_DOS_disk, Media, IntRet, Disk 0 00000DC8 1B0B0402 ErrTab sector_not_found, Media, Abort, Disk 0 00000DCC 1C020704 ErrTab out_of_paper, TempSit, IntRet, SerDev 0 00000DD0 1D0504FF ErrTab write_fault, HrdFail, Abort, 0FFh 0 00000DD4 1E0504FF ErrTab read_fault, HrdFail, Abort, 0FFh 0 00000DD8 1F0D04FF ErrTab gen_failure, Unk, Abort, 0FFh 0 00000DDC 200A0202 ErrTab sharing_violation, Locked, DlyRet, Disk 0 00000DE0 210A0202 ErrTab lock_violation, Locked, DlyRet, Disk 0 00000DE4 220B0702 ErrTab wrong_disk, Media, IntRet, Disk 0 00000DE8 32090303 ErrTab not_supported, BadFmt, User, Net 0 00000DEC 23070401 ErrTab FCB_unavailable, Apperr, Abort, Unk 0 00000DF0 24010405 ErrTab Sharing_buffer_exceeded,OutRes, Abort, Mem 0 00000DF4 FF0D05FF DB 0FFh, errCLASS_Unk, errACT_Panic, 0FFh 242 <1> 243 <1> === Switch to base=008400h -> "DOSCODETABLE" 244 <1> section DOSCODETABLE 245 <1> 246 <1> ; 247 <1> ; We need to map old int 24 errors and device driver errors into the new set 248 <1> ; of errors. The following table is indexed by the new errors 249 <1> ; 250 <1> Public ErrMap24 251 <1> ErrMap24 Label BYTE 0 000002E6 13 DB error_write_protect ; 0 0 000002E7 14 DB error_bad_unit ; 1 0 000002E8 15 DB error_not_ready ; 2 0 000002E9 16 DB error_bad_command ; 3 0 000002EA 17 DB error_CRC ; 4 0 000002EB 18 DB error_bad_length ; 5 0 000002EC 19 DB error_Seek ; 6 0 000002ED 1A DB error_not_DOS_disk ; 7 0 000002EE 1B DB error_sector_not_found ; 8 0 000002EF 1C DB error_out_of_paper ; 9 0 000002F0 1D DB error_write_fault ; A 0 000002F1 1E DB error_read_fault ; B 0 000002F2 1F DB error_gen_failure ; C 0 000002F3 1F DB error_gen_failure ; D RESERVED 0 000002F4 1F DB error_gen_failure ; E RESERVED 0 000002F5 22 DB error_wrong_disk ; F 268 <1> 269 <1> Public ErrMap24End 270 <1> ErrMap24End LABEL BYTE 271 <1> 272 <1> 273 <1> PUBLIC DISPATCH 274 <1> 275 <1> ; Standard Functions 276 <1> align 2, db 0 277 <1> DISPATCH LABEL WORD 0 000002F6 [0000] short_addr D_ABORT ; 0 0 0 000002F8 [0000] short_addr D_STD_CON_INPUT ; 1 1 0 000002FA [0000] short_addr D_STD_CON_OUTPUT ; 2 2 0 000002FC [0000] short_addr D_STD_AUX_INPUT ; 3 3 0 000002FE [0000] short_addr D_STD_AUX_OUTPUT ; 4 4 0 00000300 [0000] short_addr D_STD_PRINTER_OUTPUT ; 5 5 0 00000302 [0000] short_addr D_RAW_CON_IO ; 6 6 0 00000304 [0000] short_addr D_RAW_CON_INPUT ; 7 7 0 00000306 [0000] short_addr D_STD_CON_INPUT_NO_ECHO ; 8 8 0 00000308 [0000] short_addr D_STD_CON_STRING_OUTPUT ; 9 9 0 0000030A [0000] short_addr D_STD_CON_STRING_INPUT ; 10 A 0 0000030C [0000] short_addr D_STD_CON_INPUT_STATUS ; 11 B 0 0000030E [0000] short_addr D_STD_CON_INPUT_FLUSH ; 12 C 0 00000310 [0000] short_addr D_DISK_RESET ; 13 D 0 00000312 [0000] short_addr D_SET_DEFAULT_DRIVE ; 14 E 0 00000314 [0000] short_addr D_FCB_OPEN ; 15 F 0 00000316 [0000] short_addr D_FCB_CLOSE ; 16 10 0 00000318 [0000] short_addr D_DIR_SEARCH_FIRST ; 17 11 0 0000031A [0000] short_addr D_DIR_SEARCH_NEXT ; 18 12 0 0000031C [0000] short_addr D_FCB_DELETE ; 19 13 0 0000031E [0000] short_addr D_FCB_SEQ_READ ; 20 14 0 00000320 [0000] short_addr D_FCB_SEQ_WRITE ; 21 15 0 00000322 [0000] short_addr D_FCB_CREATE ; 22 16 0 00000324 [0000] short_addr D_FCB_RENAME ; 23 17 0 00000326 [0000] short_addr CPMFUNC ; 24 18 0 00000328 [0000] short_addr D_GET_DEFAULT_DRIVE ; 25 19 0 0000032A [0000] short_addr D_SET_DMA ; 26 1A 305 <1> 306 <1> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 307 <1> ; C A V E A T P R O G R A M M E R ; 308 <1> ; ; 0 0000032C [0000] short_addr D_SLEAZEFUNC ; 27 1B 0 0000032E [0000] short_addr D_SLEAZEFUNCDL ; 28 1C 311 <1> ; ; 312 <1> ; C A V E A T P R O G R A M M E R ; 313 <1> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 314 <1> 0 00000330 [0000] short_addr CPMFUNC ; 29 1D 0 00000332 [0000] short_addr CPMFUNC ; 30 1E 317 <1> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 318 <1> ; C A V E A T P R O G R A M M E R ; 319 <1> ; ; 0 00000334 [0000] short_addr D_GET_DEFAULT_DPB ; 31 1F 321 <1> ; ; 322 <1> ; C A V E A T P R O G R A M M E R ; 323 <1> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 0 00000336 [0000] short_addr CPMFUNC ; 32 20 0 00000338 [0000] short_addr D_FCB_RANDOM_READ ; 33 21 0 0000033A [0000] short_addr D_FCB_RANDOM_WRITE ; 34 22 0 0000033C [0000] short_addr D_GET_FCB_FILE_LENGTH ; 35 23 0 0000033E [0000] short_addr D_GET_FCB_POSITION ; 36 24 329 <1> VAL1 equ ($-DISPATCH)/2 - 1 330 <1> 331 <1> ; Extended Functions 0 00000340 [0000] short_addr D_SET_INTERRUPT_VECTOR ; 37 25 333 <1> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 334 <1> ; C A V E A T P R O G R A M M E R ; 335 <1> ; ; 0 00000342 [0000] short_addr D_CREATE_PROCESS_DATA_BLOCK ; 38 26 337 <1> ; ; 338 <1> ; C A V E A T P R O G R A M M E R ; 339 <1> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 0 00000344 [0000] short_addr D_FCB_RANDOM_READ_BLOCK ; 39 27 0 00000346 [0000] short_addr D_FCB_RANDOM_WRITE_BLOCK ; 40 28 0 00000348 [0000] short_addr D_PARSE_FILE_DESCRIPTOR ; 41 29 0 0000034A [0000] short_addr D_GET_DATE ; 42 2A 0 0000034C [0000] short_addr D_SET_DATE ; 43 2B 0 0000034E [0000] short_addr D_GET_TIME ; 44 2C 0 00000350 [0000] short_addr D_SET_TIME ; 45 2D 0 00000352 [0000] short_addr D_SET_VERIFY_ON_WRITE ; 46 2E 348 <1> 349 <1> ; Extended functionality group 0 00000354 [0000] short_addr D_GET_DMA ; 47 2F 0 00000356 [0000] short_addr D_GET_VERSION ; 48 30 0 00000358 [0000] short_addr D_Keep_Process ; 49 31 353 <1> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 354 <1> ; C A V E A T P R O G R A M M E R ; 355 <1> ; ; 0 0000035A [0000] short_addr D_GET_DPB ; 50 32 357 <1> ; ; 358 <1> ; C A V E A T P R O G R A M M E R ; 359 <1> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 0 0000035C [0000] short_addr D_SET_CTRL_C_TRAPPING ; 51 33 0 0000035E [0000] short_addr D_GET_INDOS_FLAG ; 52 34 0 00000360 [0000] short_addr D_GET_INTERRUPT_VECTOR ; 53 35 0 00000362 [0000] short_addr D_GET_DRIVE_FREESPACE ; 54 36 0 00000364 [0000] short_addr D_CHAR_OPER ; 55 37 0 00000366 [0000] short_addr D_INTERNATIONAL ; 56 38 366 <1> ; XENIX CALLS 367 <1> ; Directory Group 0 00000368 [0000] short_addr D_MKDIR ; 57 39 0 0000036A [0000] short_addr D_RMDIR ; 58 3A 0 0000036C [0000] short_addr D_CHDIR ; 59 3B 371 <1> ; File Group 0 0000036E [0000] short_addr D_CREAT ; 60 3C 0 00000370 [0000] short_addr D_OPEN ; 61 3D 0 00000372 [0000] short_addr D_CLOSE ; 62 3E 0 00000374 [0000] short_addr D_READ ; 63 3F 0 00000376 [0000] short_addr D_WRITE ; 64 40 0 00000378 [0000] short_addr D_UNLINK ; 65 41 0 0000037A [0000] short_addr D_LSEEK ; 66 42 0 0000037C [0000] short_addr D_CHMOD ; 67 43 0 0000037E [0000] short_addr D_IOCTL ; 68 44 0 00000380 [0000] short_addr D_DUP ; 69 45 0 00000382 [0000] short_addr D_DUP2 ; 70 46 0 00000384 [0000] short_addr D_CURRENT_DIR ; 71 47 384 <1> ; Memory Group 0 00000386 [0000] short_addr D_ALLOC ; 72 48 0 00000388 [0000] short_addr D_DEALLOC ; 73 49 0 0000038A [0000] short_addr D_SETBLOCK ; 74 4A 388 <1> ; Process Group 0 0000038C [0000] short_addr D_EXEC ; 75 4B 0 0000038E [0000] short_addr D_EXIT ; 76 4C 0 00000390 [0000] short_addr D_WAIT ; 77 4D 392 <1> ; Special Group 0 00000392 [0000] short_addr D_FIND_FIRST ; 78 4E 0 00000394 [0000] short_addr D_FIND_NEXT ; 79 4F 395 <1> ; SPECIAL SYSTEM GROUP 396 <1> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 397 <1> ; C A V E A T P R O G R A M M E R ; 398 <1> ; ; 0 00000396 [0000] short_addr D_SET_CURRENT_PDB ; 80 50 0 00000398 [0000] short_addr D_GET_CURRENT_PDB ; 81 51 0 0000039A [0000] short_addr D_GET_IN_VARS ; 82 52 0 0000039C [0000] short_addr D_SETDPB ; 83 53 403 <1> ; ; 404 <1> ; C A V E A T P R O G R A M M E R ; 405 <1> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 0 0000039E [0000] short_addr D_GET_VERIFY_ON_WRITE ; 84 54 407 <1> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 408 <1> ; C A V E A T P R O G R A M M E R ; 409 <1> ; ; 0 000003A0 [0000] short_addr D_DUP_PDB ; 85 55 411 <1> ; ; 412 <1> ; C A V E A T P R O G R A M M E R ; 413 <1> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 0 000003A2 [0000] short_addr D_RENAME ; 86 56 0 000003A4 [0000] short_addr D_FILE_TIMES ; 87 57 0 000003A6 [0000] short_addr D_AllocOper ; 88 58 417 <1> ; Network extention system calls 0 000003A8 [0000] short_addr D_GetExtendedError ; 89 59 0 000003AA [0000] short_addr D_CreateTempFile ; 90 5A 0 000003AC [0000] short_addr D_CreateNewFile ; 91 5B 0 000003AE [0000] short_addr D_LockOper ; 92 5C 0 000003B0 [0000] short_addr D_ServerCall ; 93 5D 0 000003B2 [0000] short_addr D_UserOper ; 94 5E 0 000003B4 [0000] short_addr D_AssignOper ; 95 5F 0 000003B6 [0000] short_addr D_NameTrans ; 96 60 0 000003B8 [0000] short_addr CPMFunc ; 97 61 0 000003BA [0000] short_addr D_Get_Current_PDB ; 98 62 428 <1> ; the next call is reserved for hangool sys call 0 000003BC [0000] short_addr D_ECS_Call ; 99 63 430 <1> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 431 <1> ; C A V E A T P R O G R A M M E R ; 432 <1> ; ; 0 000003BE [0000] short_addr D_Set_Printer_Flag ; 100 64 434 <1> ; ; 435 <1> ; C A V E A T P R O G R A M M E R ; 436 <1> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 0 000003C0 [0000] short_addr D_GetExtCntry ; 101 65 0 000003C2 [0000] short_addr D_GetSetCdPg ; 102 66 0 000003C4 [0000] short_addr D_ExtHandle ; 103 67 0 000003C6 [0000] short_addr D_Commit ; 104 68 0 000003C8 [0000] short_addr D_GSetMediaID ; 105 69 ;AN000; 0 000003CA [0000] short_addr D_Commit ; 106 6A ;AN000; 0 000003CC [0000] short_addr D_IFS_IOCTL ; 107 6B ;AN000; 0 000003CE [0000] short_addr D_Extended_Open ; 108 6C ;AN000; 445 <1> ; 446 <1> VAL2 equ ($-DISPATCH)/2 - 1 447 <1> 448 <1> %if VAL1 != 24h || VAL2 != 6Ch 449 <1> %error Adjust hardcoded table sizes in disp.nas 450 <1> %endif 451 <1> 452 <1> 453 <1> %If Installed 454 <1> 455 <1> align 2, db 0 456 <1> PUBLIC FOO 457 <1> FOO LABEL WORD 0 000003D0 [0000] Short_addr Leave2F 459 <1> DOSGroup equ DOSGROUP ; NASM port equate 0 000003D2 [A301] DTab DW OFFSET DOSTable 461 <1> DTAB equ DTab ; NASM port label 462 <1> PUBLIC FOO,DTAB 463 <1> 464 <1> align 2, db 0 0 000003D4 00 db 0 ; padding 466 <1> DOSTable LABEL WORD 0 000003D5 30 DB (DOSTableEnd-DOSTable-1)/2 0 000003D6 [0000] Short_addr DOSInstall ; 0 install check 0 000003D8 [0000] Short_addr DOS_CLOSE ; 1 DOS_CLOSE 0 000003DA [0000] Short_addr RECSET ; 2 RECSET 0 000003DC [0000] Short_addr DOSGetGroup ; 3 Get DOSGROUP 0 000003DE [0000] Short_addr PATHCHRCMP ; 4 PATHCHRCMP 0 000003E0 [0000] Short_addr OUTT ; 5 OUT 0 000003E2 [0000] Short_addr NET_I24_ENTRY ; 6 NET_I24_ENTRY 0 000003E4 [0000] Short_addr PLACEBUF ; 7 PLACEBUF 0 000003E6 [0000] Short_addr FREE_SFT ; 8 FREE_SFT 0 000003E8 [0000] Short_addr BUFWRITE ; 9 BUFWRITE 0 000003EA [0000] Short_addr SHARE_VIOLATION ; 10 SHARE_VIOLATION 0 000003EC [0000] Short_addr SHARE_ERROR ; 11 SHARE_ERROR 0 000003EE [0000] Short_addr SET_SFT_MODE ; 12 SET_SFT_MODE 0 000003F0 [0000] Short_addr DATE16 ; 13 DATE16 0 000003F2 [0000] Short_addr idle ; 14 empty slot 0 000003F4 [0000] Short_addr SCANPLACE ; 15 SCANPLACE 0 000003F6 [0000] Short_addr idle ; 16 empty slot 0 000003F8 [0000] Short_addr StrCpy ; 17 StrCpy 0 000003FA [0000] Short_addr StrLen ; 18 StrLen 0 000003FC [0000] Short_addr Ucase ; 19 Ucase 0 000003FE [0000] Short_addr POINTCOMP ; 20 POINTCOMP 0 00000400 [0000] Short_addr CHECKFLUSH ; 21 CHECKFLUSH 0 00000402 [0000] Short_addr SFFromSFN ; 22 SFFromSFN 0 00000404 [0000] Short_addr GetCDSFromDrv ; 23 GetCDSFromDrv 0 00000406 [0000] Short_addr Get_User_Stack ; 24 Get_User_Stack 0 00000408 [0000] Short_addr GetThisDrv ; 25 GetThisDrv 0 0000040A [0000] Short_addr DriveFromText ; 26 DriveFromText 0 0000040C [0000] Short_addr SETYEAR ; 27 SETYEAR 0 0000040E [0000] Short_addr DSUM ; 28 DSUM 0 00000410 [0000] Short_addr DSLIDE ; 29 DSLIDE 0 00000412 [0000] Short_addr StrCmp ; 30 StrCmp 0 00000414 [0000] Short_addr InitCDS ; 31 initcds 0 00000416 [0000] Short_addr pJFNFromHandle ; 32 pJfnFromHandle 0 00000418 [0000] Short_addr D_NameTrans ; 33 $NameTrans 0 0000041A [0000] Short_addr CAL_LK ; 34 CAL_LK 0 0000041C [0000] Short_addr DEVNAME ; 35 DEVNAME 0 0000041E [0000] Short_addr Idle ; 36 Idle 0 00000420 [0000] Short_addr DStrLen ; 37 DStrLen 0 00000422 [0000] Short_addr NLS_OPEN ; 38 NLS_OPEN DOS 3.3 0 00000424 [0000] Short_addr D_CLOSE ; 39 $CLOSE DOS 3.3 0 00000426 [0000] Short_addr NLS_LSEEK ; 40 NLS_LSEEK DOS 3.3 0 00000428 [0000] Short_addr D_READ ; 41 $READ DOS 3.3 0 0000042A [0000] Short_addr FastInit ; 42 FastInit DOS 3.4 ;AN000; 0 0000042C [0000] Short_addr NLS_IOCTL ; 43 NLS_IOCTL DOS 3.3 0 0000042E [0000] Short_addr GetDevList ; 44 GetDevList DOS 3.3 0 00000430 [0000] Short_addr NLS_GETEXT ; 45 NLS_GETEXT DOS 3.3 0 00000432 [0000] Short_addr MSG_RETRIEVAL ; 46 MSG_RETRIEVAL DOS 4.0 ;AN000; 0 00000434 [0000] Short_addr Fake_Version ; 47 Fake_Version DOS 4.0 ;AN006; 516 <1> 517 <1> DOSTableEnd LABEL BYTE 518 <1> 519 <1> %ENDIF 520 <1> 521 <1> ; NOTE WARNING: This declaration of HEADER must be THE LAST thing in this 522 <1> ; module. The reason is so that the data alignments are the same in 523 <1> ; IBM-DOS and MS-DOS up through header. 524 <1> ;---------------------------------------Start of Korean support 2/11/KK 525 <1> ; 526 <1> ; The varialbes for ECS version are moved here for the same data alignments 527 <1> ; as IBM-DOS and MS-DOS. 528 <1> ; 529 <1> === Switch to base=001140h -> "TABLE" 530 <1> section TABLE ; in DOSDATA 531 <1> 0 00000DF8 ?? I_AM InterChar, byte ; Interim character flag ( 1= interim) ;AN000; 533 <1> ;AN000; 534 <1> ;------- NOTE: NEXT TWO BYTES SOMETIMES USED AS A WORD !! --------------------- 535 <1> DUMMY LABEL WORD ;AN000; 536 <1> PUBLIC InterCon ; Console in Interim mode ( 1= interim) ;AN000; 0 00000DF9 00 InterCon db 0 ;AN000; 538 <1> PUBLIC SaveCurFlg ; Print, do not advance cursor flag ;AN000; 0 00000DFA 00 SaveCurFlg db 0 ;AN000; 540 <1> ;-----------------------------------------End of Korean support 2/11/KK 541 <1> 542 <1> 543 <1> HEADER equ Header ; NASM port label 544 <1> PUBLIC HEADER 545 <1> Header LABEL BYTE 546 <1> %IF DEBUG 547 <1> DB 13,10,"Debugging DOS version " 548 <1> DB MAJOR_VERSION + "0" 549 <1> DB "." 550 <1> DB (MINOR_VERSION / 10) + "0" 551 <1> DB (MINOR_VERSION MOD 10) + "0" 552 <1> %ENDIF 553 <1> 554 <1> %IFN IBM 555 <1> DB 13,10,"MS-DOS version " 556 <1> DB MAJOR_VERSION + "0" 557 <1> DB "." 558 <1> DB (MINOR_VERSION / 10) + "0" 559 <1> DB (MINOR_VERSION MOD 10) + "0" 560 <1> 561 <1> %IF HIGHMEM 562 <1> DB "H" 563 <1> %ENDIF 564 <1> 565 <1> DB 13,10, "Copyright 1981,82,83,84,88 Microsoft Corp.",13,10,"$" 566 <1> %ENDIF 567 <1> 568 <1> %IF DEBUG 569 <1> DB 13,10,"$" 570 <1> %ENDIF 571 <1> 572 <1> MSTAB001E label byte 573 <1> 574 <1> %include "copyrigh.mac" ;AN000; 0 00000DFB 4D5320444F53205665 DB "MS DOS Version 4.00 (C)Copyright 1988 Microsoft Corp" 0 00000E04 7273696F6E20342E30 0 00000E0D 3020284329436F7079 0 00000E16 726967687420313938 0 00000E1F 38204D6963726F736F 0 00000E28 667420436F7270 0 00000E2F 4C6963656E73656420 DB "Licensed Material - Property of Microsoft " 0 00000E38 4D6174657269616C20 0 00000E41 2D2050726F70657274 0 00000E4A 79206F66204D696372 0 00000E53 6F736F66742020 575 <1> 576 <1> ; SYS init extended table, DOS 3.3 F.C. 5/29/86 577 <1> ; 578 <1> PUBLIC SysInitTable 579 <1> I_need COUNTRY_CDPG,BYTE 580 <1> I_need SYSINITVAR,BYTE 581 <1> 582 <1> align 2, db 0 583 <1> SysInitTable label byte 0 00000E5A [0000] dw OFFSET SYSINITVAR wrt DOSGROUP ; pointer to sysinit var 0 00000E5C 0000 dw 0 ; segment 0 00000E5E [0000] dw OFFSET COUNTRY_CDPG wrt DOSGROUP ; pointer to country table 0 00000E60 0000 dw 0 ; segment of pointer 588 <1> ; DOS 3.3 F.C. 6/12/86 589 <1> 590 <1> ; FASTOPEN communications area DOS 3.3 F.C. 5/29/86 591 <1> ; 592 <1> PUBLIC FastOpenTable 593 <1> PUBLIC FastTable ; a better name 594 <1> EXTRN FastRet:FAR ; defined in misc2.asm 595 <1> extern fastentry 596 <1> 597 <1> align 2, db 0 598 <1> FastTable label byte ; a better name 599 <1> FastOpenTable label byte 0 00000E62 0200 dw 2 ; number of entries 0 00000E64 [0000] dw fastentry ; pointer to ret instr. 0 00000E66 [0000] dw DOSENTRY ; and will be modified by 0 00000E68 [0000] dw fastentry ; FASTxxx when loaded in 0 00000E6A [0000] dw DOSENTRY ; 605 <1> ; DOS 3.3 F.C. 6/12/86 606 <1> PUBLIC FastFlg ;AN000; flags 607 <1> FastFlg label byte ;AN000; don't change the following order 0 00000E6C 00 I_am FastOpenFlg,BYTE,<0> ;AN000; 0 00000E6D 00 I_am FastSeekFlg,BYTE,<0> ;AN000; 610 <1> 611 <1> PUBLIC FastOpen_Ext_Info 612 <1> 613 <1> ; FastOpen_Ext_Info is used as a temporary storage for saving dirpos,dirsec 614 <1> ; and clusnum which are filled by DOS 3.3 when calling FastOpen Insert 615 <1> ; or filled by FastOPen when calling FastOpen Lookup 616 <1> 617 <1> FastOpen_Ext_Info label byte 0 00000E6E 000000000000000000 db FASTOPEN_EXTENDED_INFO_struc_size dup(0) ;dirpos 0 00000E77 0000 619 <1> 620 <1> ; Dir_Info_Buff is a dir entry buffer which is filled by FastOPen 621 <1> ; when calling FastOpen Lookup 622 <1> 0 00000E79 00 align 2, db 0 624 <1> PUBLIC Dir_Info_Buff 625 <1> 626 <1> Dir_Info_Buff label byte 0 00000E7A 000000000000000000 db dir_entry_struc_size dup (0) 0 00000E83 000000000000000000 0 00000E8C 000000000000000000 0 00000E95 0000000000 628 <1> 629 <1> 0 00000E9A ???? I_am Next_Element_Start,WORD ; save next element start offset 631 <1> 632 <1> ; Following 4 variables moved to MSDATA.asm (P4986) 633 <1> ; I_am FSeek_drive,BYTE ;AN000; fastseek drive # 634 <1> ; I_am FSeek_firclus,WORD ;AN000; fastseek first cluster # 635 <1> ; I_am FSeek_logclus,WORD ;AN000; fastseek logical cluster # 636 <1> ; I_am FSeek_logsave,WORD ;AN000; fastseek returned log clus # 637 <1> 638 <1> ; The following is a stack and its pointer for interrupt 2F which is uesd 639 <1> ; by NLSFUNC. There is no significant use of this stack, we are just trying 640 <1> ; not to destroy the INT 21 stack saved for the user. 641 <1> 642 <1> 643 <1> User_SP_2F equ USER_SP_2F ; NASM port label 644 <1> PUBLIC User_SP_2F 645 <1> 646 <1> align 2, db 0 647 <1> USER_SP_2F LABEL WORD 0 00000E9C [8C01] dw OFFSET FAKE_STACK_2F wrt DOSGROUP 649 <1> 650 <1> PUBLIC Packet_Temp 651 <1> Packet_Temp label word ; temporary packet used by readtime 652 <1> PUBLIC DOS_TEMP ; temporary word 653 <1> DOS_TEMP label word 0 00000E9E 000000000000000000 FAKE_STACK_2F dw 14 dup (0) ; 12 register temporary storage 0 00000EA7 000000000000000000 0 00000EB0 000000000000000000 0 00000EB9 00 655 <1> 656 <1> PUBLIC Hash_Temp ;AN000; temporary word 657 <1> Hash_Temp label word ;AN000; 0 00000EBA 0000000000000000 dw 4 dup (0) ;AN000; temporary hash table during config.sys 659 <1> 660 <1> PUBLIC SCAN_FLAG ; flag to indicate key ALT_Q 661 <1> SCAN_FLAG label byte 0 00000EC2 00 db 0 663 <1> 0 00000EC3 00 align 2, db 0 665 <1> ;;; The following 2 words must be adjacent for IBMDOS reasons 666 <1> 667 <1> PUBLIC DATE_FLAG 668 <1> DATE_FLAG label word ; flag to 0 00000EC4 0000 dw 0 ; to update the date 670 <1> ;;;; special tag for IBMDOS 671 <1> PUBLIC FETCHI_TAG 672 <1> FETCHI_TAG label word ; TAG to make DOS 3.3 work 0 00000EC6 0000 dw 0 ; must be 22642 674 <1> ;;; The above 2 words must be adjacent for IBMDOS reasons 675 <1> ; DOS 3.3 F.C. 6/12/86 0 00000EC8 ???? I_am Del_ExtCluster,WORD ; for dos_delete ;AN000; 677 <1> 678 <1> align 2, db 0 679 <1> PUBLIC MSG_EXTERROR ; for system message addr ;AN000; 680 <1> MSG_EXTERROR label DWORD ;AN000; 0 00000ECA 00000000 dd 0 ; for extended error ;AN000; 0 00000ECE 00000000 dd 0 ; for parser ;AN000; 0 00000ED2 00000000 dd 0 ; for critical errror ;AN000; 0 00000ED6 00000000 dd 0 ; for IFS ;AN000; 0 00000EDA 00000000 dd 0 ; for code reduction ;AN000; 686 <1> 687 <1> PUBLIC SEQ_SECTOR ; last sector read ;AN000; 688 <1> SEQ_SECTOR label DWORD ;AN000; 0 00000EDE FFFFFFFF dd -1 ;AN000; 690 <1> 0 00000EE2 00 I_am XA_CONDITION,BYTE,<0> ; for Extended Attributes ;AN000; 692 <1> ; I_am XA_ES,WORD ; for extended find ;AN000; 693 <1> ; I_am XA_BP,WORD ; for extended find ;AN000; 694 <1> ; I_am XA_handle,WORD ; for get/set EA ;AN000; 0 00000EE3 ?? I_am XA_type,BYTE ; for get/set EA ;AN000; 696 <1> ; I_am XA_device,BYTE ; for get/set EA ;AN000; 0 00000EE4 ?? I_am XA_from,BYTE ; for get/set EA ;AN000; 698 <1> ; I_am XA_VAR,WORD ; for get/set EA ;AN000; 699 <1> ; I_am XA_TEMP,WORD ; for get/set EA ;AN000; 700 <1> ; I_am XA_TEMP2,WORD ; for get/set EA ;AN000; 701 <1> ; 702 <1> 703 <1> ; I_am MAX_EA_SIZE,WORD,<29> ; max EA list size ;AN000; 704 <1> ; I_am MAX_EANAME_SIZE,WORD,<20> ; max EA name list size ;AN000; 705 <1> ; I_am XA_COUNT,WORD,<2> ; number of EA entries ;AN000; 706 <1> 707 <1> 708 <1> ; PUBLIC XA_TABLE ; for get/set EA ;AN000; 709 <1> ; 710 <1> ;XA_TABLE label byte ;AN000; 711 <1> ; db EAISBINARY ;Code Page ;AN000; 712 <1> ; dw EASYSTEM ;AN000; 713 <1> ; db 0,2 ;AN000; 714 <1> ; dw 2 ;AN000; 715 <1> ; db 'CP' ;AN000; 716 <1> ; 717 <1> ; db EAISBINARY ;File Type ;AN000; 718 <1> ; dw EASYSTEM ;AN000; 719 <1> ; db 0,8 ;AN000; 720 <1> ; dw 1 ;AN000; 721 <1> ; db 'FILETYPE' ;AN000; 722 <1> ; 723 <1> 724 <1> ; PUBLIC XA_PACKET ;AN000; 725 <1> ;XA_PACKET label byte ;AN000; 726 <1> ;IF DBCS ;AN000; 727 <1> ; dw 18 ;AN000; 728 <1> ; db 18 dup(0) ;AN000; 729 <1> ; PUBLIC DBCS_PACKET ;AN000; 730 <1> ;DBCS_PACKET label byte ;AN000; 731 <1> ; db 5 dup(0) 732 <1> ;ELSE 733 <1> ; dw 2, 0 ; get/set device code page ;AN000; 734 <1> ;ENDIF 0 00000EE5 00 align 2, db 0 0 00000EE6 ???????? I_am CurHashEntry,DWORD ; current hash buffer entry ;AN000; 737 <1> ;; I_am ACT_PAGE,WORD,<-1> ;BL ; active EMS page ;AN000; 0 00000EEA ???? I_am SC_SECTOR_SIZE,WORD ; sector size for SC ;AN000; 0 00000EEC ?? I_am SC_DRIVE,BYTE ; drive # for secondary cache ;AN000; 0 00000EED FF I_am CurSC_DRIVE,BYTE,<-1> ; current SC drive ;AN000; 0 00000EEE ???????? I_am CurSC_SECTOR,DWORD ; current SC starting sector ;AN000; 0 00000EF2 0000 I_am SC_STATUS,WORD,<0> ; SC status word ;AN000; 0 00000EF4 00 I_am SC_FLAG,BYTE,<0> ; SC flag ;AN000; 0 00000EF5 0000 I_am IFS_DRIVER_ERR,WORD,<0> ; driver error for IFS ;AN000; 745 <1> 746 <1> PUBLIC NO_NAME_ID ;AN000; 747 <1> NO_NAME_ID label byte ;AN000; 0 00000EF7 4E4F204E414D452020 db 'NO NAME ' ; null media id ;AN000; 0 00000F00 2020 749 <1> 750 <1> align 2, db 0 751 <1> PUBLIC SWAP_AREA_TABLE ;AN000; 752 <1> SWAP_AREA_TABLE label byte ;AN000; 0 00000F02 0200 I_am NUM_SWAP_AREA,WORD,<2> ; number of swap areas ;AN000; 0 00000F04 ???????? I_am SWAP_IN_DOS,DWORD ; swap in dos area ;AN000; 0 00000F08 ???? I_am SWAP_IN_DOS_LEN,WORD ; swap in dos area length ;AN000; 0 00000F0A ???????? I_am SWAP_ALWAYS_AREA,DWORD ; swap always area ;AN000; 0 00000F0E ???? I_am SWAP_ALWAYS_AREA_LEN,WORD ; swap always area length ;AN000; 0 00000F10 ???????? I_am IFSFUNC_SWAP_IN_DOS,DWORD ; ifsfunc swap in dos area ;AN000; 0 00000F14 ???? I_am IFSFUNC_SWAP_IN_DOS_LEN,WORD ; ifsfunc swap in dos area length ;AN000; 760 <1> 0 00000F16 ???? I_am SWAP_AREA_LEN,WORD ; swap area length ;AN000; 0 00000F18 ???? I_am FIRST_BUFF_ADDR,WORD ; first buffer address ;AN000; 0 00000F1A 0000 I_am SPECIAL_VERSION,WORD,<0> ;AN006; used by INT 2F 47H 0 00000F1C FF I_am FAKE_COUNT,BYTE,<255> ;AN008; fake version count 0 00000F1D ???? I_am OLD_FIRSTCLUS,WORD ;AN011; save old first cluster for fastopen 19 ;=== Pop trace listing source 20 END === Trace listing source: ../DOS/msdisp.lst 1 ; SCCSID = @(#)ibmdisp.asm 1.1 85/04/10 2 ;TITLE IBM DOS DISPATCHER - System call dispatch code 3 ;NAME DISP 4 5 ; 6 ; System call dispatch code 7 ; 8 9 [list -] 9 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 14 15 ;=== Push trace listing source: disp.nas 16 %include "disp.nas" 1 <1> ; SCCSID = @(#)disp.asm 1.1 85/04/10 2 <1> ; SCCSID = @(#)disp.asm 1.1 85/04/10 3 <1> ; 4 <1> ; Dispatcher code 5 <1> ; 6 <1> 7 <1> [list -] 7 ****************** <1> warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi] 14 <2> [list -] 10 <1> %include "dosseg.nas" 1 <2> ; SCCSID = @(#)dosseg.asm 1.1 85/04/10 2 <2> ; SCCSID = @(#)dosseg.asm 1.1 85/04/10 3 <2> ; 4 <2> ; segment ordering for MSDOS 5 <2> ; 6 <2> 7 <2> %include "ddataseg.nas" 1 <3> === Switch to base=001140h -> "DOSSTART" 2 <3> section DOSSTART align=16 PUBLIC class=DOSSTART 3 <3> ; (no prior section) ; DOSSTART ENDS 4 <3> === Switch to base=001140h -> "START" 5 <3> section START align=1 PUBLIC class=START 6 <3> ; (no prior section) ; START ENDS 7 <3> === Switch to base=001140h -> "CONSTANTS" 8 <3> section CONSTANTS align=2 PUBLIC class=CONST 9 <3> ; (no prior section) ; CONSTANTS ENDS 10 <3> === Switch to base=001140h -> "DATA" 11 <3> section DATA align=2 PUBLIC class=DATA 12 <3> ; (no prior section) ; DATA ENDS 13 <3> === Switch to base=001140h -> "TABLE" 14 <3> section TABLE align=2 PUBLIC class=TABLE 15 <3> ; (no prior section) ; TABLE ENDS 16 <3> === Switch to base=001140h -> "CODE" 17 <3> section CODE align=1 PUBLIC class=CODE 18 <3> ; (no prior section) ; CODE ENDS 19 <3> === Switch to base=001140h -> "DOSDATATABLE" 20 <3> section DOSDATATABLE align=2 PUBLIC class=DOSDATACODE 21 <3> ; (no prior section) ; DOSDATATABLE ENDS 22 <3> === Switch to base=001140h -> "DOSDATACODE" 23 <3> section DOSDATACODE align=1 PUBLIC class=DOSDATACODE 24 <3> ; (no prior section) ; DOSDATACODE ENDS 25 <3> === Switch to base=001140h -> "LAST" 26 <3> section LAST align=16 PUBLIC class=LAST 27 <3> ; (no prior section) ; LAST ENDS 28 <3> 29 <3> group DOSGROUP DOSSTART START CONSTANTS DATA TABLE CODE DOSDATATABLE DOSDATACODE LAST 8 <2> 9 <2> %include "dcodeseg.nas" 1 <3> 2 <3> %ifndef DCODESEGNAS 3 <3> %assign DCODESEGNAS 1 4 <3> === Switch to base=008400h -> "DOSCODETABLE" 5 <3> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <3> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=008400h -> "DOSCODECODE" 7 <3> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <3> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=008400h -> "DOSBIOCODE" 9 <3> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=008400h -> "BIOCODE" 10 <3> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <3> 12 <3> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <3> 14 <3> %endif 10 <2> === Switch to base=001140h -> "LAST" 11 <2> section LAST 12 <2> ; (no prior section) ; LAST ENDS 11 <1> %include "dossym.mac" 1 <2> ; SCCSID = @(#)dossym.asm 1.1 85/04/10 2 <2> ; SCCSID = @(#)dossym.asm 1.1 85/04/10 3 <2> ; PAGE 80,132 4 <2> TRUE EQU 0FFFFh 5 <2> FALSE EQU 0 6 <2> 7 <2> Installed equ TRUE 8 <2> %IFNDEF DEBUG 9 <2> DEBUG equ FALSE 10 <2> %ENDIF 11 <2> %IFNDEF debug 12 <2> debug equ DEBUG 13 <2> %ENDIF 14 <2> 15 <2> %if 0 16 <2> DBCS equ FALSE ; for fixmem.pl operation 17 <2> %endif 18 <2> 19 <2> ; NASM original macros 20 <2> 21 <2> %macro DBCS 1.nolist 22 <2> %defstr %%string %1 23 <2> %substr %%prefix %%string 1,2 24 <2> %substr %%suffix %%string 3,-1 25 <2> %ifnidni %%prefix, "= " 26 <2> %error Unexpected DBCS prefix 27 <2> %endif 28 <2> %deftok %%token %%suffix 29 <2> %xdefine DBCS %%token 30 <2> %endmacro 31 <2> 32 <2> %include "DBCS.SW" 1 <3> DBCS = FALSE 2 <3> 33 <2> %unmacro DBCS 1.nolist 34 <2> 35 <2> ; end of NASM original macros 36 <2> 37 <2> %include "dosmac.mac" 1 <3> ; SCCSID = @(#)dosmac.asm 1.1 85/04/10 2 <3> ; SCCSID = @(#)dosmac.asm 1.1 85/04/10 3 <3> ; 4 <3> ; Macro file for MSDOS. 5 <3> ; 6 <3> 7 <3> %ifndef __DOSMAC_MAC__ 8 <3> %assign __DOSMAC_MAC__ 1 9 <3> 10 <3> TRUE EQU 0FFFFh 11 <3> FALSE EQU 0 12 <3> 13 <3> 14 <3> ; NASM original macros (comment for fixmem.pl) 15 <3> 16 <3> ;SUBTTL BREAK a listing into pages and give new subtitles 17 <3> ;PAGE 18 <3> %imacro BREAK 0-1+.nolist 19 <3> ;SUBTTL subtitle 20 <3> ;PAGE 21 <3> %endmacro 22 <3> ;.xcref break 23 <3> 24 <3> BREAK 25 <3> 26 <3> %if 0 27 <3> AsmVars Macro varlist 28 <3> IRP var, 29 <3> AsmVar var 30 <3> ENDM 31 <3> ENDM 32 <3> 33 <3> AsmVar Macro var 34 <3> IFNDEF var 35 <3> var = FALSE 36 <3> ENDIF 37 <3> ENDM 38 <3> %endif 39 <3> 40 <3> BREAK 41 <3> 42 <3> ; 43 <3> ; declare a variable external and allocate a size 44 <3> ; 45 <3> ;AsmVar InstalledData 46 <3> %ifndef InstalledData 47 <3> %define InstalledData 0 48 <3> %endif 49 <3> 50 <3> %imacro I_NEED 1-2.nolist 51 <3> %ifn InstalledData === Switch to base=001140h -> "DATA" 52 <3> [section DATA] 53 <3> %IFIDNi %2, WORD 54 <3> EXTRN %1:WORD 55 <3> %ELSE 56 <3> %IFIDNi %2, DWORD 57 <3> EXTRN %1:DWORD 58 <3> %ELSE 59 <3> EXTRN %1:BYTE 60 <3> %ENDIF 61 <3> %ENDIF 62 <3> __SECT__ 63 <3> %ENDIF 64 <3> %endmacro 65 <3> ;.xcref I_need 66 <3> 67 <3> ; 68 <3> ; call a procedure that may be external. The call will be short. 69 <3> ; 70 <3> %imacro invoke 1.nolist 71 <3> ;.xcref 72 <3> EXTRN %1:NEAR 73 <3> ;.cref 74 <3> CALL %1 75 <3> %endmacro 76 <3> ;.xcref invoke 77 <3> 78 <3> ;PAGE 79 <3> ; 80 <3> ; jump to a label that may be external. The jump will be near. 81 <3> ; 82 <3> %imacro transfer 1.nolist 83 <3> ;.xcref 84 <3> EXTRN %1:NEAR 85 <3> ;.cref 86 <3> JUMP %1 87 <3> %endmacro 88 <3> ;.xcref transfer 89 <3> 90 <3> ; 91 <3> ; get a short address in a word 92 <3> ; 93 <3> %imacro short_addr 1.nolist 94 <3> %ifnidn %1, ? 95 <3> EXTRN %1:NEAR 96 <3> DW OFFSET %1 97 <3> %ELSE 98 <3> DW ? 99 <3> %ENDIF 100 <3> %endmacro 101 <3> ;.xcref short_addr 102 <3> 103 <3> ; 104 <3> ; get a long address in a dword 105 <3> ; 106 <3> %imacro long_addr 1.nolist 107 <3> EXTRN %1:NEAR 108 <3> DD %1 109 <3> %endmacro 110 <3> ;.xcref long_addr 111 <3> 112 <3> ; 113 <3> ; declare a PROC near or far but PUBLIC nonetheless 114 <3> ; 115 <3> ;.xcref ?frame 116 <3> ;.xcref ?aframe 117 <3> ;.xcref ?stackdepth 118 <3> ;.xcref ?initstack 119 <3> %assign ?frame 0 ; initial 120 <3> %assign ?aframe 0 ; initial 121 <3> %assign ?stackdepth 0 ; initial stack size 122 <3> %assign ?initstack 0 ; initial stack size 123 <3> 124 <3> %imacro procedure 1-2.nolist 125 <3> %assign ?frame 0 126 <3> %assign ?aframe 2 ;; remember the pushed BP 127 <3> %warning proc %1... 128 <3> %1 PROC %2 129 <3> PUBLIC %1 130 <3> %assign ?initstack ?stackdepth ;; beginning of procedure 131 <3> %endmacro 132 <3> ;.xcref procedure 133 <3> 134 <3> ; 135 <3> ; end a procedure and check that stack depth is preserved 136 <3> ; 137 <3> %imacro EndProc 1-2.nolist 138 <3> %ifnidni %2, NoCheck ;; check the stack size 139 <3> %if ?initstack != ?stackdepth ;; is it different? 140 <3> %warning ***** Possible stack size error in %1 ***** 141 <3> %endif 142 <3> %endif 143 <3> %1 ENDP 144 <3> %endmacro 145 <3> ;.xcref endproc 146 <3> ;PAGE 147 <3> ; 148 <3> ; define a data item to be public and of an appropriate size/type 149 <3> ; 150 <3> 151 <3> %imacro stripangles 2.nolist 152 <3> %defstr %%param %2 153 <3> %rep 16 154 <3> %substr %%opening %%param 1 155 <3> %ifidn %%opening, '<' 156 <3> %substr %%param %%param 2,-1 157 <3> %endif 158 <3> %endrep 159 <3> %rep 16 160 <3> %strlen %%length %%param 161 <3> %substr %%closing %%param %%length 162 <3> %ifidn %%closing, '>' 163 <3> %substr %%param %%param 1,-2 164 <3> %endif 165 <3> %endrep 166 <3> %deftok %%token %%param 167 <3> %1 %%token 168 <3> %endmacro 169 <3> 170 <3> %imacro I_AM 2-*.nolist 171 <3> ;I_AM MACRO name,size,init 172 <3> %xdefine %%name %1 173 <3> ;; declare the type of the object 174 <3> %IFIDNi %2, WORD 175 <3> %1 LABEL WORD 176 <3> %assign I_AM_SIZE 1 177 <3> %assign I_AM_LEN 2 178 <3> %ELSE 179 <3> %IFIDNi %2, DWORD 180 <3> %1 LABEL DWORD 181 <3> %assign I_AM_SIZE 2 182 <3> %assign I_AM_LEN 2 183 <3> %ELSE 184 <3> %IFIDNi %2, BYTE 185 <3> %1 LABEL BYTE 186 <3> %assign I_AM_SIZE 1 187 <3> %assign I_AM_LEN 1 188 <3> %ELSE 189 <3> %1 LABEL BYTE 190 <3> %undef I_AM_SIZE 191 <3> stripangles %assign I_AM_SIZE, %2 192 <3> %assign I_AM_LEN 1 193 <3> %ENDIF 194 <3> %ENDIF 195 <3> %ENDIF 196 <3> ;; declare the object public 197 <3> PUBLIC %%name 198 <3> ;; if no initialize then allocate blank storage 199 <3> %IF %0 == 2 200 <3> DB I_AM_SIZE*I_AM_LEN DUP (?) 201 <3> %ELSE 202 <3> %ifn InstalledData 203 <3> %rotate 2 204 <3> %rep %0 - 2 205 <3> %IF I_AM_LEN == 1 206 <3> stripangles db, %1 207 <3> %ELSE 208 <3> stripangles dw, %1 209 <3> %ENDIF 210 <3> %assign I_AM_SIZE I_AM_SIZE - 1 211 <3> %rotate 1 212 <3> %endrep 213 <3> %IF I_AM_SIZE != 0 214 <3> %error ***** initialization of %%name not complete ***** 215 <3> %ENDIF 216 <3> %ELSE 217 <3> DB I_AM_SIZE*I_AM_LEN DUP (?) 218 <3> %ENDIF 219 <3> %ENDIF 220 <3> %endmacro 221 <3> 222 <3> %imacro I_AM_NOBITS 2-*.nolist 223 <3> ;I_AM MACRO name,size,init 224 <3> %xdefine %%name %1 225 <3> ;; declare the type of the object 226 <3> %IFIDNi %2, WORD 227 <3> %1 LABEL WORD 228 <3> %assign I_AM_SIZE 1 229 <3> %assign I_AM_LEN 2 230 <3> %ELSE 231 <3> %IFIDNi %2, DWORD 232 <3> %1 LABEL DWORD 233 <3> %assign I_AM_SIZE 2 234 <3> %assign I_AM_LEN 2 235 <3> %ELSE 236 <3> %IFIDNi %2, BYTE 237 <3> %1 LABEL BYTE 238 <3> %assign I_AM_SIZE 1 239 <3> %assign I_AM_LEN 1 240 <3> %ELSE 241 <3> %1 LABEL BYTE 242 <3> %undef I_AM_SIZE 243 <3> stripangles %assign I_AM_SIZE, %2 244 <3> %assign I_AM_LEN 1 245 <3> %ENDIF 246 <3> %ENDIF 247 <3> %ENDIF 248 <3> ;; declare the object public 249 <3> PUBLIC %%name 250 <3> ;; if no initialize then allocate blank storage 251 <3> %IF %0 == 2 252 <3> resb I_AM_SIZE*I_AM_LEN 253 <3> %ELSE 254 <3> %ifn InstalledData 255 <3> %rotate 2 256 <3> %rep %0 - 2 257 <3> %IF I_AM_LEN == 1 258 <3> resb 1 259 <3> %ELSE 260 <3> resw 1 261 <3> %ENDIF 262 <3> %assign I_AM_SIZE I_AM_SIZE - 1 263 <3> %rotate 1 264 <3> %endrep 265 <3> %IF I_AM_SIZE != 0 266 <3> %error ***** initialization of %%name not complete ***** 267 <3> %ENDIF 268 <3> %ELSE 269 <3> resb I_AM_SIZE*I_AM_LEN 270 <3> %ENDIF 271 <3> %ENDIF 272 <3> %endmacro 273 <3> 274 <3> ;.xcref I_AM 275 <3> ;.xcref I_AM_SIZE 276 <3> ;.xcref I_AM_LEN 277 <3> %assign I_AM_SIZE 0 278 <3> %assign I_AM_LEN 0 279 <3> 280 <3> ;PAGE 281 <3> 282 <3> ; 283 <3> ; define an entry in a procedure 284 <3> ; 285 <3> %imacro entry 1.nolist 286 <3> %1: 287 <3> PUBLIC %1 288 <3> %endmacro 289 <3> ;.xcref entry 290 <3> 291 <3> BREAK 292 <3> 293 <3> %imacro error 1.nolist 294 <3> ;.xcref 295 <3> MOV AL, %1 296 <3> transfer SYS_RET_ERR 297 <3> ;.cref 298 <3> %endmacro 299 <3> ;.xcref error 300 <3> 301 <3> BREAK 302 <3> ; 303 <3> ; given a label either 2 byte jump to another label _J 304 <3> ; if it is near enough or 3 byte jump to 305 <3> ; 306 <3> 307 <3> %imacro jump 1.nolist 308 <3> ;.xcref 309 <3> 310 <3> %ifndef %1_J ;; is this the first invocation 311 <3> %%a: JMP %1 312 <3> %ELSE 313 <3> %IF (%1_J >= $) || ($-%1_J > 126) 314 <3> %%a: JMP %1 ;; is the jump too far away? 315 <3> %ELSE 316 <3> %%a: JMP %1_J ;; do the short one... 317 <3> %ENDIF 318 <3> %ENDIF 319 <3> %ixdefine %1_j %%a 320 <3> ;.cref 321 <3> %endmacro 322 <3> ;.xcref jump 323 <3> 324 <3> BREAK 325 <3> 326 <3> %imacro return 0.nolist 327 <3> %%a: 328 <3> RET 329 <3> %xdefine ret_l %%a 330 <3> %endmacro 331 <3> ;.xcref return 332 <3> 333 <3> BREAK 334 <3> 335 <3> %imacro condret 2.nolist 336 <3> %assign %%exit 0 337 <3> %ifdef ret_l ;; if ret_l is defined 338 <3> %if (($ - ret_l) <= 126) && ($ > ret_l) 339 <3> ;; if ret_l is near enough then 340 <3> %%a: j%1 ret_l ;; a: j to ret_l 341 <3> %xdefine ret_%1 %%a ;; define ret_ to be a: 342 <3> %assign %%exit 1 343 <3> %endif 344 <3> %endif 345 <3> %ifn %%exit 346 <3> %ifdef ret_%1 ;; if ret_ defined 347 <3> %if (($ - ret_%1) <= 126) && ($ > ret_%1) 348 <3> ;; if ret_ is near enough 349 <3> %%a: j%1 ret_%1 ;; a: j to ret_ 350 <3> %xdefine ret_%1 %%a ;; define ret_ to be a: 351 <3> %assign %%exit 1 352 <3> %endif 353 <3> %endif 354 <3> %endif 355 <3> %ifn %%exit 356 <3> j%2 %%a ;; j a: 357 <3> return ;; return 358 <3> %%a: ;; a: 359 <3> %xdefine ret_%1 ret_l ;; define ret_ to be ret_l 360 <3> %endif 361 <3> %endmacro 362 <3> ;.xcref condret 363 <3> 364 <3> BREAK 365 <3> 366 <3> %imacro retz 0.nolist 367 <3> condret z,nz 368 <3> %endmacro 369 <3> ;.xcref retz 370 <3> 371 <3> BREAK 372 <3> 373 <3> %imacro retnz 0.nolist 374 <3> condret nz,z 375 <3> %endmacro 376 <3> ;.xcref retnz 377 <3> 378 <3> BREAK 379 <3> 380 <3> %imacro retc 0.nolist 381 <3> condret c,nc 382 <3> %endmacro 383 <3> ;.xcref retc 384 <3> 385 <3> BREAK 386 <3> 387 <3> %imacro retnc 0.nolist 388 <3> condret nc,c 389 <3> %endmacro 390 <3> ;.xcref retnc 391 <3> 392 <3> BREAK 393 <3> 394 <3> %imacro context 1.nolist 395 <3> PUSH SS 396 <3> stripangles POP, %1 397 <3> ; ASSUME %1:DOSGROUP 398 <3> %endmacro 399 <3> ;.xcref context 400 <3> 401 <3> BREAK 402 <3> 403 <3> %imacro SaveReg 0-*.nolist ;; push those registers 404 <3> %rep %0 405 <3> %assign ?stackdepth ?stackdepth + 1 406 <3> stripangles push, %1 407 <3> %rotate 1 408 <3> %endrep 409 <3> %endmacro 410 <3> ;.xcref SaveReg 411 <3> 412 <3> BREAK 413 <3> 414 <3> %imacro RestoreReg 0-*.nolist ;; pop those registers 415 <3> %rep %0 416 <3> %assign ?stackdepth ?stackdepth - 1 417 <3> stripangles pop, %1 418 <3> %rotate 1 419 <3> %endrep 420 <3> %endmacro 421 <3> ;.xcref RestoreReg 422 <3> 423 <3> BREAK 424 <3> 425 <3> %imacro EnterCrit 1.nolist 426 <3> Invoke E%1 427 <3> %endmacro 428 <3> 429 <3> %imacro LeaveCrit 1.nolist 430 <3> Invoke L%1 431 <3> %endmacro 432 <3> 433 <3> Break 434 <3> 435 <3> ;AsmVars 436 <3> %ifndef ShareF 437 <3> %idefine ShareF 0 438 <3> %endif 439 <3> %ifndef Cargs 440 <3> %idefine Cargs 0 441 <3> %endif 442 <3> %ifndef Redirector 443 <3> %idefine Redirector 0 444 <3> %endif 445 <3> %ifndef debug 446 <3> %idefine debug 0 447 <3> %endif 448 <3> 449 <3> %if debug 450 <3> %imacro fmt 3-*.nolist 451 <3> ;fmt MACRO typ,lev,fmts,args 452 <3> ;local a,b,c 453 <3> PUSHF 454 <3> %IFNempty %1 455 <3> TEST word [BugTyp],%1 456 <3> JZ %%c 457 <3> CMP word [BugLev],%2 458 <3> JB %%c 459 <3> %ENDIF 460 <3> PUSH AX 461 <3> PUSH BP 462 <3> MOV BP,SP 463 <3> %If (! sharef) && (! redirector) === Switch to base=001140h -> "TABLE" 464 <3> [section Table] 465 <3> %%a: db %3,0 466 <3> __SECT__ 467 <3> MOV AX,OFFSET %%a wrt DOSGROUP 468 <3> %else 469 <3> jmp short %%b 470 <3> %%a: db %3,0 471 <3> %if sharef 472 <3> %%b: mov ax,offset %%a wrt share 473 <3> %else 474 <3> %%b: mov ax,offset %%a wrt netwrk 475 <3> %endif 476 <3> %endif 477 <3> PUSH AX 478 <3> %iassign cargs 2 479 <3> %rotate 3 480 <3> %rep %0 - 3 481 <3> %ifidni ax, %1 482 <3> MOV AX,[BP+2] 483 <3> %ELSE 484 <3> MOV AX, %1 485 <3> %ENDIF 486 <3> PUSH AX 487 <3> %iassign cargs cargs + 2 488 <3> %rotate 1 489 <3> %endrep 490 <3> invoke PFMT 491 <3> ADD SP, Cargs 492 <3> POP BP 493 <3> POP AX 494 <3> %%c: 495 <3> POPF 496 <3> %endmacro 497 <3> %else 498 <3> %imacro fmt 3-*.nolist 499 <3> %endmacro 500 <3> %endif 501 <3> 502 <3> Break 503 <3> 504 <3> ;AsmVar Debug,$temp 505 <3> 506 <3> %imacro detectstripangles 4.nolist 507 <3> %defstr %%param %4 508 <3> %assign ?%2 0 509 <3> %assign ?%3 0 510 <3> %rep 16 511 <3> %substr %%opening %%param 1 512 <3> %ifidn %%opening, '<' 513 <3> %substr %%param %%param 2,-1 514 <3> %assign ?%2 ?%2 + 1 515 <3> %endif 516 <3> %endrep 517 <3> %rep 16 518 <3> %strlen %%length %%param 519 <3> %substr %%closing %%param %%length 520 <3> %ifidn %%closing, '>' 521 <3> %substr %%param %%param 1,-2 522 <3> %assign ?%3 ?%3 + 1 523 <3> %endif 524 <3> %endrep 525 <3> %deftok %%token %%param 526 <3> %define ?%1 %%token 527 <3> %endmacro 528 <3> 529 <3> 530 <3> %IF debug 531 <3> %imacro DOSAssume 3-*.nolist 532 <3> ;DOSAssume Macro reg,reglist,message 533 <3> %ifidni %1, CS 534 <3> %assign %%temp 1 535 <3> %else 536 <3> %ifidni %1, SS 537 <3> %assign %%temp 0 538 <3> %else 539 <3> %error ***** Invalid DOS register %1 in DOSAssume ***** 540 <3> %endif 541 <3> %endif 542 <3> %rotate 1 543 <3> %assign %%level 0 544 <3> %assign %%amount %0 - 1 545 <3> %rep 16 546 <3> detectstripangles %%token, %%opening, %%closing, %1 547 <3> %assign %%level %%level + ? %+ %%opening 548 <3> %assign %%level %%level - ? %+ %%closing 549 <3> %ifidni ? %+ %%token, DS 550 <3> %assign %%temp %%temp | 2 551 <3> %else 552 <3> %ifidni ? %+ %%token, ES 553 <3> %assign %%temp %%temp | 4 554 <3> %else 555 <3> %error ***** Invalid register reg in DOSAssume ***** 556 <3> %endif 557 <3> %endif 558 <3> %assign %%amount %%amount - 1 559 <3> %rotate 1 560 <3> %if %%level <= 0 561 <3> %exitrep 562 <3> %endif 563 <3> %endrep 564 <3> 565 <3> PUSH AX 566 <3> MOV AX, %%temp 567 <3> PUSH AX 568 <3> %IF SHAREF 569 <3> MOV AX,OFFSET %%a 570 <3> %ELSE 571 <3> MOV AX,OFFSET %%a wrt DOSGroup 572 <3> %ENDIF 573 <3> PUSH AX 574 <3> Invoke SegCheck 575 <3> POP AX 576 <3> %IFN SHAREF === Switch to base=001140h -> "TABLE" 577 <3> [section Table] 578 <3> %ELSE 579 <3> JMP SHORT %%b 580 <3> %ENDIF 581 <3> %%a: 582 <3> %rep %%amount 583 <3> DB %1 584 <3> %rotate 1 585 <3> %endrep 586 <3> db 0 587 <3> %IFN SHAREF 588 <3> __SECT__ 589 <3> %ELSE 590 <3> %%b: 591 <3> %ENDIF 592 <3> ;IRP r, 593 <3> ; ASSUME r:DOSGroup 594 <3> ;ENDM 595 <3> %endmacro 596 <3> %ELSE 597 <3> %imacro DOSAssume 3-*.nolist 598 <3> ;DOSAssume Macro reg,reglist,message 599 <3> ;IRP r, 600 <3> ; ASSUME r:DOSGroup 601 <3> ;ENDM 602 <3> %endmacro 603 <3> %ENDIF 604 <3> 605 <3> BREAK 606 <3> 607 <3> %if 0 608 <3> ;IF DEBUG 609 <3> Assert MACRO kind, objs, message 610 <3> LOCAL a,b 611 <3> IFIDN , 612 <3> CMP objs,0 613 <3> JZ a 614 <3> fmt <>,<>, 615 <3> a: 616 <3> ELSE 617 <3> IFIDN , 618 <3> CMP objs,0 619 <3> JNZ a 620 <3> fmt <>,<>, 621 <3> a: 622 <3> ELSE 623 <3> PUSH AX 624 <3> IRP obj, 625 <3> PUSH obj 626 <3> ENDM 627 <3> IF SHAREF 628 <3> MOV AX,OFFSET b 629 <3> ELSE 630 <3> MOV AX,OFFSET DOSGroup:b 631 <3> ENDIF 632 <3> PUSH AX 633 <3> IFIDN , 634 <3> Invoke BUFCheck 635 <3> ENDIF 636 <3> IFIDN , 637 <3> Invoke SFTCheck 638 <3> ENDIF 639 <3> IFIDN , 640 <3> Invoke DPBCheck 641 <3> ENDIF 642 <3> POP AX 643 <3> IF SHAREF 644 <3> JMP SHORT a 645 <3> b DB Message,0 646 <3> a: 647 <3> ELSE === Switch to base=001140h -> "TABLE" 648 <3> Table segment 649 <3> b db Message,0 === Switch to base=001140h -> "TABLE" 650 <3> Table ends 651 <3> ENDIF 652 <3> ENDIF 653 <3> ENDIF 654 <3> ENDM 655 <3> %ELSE 656 <3> %imacro Assert 0-*.nolist 657 <3> %endmacro 658 <3> %ENDIF 659 <3> 660 <3> %ifndef Installed 661 <3> %idefine Installed 1 662 <3> %endif 663 <3> 664 <3> Break 665 <3> 666 <3> %imacro CallInstall 3-*.nolist 667 <3> ;CallInstall MACRO name,mpx,fn,save,restore 668 <3> %define %%name %1 669 <3> %assign %%mpx %2 670 <3> %assign %%fn %3 671 <3> %IF Installed 672 <3> %rotate 3 673 <3> %assign %%level 0 674 <3> %assign %%amountsaved 0 675 <3> %rep %0 - 3 676 <3> %ifnempty %1 677 <3> detectstripangles %%token, %%opening, %%closing, %1 678 <3> %assign %%level %%level + ? %+ %%opening 679 <3> %assign %%level %%level - ? %+ %%closing 680 <3> SaveReg ? %+ %%token 681 <3> %endif 682 <3> %assign %%amountsaved %%amountsaved + 1 683 <3> %rotate 1 684 <3> %if %%level <= 0 685 <3> %exitrep 686 <3> %endif 687 <3> %endrep 688 <3> MOV AX,(%%mpx << 8) + %%fn 689 <3> INT 2Fh 690 <3> %assign %%level 0 691 <3> %assign %%amountrestored 0 692 <3> %rep %0 - 3 - %%amountsaved 693 <3> %ifnempty %1 694 <3> detectstripangles %%token, %%opening, %%closing, %1 695 <3> %assign %%level %%level + ? %+ %%opening 696 <3> %assign %%level %%level - ? %+ %%closing 697 <3> RestoreReg ? %+ %%token 698 <3> %endif 699 <3> %assign %%amountrestored %%amountrestored + 1 700 <3> %rotate 1 701 <3> %if %%level <= 0 702 <3> %exitrep 703 <3> %endif 704 <3> %endrep 705 <3> %if %%level > 0 || %0 != 3 + %%amountsaved + %%amountrestored 706 <3> %error Wrong amount saved or restored 707 <3> %endif 708 <3> %ELSE 709 <3> Invoke %%name 710 <3> %ENDIF 711 <3> %endmacro 712 <3> 713 <3> Break 714 <3> 715 <3> %imacro localvar 2.nolist 716 <3> %ifidni %2, BYTE 717 <3> %assign ?frame ?frame + 1 718 <3> %assign %%a ?frame 719 <3> labelsize %1, byte, bp - %%a 720 <3> %else 721 <3> %ifidni %2, WORD 722 <3> %assign ?frame ?frame + 2 723 <3> %assign %%a ?frame 724 <3> labelsize %1, word, bp - %%a 725 <3> %else 726 <3> %ifidni %2, DWORD 727 <3> %assign ?frame ?frame + 4 728 <3> %assign %%a ?frame 729 <3> labelsize %1 %+ l, word, bp - %%a 730 <3> labelsize %1 %+ h, word, bp - %%a + 2 731 <3> labelsize %1, dword, bp - %%a 732 <3> %else 733 <3> %assign ?frame ?frame + %2 734 <3> %assign %%a ?frame 735 <3> labelsize %1, byte, bp - %%a 736 <3> %endif 737 <3> %endif 738 <3> %endif 739 <3> %endmacro 740 <3> 741 <3> %imacro enter 0.nolist 742 <3> push bp 743 <3> mov bp,sp 744 <3> sub sp,?frame 745 <3> %endmacro 746 <3> 747 <3> %imacro leave 0.nolist 748 <3> mov sp,bp 749 <3> pop bp 750 <3> %endmacro 751 <3> 752 <3> 753 <3> %imacro argvar 2.nolist 754 <3> %ifidni %2, BYTE 755 <3> %assign %%a ?aframe 756 <3> %assign ?aframe ?aframe + 1 757 <3> labelsize %1, byte, bp + %%a 758 <3> %else 759 <3> %ifidni %2, WORD 760 <3> %assign %%a ?aframe 761 <3> %assign ?aframe ?aframe + 2 762 <3> labelsize %1, word, bp + %%a 763 <3> %else 764 <3> %ifidni %2, DWORD 765 <3> %assign %%a ?aframe 766 <3> %assign ?aframe ?aframe + 4 767 <3> labelsize %1 %+ l, word, bp + %%a 768 <3> labelsize %1 %+ h, word, bp + %%a + 2 769 <3> labelsize %1, dword, bp + %%a 770 <3> %else 771 <3> %assign %%a ?aframe 772 <3> %assign ?aframe ?aframe + %2 773 <3> labelsize %1, byte, bp + %%a 774 <3> %endif 775 <3> %endif 776 <3> %endif 777 <3> %endmacro 778 <3> 779 <3> BREAK 780 <3> 781 <3> %imacro errnz 1.nolist 782 <3> detectstripangles %%token, %%opening, %%closing, %1 783 <3> %if ? %+ %%token 784 <3> %error %1 <> 0 785 <3> %endif 786 <3> %endmacro 787 <3> 788 <3> %endif 38 <2> 39 <2> %include "versiona.mac" 1 <3> 2 <3> major_version equ 4 ;Major DOS version 3 <3> minor_version equ 00 ;Minor DOS Version 4 <3> 5 <3> MINOR_VERSION equ minor_version ; NASM port equate 6 <3> MAJOR_VERSION equ major_version ; NASM port equate 7 <3> expected_version equ (MINOR_VERSION << 8)+MAJOR_VERSION 8 <3> 9 <3> alt_major_version equ 5 ;Major DOS version 10 <3> alt_minor_version equ 26 ;Minor DOS Version 11 <3> 12 <3> alt_expected_version equ (alt_minor_version << 8) + alt_major_version 13 <3> 14 <3> %warning out: ... for DOS Version 4.00 ... 14 ****************** <3> warning: out: ... for DOS Version 4.00 ... [-w+user] 15 <3> 16 <3> ;****************************** 17 <3> ;Each assembler program should: 18 <3> ; mov ah,030h ;DOS Get Version function 19 <3> ; int 021h ;Version ret. in AX,minor version first 20 <3> ; cmp ax,expected_version ;ALL utilities should check for an 21 <3> ; jne error_handler ; EXACT version match. 22 <3> ;****************************** 23 <3> 40 <2> 41 <2> BREAK 42 <2> 43 <2> c_DEL EQU 7Fh ; ASCII rubout or delete previous char 44 <2> c_BS EQU 08h ; ^H ASCII backspace 45 <2> c_CR EQU 0Dh ; ^M ASCII carriage return 46 <2> c_LF EQU 0Ah ; ^J ASCII linefeed 47 <2> c_ETB EQU 17h ; ^W ASCII end of transmission 48 <2> c_NAK EQU 15h ; ^U ASCII negative acknowledge 49 <2> c_ETX EQU 03h ; ^C ASCII end of text 50 <2> c_HT EQU 09h ; ^I ASCII tab 51 <2> 52 <2> BREAK 53 <2> 54 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 55 <2> ; ; 56 <2> ; C A V E A T P R O G R A M M E R ; 57 <2> ; ; 58 <2> ; Certain structures, constants and system calls below are private to ; 59 <2> ; the DOS and are extremely version-dependent. They may change at any ; 60 <2> ; time at the implementors' whim. As a result, they must not be ; 61 <2> ; documented to the general public. If an extreme case arises, they ; 62 <2> ; must be documented with this warning. ; 63 <2> ; ; 64 <2> ; Those structures and constants that are subject to the above will be ; 65 <2> ; marked and bracketed with the flag: ; 66 <2> ; ; 67 <2> ; C A V E A T P R O G R A M M E R ; 68 <2> ; ; 69 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 70 <2> 71 <2> %include "bpb.mac" 1 <3> %warning out: BPB.INC... 1 ****************** <3> warning: out: BPB.INC... [-w+user] 2 <3> ; SCCSID = @(#)BPB.ASM 1.1 85/04/29 3 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 4 <3> ; C A V E A T P R O G R A M M E R ; 5 <3> ; ; 6 <3> 7 <3> ; BIOS PARAMETER BLOCK DEFINITION 8 <3> ; THIS STRUCTURE IS USED TO BUILD A FULL DPB 9 <3> 10 <3> BPBLOCK STRUC 0 00000F20 ???? BPSECSZ DW ? ; SIZE IN BYTES OF PHYSICAL SECTOR 0 00000F22 ?? BPCLUS DB ? ; SECTORS/ALLOC UNIT 0 00000F23 ???? BPRES DW ? ; NUMBER OF RESERVED SECTORS 0 00000F25 ?? BPFTCNT DB ? ; NUMBER OF FATS 0 00000F26 ???? BPDRCNT DW ? ; NUMBER OF DIRECTORY ENTRIES 0 00000F28 ???? BPSCCNT DW ? ; TOTAL NUMBER OF SECTORS 0 00000F2A ?? BPMEDIA DB ? ; MEDIA DESCRIPTOR BYTE 0 00000F2B ???? BPFTSEC DW ? ; NUMBER OF SECTORS TAKEN UP BY ONE FAT 19 <3> BPBLOCK ENDS 20 <3> 21 <3> A_BPB STRUC 0 00000F20 ???? BPB_BYTESPERSECTOR DW ? 0 00000F22 ?? BPB_SECTORSPERCLUSTER DB ? 0 00000F23 ???? BPB_RESERVEDSECTORS DW ? 0 00000F25 ?? BPB_NUMBEROFFATS DB ? 0 00000F26 ???? BPB_ROOTENTRIES DW ? 0 00000F28 ???? BPB_TOTALSECTORS DW ? 0 00000F2A ?? BPB_MEDIADESCRIPTOR DB ? 0 00000F2B ???? BPB_SECTORSPERFAT DW ? 0 00000F2D ???? BPB_SECTORSPERTRACK DW ? 0 00000F2F ???? BPB_HEADS DW ? 0 00000F31 ???? BPB_HIDDENSECTORS DW ? 0 00000F33 ???? DW ? 0 00000F35 ???? BPB_BIGTOTALSECTORS DW ? 0 00000F37 ???? DW ? 0 00000F39 ???????????? DB 6 DUP(?) 37 <3> A_BPB ENDS 38 <3> ; ; 39 <3> ; C A V E A T P R O G R A M M E R ; 40 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 41 <3> 72 <2> 73 <2> %include "buffer.mac" 1 <3> %include "buf2sw.mac" 1 <4> %define BUF2 1 2 <3> 3 <3> ; SCCSID = @(#)buffer.asm 1.1 85/04/09 4 <3> BREAK 5 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 6 <3> ; C A V E A T P R O G R A M M E R ; 7 <3> ; ; 8 <3> 9 <3> %ifdef BUF2 10 <3> 11 <3> ; Field definition for I/O buffer information 12 <3> 13 <3> BUFFINFO STRUC 0 00000F20 ???????? NEXTBUF DD ? ; Pointer to next buffer in list 15 <3> ; The next two items are often refed as a word 16 <3> buf_ID: 0 00000F24 ?? BUFDRV DB ? ; Logical drive # assoc with buffer FF = free 18 <3> buf_flags: 0 00000F25 ?? BUFDATAFLAG db ? 0 00000F26 ?? BUFPRI DB ? ; Buffer selection priority (see EQUs below) 0 00000F27 ?? alignb 2 22 <3> buf_sector: 0 00000F28 ???????? BUFSECNO dd ? ; Sector number of buffer 24 <3> alignb 2 0 00000F2C ???????? BUFDRVDP DD ? ; Pointer to drive parameters 26 <3> BUFFINFO ENDS 27 <3> 28 <3> BUFINSIZ EQU BUFFINFO_struc_size 29 <3> ; Size of structure in bytes 30 <3> BUFINSIZE equ BUFINSIZ 31 <3> 32 <3> FREEPRI EQU 0 33 <3> LBRPRI EQU 2 ; Last byte of buffer read 34 <3> LBWPRI EQU 4 ; Last byte written 35 <3> RPRI EQU 6 ; Read but not last byte 36 <3> WPRI EQU 8 ; Written but not last byte 37 <3> DIRPRI EQU 15 ; Directory Sector 38 <3> FATPRI EQU 30 ; FAT sector 39 <3> 40 <3> buf_dirty EQU 01000000B 41 <3> buf_isDATA EQU 00001000B 42 <3> buf_isDIR EQU 00000100B 43 <3> buf_isFAT EQU 00000010B 44 <3> buf_type_0 EQU 11110001B ; AND sets type to "none" 45 <3> 46 <3> %else 47 <3> 48 <3> ; Field definition for I/O buffer information 49 <3> 50 <3> BUFFINFO STRUC 51 <3> buf_next DW ? ; Pointer to next buffer in list 52 <3> buf_prev DW ? ; Pointer to prev buffer in list 53 <3> buf_ID DB ? ; Drive of buffer (bit 7 = 0) 54 <3> ; SFT table index (bit 7 = 1) 55 <3> ; = FFH if buffer free 56 <3> buf_flags DB ? ; Bit 7 = 1 if Remote file buffer 57 <3> ; = 0 if Local device buffer 58 <3> ; Bit 6 = 1 if buffer dirty 59 <3> ; Bit 5 = Reserved 60 <3> ; Bit 4 = Search bit (bit 7 = 1) 61 <3> ; Bit 3 = 1 if buffer is DATA 62 <3> ; Bit 2 = 1 if buffer is DIR 63 <3> ; Bit 1 = 1 if buffer is FAT 64 <3> ; Bit 0 = Reserved 65 <3> buf_sector DD ? ; Sector number of buffer (bit 7 = 0) 66 <3> ; The next two items are often refed as a word (bit 7 = 0) 67 <3> buf_wrtcnt DB ? ; For FAT sectors, # times sector written out 68 <3> buf_wrtcntinc DW ? ; " " " , # sectors between each write 69 <3> buf_DPB DD ? ; Pointer to drive parameters 70 <3> buf_fill DW ? ; How full buffer is (bit 7 = 1) 71 <3> buf_reserved DB ? ; make DWORD boundary for 386 72 <3> BUFFINFO ENDS 73 <3> 74 <3> labelsize buf_offset, dword, buf_sector 75 <3> ;For bit 7 = 1, this is the byte 76 <3> ;offset of the start of the buffer in 77 <3> ;the file pointed to by buf_ID. Thus 78 <3> ;the buffer starts at location 79 <3> ;buf_offset in the file and contains 80 <3> ;buf_fill bytes. 81 <3> 82 <3> BUFINSIZ EQU BUFFINFO_struc_size 83 <3> ; Size of structure in bytes 84 <3> 85 <3> buf_Free EQU 0FFh ; buf_id of free buffer 86 <3> 87 <3> ;Flag byte masks 88 <3> buf_isnet EQU 10000000B 89 <3> buf_dirty EQU 01000000B 90 <3> 91 <3> buf_isDATA EQU 00001000B 92 <3> buf_isDIR EQU 00000100B 93 <3> buf_isFAT EQU 00000010B 94 <3> buf_type_0 EQU 11110001B ; AND sets type to "none" 95 <3> 96 <3> buf_NetID EQU BUFINSIZ 97 <3> 98 <3> ; 99 <3> ; Buffer Hash Entry Structure 100 <3> 101 <3> BUFFER_HASH_ENTRY STRUC ; DOS 4.00 102 <3> EMS_PAGE_NUM DW ? ; logical page number for EMS handle 103 <3> BUFFER_BUCKET DD ? ; pointer to buffers 104 <3> DIRTY_COUNT DB ? ; number of dirty buffers 105 <3> BUFFER_RESERVED DB ? ; reserved 106 <3> BUFFER_HASH_ENTRY ENDS 107 <3> 108 <3> MaxBuffinBucket EQU 15 ; Max number of buffers per bucket 109 <3> MaxBucketinPage EQU 2 ; Max number of buckets per 16kb page 110 <3> 111 <3> %endif 112 <3> 113 <3> ; ; 114 <3> ; C A V E A T P R O G R A M M E R ; 115 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 74 <2> 75 <2> BREAK 76 <2> ; Location of user registers relative user stack pointer 77 <2> 78 <2> user_environ STRUC 0 00000F20 ???? user_AX DW ? 0 00000F22 ???? user_BX DW ? 0 00000F24 ???? user_CX DW ? 0 00000F26 ???? user_DX DW ? 0 00000F28 ???? user_SI DW ? 0 00000F2A ???? user_DI DW ? 0 00000F2C ???? user_BP DW ? 0 00000F2E ???? user_DS DW ? 0 00000F30 ???? user_ES DW ? 0 00000F32 ???? user_IP DW ? 0 00000F34 ???? user_CS DW ? 0 00000F36 ???? user_F DW ? 91 <2> user_environ ENDS 92 <2> 93 <2> %include "sysvar.mac" 1 <3> ; SCCSID = @(#)sysvar.asm 1.1 85/04/10 2 <3> %include "version.mac" 1 <4> ; Some modules really want TRUE to be 0FFH. Best to let them have their way. 2 <4> TRUE EQU 0FFFFh 3 <4> TRUEBYTE EQU 0FFh 4 <4> FALSE EQU 0 5 <4> 6 <4> ; 7 <4> ; Use the following switches to control cmacros.inc 8 <4> ; 9 <4> ?PLM equ 0 10 <4> ?WIN equ 0 11 <4> 12 <4> memS EQU 1 ; Small model 13 <4> ; 14 <4> ; Use the switches below to produce the standard Microsoft version or the IBM 15 <4> ; version of the operating system 16 <4> ; 17 <4> ; The below chart will indicate how to set the switches to build the various 18 <4> ; versions 19 <4> ; 20 <4> ; IBMVER IBMCOPYRIGHT 21 <4> ; -------------------------------------------------------- 22 <4> ; IBM Version | TRUE TRUE 23 <4> ; -------------------------------------------------------- 24 <4> ; MS Version | FALSE FALSE 25 <4> ; -------------------------------------------------------- 26 <4> ; Clone Version | TRUE FALSE 27 <4> ; 28 <4> IBMVER EQU TRUE 29 <4> IBMCOPYRIGHT EQU FALSE 30 <4> 31 <4> BUFFERFLAG EQU ~ IBMCOPYRIGHT 32 <4> 33 <4> %ifndef MSVER 34 <4> MSVER EQU ~ IBMVER 35 <4> %endif 36 <4> IBM EQU IBMVER 37 <4> ; 38 <4> ; 39 <4> %IF IBMVER 40 <4> %IF IBMCOPYRIGHT 41 <4> %warning out: ... IBM version build switch on ... 42 <4> %ELSE 43 <4> %warning out: ... CLONE version build switch on ... 43 ****************** <4> warning: out: ... CLONE version build switch on ... [-w+user] 44 <4> %ENDIF 45 <4> %ELSE 46 <4> %IFN IBMCOPYRIGHT 47 <4> %warning out: ... MS version build switch on ... 48 <4> %ELSE 49 <4> %warning out: !!!!!!!!! VERSION SWITCHES SET INCORECTLY !!!!!!!!! 50 <4> %warning out: !!!!!!!!! CHECK SETTINGS IN INC\VERSION.INC !!!!!!!!! 51 <4> %ENDIF 52 <4> %ENDIF 53 <4> ; 54 <4> ; 55 <4> ;*************************************************************************** 56 <4> ;* The following switches are for DBCS or SBCS support * 57 <4> ;* * 58 <4> ;* Set INTERNAT EQU TRUE FOR DBCS * 59 <4> ;* Set INTERNAT EQU FALSE FOR SBCS * 60 <4> ;* * 61 <4> ;*************************************************************************** 62 <4> ; 63 <4> IBMJAPVER EQU FALSE ;If TRUE set KANJI true also 64 <4> 65 <4> ; 66 <4> ; Switch INTERNAT for DBCS support 67 <4> ; 68 <4> INTERNAT EQU FALSE 69 <4> ; 70 <4> %IF INTERNAT 71 <4> %ifndef KANJI 72 <4> KANJI EQU TRUE 73 <4> %endif 74 <4> IBMJAPAN EQU TRUE 75 <4> %ELSE 76 <4> %ifndef KANJI 77 <4> KANJI EQU FALSE 78 <4> %endif 79 <4> IBMJAPAN EQU FALSE 80 <4> %ENDIF 81 <4> 82 <4> %ifndef altvect ; avoid jerking off vector.inc 83 <4> ALTVECT EQU FALSE ;Switch to build ALTVECT version 84 <4> %endif 85 <4> 86 <4> ; 87 <4> ; Country code switches 88 <4> ; The default contry code is assumed as USA. 89 <4> ; 90 <4> %IF INTERNAT 91 <4> KOREA EQU TRUE 92 <4> JAPAN EQU FALSE 93 <4> %ELSE 94 <4> KOREA EQU FALSE 95 <4> JAPAN EQU FALSE 96 <4> %ENDIF 97 <4> ; 98 <4> %IF INTERNAT 99 <4> %warning out: Internat(ECS) version build switch on 100 <4> %ENDIF 3 <3> 4 <3> SysInitVars STRUC 0 00000F20 ???????? SYSI_DPB DD ? ; DPB chain 0 00000F24 ???????? SYSI_SFT DD ? ; SFT chain 0 00000F28 ???????? SYSI_CLOCK DD ? ; CLOCK device 0 00000F2C ???????? SYSI_CON DD ? ; CON device 0 00000F30 ???? SYSI_MAXSEC DW ? ; maximum sector size 0 00000F32 ???????? SYSI_BUF DD ? ; points to Hashinitvar 0 00000F36 ???????? SYSI_CDS DD ? ; CDS list 0 00000F3A ???????? SYSI_FCB DD ? ; FCB chain 0 00000F3E ???? SYSI_Keep DW ? ; keep count 0 00000F40 ?? SYSI_NUMIO DB ? ; Number of block devices 0 00000F41 ?? SYSI_NCDS DB ? ; number of CDS's 0 00000F42 ???????? SYSI_DEV DD ? ; device list 0 00000F46 ???? SYSI_ATTR DW ? ; null device attribute word 0 00000F48 ???? SYSI_STRAT DW ? ; null device strategy entry point 0 00000F4A ???? SYSI_INTER DW ? ; null device interrupt entry point 0 00000F4C ???????????????? SYSI_NAME DB 8 DUP(?) ; null device name 0 00000F54 ?? SYSI_SPLICE DB ? ; TRUE -> splicees being done 0 00000F55 ???? SYSI_IBMDOS_SIZE DW ? ; DOS size in paragraphs 0 00000F57 ???????? SYSI_IFS_DOSCALL@ DD ? ; IFS DOS service rountine entry 0 00000F5B ???????? SYSI_IFS DD ? ; IFS header chain 0 00000F5F ???????? SYSI_BUFFERS DW ?,? ; BUFFERS= values (m,n) 0 00000F63 ?? SYSI_BOOT_DRIVE DB ? ; boot drive A=1 B=2,.. 0 00000F64 ?? SYSI_DWMOVE DB ? ; 1 if 386 machine 0 00000F65 ???? SYSI_EXT_MEM DW ? ; Extended memory size in KB. 29 <3> SysInitVars ENDS 30 <3> 31 <3> ;This is added for more information exchage between DOS, BIOS. 32 <3> ;DOS will give the pointer to SysInitTable in ES:DI. - J.K. 5/29/86 33 <3> SysInitVars_Ext struc 0 00000F20 ???????? SYSI_InitVars DD ? ; Points to the above structure. 0 00000F24 ???????? SYSI_Country_Tab DD ? ; DOS_Country_cdpg_info 36 <3> SysInitVars_Ext ends 37 <3> 38 <3> ;The SYSI_BUF of SysInitVars points to the follwong structure 39 <3> EMS_MAP_BUFF_SIZE EQU 12 ; EMS map buffer size 40 <3> 41 <3> Buffinfo STRUC 0 00000F20 ???????? Hash_ptr DD ? ; pointer to Hash table 0 00000F24 ???? Hash_count DW ? ; number of Hash entries 0 00000F26 ???????? Cache_ptr DD ? ; pointer to secondary cache 0 00000F2A ???? Cache_count DW ? ; number of secondary cache entries 46 <3> 47 <3> %IF BUFFERFLAG 48 <3> 0 00000F2C ?? EMS_SAFE_FLAG DB ? 0 00000F2D ???????? EMS_LAST_PAGE DW ?, ? 0 00000F31 ???????? EMS_FIRST_PAGE DW ?, ? 0 00000F35 ???? EMS_NPA640 DW ? 53 <3> 54 <3> %ENDIF 55 <3> 0 00000F37 ?? EMS_mode DB ? ; no EMS = -1 0 00000F38 ???? EMS_handle DW ? ; EMS handle for buffers 0 00000F3A ???? EMS_PageFrame_Number DW ? ; EMS page frame number 0 00000F3C ???? EMS_Seg_Cnt DW ? ; EMS segment count 0 00000F3E ???? EMS_Page_Frame DW ? ; EMS page frame segment address 0 00000F40 ???? EMS_reserved DW ? ; EMS segment count 62 <3> 63 <3> %IF BUFFERFLAG 0 00000F42 ?? EMS_Map_Buff DB ? ; map buffer 65 <3> %ELSE 66 <3> EMS_Map_Buff DB 12 dup(?) 67 <3> %ENDIF 68 <3> 69 <3> Buffinfo ENDS 70 <3> 71 <3> 72 <3> 73 <3> 74 <3> 75 <3> 76 <3> 77 <3> 78 <3> 94 <2> 95 <2> %include "vector.mac" 1 <3> ; SCCSID = @(#)vector.asm 1.1 85/04/10 2 <3> BREAK 3 <3> 4 <3> ;Asmvar AltVect 5 <3> %ifndef AltVect 6 <3> %iassign AltVect 0 7 <3> %endif 8 <3> 9 <3> INTTAB EQU 20H 10 <3> inttab equ INTTAB ; NASM port equate 11 <3> INTBASE EQU 4 * inttab 12 <3> ENTRYPOINT EQU INTBASE+40H 13 <3> 14 <3> %IF ALTVECT 15 <3> ALTTAB EQU 0F0H 16 <3> ALTBASE EQU 4 * ALTTAB 17 <3> %ENDIF 18 <3> 19 <3> ; 20 <3> ; interrupt assignments 21 <3> ; 22 <3> %IFN ALTVECT 23 <3> int_abort EQU INTTAB ; abort process 24 <3> int_command EQU int_abort+1 ; call MSDOS 25 <3> int_terminate EQU int_abort+2 ; int to terminate address 26 <3> int_ctrl_c EQU int_abort+3 ; ^c trapper 27 <3> int_fatal_abort EQU int_abort+4 ; hard disk error 28 <3> int_disk_read EQU int_abort+5 ; logical sector disk read 29 <3> int_disk_write EQU int_abort+6 ; logical sector disk write 30 <3> int_keep_process EQU int_abort+7 ; terminate program and stay 31 <3> ; resident 32 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 33 <3> ; C A V E A T P R O G R A M M E R ; 34 <3> ; ; 35 <3> int_spooler EQU int_abort+8 ; spooler call 36 <3> int_fastcon EQU int_abort+9 ; fast CON interrupt 37 <3> int_IBM EQU int_abort+10; critical section maintenance 38 <3> ; ; 39 <3> ; C A V E A T P R O G R A M M E R ; 40 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 41 <3> %ELSE 42 <3> int_abort EQU INTTAB ; abort process 43 <3> int_command EQU int_abort+1 ; call MSDOS 44 <3> int_terminate EQU ALTTAB ; int to terminate address 45 <3> int_ctrl_c EQU int_terminate+1 ; ^c trapper 46 <3> int_fatal_abort EQU int_terminate+2 ; hard disk error 47 <3> int_disk_read EQU int_abort+5 ; logical sector disk read 48 <3> int_disk_write EQU int_abort+6 ; logical sector disk write 49 <3> int_keep_process EQU int_abort+7 ; terminate program and stay resident 50 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 51 <3> ; C A V E A T P R O G R A M M E R ; 52 <3> ; ; 53 <3> int_spooler EQU int_terminate+3 ; spooler call 54 <3> int_fastcon EQU int_abort+9 ; fast CON interrupt 55 <3> ; ; 56 <3> ; C A V E A T P R O G R A M M E R ; 57 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 58 <3> %ENDIF 59 <3> 60 <3> addr_int_abort EQU 4 * int_abort 61 <3> addr_int_command EQU 4 * int_command 62 <3> addr_int_terminate EQU 4 * int_terminate 63 <3> addr_int_ctrl_c EQU 4 * int_ctrl_c 64 <3> addr_int_fatal_abort EQU 4 * int_fatal_abort 65 <3> addr_int_disk_read EQU 4 * int_disk_read 66 <3> addr_int_disk_write EQU 4 * int_disk_write 67 <3> addr_int_keep_process EQU 4 * int_keep_process 68 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 69 <3> ; C A V E A T P R O G R A M M E R ; 70 <3> ; ; 71 <3> addr_int_spooler EQU 4 * int_spooler 72 <3> addr_int_fastcon EQU 4 * int_fastcon 73 <3> addr_int_IBM EQU 4 * int_IBM 74 <3> ; ; 75 <3> ; C A V E A T P R O G R A M M E R ; 76 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 96 <2> 97 <2> %include "mult.mac" 1 <3> ; SCCSID = @(#)mult.asm 1.2 85/04/12 2 <3> Break 3 <3> 4 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 5 <3> ; C A V E A T P R O G R A M M E R ; 6 <3> ; ; 7 <3> ; Critical section definitions 8 <3> ; 9 <3> ; These below are subject to leave-all sections 10 <3> critDisk EQU 1 ; Disk I/O critical section 11 <3> critDevice EQU 2 ; Device I/O critical section 12 <3> critShare EQU 1 ; Sharer I/O critical section 13 <3> critMem EQU 1 ; memory maintenance critical section 14 <3> critNet EQU 5 ; network critical section 15 <3> critSFT EQU 1 ; sft table allocation 16 <3> critIFS EQU 6 ; ifsfunc critical section 17 <3> ; These below are not subject to leave-all sections 18 <3> critASSIGN EQU 8 ; Assign has munged a system call 19 <3> ; ; 20 <3> ; C A V E A T P R O G R A M M E R ; 21 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 22 <3> 23 <3> ; 24 <3> ; The current set of defined multiplex channels is (* means documented): 25 <3> ; 26 <3> ; Channel(h) Issuer Receiver Function 27 <3> ; 00 server PSPRINT print job control 28 <3> ; *01 print/apps PRINT Queueing of files 29 <3> ; 02 BIOS REDIR signal open/close of printers 30 <3> ; 31 <3> ; 05 command REDIR obtain text of net int 24 message 32 <3> ; *06 server/assign ASSIGN Install check 33 <3> ; 34 <3> ; 08 external driver IBMBIO interface to internal routines 35 <3> ; 36 <3> ; 10 sharer/server Sharer install check 37 <3> ; 11 DOS/server Redir install check/redirection funcs 38 <3> ; 12 sharer/redir DOS dos functions and structure maint 39 <3> ; 13 MSNET MSNET movement of NCBs 40 <3> ; 13 external driver IBMBIO Reset_Int_13, allows installation 41 <3> ; of alternative INT_13 drivers after 42 <3> ; boot_up 43 <3> ; 14 (IBM) DOS NLSFUNC down load NLS country info,DOS 3.3 44 <3> ; 14 (MS) APPS POPUP MSDOS 4 popup screen functions 45 <3> ; 15 APPS MSCDEX CD-ROM extensions interface 46 <3> ; 16 WIN386 WIN386 Windows communications 47 <3> ; 17 Clipboard WINDOWS Clipboard interface 48 <3> ; *18 Applications MS-Manger Toggle interface to manager 49 <3> ; 19 Shell 50 <3> ; 1A Ansi.sys 51 <3> ; 1B Fastopen,Vdisk IBMBIO EMS INT 67H stub handler 52 <3> ; 53 <3> ; AC Graphics 54 <3> ; AD NLS (toronto) 55 <3> ; AE 56 <3> ; AF Mode 57 <3> ; B0 GRAFTABL GRAFTABL 58 <3> ; 59 <3> 60 <3> 61 <3> ;MUX 00-3F reserverd for IBM 62 <3> ;MUX 80-BF reserverd for IBM 63 <3> ;MUX 40-7F reserved for Microsoft 64 <3> ;MUX C0-FF users 65 <3> 66 <3> 67 <3> 68 <3> MultSHARE EQU 10h ; sharer 69 <3> ; 1 MFT_enter 70 <3> ; 2 MFTClose 71 <3> ; 3 MFTclU 72 <3> ; 4 MFTCloseP 73 <3> ; 5 MFTCloN 74 <3> ; 6 set_block 75 <3> ; 7 clr_block 76 <3> ; 8 chk_block 77 <3> ; 9 MFT_get 78 <3> ; 10 ShSave 79 <3> ; 11 ShChk 80 <3> ; 12 ShCol 81 <3> ; 13 ShCloseFile 82 <3> 83 <3> MultNET EQU 11h ; Network support 84 <3> MultIFS EQU 11h ; Network support 85 <3> ; 1 IFS_RMDIR 86 <3> ; 2 IFS_SEQ_RMDIR 87 <3> ; 3 IFS_MKDIR 88 <3> ; 4 IFS_SEQ_MKDIR 89 <3> ; 5 IFS_CHDIR 90 <3> ; 6 IFS_CLOSE 91 <3> ; 7 IFS_COMMIT 92 <3> ; 8 IFS_READ 93 <3> ; 9 IFS_WRITE 94 <3> ; 10 IFS_LOCK 95 <3> ; 11 IFS_UNLOCK 96 <3> ; 12 IFS_DISK_INFO 97 <3> ; 13 IFS_SET_FILE_ATTRIBUTE 98 <3> ; 14 IFS_SEQ_SET_FILE_ATTRIBUTE 99 <3> ; 15 IFS_GET_FILE_INFO 100 <3> ; 16 IFS_SEQ_GET_FILE_INFO 101 <3> ; 17 IFS_RENAME 102 <3> ; 18 IFS_SEQ_RENAME 103 <3> ; 19 IFS_DELETE 104 <3> ; 20 IFS_SEQ_DELETE 105 <3> ; 21 IFS_OPEN 106 <3> ; 22 IFS_SEQ_OPEN 107 <3> ; 23 IFS_CREATE 108 <3> ; 24 IFS_SEQ_CREATE 109 <3> ; 25 IFS_SEQ_SEARCH_FIRST 110 <3> ; 26 IFS_SEQ_SEARCH_NEXT 111 <3> ; 27 IFS_SEARCH_FIRST 112 <3> ; 28 IFS_SEARCH_NEXT 113 <3> ; 29 IFS_ABORT 114 <3> ; 30 IFS_ASSOPER 115 <3> ; 31 Printer_SET_STRING 116 <3> ; 32 IFSFlushBuf 117 <3> ; 33 IFSBufWrite 118 <3> ; 34 IFSResetEnvironment 119 <3> ; 35 IFSSpoolCheck 120 <3> ; 36 IFSSpoolClose 121 <3> 122 <3> MultDOS EQU 12h ; DOS call back 123 <3> ; 1 DOS_CLOSE 124 <3> ; 2 RECSET 125 <3> ; 3 Get DOSGROUP 126 <3> ; 4 PATHCHRCMP 127 <3> ; 5 OUT 128 <3> ; 6 NET_I24_ENTRY 129 <3> ; 7 PLACEBUF 130 <3> ; 8 FREE_SFT 131 <3> ; 9 BUFWRITE 132 <3> ; 10 SHARE_VIOLATION 133 <3> ; 11 SHARE_ERROR 134 <3> ; 12 SET_SFT_MODE 135 <3> ; 13 DATE16 136 <3> ; 14 SETVISIT 137 <3> ; 15 SCANPLACE 138 <3> ; 16 SKIPVISIT 139 <3> ; 17 StrCpy 140 <3> ; 18 StrLen 141 <3> ; 19 Ucase 142 <3> ; 20 POINTCOMP 143 <3> ; 21 CHECKFLUSH 144 <3> ; 22 SFFromSFN 145 <3> ; 23 GetCDSFromDrv 146 <3> ; 24 Get_User_Stack 147 <3> ; 25 GetThisDrv 148 <3> ; 26 DriveFromText 149 <3> ; 27 SETYEAR 150 <3> ; 28 DSUM 151 <3> ; 29 DSLIDE 152 <3> ; 30 StrCmp 153 <3> ; 31 initcds 154 <3> ; 32 pjfnfromhandle 155 <3> ; 33 $NameTrans 156 <3> ; 34 CAL_LK 157 <3> ; 35 DEVNAME 158 <3> ; 36 Idle 159 <3> ; 37 DStrLen 160 <3> ; 38 NLS_OPEN DOS 3.3 161 <3> ; 39 $CLOSE DOS 3.3 162 <3> ; 40 NLS_LSEEK DOS 3.3 163 <3> ; 41 $READ DOS 3.3 164 <3> ; 42 FastInit DOS 4.0 165 <3> ; 43 NLS_IOCTL DOS 3.3 166 <3> ; 44 GetDevList DOS 3.3 167 <3> ; 45 NLS_GETEXT DOS 3.3 168 <3> ; 46 MSG_RETRIEVAL DOS 4.0 169 <3> ; 47 FAKE_VERSION DOS 4.0 170 <3> ; 171 <3> NLSFUNC EQU 14h ; NLSFUNC CALL , DOS 3.3 172 <3> ; 0 NLSInstall 173 <3> ; 1 ChgCodePage 174 <3> ; 2 GetExtInfo 175 <3> ; 3 SetCodePage 176 <3> ; 4 GetCntry 177 <3> ; 178 <3> ;FASTOPEN is not chained through INT 2F ; DOS 3.3 F.C. 179 <3> ; it calls Multdos 42 to set up an entry routine address 180 <3> ; 0 Install status (reserved) 181 <3> ; 1 Lookup 182 <3> ; 2 Insert 183 <3> ; 3 Delete 184 <3> ; 4 Purge (reserved) 98 <2> 99 <2> BREAK 100 <2> ; MSDOS partitions the disk into 4 sections: 101 <2> ; 102 <2> ; phys sector 0: +-------------------+ 103 <2> ; | | boot/reserved | 104 <2> ; | +-------------------+ 105 <2> ; | | File allocation | 106 <2> ; v | table(s) | 107 <2> ; | (multiple copies | 108 <2> ; | are kept) | 109 <2> ; +-------------------+ 110 <2> ; | Directory | 111 <2> ; +-------------------+ 112 <2> ; | File space | 113 <2> ; +-------------------+ 114 <2> ; | Unaddressable | 115 <2> ; | (to end of disk) | 116 <2> ; +-------------------+ 117 <2> ; 118 <2> ; All partition boundaries are sector boundaries. The size of the FAT is 119 <2> ; adjusted to maximize the file space addressable. 120 <2> 121 <2> %include "dirent.mac" 1 <3> ; SCCSID = @(#)dirent.asm 1.1 85/04/10 2 <3> ; SCCSID = @(#)dirent.asm 1.1 85/04/10 3 <3> Break 4 <3> 5 <3> ; 6 <3> ; +---------------------------+ 7 <3> ; | (12 BYTE) filename/ext | 0 0 8 <3> ; +---------------------------+ 9 <3> ; | (BYTE) attributes | 11 B 10 <3> ; +---------------------------+ 11 <3> ; | (10 BYTE) reserved | 12 C 12 <3> ; +---------------------------+ 13 <3> ; | (WORD) time of last write | 22 16 14 <3> ; +---------------------------+ 15 <3> ; | (WORD) date of last write | 24 18 16 <3> ; +---------------------------+ 17 <3> ; | (WORD) First cluster | 26 1A 18 <3> ; +---------------------------+ 19 <3> ; | (DWORD) file size | 28 1C 20 <3> ; +---------------------------+ 21 <3> ; 22 <3> ; First byte of filename = E5 -> free directory entry 23 <3> ; = 00 -> end of allocated directory 24 <3> ; Time: Bits 0-4=seconds/2, bits 5-10=minute, 11-15=hour 25 <3> ; Date: Bits 0-4=day, bits 5-8=month, bits 9-15=year-1980 26 <3> ; 27 <3> 28 <3> dir_entry STRUC 29 00000000 <3> dir_name DB 11 DUP (?) ; file name 0 00000F2B ?? dir_attr DB ? ; attribute bits 0 00000F2C ???? dir_codepg dw ? ; code page DOS 4.00 0 00000F2E ???? dir_extcluster dw ? ; extended attribute starting cluster 0 00000F30 ?? dir_attr2 db ? ; reserved 0 00000F31 ?????????? dir_pad DB 5 DUP (?) ; reserved for expansion 0 00000F36 ???? dir_time DW ? ; time of last write 0 00000F38 ???? dir_date DW ? ; date of last write 0 00000F3A ???? dir_first DW ? ; first allocation unit of file 0 00000F3C ???? dir_size_l DW ? ; low 16 bits of file size 0 00000F3E ???? dir_size_h DW ? ; high 16 bits of file size 40 <3> dir_entry ENDS 41 <3> 42 <3> attr_read_only EQU 1h 43 <3> attr_hidden EQU 2h 44 <3> attr_system EQU 4h 45 <3> attr_volume_id EQU 8h 46 <3> attr_directory EQU 10h 47 <3> attr_archive EQU 20h 48 <3> attr_device EQU 40h ; This is a VERY special bit. 49 <3> ; NO directory entry on a disk EVER 50 <3> ; has this bit set. It is set non-zero 51 <3> ; when a device is found by GETPATH 52 <3> 53 <3> attr_all EQU attr_hidden+attr_system+attr_directory 54 <3> ; OR of hard attributes for FINDENTRY 55 <3> 56 <3> attr_ignore EQU attr_read_only+attr_archive+attr_device 57 <3> ; ignore this(ese) attribute(s) during 58 <3> ; search first/next 59 <3> 60 <3> attr_changeable EQU attr_read_only+attr_hidden+attr_system+attr_archive 61 <3> ; changeable via CHMOD 122 <2> 123 <2> BREAK 124 <2> ; 125 <2> ; The File Allocation Table uses a 12-bit entry for each allocation unit on 126 <2> ; the disk. These entries are packed, two for every three bytes. The contents 127 <2> ; of entry number N is found by 1) multiplying N by 1.5; 2) adding the result 128 <2> ; to the base address of the Allocation Table; 3) fetching the 16-bit word 129 <2> ; at this address; 4) If N was odd (so that N*1.5 was not an integer), shift 130 <2> ; the word right four bits; 5) mask to 12 bits (AND with 0FFF hex). Entry 131 <2> ; number zero is used as an end-of-file trap in the OS and is passed to the 132 <2> ; BIOS to help determine disk format. Entry 1 is reserved for future use. 133 <2> ; The first available allocation unit is assigned entry number two, and even 134 <2> ; though it is the first, is called cluster 2. Entries greater than 0FF8H 135 <2> ; (12-bit fats) or 0FFF8H (16-bit fats) are end of file marks; entries of zero 136 <2> ; are unallocated. Otherwise, the contents of a FAT entry is the number of 137 <2> ; the next cluster in the file. 138 <2> ; 139 <2> ; Clusters with bad sectors are tagged with FF7H. Any non-zero number would 140 <2> ; do because these clusters show as allocated, but are not part of any 141 <2> ; allocation chain and thus will never be allocated to a file. A particular 142 <2> ; number is selected so that disk checking programs know what to do (ie. a 143 <2> ; cluster with entry FF7H which is not in a chain is not an error). 144 <2> 145 <2> %include "dpb.mac" 1 <3> ; SCCSID = @(#)dpb.asm 1.1 85/04/10 2 <3> ; SCCSID = @(#)dpb.asm 1.1 85/04/10 3 <3> BREAK 4 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 5 <3> ; C A V E A T P R O G R A M M E R ; 6 <3> ; ; 7 <3> dpb STRUC 0 00000F20 ?? dpb_drive DB ? ; Logical drive # assoc with DPB (A=0,B=1,...) 0 00000F21 ?? dpb_UNIT DB ? ; Driver unit number of DPB 0 00000F22 ???? dpb_sector_size DW ? ; Size of physical sector in bytes 0 00000F24 ?? dpb_cluster_mask DB ? ; Sectors/cluster - 1 0 00000F25 ?? dpb_cluster_shift DB ? ; Log2 of sectors/cluster 0 00000F26 ???? dpb_first_FAT DW ? ; Starting record of FATs 0 00000F28 ?? dpb_FAT_count DB ? ; Number of FATs for this drive 0 00000F29 ???? dpb_root_entries DW ? ; Number of directory entries 0 00000F2B ???? dpb_first_sector DW ? ; First sector of first cluster 0 00000F2D ???? dpb_max_cluster DW ? ; Number of clusters on drive + 1 0 00000F2F ???? dpb_FAT_size DW ? ;;Number of records occupied by FAT 0 00000F31 ???? dpb_dir_sector DW ? ; Starting record of directory 0 00000F33 ???????? dpb_driver_addr DD ? ; Pointer to driver 0 00000F37 ?? dpb_media DB ? ; Media byte 0 00000F38 ?? dpb_first_access DB ? ; This is initialized to -1 to force a media 23 <3> ; check the first time this DPB is used 0 00000F39 ???????? dpb_next_dpb DD ? ; Pointer to next Drive parameter block 0 00000F3D ???? dpb_next_free DW ? ; Cluster # of last allocated cluster 0 00000F3F ???? dpb_free_cnt DW ? ; Count of free clusters, -1 if unknown 27 <3> dpb ENDS 28 <3> 29 <3> DPBSIZ EQU dpb_struc_size ; Size of the structure in bytes 30 <3> 31 <3> DSKSIZ equ dpb_max_cluster ; Size of disk (temp used during init only) 32 <3> ; ; 33 <3> ; C A V E A T P R O G R A M M E R ; 34 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 35 <3> 146 <2> 147 <2> %include "curdir.mac" 1 <3> ; SCCSID = @(#)curdir.asm 1.1 85/04/10 2 <3> ; SCCSID = @(#)curdir.asm 1.1 85/04/10 3 <3> BREAK 4 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 5 <3> ; C A V E A T P R O G R A M M E R ; 6 <3> ; ; 7 <3> ; CDS items are used bu the internal routines to store cluster numbers and ; 8 <3> ; network identifiers for each logical name. The ID field is used dually, ; 9 <3> ; both as net ID and for a cluster number for local devices. In the case ; 10 <3> ; of local devices, the cluster number will be -1 if there is a potential ; 11 <3> ; of the disk being changed or if the path must be recracked. The END ; 12 <3> ; field is the location of the end of the definition. No .. is allowed ; 13 <3> ; past this point ; 14 <3> 15 <3> DIRSTRLEN EQU 64+3 ; Max length in bytes of directory strings 16 <3> TEMPLEN EQU DIRSTRLEN*2 17 <3> 18 <3> curdir_list STRUC 19 00000000 <3> curdir_text DB DIRSTRLEN DUP (?) ; text of assignment and curdir 0 00000F63 ???? curdir_flags DW ? ; various flags 0 00000F65 ???????? curdir_devptr DD ? ; local pointer to DPB or net device 0 00000F69 ???? curdir_ID DW ? ; cluster of current dir (net ID) 0 00000F6B ???? DW ? 0 00000F6D ???? curdir_user_word DW ? 0 00000F6F ???? curdir_end DW ? ; end of assignment 0 00000F71 ?? curdir_type DB ? ; IFS drive (2=ifs, 4=netuse) 0 00000F72 ???????? curdir_ifs_hdr DD ? ; Ptr to File System Header 0 00000F76 ???? curdir_fsda DB 2 DUP (?) ; File System Dependent Data Area 29 <3> curdir_list ENDS 30 <3> 31 <3> curdirLen EQU curdir_list_struc_size ; Needed for screwed up 32 <3> ; ASM87 which doesn't allow 33 <3> ; Size directive as a macro 34 <3> ; argument 35 <3> labelsize curdir_netID, dword, curdir_ID 36 <3> 37 <3> ;Flag word masks 38 <3> curdir_isnet EQU 1000000000000000B 39 <3> curdir_isifs EQU 1000000000000000B ; DOS 4.00 40 <3> curdir_inuse EQU 0100000000000000B 41 <3> curdir_splice EQU 0010000000000000B 42 <3> curdir_local EQU 0001000000000000B 43 <3> ; ; 44 <3> ; C A V E A T P R O G R A M M E R ; 45 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 148 <2> 149 <2> %include "cpmfcb.mac" 1 <3> ; SCCSID = @(#)cpmfcb.asm 1.1 85/04/10 2 <3> ; SCCSID = @(#)cpmfcb.asm 1.1 85/04/10 3 <3> ;BREAK 4 <3> 5 <3> ; 6 <3> ; Field definition for FCBs 7 <3> ; The FCB has the following structure: 8 <3> ; 9 <3> ; +---------------------------+ 10 <3> ; | Drive indicator(byte) | 11 <3> ; +---------------------------+ 12 <3> ; | Filename (8 chars) | 13 <3> ; +---------------------------+ 14 <3> ; | Extension (3 chars) | 15 <3> ; +---------------------------+ 16 <3> ; | Current Extent(word) | 17 <3> ; +---------------------------+ 18 <3> ; | Record size (word) | 19 <3> ; +---------------------------+ 20 <3> ; | File Size (2 words) | 21 <3> ; +---------------------------+ 22 <3> ; | Date of write | 23 <3> ; +---------------------------+ 24 <3> ; | Time of write | 25 <3> ; +---------------------------+ 26 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 27 <3> ; C A V E A T P R O G R A M M E R ; 28 <3> ; ; 29 <3> ; +---------------------------+ 30 <3> ; | 8 bytes reserved | 31 <3> ; +---------------------------+ 32 <3> ; ; 33 <3> ; C A V E A T P R O G R A M M E R ; 34 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 35 <3> ; | next record number | 36 <3> ; +---------------------------+ 37 <3> ; | random record number | 38 <3> ; +---------------------------+ 39 <3> ; 40 <3> 41 <3> sys_fcb STRUC 0 00000F20 ?? fcb_drive DB ? 0 00000F21 ???????????????? fcb_name DB 8 DUP (?) 0 00000F29 ?????? fcb_ext DB 3 DUP (?) 0 00000F2C ???? fcb_EXTENT DW ? 0 00000F2E ???? fcb_RECSIZ DW ? ; Size of record (user settable) 0 00000F30 ???? fcb_FILSIZ DW ? ; Size of file in bytes; used with the 48 <3> ; following word 0 00000F32 ???? fcb_DRVBP DW ? ; BP for SEARCH FIRST and SEARCH NEXT 0 00000F34 ???? fcb_FDATE DW ? ; Date of last writing 0 00000F36 ???? fcb_FTIME DW ? ; Time of last writing 52 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 53 <3> ; C A V E A T P R O G R A M M E R ; 54 <3> ; ; 0 00000F38 ???????????????? fcb_reserved DB 8 DUP (?) ; RESERVED 56 <3> ; ; 57 <3> ; C A V E A T P R O G R A M M E R ; 58 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 0 00000F40 ?? fcb_NR DB ? ; Next record 0 00000F41 ???????? fcb_RR DB 4 DUP (?) ; Random record 61 <3> sys_fcb ENDS 62 <3> 63 <3> FILDIRENT equ fcb_FILSIZ ; Used only by SEARCH FIRST and SEARCH 64 <3> ; NEXT 65 <3> 66 <3> labelsize fcb_sfn, byte, fcb_reserved 67 <3> 68 <3> ; Note that fcb_net_handle, fcb_nsl_drive, fcb_nsld_drive and fcb_l_drive 69 <3> ; all must point to the same byte. Otherwise, the FCBRegen will fail. 70 <3> ; NOTE about this byte (fcb_nsl_drive) 71 <3> ; The high two bits of this byte are used as follows to indicate the FCB type 72 <3> ; 00 means a local file or device with sharing loaded 73 <3> ; 10 means a remote (network) file 74 <3> ; 01 means a local file with no sharing loaded 75 <3> ; 11 means a local device with no sharing loaded 76 <3> 77 <3> ; 78 <3> ; Network FCB 79 <3> ; 80 <3> labelsize fcb_net_drive, byte, fcb_reserved+1 81 <3> labelsize fcb_net_handle, word, fcb_reserved+2 82 <3> labelsize fcb_netID, dword, fcb_reserved+4 83 <3> 84 <3> ; 85 <3> ; No sharing local file FCB 86 <3> ; 87 <3> labelsize fcb_nsl_drive, byte, fcb_reserved+1 88 <3> labelsize fcb_nsl_bits, byte, fcb_reserved+2 89 <3> labelsize fcb_nsl_firclus, word, fcb_reserved+3 90 <3> labelsize fcb_nsl_dirsec, word, fcb_reserved+5 91 <3> labelsize fcb_nsl_dirpos, byte, fcb_reserved+7 92 <3> 93 <3> ; 94 <3> ; No sharing local device FCB 95 <3> ; 96 <3> labelsize fcb_nsld_drive, byte, fcb_reserved+1 97 <3> labelsize fcb_nsld_drvptr, dword, fcb_reserved+2 98 <3> 99 <3> ; 100 <3> ; Sharing local FCB 101 <3> ; 102 <3> labelsize fcb_l_drive, byte, fcb_reserved+1 103 <3> labelsize fcb_l_firclus, word, fcb_reserved+2 104 <3> labelsize fcb_l_mfs, word, fcb_reserved+4 105 <3> labelsize fcb_l_attr, byte, fcb_reserved+6 106 <3> 107 <3> ; 108 <3> ; Bogusness: the four cases are: 109 <3> ; 110 <3> ; local file 00 111 <3> ; local device 40 112 <3> ; local sharing C0 113 <3> ; network 80 114 <3> ; 115 <3> ; Since sharing and network collide, we cannot use a test instruction for 116 <3> ; deciding whether a network or a share check in involved 117 <3> ; 118 <3> FCBDEVICE EQU 040h 119 <3> FCBNETWORK EQU 080h 120 <3> FCBSHARE EQU 0C0h 121 <3> 122 <3> ; FCBSPECIAL must be able to mask off both net and share 123 <3> FCBSPECIAL EQU 080h 124 <3> FCBMASK EQU 0C0h 125 <3> 150 <2> 151 <2> %include "find.mac" 1 <3> ; SCCSID = @(#)find.asm 1.1 85/04/10 2 <3> ; SCCSID = @(#)find.asm 1.1 85/04/10 3 <3> Break 4 <3> 5 <3> find_buf STRUC 6 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 7 <3> ; C A V E A T P R O G R A M M E R ; 8 <3> ; ; 0 00000F20 ?? find_buf_drive DB ? ; drive of search 10 00000001 <3> find_buf_name DB 11 DUP (?) ; formatted name 0 00000F2C ?? find_buf_sattr DB ? ; attribute of search 0 00000F2D ???? find_buf_LastEnt DW ? ; LastEnt 0 00000F2F ???? find_buf_DirStart DW ? ; DirStart 0 00000F31 ???????? find_buf_NetID DB 4 DUP (?) ; Reserved for NET 15 <3> ; ; 16 <3> ; C A V E A T P R O G R A M M E R ; 17 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 18 <3> 0 00000F35 ?? find_buf_attr DB ? ; attribute found 0 00000F36 ???? find_buf_time DW ? ; time 0 00000F38 ???? find_buf_date DW ? ; date 0 00000F3A ???? find_buf_size_l DW ? ; low(size) 0 00000F3C ???? find_buf_size_h DW ? ; high(size) 24 0000001E <3> find_buf_pname DB 13 DUP (?) ; packed name 25 <3> find_buf ENDS 152 <2> 153 <2> %include "pdb.mac" 1 <3> ; SCCSID = @(#)pdb.asm 1.1 85/04/10 2 <3> BREAK 3 <3> 4 <3> ; 5 <3> ; Process data block (otherwise known as program header) 6 <3> ; 7 <3> 8 <3> FilPerProc EQU 20 9 <3> 10 <3> Process_data_block STRUC 0 00000F20 ???? PDB_Exit_Call DW ? ; INT int_abort system terminate 0 00000F22 ???? PDB_block_len DW ? ; size of execution block 0 00000F24 ?? DB ? 0 00000F25 ?????????? PDB_CPM_Call DB 5 DUP (?) ; ancient call to system 0 00000F2A ???????? PDB_Exit DD ? ; pointer to exit routine 0 00000F2E ???????? PDB_Ctrl_C DD ? ; pointer to ^C routine 0 00000F32 ???????? PDB_Fatal_abort DD ? ; pointer to fatal error 18 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 19 <3> ; C A V E A T P R O G R A M M E R ; 20 <3> ; ; 0 00000F36 ???? PDB_Parent_PID DW ? ; PID of parent (terminate PID) 22 00000018 <3> PDB_JFN_Table DB FilPerProc DUP (?) 23 <3> ; indices into system table 24 <3> ; ; 25 <3> ; C A V E A T P R O G R A M M E R ; 26 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 0 00000F4C ???? PDB_environ DW ? ; seg addr of environment 28 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 29 <3> ; C A V E A T P R O G R A M M E R ; 30 <3> ; ; 0 00000F4E ???????? PDB_User_stack DD ? ; stack of self during system calls 0 00000F52 ???? PDB_JFN_Length DW ? ; number of handles allowed 0 00000F54 ???????? PDB_JFN_Pointer DD ? ; pointer to JFN table 0 00000F58 ???????? PDB_Next_PDB DD ? ; pointer to nested PDB's 35 0000003C <3> PDB_PAD1 DB 14h DUP (?) 36 <3> ; ; 37 <3> ; C A V E A T P R O G R A M M E R ; 38 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 0 00000F70 ?????????? PDB_Call_system DB 5 DUP (?) ; portable method of system call 40 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 41 <3> ; C A V E A T P R O G R A M M E R ; 42 <3> ; ; 0 00000F75 ?????????????? PDB_PAD2 DB 7h DUP (?) 44 <3> ; ; 45 <3> ; C A V E A T P R O G R A M M E R ; 46 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 47 <3> Process_data_block ENDS 48 <3> 49 <3> labelsize PDB_InterCon, byte, PDB_PAD1 ; 2/12/KK 50 <3> labelsize PDB_Append, byte, PDB_PAD1+1 ; 2/12/KK 51 <3> 154 <2> 155 <2> %include "exe.mac" 1 <3> ; SCCSID = @(#)exe.asm 1.1 85/04/10 2 <3> ; SCCSID = @(#)exe.asm 1.1 85/04/10 3 <3> BREAK 4 <3> ; 5 <3> ; EXEC arg block - load/go program 6 <3> ; 7 <3> 8 <3> ; 9 <3> ; The following get used as arguments to the EXEC system call. They indicate 10 <3> ; whether or not the program is executed or whether or not a program header 11 <3> ; gets created. 12 <3> ; 13 <3> exec_func_no_execute EQU 1 ; no execute bit 14 <3> exec_func_overlay EQU 2 ; overlay bit 15 <3> 16 <3> Exec0 STRUC 0 00000F20 ???? Exec0_environ DW ? ; seg addr of environment 0 00000F22 ???????? Exec0_com_line DD ? ; pointer to asciz command line 0 00000F26 ???????? Exec0_5C_FCB DD ? ; default fcb at 5C 0 00000F2A ???????? Exec0_6C_FCB DD ? ; default fcb at 6C 21 <3> Exec0 ENDS 22 <3> 23 <3> Exec1 STRUC 0 00000F20 ???? Exec1_environ DW ? ; seg addr of environment 0 00000F22 ???????? Exec1_com_line DD ? ; pointer to asciz command line 0 00000F26 ???????? Exec1_5C_FCB DD ? ; default fcb at 5C 0 00000F2A ???????? Exec1_6C_FCB DD ? ; default fcb at 6C 0 00000F2E ???? Exec1_SP DW ? ; stack pointer of program 0 00000F30 ???? Exec1_SS DW ? ; stack seg register of program 0 00000F32 ???? Exec1_IP DW ? ; entry point IP 0 00000F34 ???? Exec1_CS DW ? ; entry point CS 32 <3> Exec1 ENDS 33 <3> 34 <3> Exec3 STRUC 0 00000F20 ???? Exec3_load_addr DW ? ; seg address of load point 0 00000F22 ???? Exec3_reloc_fac DW ? ; relocation factor 37 <3> Exec3 ENDS 38 <3> 39 <3> ; 40 <3> ; Exit codes in upper byte 41 <3> ; 42 <3> Exit_terminate EQU 0 43 <3> Exit_abort EQU 0 44 <3> Exit_Ctrl_C EQU 1 45 <3> Exit_Hard_Error EQU 2 46 <3> Exit_Keep_process EQU 3 47 <3> 48 <3> ; 49 <3> ; EXE file header 50 <3> ; 51 <3> 52 <3> EXE_file STRUC 0 00000F20 ???? exe_signature DW ? ; must contain 4D5A (yay zibo!) 0 00000F22 ???? exe_len_mod_512 DW ? ; low 9 bits of length 0 00000F24 ???? exe_pages DW ? ; number of 512b pages in file 0 00000F26 ???? exe_rle_count DW ? ; count of reloc entries 0 00000F28 ???? exe_par_dir DW ? ; number of paragraphs before image 0 00000F2A ???? exe_min_BSS DW ? ; minimum number of para of BSS 0 00000F2C ???? exe_max_BSS DW ? ; max number of para of BSS 0 00000F2E ???? exe_SS DW ? ; stack of image 0 00000F30 ???? exe_SP DW ? ; SP of image 0 00000F32 ???? exe_chksum DW ? ; checksum of file (ignored) 0 00000F34 ???? exe_IP DW ? ; IP of entry 0 00000F36 ???? exe_CS DW ? ; CS of entry 0 00000F38 ???? exe_rle_table DW ? ; byte offset of reloc table 0 00000F3A ???? exe_iov DW ? ; overlay number (0 for root) 0 00000F3C ???????? exe_sym_tab DD ? ; offset of symbol table in file 68 <3> EXE_file ENDS 69 <3> 70 <3> exe_valid_signature EQU 5A4Dh 71 <3> exe_valid_old_signature EQU 4D5Ah 72 <3> 73 <3> symbol_entry STRUC 0 00000F20 ???????? sym_value DD ? 0 00000F24 ???? sym_type DW ? 0 00000F26 ?? sym_len DB ? 77 00000007 <3> sym_name DB 255 dup (?) 78 <3> symbol_entry ENDS 156 <2> 157 <2> %include "sf.mac" 1 <3> ; SCCSID = @(#)sf.asm 1.1 85/04/10 2 <3> BREAK 3 <3> ; 4 <3> ; AN000 version 4.00 Jan. 1988 5 <3> ; AN003 PTM 3680 -- make NAME offset the same as before (<=3.30) 6 <3> ; AN009 PTM 3839 reorder SFT for MS WINDOWS 7 <3> 8 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 9 <3> ; C A V E A T P R O G R A M M E R ; 10 <3> ; ; 11 <3> ; 12 <3> ; system file table 13 <3> ; 14 <3> 15 <3> SF STRUC 0 00000F20 ???????? SFLink DD ? 0 00000F24 ???? SFCount DW ? ; number of entries 0 00000F26 ???? SFTable DW ? ; beginning of array of the following 19 <3> SF ENDS 20 <3> 21 <3> ; 22 <3> ; system file table entry 23 <3> ; 24 <3> 25 <3> sf_entry STRUC 0 00000F20 ???? sf_ref_count DW ? ; number of processes sharing entry 27 <3> ; if FCB then ref count 0 00000F22 ???? sf_mode DW ? ; mode of access or high bit on if FCB 0 00000F24 ?? sf_attr DB ? ; attribute of file 0 00000F25 ???? sf_flags DW ? ;Bits 8-15 31 <3> ; Bit 15 = 1 if remote file 32 <3> ; = 0 if local file or device 33 <3> ; Bit 14 = 1 if date/time is not to be 34 <3> ; set from clock at CLOSE. Set by 35 <3> ; FILETIMES and FCB_CLOSE. Reset by 36 <3> ; other reseters of the dirty bit 37 <3> ; (WRITE) 38 <3> ; Bit 13 = Pipe bit (reserved) 39 <3> ; 40 <3> ; Bits 0-7 (old FCB_devid bits) 41 <3> ; If remote file or local file, bit 42 <3> ; 6=0 if dirty Device ID number, bits 43 <3> ; 0-5 if local file. 44 <3> ; bit 7=0 for local file, bit 7 45 <3> ; =1 for local I/O device 46 <3> ; If local I/O device, bit 6=0 if EOF (input) 47 <3> ; Bit 5=1 if Raw mode 48 <3> ; Bit 0=1 if console input device 49 <3> ; Bit 1=1 if console output device 50 <3> ; Bit 2=1 if null device 51 <3> ; Bit 3=1 if clock device 0 00000F27 ???????? sf_devptr DD ? ; Points to DPB if local file, points 53 <3> ; to device header if local device, 54 <3> ; points to net device header if 55 <3> ; remote 0 00000F2B ???? sf_firclus DW ? ; First cluster of file (bit 15 = 0) 0 00000F2D ???? sf_time DW ? ; Time associated with file 0 00000F2F ???? sf_date DW ? ; Date associated with file 0 00000F31 ???????? sf_size DD ? ; Size associated with file 0 00000F35 ???????? sf_position DD ? ; Read/Write pointer or LRU count for FCBs 61 <3> ; 62 <3> ; Starting here, the next 7 bytes may be used by the file system to store an 63 <3> ; ID 64 <3> ; 0 00000F39 ???? sf_cluspos DW ? ; Position of last cluster accessed 0 00000F3B ???????? sf_dirsec DD ? ; Sector number of directory sector for 67 <3> ; for this file 0 00000F3F ?? sf_dirpos DB ? ; Offset of this entry in the above 69 <3> ; 70 <3> ; End of 7 bytes of file-system specific info. 71 <3> ; 72 00000020 <3> sf_name DB 11 DUP (?) ; 11 character name that is in the 73 <3> ; directory entry. This is used by 74 <3> ; close to detect file deleted and 75 <3> ; disk changed errors. 76 <3> 77 <3> ; SHARING INFO 0 00000F4B ???????? sf_chain DD ? ; link to next SF 0 00000F4F ???? sf_UID DW ? 0 00000F51 ???? sf_PID DW ? 0 00000F53 ???? sf_MFT DW ? 0 00000F55 ???? sf_lstclus DW ? ;AN009; Last cluster accessed 0 00000F57 ???????? sf_IFS_HDR DD ? 84 <3> sf_entry ENDS 85 <3> 86 <3> labelsize sf_fsda, byte, sf_cluspos ;DOS 4.00 87 <3> labelsize sf_serial_ID, word, sf_firclus ;DOS 4.00 88 <3> labelsize sf_netid, byte, sf_cluspos 89 <3> labelsize sf_OpenAge, word, sf_position+2 90 <3> labelsize sf_LRU, word, sf_position 91 <3> 92 <3> sf_default_number EQU 5h 93 <3> 94 <3> ; 95 <3> ; Note that we need to mark an SFT as being busy for OPEN/CREATE. This is 96 <3> ; because an INT 24 may prevent us from 'freeing' it. We mark this as such 97 <3> ; by placing a -1 in the ref_count field. 98 <3> ; 99 <3> 100 <3> sf_busy EQU -1 101 <3> 102 <3> 103 <3> ; mode mask for FCB detection 104 <3> sf_isfcb EQU 1000000000000000B 105 <3> 106 <3> ; Flag word masks 107 <3> sf_isnet EQU 1000000000000000B 108 <3> sf_close_nodate EQU 0100000000000000B 109 <3> sf_pipe EQU 0010000000000000B 110 <3> sf_no_inherit EQU 0001000000000000B 111 <3> sf_net_spool EQU 0000100000000000B 112 <3> Handle_Fail_I24 EQU 0000000100000000B ;BIT 8 - DISK FULL I24 ERROR 113 <3> 114 <3> ; Local file/device flag masks 115 <3> devid_file_clean EQU 40h ; true if file and not written 116 <3> devid_file_mask_drive EQU 3Fh ; mask for drive number 117 <3> 118 <3> devid_device EQU 80h ; true if a device 119 <3> devid_device_EOF EQU 40h ; true if end of file reached 120 <3> devid_device_raw EQU 20h ; true if in raw mode 121 <3> devid_device_special EQU 10h ; true if special device 122 <3> devid_device_clock EQU 08h ; true if clock device 123 <3> devid_device_null EQU 04h ; true if null device 124 <3> devid_device_con_out EQU 02h ; true if console output 125 <3> devid_device_con_in EQU 01h ; true if consle input 126 <3> ; ; 127 <3> ; C A V E A T P R O G R A M M E R ; 128 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 129 <3> 130 <3> ; 131 <3> ; structure of devid field as returned by IOCTL is: 132 <3> ; 133 <3> ; BIT 7 6 5 4 3 2 1 0 134 <3> ; |---|---|---|---|---|---|---|---| 135 <3> ; | I | E | R | S | I | I | I | I | 136 <3> ; | S | O | A | P | S | S | S | S | 137 <3> ; | D | F | W | E | C | N | C | C | 138 <3> ; | E | | | C | L | U | O | I | 139 <3> ; | V | | | L | K | L | T | N | 140 <3> ; |---|---|---|---|---|---|---|---| 141 <3> ; ISDEV = 1 if this channel is a device 142 <3> ; = 0 if this channel is a disk file 143 <3> ; 144 <3> ; If ISDEV = 1 145 <3> ; 146 <3> ; EOF = 0 if End Of File on input 147 <3> ; RAW = 1 if this device is in Raw mode 148 <3> ; = 0 if this device is cooked 149 <3> ; ISCLK = 1 if this device is the clock device 150 <3> ; ISNUL = 1 if this device is the null device 151 <3> ; ISCOT = 1 if this device is the console output 152 <3> ; ISCIN = 1 if this device is the console input 153 <3> ; 154 <3> ; If ISDEV = 0 155 <3> ; EOF = 0 if channel has been written 156 <3> ; Bits 0-5 are the block device number for 157 <3> ; the channel (0 = A, 1 = B, ...) 158 <3> ; 159 <3> devid_ISDEV EQU 80h 160 <3> devid_EOF EQU 40h 161 <3> devid_RAW EQU 20h 162 <3> devid_SPECIAL EQU 10H 163 <3> devid_ISCLK EQU 08h 164 <3> devid_ISNUL EQU 04h 165 <3> devid_ISCOT EQU 02h 166 <3> devid_ISCIN EQU 01h 167 <3> 168 <3> devid_block_dev EQU 1Fh ; mask for block device number 158 <2> 159 <2> %include "arena.mac" 1 <3> ; SCCSID = @(#)arena.asm 1.1 85/04/09 2 <3> ;BREAK 3 <3> 4 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 5 <3> ; C A V E A T P R O G R A M M E R ; 6 <3> ; ; 7 <3> ; 8 <3> ; arena item 9 <3> ; 10 <3> arena STRUC 0 00000F20 ?? arena_signature DB ? ; 4D for valid item, 5A for last item 0 00000F21 ???? arena_owner DW ? ; owner of arena item 0 00000F23 ???? arena_size DW ? ; size in paragraphs of item 0 00000F25 ?????? arena_reserved DB 3 DUP(?) ; reserved 0 00000F28 ???????????????? arena_name DB 8 DUP(?) ; owner file name 16 <3> arena ENDS 17 <3> 18 <3> ; 19 <3> ; CAUTION: The routines in ALLOC.ASM rely on the fact that arena_signature 20 <3> ; and arena_owner_system are all equal to zero and are contained in DI. Change 21 <3> ; them and change ALLOC.ASM. 22 <3> 23 <3> arena_owner_system EQU 0 ; free block indication 24 <3> 25 <3> arena_signature_normal EQU 4Dh ; valid signature, not end of arena 26 <3> arena_signature_end EQU 5Ah ; valid signature, last block in arena 27 <3> ; ; 28 <3> ; C A V E A T P R O G R A M M E R ; 29 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 30 <3> 31 <3> 160 <2> 161 <2> %include "intnat.mac" 1 <3> ; SCCSID = @(#)intnat.asm 1.1 85/04/10 2 <3> BREAK 3 <3> 4 <3> ; 5 <3> ; Current structure of the data returned by the international call 6 <3> ; 7 <3> internat_block STRUC 0 00000F20 ???? Date_tim_format DW ? ; 0-USA, 1-EUR, 2-JAP 0 00000F22 ?? Currency_sym DB ? ; Currency Symbol 5 bytes 0 00000F23 ?? DB ? 0 00000F24 ?? DB ? 0 00000F25 ?? DB ? 0 00000F26 ?? DB ? 0 00000F27 ?? Thous_sep DB ? ; Thousands separator 2 bytes 0 00000F28 ?? DB ? 0 00000F29 ?? Decimal_sep DB ? ; Decimal separator 2 bytes 0 00000F2A ?? DB ? 0 00000F2B ?? Date_sep DB ? ; Date separator 2 bytes 0 00000F2C ?? DB ? 0 00000F2D ?? Time_sep DB ? ; Decimal separator 2 bytes 0 00000F2E ?? DB ? 0 00000F2F ?? Bit_field DB ? ; Bit values 23 <3> ; Bit 0 = 0 if currency symbol first 24 <3> ; = 1 if currency symbol last 25 <3> ; Bit 1 = 0 if No space after currency symbol 26 <3> ; = 1 if space after currency symbol 0 00000F30 ?? Currency_cents DB ? ; Number of places after currency dec point 0 00000F31 ?? Time_24 DB ? ; 1 if 24 hour time, 0 if 12 hour time 0 00000F32 ???? Map_call DW ? ; Address of case mapping call (DWORD) 0 00000F34 ???? DW ? ; THIS IS TWO WORDS SO IT CAN BE INITIALIZED 31 <3> ; in pieces. 0 00000F36 ?? Data_sep DB ? ; Data list separator character 0 00000F37 ?? DB ? 34 <3> internat_block ENDS 35 <3> 36 <3> ; 37 <3> ; Max size of the block returned by the INTERNATIONAL call 38 <3> ; 39 <3> internat_block_max EQU 32 162 <2> 163 <2> %include "mi.mac" 1 <3> ; SCCSID = @(#)mi.asm 1.1 85/04/10 2 <3> BREAK 3 <3> 4 <3> mi_INT EQU 0CDh 5 <3> mi_Long_JMP EQU 0EAh 6 <3> mi_Long_CALL EQU 09Ah 7 <3> mi_Long_RET EQU 0CBh 8 <3> mi_Near_RET EQU 0C3h 9 <3> 10 <3> ; xxxxoditszxaxpxc 11 <3> f_Overflow EQU 0000100000000000B 12 <3> f_Direction EQU 0000010000000000B 13 <3> f_Interrupt EQU 0000001000000000B 14 <3> f_Trace EQU 0000000100000000B 15 <3> f_Sign EQU 0000000010000000B 16 <3> f_Zero EQU 0000000001000000B 17 <3> f_Aux EQU 0000000000010000B 18 <3> f_Parity EQU 0000000000000100B 19 <3> f_Carry EQU 0000000000000001B 164 <2> 165 <2> fChk equ 1 166 <2> fDelim equ 2 167 <2> fSpChk equ 4 168 <2> fFCB equ 8 169 <2> 170 <2> %include "filemode.mac" 1 <3> ; SCCSID = @(#)filemode.asm 1.1 85/04/10 2 <3> ; SCCSID = @(#)filemode.asm 1.1 85/04/10 3 <3> BREAK 4 <3> 5 <3> stdin EQU 0 6 <3> stdout EQU 1 7 <3> stderr EQU 2 8 <3> stdaux EQU 3 9 <3> stdprn EQU 4 10 <3> 11 <3> BREAK 12 <3> 13 <3> access_mask EQU 0FH 14 <3> open_for_read EQU 00h 15 <3> open_for_write EQU 01h 16 <3> open_for_both EQU 02h 17 <3> 18 <3> sharing_mask EQU 0F0H 19 <3> sharing_compat EQU 000H 20 <3> sharing_deny_both EQU 010H 21 <3> sharing_deny_write EQU 020H 22 <3> sharing_deny_read EQU 030H 23 <3> sharing_deny_none EQU 040H 24 <3> sharing_net_FCB EQU 070h 25 <3> sharing_no_inherit EQU 080H 26 <3> 27 <3> BREAK 28 <3> 29 <3> no_code_page_check EQU 0100H 30 <3> int_24_error EQU 2000H 31 <3> auto_commit_write EQU 4000H 32 <3> ext_open_on EQU 01H 33 <3> ext_file_not_exists EQU 04H 34 <3> ext_open_I24_off EQU 02H 35 <3> io_mode_id EQU 00000010B 36 <3> reserved_bits_mask EQU 0FE00H 37 <3> exists_mask EQU 0FH 38 <3> not_exists_mask EQU 0F0H 39 <3> action_opened EQU 01H 40 <3> action_created_opened EQU 02H 41 <3> action_replaced_opened EQU 03H 42 <3> 43 <3> ext_exists_open EQU 01H 44 <3> ext_exists_fail EQU 0H 45 <3> ext_nexists_create EQU 10H 46 <3> 47 <3> 48 <3> 49 <3> ext_open_parm struc 0 00000F20 ???????? ext_set_list dd ? 0 00000F24 ???? ext_num_of_parm dw ? 52 <3> ext_open_parm ends 53 <3> 54 <3> 55 <3> 56 <3> 171 <2> 172 <2> %include "error.mac" 1 <3> ; SCCSID = @(#)error.asm 1.1 85/04/10 2 <3> ; SCCSID = @(#)error.asm 1.1 85/04/10 3 <3> BREAK 4 <3> 5 <3> ; 6 <3> ; XENIX calls all return error codes through AX. If an error occurred then 7 <3> ; the carry bit will be set and the error code is in AX. If no error occurred 8 <3> ; then the carry bit is reset and AX contains returned info. 9 <3> ; 10 <3> ; Since the set of error codes is being extended as we extend the operating 11 <3> ; system, we have provided a means for applications to ask the system for a 12 <3> ; recommended course of action when they receive an error. 13 <3> ; 14 <3> ; The GetExtendedError system call returns a universal error, an error 15 <3> ; location and a recommended course of action. The universal error code is 16 <3> ; a symptom of the error REGARDLESS of the context in which GetExtendedError 17 <3> ; is issued. 18 <3> ; 19 <3> 20 <3> ; 21 <3> ; These are the 2.0 error codes 22 <3> ; 23 <3> error_invalid_function EQU 1 24 <3> error_file_not_found EQU 2 25 <3> error_path_not_found EQU 3 26 <3> error_too_many_open_files EQU 4 27 <3> error_access_denied EQU 5 28 <3> error_invalid_handle EQU 6 29 <3> error_arena_trashed EQU 7 30 <3> error_not_enough_memory EQU 8 31 <3> error_invalid_block EQU 9 32 <3> error_bad_environment EQU 10 33 <3> error_bad_format EQU 11 34 <3> error_invalid_access EQU 12 35 <3> error_invalid_data EQU 13 36 <3> ;**** reserved EQU 14 ; ***** 37 <3> error_invalid_drive EQU 15 38 <3> error_current_directory EQU 16 39 <3> error_not_same_device EQU 17 40 <3> error_no_more_files EQU 18 41 <3> ; 42 <3> ; These are the universal int 24 mappings for the old INT 24 set of errors 43 <3> ; 44 <3> error_write_protect EQU 19 45 <3> error_bad_unit EQU 20 46 <3> error_not_ready EQU 21 47 <3> error_bad_command EQU 22 48 <3> error_CRC EQU 23 49 <3> error_bad_length EQU 24 50 <3> error_Seek EQU 25 51 <3> error_not_DOS_disk EQU 26 52 <3> error_sector_not_found EQU 27 53 <3> error_out_of_paper EQU 28 54 <3> error_write_fault EQU 29 55 <3> error_read_fault EQU 30 56 <3> error_gen_failure EQU 31 57 <3> ; 58 <3> ; These are the new 3.0 error codes reported through INT 24 59 <3> ; 60 <3> error_sharing_violation EQU 32 61 <3> error_lock_violation EQU 33 62 <3> error_wrong_disk EQU 34 63 <3> error_FCB_unavailable EQU 35 64 <3> error_sharing_buffer_exceeded EQU 36 65 <3> error_Code_Page_Mismatched EQU 37 ; DOS 4.00 ;AN000; 66 <3> error_handle_EOF EQU 38 ; DOS 4.00 ;AN000; 67 <3> error_handle_Disk_Full EQU 39 ; DOS 4.00 ;AN000; 68 <3> ; 69 <3> ; New OEM network-related errors are 50-79 70 <3> ; 71 <3> error_not_supported EQU 50 72 <3> ; 73 <3> ; End of INT 24 reportable errors 74 <3> ; 75 <3> error_file_exists EQU 80 76 <3> error_DUP_FCB EQU 81 ; ***** 77 <3> error_cannot_make EQU 82 78 <3> error_FAIL_I24 EQU 83 79 <3> ; 80 <3> ; New 3.0 network related error codes 81 <3> ; 82 <3> error_out_of_structures EQU 84 83 <3> error_Already_assigned EQU 85 84 <3> error_invalid_password EQU 86 85 <3> error_invalid_parameter EQU 87 86 <3> error_NET_write_fault EQU 88 87 <3> error_sys_comp_not_loaded EQU 90 ; DOS 4.00 ;AN000; 88 <3> 89 <3> BREAK 90 <3> 91 <3> error_I24_write_protect EQU 0 92 <3> error_I24_bad_unit EQU 1 93 <3> error_I24_not_ready EQU 2 94 <3> error_I24_bad_command EQU 3 95 <3> error_I24_CRC EQU 4 96 <3> error_I24_bad_length EQU 5 97 <3> error_I24_Seek EQU 6 98 <3> error_I24_not_DOS_disk EQU 7 99 <3> error_I24_sector_not_found EQU 8 100 <3> error_I24_out_of_paper EQU 9 101 <3> error_I24_write_fault EQU 0Ah 102 <3> error_I24_read_fault EQU 0Bh 103 <3> error_I24_gen_failure EQU 0Ch 104 <3> ; NOTE: Code 0DH is used by MT-DOS. 105 <3> error_I24_wrong_disk EQU 0Fh 106 <3> 107 <3> ; THE FOLLOWING ARE MASKS FOR THE AH REGISTER ON Int 24 108 <3> 109 <3> Allowed_FAIL EQU 00001000B 110 <3> Allowed_RETRY EQU 00010000B 111 <3> Allowed_IGNORE EQU 00100000B 112 <3> ;NOTE: ABORT is ALWAYS allowed 113 <3> 114 <3> I24_operation EQU 00000001B ;Z if READ,NZ if Write 115 <3> I24_area EQU 00000110B ; 00 if DOS 116 <3> ; 01 if FAT 117 <3> ; 10 if root DIR 118 <3> ; 11 if DATA 119 <3> I24_class EQU 10000000B ;Z if DISK, NZ if FAT or char 120 <3> 121 <3> BREAK 122 <3> 123 <3> ; Values for error CLASS 124 <3> 125 <3> errCLASS_OutRes EQU 1 ; Out of Resource 126 <3> errCLASS_TempSit EQU 2 ; Temporary Situation 127 <3> errCLASS_Auth EQU 3 ; Permission problem 128 <3> errCLASS_Intrn EQU 4 ; Internal System Error 129 <3> errCLASS_HrdFail EQU 5 ; Hardware Failure 130 <3> errCLASS_SysFail EQU 6 ; System Failure 131 <3> errCLASS_Apperr EQU 7 ; Application Error 132 <3> errCLASS_NotFnd EQU 8 ; Not Found 133 <3> errCLASS_BadFmt EQU 9 ; Bad Format 134 <3> errCLASS_Locked EQU 10 ; Locked 135 <3> errCLASS_Media EQU 11 ; Media Failure 136 <3> errCLASS_Already EQU 12 ; Collision with Existing Item 137 <3> errCLASS_Unk EQU 13 ; Unknown/other 138 <3> 139 <3> ; Values for error ACTION 140 <3> 141 <3> errACT_Retry EQU 1 ; Retry 142 <3> errACT_DlyRet EQU 2 ; Delay Retry, retry after pause 143 <3> errACT_User EQU 3 ; Ask user to regive info 144 <3> errACT_Abort EQU 4 ; abort with clean up 145 <3> errACT_Panic EQU 5 ; abort immediately 146 <3> errACT_Ignore EQU 6 ; ignore 147 <3> errACT_IntRet EQU 7 ; Retry after User Intervention 148 <3> 149 <3> ; Values for error LOCUS 150 <3> 151 <3> errLOC_Unk EQU 1 ; No appropriate value 152 <3> errLOC_Disk EQU 2 ; Random Access Mass Storage 153 <3> errLOC_Net EQU 3 ; Network 154 <3> errLOC_SerDev EQU 4 ; Serial Device 155 <3> errLOC_Mem EQU 5 ; Memory 173 <2> 174 <2> %include "syscall.mac" 1 <3> ; SCCSID = @(#)syscall.asm 1.1 85/04/10 2 <3> ;BREAK 3 <3> ;SUBTTL system call definitions 4 <3> ;PAGE 5 <3> 6 <3> Abort EQU 0 ; 0 0 7 <3> Std_Con_Input EQU 1 ; 1 1 8 <3> Std_Con_Output EQU 2 ; 2 2 9 <3> Std_Aux_Input EQU 3 ; 3 3 10 <3> Std_Aux_Output EQU 4 ; 4 4 11 <3> Std_Printer_Output EQU 5 ; 5 5 12 <3> Raw_Con_IO EQU 6 ; 6 6 13 <3> Raw_Con_Input EQU 7 ; 7 7 14 <3> Std_Con_Input_No_Echo EQU 8 ; 8 8 15 <3> Std_Con_String_Output EQU 9 ; 9 9 16 <3> Std_Con_String_Input EQU 10 ; 10 A 17 <3> Std_Con_Input_Status EQU 11 ; 11 B 18 <3> Std_Con_Input_Flush EQU 12 ; 12 C 19 <3> Disk_Reset EQU 13 ; 13 D 20 <3> Set_Default_Drive EQU 14 ; 14 E 21 <3> FCB_Open EQU 15 ; 15 F 22 <3> FCB_Close EQU 16 ; 16 10 23 <3> Dir_Search_First EQU 17 ; 17 11 24 <3> Dir_Search_Next EQU 18 ; 18 12 25 <3> FCB_Delete EQU 19 ; 19 13 26 <3> FCB_Seq_Read EQU 20 ; 20 14 27 <3> FCB_Seq_Write EQU 21 ; 21 15 28 <3> FCB_Create EQU 22 ; 22 16 29 <3> FCB_Rename EQU 23 ; 23 17 30 <3> Get_Default_Drive EQU 25 ; 25 19 31 <3> Set_DMA EQU 26 ; 26 1A 32 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 33 <3> ; C A V E A T P R O G R A M M E R ; 34 <3> ; ; 35 <3> Get_Default_DPB EQU 31 ; 31 1F 36 <3> ; ; 37 <3> ; C A V E A T P R O G R A M M E R ; 38 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 39 <3> FCB_Random_Read EQU 33 ; 33 21 40 <3> FCB_Random_Write EQU 34 ; 34 22 41 <3> Get_FCB_File_Length EQU 35 ; 35 23 42 <3> Get_FCB_Position EQU 36 ; 36 24 43 <3> Set_Interrupt_Vector EQU 37 ; 37 25 44 <3> Create_Process_Data_Block EQU 38 ; 38 26 45 <3> FCB_Random_Read_Block EQU 39 ; 39 27 46 <3> FCB_Random_Write_Block EQU 40 ; 40 28 47 <3> Parse_File_Descriptor EQU 41 ; 41 29 48 <3> Get_Date EQU 42 ; 42 2A 49 <3> Set_Date EQU 43 ; 43 2B 50 <3> Get_Time EQU 44 ; 44 2C 51 <3> Set_Time EQU 45 ; 45 2D 52 <3> Set_Verify_On_Write EQU 46 ; 46 2E 53 <3> ; Extended functionality group 54 <3> Get_DMA EQU 47 ; 47 2F 55 <3> Get_Version EQU 48 ; 48 30 56 <3> Keep_Process EQU 49 ; 49 31 57 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 58 <3> ; C A V E A T P R O G R A M M E R ; 59 <3> ; ; 60 <3> Get_DPB EQU 50 ; 50 32 61 <3> ; ; 62 <3> ; C A V E A T P R O G R A M M E R ; 63 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 64 <3> Set_CTRL_C_Trapping EQU 51 ; 51 33 65 <3> Get_InDOS_Flag EQU 52 ; 52 34 66 <3> Get_Interrupt_Vector EQU 53 ; 53 35 67 <3> Get_Drive_Freespace EQU 54 ; 54 36 68 <3> Char_Oper EQU 55 ; 55 37 69 <3> International EQU 56 ; 56 38 70 <3> ; Directory Group 71 <3> MKDir EQU 57 ; 57 39 72 <3> RMDir EQU 58 ; 58 3A 73 <3> CHDir EQU 59 ; 59 3B 74 <3> ; File Group 75 <3> Creat EQU 60 ; 60 3C 76 <3> Open EQU 61 ; 61 3D 77 <3> Close EQU 62 ; 62 3E 78 <3> Read EQU 63 ; 63 3F 79 <3> Write EQU 64 ; 64 40 80 <3> Unlink EQU 65 ; 65 41 81 <3> LSeek EQU 66 ; 66 42 82 <3> CHMod EQU 67 ; 67 43 83 <3> IOCtl EQU 68 ; 68 44 84 <3> XDup EQU 69 ; 69 45 85 <3> XDup2 EQU 70 ; 70 46 86 <3> Current_Dir EQU 71 ; 71 47 87 <3> ; Memory Group 88 <3> Alloc EQU 72 ; 72 48 89 <3> Dealloc EQU 73 ; 73 49 90 <3> Setblock EQU 74 ; 74 4A 91 <3> ; Process Group 92 <3> Exec EQU 75 ; 75 4B 93 <3> Exit EQU 76 ; 76 4C 94 <3> WaitProcess EQU 77 ; 77 4D 95 <3> Find_First EQU 78 ; 78 4E 96 <3> ; Special Group 97 <3> Find_Next EQU 79 ; 79 4F 98 <3> ; SPECIAL SYSTEM GROUP 99 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 100 <3> ; C A V E A T P R O G R A M M E R ; 101 <3> ; ; 102 <3> Set_Current_PDB EQU 80 ; 80 50 103 <3> Get_Current_PDB EQU 81 ; 81 51 104 <3> Get_In_Vars EQU 82 ; 82 52 105 <3> SetDPB EQU 83 ; 83 53 106 <3> ; ; 107 <3> ; C A V E A T P R O G R A M M E R ; 108 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 109 <3> Get_Verify_On_Write EQU 84 ; 84 54 110 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 111 <3> ; C A V E A T P R O G R A M M E R ; 112 <3> ; ; 113 <3> Dup_PDB EQU 85 ; 85 55 114 <3> ; ; 115 <3> ; C A V E A T P R O G R A M M E R ; 116 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 117 <3> Rename EQU 86 ; 86 56 118 <3> File_Times EQU 87 ; 87 57 119 <3> AllocOper EQU 88 ; 88 58 120 <3> ; Network extention system calls 121 <3> GetExtendedError EQU 89 ; 89 59 122 <3> CreateTempFile EQU 90 ; 90 5A 123 <3> CreateNewFile EQU 91 ; 91 5B 124 <3> LockOper EQU 92 ; 92 5C Lock and Unlock 125 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 126 <3> ; C A V E A T P R O G R A M M E R ; 127 <3> ; ; 128 <3> ServerCall EQU 93 ; 93 5D CommitAll, ServerDOSCall, 129 <3> ; CloseByName, CloseUser, 130 <3> ; CloseUserProcess, 131 <3> ; GetOpenFileList 132 <3> ; ; 133 <3> ; C A V E A T P R O G R A M M E R ; 134 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 135 <3> UserOper EQU 94 ; 94 5E Get and Set 136 <3> AssignOper EQU 95 ; 95 5F On, Off, Get, Set, Cancel 137 <3> xNameTrans EQU 96 ; 96 60 138 <3> PathParse EQU 97 ; 97 61 139 <3> GetCurrentPSP EQU 98 ; 98 62 140 <3> Hongeul EQU 99 ; 99 63 141 <3> ECS_CALL EQU 99 ; 99 63 ;; DBCS support 142 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 143 <3> ; C A V E A T P R O G R A M M E R ; 144 <3> ; ; 145 <3> Set_Printer_Flag EQU 100 ; 100 64 146 <3> ; ; 147 <3> ; C A V E A T P R O G R A M M E R ; 148 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 149 <3> GetExtCntry EQU 101 ; 101 65 150 <3> GetSetCdPg EQU 102 ; 102 66 151 <3> ExtHandle EQU 103 ; 103 67 152 <3> Commit EQU 104 ; 104 68 153 <3> GetSetMediaID EQU 105 ; 105 69 154 <3> IFS_IOCTL EQU 107 ; 107 6B 155 <3> ExtOpen EQU 108 ; 108 6C 156 <3> ; 157 <3> ; 158 <3> Set_Oem_Handler EQU 248 ; 248 F8 159 <3> OEM_C1 EQU 249 ; 249 F9 160 <3> OEM_C2 EQU 250 ; 250 FA 161 <3> OEM_C3 EQU 251 ; 251 FB 162 <3> OEM_C4 EQU 252 ; 252 FC 163 <3> OEM_C5 EQU 253 ; 253 FD 164 <3> OEM_C6 EQU 254 ; 254 FE 165 <3> OEM_C7 EQU 255 ; 255 FF 166 <3> 175 <2> 176 <2> ;SUBTTL 177 <2> 178 <2> 12 <1> ;.cref 13 <1> [list +] 14 <1> 15 <1> ;AsmVars 16 <1> %ifndef Kanji 17 <1> %assign Kanji 0 18 <1> %endif 19 <1> %ifndef Debug 20 <1> %assign Debug 0 21 <1> %endif 22 <1> 23 <1> BREAK === Switch to base=008400h -> "DOSCODECODE" 24 <1> section DOSCODECODE 25 <1> 26 <1> 27 <1> I_need CurrentPDB,WORD 28 <1> I_need CntCFlag,BYTE 29 <1> I_need User_SS,WORD 30 <1> I_need User_SP,WORD 31 <1> I_need NSS,WORD 32 <1> I_need NSP,WORD 33 <1> I_need SaveDS,WORD 34 <1> I_need SaveBX,WORD 35 <1> I_need INDOS,BYTE 36 <1> I_need User_ID,WORD 37 <1> I_need Proc_ID,WORD 38 <1> I_need AuxStack,BYTE 39 <1> I_need IOSTACK,BYTE 40 <1> I_need DSKSTACK,BYTE 41 <1> I_need fsharing,BYTE 42 <1> I_need NoSetDir,BYTE 43 <1> I_need FailERR,BYTE 44 <1> I_need Errormode,BYTE 45 <1> I_need restore_tmp,WORD 46 <1> I_need WPERR,BYTE 47 <1> I_need Dispatch,WORD 48 <1> I_need ConSwap,BYTE 49 <1> I_need User_In_AX,WORD 50 <1> I_need EXTERR_LOCUS,BYTE 51 <1> I_need IdleInt,BYTE 52 <1> I_need Printer_Flag,BYTE 53 <1> I_need CPSWFLAG,BYTE ;AN000; 54 <1> I_need CPSWSAVE,BYTE ;AN000; 55 <1> I_need DISK_FULL,BYTE ;AN000; 56 <1> I_need InterCon,BYTE ;AN000; 57 <1> I_need BOOTDRIVE,BYTE ;AN000; 58 <1> I_need EXTOPEN_ON,BYTE ;AN000; 59 <1> I_need DOS34_FLAG,WORD ;AN000; 60 <1> %ifndef BUF2 61 <1> I_need ACT_PAGE,WORD ;AN000; 62 <1> %endif 63 <1> i_need MSVERS,WORD 64 <1> I_need doslocation3306, byte 65 <1> 66 <1> %IFN IBM 67 <1> I_need OEM_HANDLER,DWORD 68 <1> %ENDIF 69 <1> 70 <1> %ifndef BUF2 71 <1> %IF BUFFERFLAG 72 <1> I_am SETVECTFLAG,BYTE,<0> 73 <1> i_need BUF_EMS_SEG_CNT,WORD ; DOS 4.00 EMS seg count ;AN000; 74 <1> i_need BUF_EMS_MODE,BYTE ; DOS 4.00 EMS mode ;AN000; 75 <1> i_am BUF_EMS_MAP_USER,12,<0,0,0,0,0,0,0,0,0,0,0,0> 76 <1> %ENDIF 77 <1> %endif 78 <1> 79 <1> 80 <1> BREAK 81 <1> 82 <1> versionstring: 83 <1> %include "../../version.inc" 0 0000059C 6C444F532028323032 db "lDOS (2025 February) based on MS-DOS v4.01" 0 000005A5 352046656272756172 0 000005AE 792920626173656420 0 000005B7 6F6E204D532D444F53 0 000005C0 2076342E3031 0 000005C6 00 db 0 85 <1> 86 <1> 87 <1> BREAK <$Set_CTRL_C_Trapping -- En/Disable ^C check in dispatcher> 88 <1> 89 <1> ; Inputs: 90 <1> ; ds => DOSDATA 91 <1> ; ss:sp -> original ds, original ip, original cs, original fl 92 <1> ; AL = 0 read ^C status 93 <1> ; AL = 1 Set ^C status, DL = 0/1 for ^C off/on 94 <1> ; AL = 2 Set ^C status to contents of DL. Output is old state. 95 <1> ; AL = 3 Get CPSW state to DL DOS 3.4 96 <1> ; AL = 4 Set CPSW state from DL DOS 3.4 97 <1> ; AL = 5 get DOS boot drive 98 <1> ; Function: 99 <1> ; Enable disable ^C checking in dispatcher 100 <1> ; Outputs: 101 <1> ; If AL = 0 then DL = 0/1 for ^C off/on 102 <1> 103 <1> procedure D_SET_CTRL_C_TRAPPING,NEAR 103 ****************** <1> warning: proc D_SET_CTRL_C_TRAPPING... [-w+user] 104 <1> ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING 0 000005C7 3C06 cmp al, 6 0 000005C9 750C jne .nottrueversion 0 000005CB 31D2 xor dx, dx 0 000005CD 8A36[0000] mov dh, [doslocation3306] 0 000005D1 8B1E[0000] mov bx, [MSVERS] 0 000005D5 1F pop ds 0 000005D6 CF iret 112 <1> 113 <1> .nottrueversion: 0 000005D7 3CFF cmp al, 0FFh ; function 33FFh ? 0 000005D9 7507 jne .notversionstring ; no --> 0 000005DB B8[0000] mov ax, offset versionstring 0 000005DE 8CCA mov dx, cs ; yes, return dx:ax -> ASCIZ 0 000005E0 1F pop ds 0 000005E1 CF iret ; (CF preserved) 120 <1> 121 <1> .notversionstring: 0 000005E2 84C0 test AL,AL 0 000005E4 7506 JNZ Check1 0 000005E6 8A16[0000] MOV DL,[CntCFlag] 0 000005EA 1F pop ds 0 000005EB CF IRET 127 <1> Check1: 0 000005EC 3C02 CMP AL,2 0 000005EE 771A JA CPSWchk ;AN000; 0 000005F0 740B JZ SetAndRet 0 000005F2 52 PUSH DX 0 000005F3 80E201 AND DL,01h 133 <1> CNTCFLAG equ CntCFlag ; NASM port label 0 000005F6 8816[0000] MOV [CNTCFLAG],DL 0 000005FA 5A POP DX 0 000005FB 1F pop ds 0 000005FC CF IRET 138 <1> SetAndRet: 0 000005FD 80E201 AND DL,01h 0 00000600 8616[0000] XCHG [CntCFlag],DL 0 00000604 1F pop ds 0 00000605 CF IRET 143 <1> BadVal: 0 00000606 B0FF MOV AL,0FFH 145 <1> doscode_popds_iret: 0 00000608 1F pop ds 0 00000609 CF IRET 148 <1> ;; DOS 4.00 File Tagging 149 <1> 150 <1> CPSWchk: ;AN000; 151 <1> ; PUSH AX ;AN000;;FT. 152 <1> ; MOV AL,[CPSWSAVE] ;AN000;;FT. DOS 3.4 153 <1> ; MOV [CPSWFLAG],AL ;AN000;;FT. DOS 3.4 in case ABORT 154 <1> ; POP AX ;AN000;;FT. 0 0000060A 3C03 CMP AL,3 ;AN000;;FT get CPSW state ? 156 <1> ; JNZ CPSWset ;AN000;;FT. no 0 0000060C 74FA je doscode_popds_iret 158 <1> ; MOV DL,CPSWFLAG ;AN000;;FT. return CPSW state 159 <1> ; pop ds 160 <1> ; IRET ;AN000; 161 <1> CPSWset: ;AN000; 0 0000060E 3C04 CMP AL,4 ;AN000;;FT. set CPSW state ? 163 <1> ; JA QueryDOSboot ;AN000;;FT. check query dos boot drive 0 00000610 76F6 jbe doscode_popds_iret 165 <1> ; PUSH AX ;AN000;;FT. 166 <1> ; CallInstall NLSInstall,NLSFUNC,0 ;AN000;;FT. NLSFUNC installed ? 167 <1> ; CMP AL,0FFH ;AN000;;FT. 168 <1> ; POP AX ;AN000;;FT. 169 <1> ; JNZ BadVal ;AN000;;FT. not loaded, therefore ignore 170 <1> ;;;; AND DL,01H ;AN000;;FT. only 0 or 1 171 <1> ;;;; MOV [CPSWFLAG],DL ;AN000;;FT. set the flag 172 <1> ;;;; MOV [CPSWSAVE],DL ;AN000;;FT. save one copy 173 <1> ; pop ds 174 <1> ; IRET ;AN000;;FT. 175 <1> QueryDOSboot: ;AN000; 0 00000612 3C05 CMP AL,5 ;AN000;MS. 0 00000614 77F0 JA BadVal ;AN000;MS. 0 00000616 8A16[0000] MOV DL,[BOOTDRIVE] ;AN000;;MS. put boot drive in DL 0 0000061A 1F pop ds 0 0000061B CF IRET ;AN000;;MS. 181 <1> 182 <1> 183 <1> ;; DOS 4.00 File Tagging 184 <1> 185 <1> EndProc D_SET_CTRL_C_TRAPPING 186 <1> 187 <1> BREAK <$Get_current_PDB -- Set/Get PDB value> 188 <1> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 189 <1> ; C A V E A T P R O G R A M M E R ; 190 <1> ; ; 191 <1> ; The following two routines are dispatched to directly with ints disabled 192 <1> ; immediately after the int 21h entry. no DIS state is set. 193 <1> ; 194 <1> ; $Set_current_PDB takes BX and sets it to be the current process 195 <1> ; *** THIS FUNCTION CALL IS SUBJECT TO CHANGE!!! *** 196 <1> ; 197 <1> procedure D_SET_CURRENT_PDB,NEAR 197 ****************** <1> warning: proc D_SET_CURRENT_PDB... [-w+user] 198 <1> ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING 0 0000061C 891E[0000] MOV [CurrentPDB],BX 0 00000620 1F pop ds 0 00000621 CF IRET 202 <1> EndProc D_SET_CURRENT_PDB 203 <1> 204 <1> ; 205 <1> ; $get_current_PDB returns in BX the current process 206 <1> ; *** THIS FUNCTION CALL IS SUBJECT TO CHANGE!!! *** 207 <1> ; 208 <1> procedure D_GET_CURRENT_PDB,NEAR 208 ****************** <1> warning: proc D_GET_CURRENT_PDB... [-w+user] 209 <1> ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING 0 00000622 8B1E[0000] MOV BX,[CurrentPDB] 0 00000626 1F pop ds 0 00000627 CF IRET 213 <1> EndProc D_GET_CURRENT_PDB 214 <1> ; C A V E A T P R O G R A M M E R ; 215 <1> ; ; 216 <1> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 217 <1> 218 <1> ; 219 <1> ; Sets the Printer Flag to whatever is in AL. 220 <1> ; NOTE: THIS PROCEDURE IS SUBJECT TO CHANGE!!! 221 <1> ; 222 <1> Procedure D_Set_Printer_Flag 222 ****************** <1> warning: proc D_Set_Printer_Flag... [-w+user] 223 <1> ASSUME DS:NOTHING, ES:NOTHING, SS:NOTHING 0 00000628 A2[0000] mov [Printer_Flag],al 0 0000062B 1F pop ds 0 0000062C CF IRET 227 <1> EndProc D_Set_Printer_Flag 228 <1> 229 <1> procedure SYSTEM_CALL,NEAR 229 ****************** <1> warning: proc SYSTEM_CALL... [-w+user] 230 <1> 231 <1> %if 0 232 <1> ; 233 <1> ; The Quit entry point is where all INT 20h's come from. These are old- style 234 <1> ; exit system calls. The CS of the caller indicates which Process is dying. 235 <1> ; The error code is presumed to be 0. We simulate an ABORT system call. 236 <1> ; 237 <1> entry QUIT 238 <1> MOV AH,0 239 <1> JMP SHORT SAVREGS 240 <1> %endif 241 <1> 242 <1> ; 243 <1> ; The system call in AH is out of the range that we know how to handle. We 244 <1> ; arbitrarily set the contents of AL to 0 and IRET. Note that we CANNOT set 245 <1> ; the carry flag to indicate an error as this may break some programs 246 <1> ; compatability. 247 <1> ; 248 <1> BADCALL: 0 0000062D B000 MOV AL,0 250 <1> entry IRETT 0 0000062F CF IRET 252 <1> ; 253 <1> ; An alternative method of entering the system is to perform a CALL 5 in the 254 <1> ; program segment prefix with the contents of CL indicating what system call 255 <1> ; the user would like. A subset of the possible system calls is allowed here; 256 <1> ; only the CPM-compatible calls may get dispatched. 257 <1> ; 258 <1> 259 <1> ; Call DOS interface for CP/M compatibility, "CALL 5" 260 <1> relocated call5 261 <1> entry CALL_ENTRY ; System call entry point and dispatcher 262 <1> 263 <1> ; The CALL 5 interface isn't just a far call to this address. 264 <1> ; Rather it's a near call (inside the program's PSP) to address 5, which 265 <1> ; then calls far to this address. Doing a retf here will screw everything 266 <1> ; up and return into the PSP data instead of into the actual caller code. 0 00000630 9C pushf 0 00000631 55 push bp 0 00000632 89E5 mov bp, sp 270 <1> ; [ bp ] = bp 271 <1> ; [ bp + 2 ] = flags (that we just pushed) 272 <1> ; [ bp + 4 ] = call far's ip (will point into PSP so it's garbage) 273 <1> ; [ bp + 6 ] = call far's cs 274 <1> ; [ bp + 8 ] = "CALL 5"'s ip 275 <1> 0 00000634 874602 xchg ax, word [ byte bp + 2] ; ax = flags 277 <1> ; [ bp + 2 ] = original ax 0 00000637 874608 xchg ax, word [ byte bp + 8] ; [ bp + 8 ] = flags 279 <1> ; ax = "CALL 5"'s ip 0 0000063A 874604 xchg ax, word [ byte bp + 4] ; [ bp + 4 ] = "CALL 5"'s ip 281 <1> ; clobbers ax (call far's ip) 0 0000063D 5D pop bp 0 0000063E 58 pop ax ; ax = original ax 284 <1> 285 <1> ; [ sp ] = "CALL 5"'s IP 286 <1> ; [ sp + 2 ] = call far's cs 287 <1> ; [ sp + 4 ] = flags 288 <1> ; Surprisingly this really looks like the stack for an interrupt! 0 0000063F FA cli ; Real interrupt entries do the same 290 <1> 291 <1> 0 00000640 80F924 cmp cl, 24h ; CP/M function number 293 <1> ; hardcoded ms_table.nas table size 0 00000643 77E8 ja .nocpmfunc ; is it above 24h? Really no CP/M function --> 295 <1> ; (I found this behaviour while debugging MS-DOS) 296 <1> 0 00000645 88CC mov ah,cl ; CP/M compatibility interface uses cl as function 298 <1> SavRegs equ SAVREGS ; NASM port label 0 00000647 EB05 JMP SHORT SavRegs 300 <1> ; Pass it through to our normal Int21 entry 301 <1> 302 <1> .nocpmfunc: equ BADCALL 303 <1> ; xor al,al ; Report "Unused" function 304 <1> ; iret ; (don't need to care about CY/NC) 305 <1> ; RxDOS 7.20N: The above, correct, code requires some space you may want to save. 306 <1> ; A short solution for all this CP/M crap is to place "xor al,al", 307 <1> ; "retn" at address 5 of the PSP. This will report an error to all CP/M 308 <1> ; CALL 5s and it's even shorter than the code used by RxDOS <= 7.20N 309 <1> 310 <1> 311 <1> ; 312 <1> ; This is the normal INT 21 entry point. We first perform a quick test to see 313 <1> ; if we need to perform expensive DOS-entry functions. Certain system calls 314 <1> ; are done without interrupts being enabled. 315 <1> ; 316 <1> 317 <1> relocated i21 318 <1> entry COMMAND ; Interrupt call entry point (INT 21H) 319 <1> 320 <1> %IFN IBM 321 <1> SET_OEM_HANDLER equ Set_Oem_Handler ; NASM port equate 322 <1> CMP AH,SET_OEM_HANDLER 323 <1> JB NOTOEM 324 <1> JMP D_SET_OEM_HANDLER 325 <1> NOTOEM: 326 <1> %ENDIF 327 <1> 0 00000649 80FC6C CMP AH, 6Ch ; hardcoded ms_table.nas table size 329 <1> BadCall equ BADCALL ; NASM port label 0 0000064C 77DF JA BadCall 331 <1> 332 <1> ; 333 <1> ; The following set of calls are issued by the server at *arbitrary* times 334 <1> ; and, therefore, must be executed on the user's entry stack and executed with 335 <1> ; interrupts off. 336 <1> ; lDOS: Set up a minimal stack frame consisting of the original ds, 337 <1> ; so that we can access DOSDATA with ds. 338 <1> ; 339 <1> SAVREGS: 340 <1> 341 <1> extern doscode_getdosdata 342 <1> 0 0000064E 1E push ds ; now ds on stack 0 0000064F 50 push ax 0 00000650 E8[0000] call doscode_getdosdata 0 00000653 8ED8 mov ds, ax ; => DOSDATA 0 00000655 58 pop ax 348 <1> 349 <1> GET_CURRENT_PDB equ Get_Current_PDB ; NASM port equate 0 00000656 80FC51 CMP AH,GET_CURRENT_PDB 0 00000659 74C7 JZ D_GET_CURRENT_PDB 0 0000065B 80FC62 CMP AH,GetCurrentPSP 0 0000065E 74C2 JZ D_GET_CURRENT_PDB 354 <1> SET_CURRENT_PDB equ Set_Current_PDB ; NASM port equate 0 00000660 80FC50 CMP AH,SET_CURRENT_PDB 0 00000663 74B7 JZ D_SET_CURRENT_PDB 0 00000665 80FC33 CMP AH,Set_CTRL_C_Trapping 0 00000668 7503 JNZ chkprt 359 <1> D_Set_CTRL_C_Trapping equ D_SET_CTRL_C_TRAPPING 0 0000066A E95AFF JMP D_Set_CTRL_C_Trapping 361 <1> chkprt: 362 <1> SET_PRINTER_FLAG equ Set_Printer_Flag ; NASM port equate 0 0000066D 80FC64 CMP AH,SET_PRINTER_FLAG 0 00000670 74B6 JZ D_Set_Printer_Flag 0 00000672 1F pop ds ; restore ds before save_world 366 <1> ; 367 <1> ; Preserve all user's registers on his own stack. 368 <1> ; 0 00000673 E80601 CALL save_world 0 00000676 E8[0000] call doscode_getdosdata ; ax => DOSDATA 0 00000679 1E push ds ; stack original ds 0 0000067A 8ED8 mov ds, ax ; => DOSDATA 0 0000067C 8F06[0000] pop word [SaveDS] ; = original ds 0 00000680 891E[0000] MOV [SaveBX],BX 375 <1> ASSUME DS:DOSGROUP 0 00000684 FE06[0000] INC byte [INDOS] ; Flag that we're in the DOS 0 00000688 31C0 XOR AX,AX 378 <1> USER_ID equ User_ID ; NASM port label 0 0000068A A3[0000] MOV [USER_ID],AX 0 0000068D A1[0000] MOV AX,[CurrentPDB] ; current process 381 <1> PROC_ID equ Proc_ID ; NASM port label 0 00000690 A3[0000] MOV [PROC_ID],AX ; Assume local machine for the moment 383 <1> ; 384 <1> ; Provide one level of reentrancy for INT 24 recallability. 385 <1> ; 386 <1> user_SP equ User_SP ; NASM port label 0 00000693 A1[0000] MOV AX,[user_SP] 0 00000696 A3[0000] MOV [NSP],AX 389 <1> user_SS equ User_SS ; NASM port label 0 00000699 A1[0000] MOV AX,[user_SS] 0 0000069C A3[0000] MOV [NSS],AX 0 0000069F 58 POP AX 0 000006A0 50 PUSH AX 0 000006A1 8926[0000] MOV [user_SP],SP 0 000006A5 8C16[0000] MOV [user_SS],SS 396 <1> ; 397 <1> ; save user stack in his area for later returns (possibly from EXEC) 398 <1> ; 399 <1> fSharing equ fsharing ; NASM port label 0 000006A9 C606[0000]00 MOV byte [fSharing],0 ; allow redirection 401 <1> 0 000006AE 8CDB mov bx, ds 0 000006B0 8E1E[0000] MOV DS,[CurrentPDB] 404 <1> ASSUME DS:NOTHING 0 000006B4 89262E00 MOV WORD PTR [PDB_User_stack],SP 0 000006B8 8C163000 MOV WORD PTR [PDB_User_stack+2],SS 407 <1> 408 <1> ; MOV BX,CS ; no holes here. 0 000006BC 8ED3 MOV SS,BX 410 <1> ASSUME SS:DOSGROUP 411 <1> 412 <1> entry REDISP 413 <1> AUXSTACK equ AuxStack ; NASM port label 0 000006BE BC[0000] MOV SP,OFFSET AUXSTACK wrt DOSGROUP ; Enough stack for interrupts 0 000006C1 FB STI ; stack is in our space now... 416 <1> %IF DBCS ;AN000; 417 <1> MOV BH, BYTE PTR [PDB_InterCon] ;AN000;; get interim mode 2/13/KK 418 <1> MOV [SS:InterCon], BH ;AN000;; 2/13/KK 419 <1> %ENDIF ;AN000; 0 000006C2 16 push ss 0 000006C3 1F pop ds 422 <1> DOSAssume CS,,"MSCODE/ReDisp" 423 <1> ;; DOS 3.4 INIT 424 <1> ; MOV BL,[CPSWSAVE] ;AN000;;FT. DOS 3.4 425 <1> ; MOV [CPSWFLAG],BL ;AN000;;FT. DOS 3.4 in case ABORT 0 000006C4 C606[0000]00 MOV byte [DISK_FULL],0 ;AN000;;MS. no disk full 0 000006C9 C606[0000]00 MOV byte [EXTOPEN_ON],0 ;AN000;;EO. clear extended open flag 0 000006CE C706[0000]0000 MOV word [DOS34_FLAG],0 ;AN000;;MS. clear common flag 429 <1> %ifndef BUF2 430 <1> MOV word [ACT_PAGE],-1 ;BN000;BL;AN000;;LB. invalidate active page 431 <1> %endif 432 <1> ;; DOS 4.00 INIT 0 000006D4 30FF XOR BH,BH 434 <1> CONSWAP equ ConSwap ; NASM port label 0 000006D6 883E[0000] MOV [CONSWAP],BH ; random clean up of possibly mis-set flags 436 <1> IDLEINT equ IdleInt ; NASM port label 0 000006DA C606[0000]01 MOV byte [IDLEINT],1 ; presume that we can issue INT 28 0 000006DF 883E[0000] MOV BYTE PTR [NoSetDir],BH ; set directories on search 439 <1> FAILERR equ FailERR ; NASM port label 0 000006E3 883E[0000] MOV BYTE PTR [FAILERR],BH ; FAIL not in progress 0 000006E7 88E3 MOV BL,AH 0 000006E9 D1E3 SHL BX,1 ; 2 bytes per call in table 0 000006EB FC CLD 444 <1> ; 445 <1> ; Since the DOS maintains mucho state information across system calls, we 446 <1> ; must be very careful about which stack we use. 447 <1> ; 448 <1> ; First, all abort operations must be on the disk stack. THis is due to the 449 <1> ; fact that we may be hitting the disk (close operations, flushing) and may 450 <1> ; need to report an INT 24. 451 <1> ; 0 000006EC 08E4 OR AH,AH 0 000006EE 7416 JZ DSKROUT ; ABORT 454 <1> ; 455 <1> ; Second, PRINT and PSPRINT and the server issue GetExtendedError calls at 456 <1> ; INT 28 and INT 24 time. This call MUST, therefore, use the AUXSTACK. 457 <1> ; 0 000006F0 80FC59 CMP AH,GetExtendedError 0 000006F3 743D JZ DISPCALL 460 <1> ; 461 <1> ; Old 1-12 system calls may be either on the IOSTACK (normal operation) or 462 <1> ; on the AUXSTACK (at INT 24 time). 463 <1> ; 0 000006F5 80FC0C CMP AH,12 0 000006F8 770C JA DSKROUT 466 <1> ERRORMODE equ Errormode ; NASM port label 0 000006FA 803E[0000]00 CMP byte [ERRORMODE],0 ; Are we in an INT 24? 0 000006FF 7531 JNZ DISPCALL ; Stay on AUXSTACK if INT 24. 0 00000701 BC[0000] MOV SP,OFFSET IOSTACK wrt DOSGROUP 0 00000704 EB2C JMP SHORT DISPCALL 471 <1> ; 472 <1> ; We are on a system call that is classified as "the rest". We place 473 <1> ; ourselves onto the DSKSTACK and away we go. We know at this point: 474 <1> ; 475 <1> ; o An INT 24 cannot be in progress. Therefore we reset errormode and 476 <1> ; wperr 477 <1> ; o That there can be no critical sections in effect. We signal the 478 <1> ; server to remove all the resources. 479 <1> ; 480 <1> DSKROUT: 481 <1> USER_IN_AX equ User_In_AX ; NASM port label 0 00000706 A3[0000] MOV [USER_IN_AX],AX ; Remember what user is doing 0 00000709 C606[0000]01 MOV byte [EXTERR_LOCUS],errLOC_Unk ; Default 0 0000070E C606[0000]00 MOV byte [ERRORMODE],0 ; Cannot make non 1-12 calls in 0 00000713 C606[0000]FF MOV byte [WPERR],-1 ; error mode, so good place to make 486 <1> ; 487 <1> ; Release all resource information 488 <1> ; 0 00000718 50 PUSH AX 0 00000719 B482 MOV AH,82h 0 0000071B CD2A INT int_IBM 0 0000071D 58 POP AX 493 <1> 494 <1> ; 495 <1> ; Since we are going to be running on the DSKStack and since INT 28 people 496 <1> ; will use the DSKStack, we must turn OFF the generation of INT 28's. 497 <1> ; 0 0000071E C606[0000]00 MOV byte [IdleInt],0 0 00000723 BC[0000] MOV SP,OFFSET DSKSTACK wrt DOSGROUP 0 00000726 F606[0000]FF TEST byte [CNTCFLAG],-1 0 0000072B 7405 JZ DISPCALL ; Extra ^C checking is disabled 0 0000072D 50 PUSH AX 0 0000072E E8[0000] invoke DSKSTATCHK 0 00000731 58 POP AX 505 <1> DISPCALL: 0 00000732 2E8B9F[0000] MOV BX,[CS:Dispatch + BX] 0 00000737 871E[0000] XCHG BX,[SaveBX] 0 0000073B 8E1E[0000] MOV DS,[SaveDS] 509 <1> 510 <1> %ifndef BUF2 511 <1> %IF BUFFERFLAG 512 <1> mov byte [ss:SETVECTFLAG], 0 513 <1> cmp ah, 25h 514 <1> jne saveuser 515 <1> cmp ah, 35h 516 <1> jne saveuser 517 <1> mov byte [ss:SETVECTFLAG], 1 518 <1> saveuser: 519 <1> invoke SAVE_USER_MAP ;AN000;LB. save EMS map 520 <1> %ENDIF 521 <1> %endif 522 <1> 523 <1> ASSUME DS:NOTHING 0 0000073F 36FF16[0000] CALL near [ss:SaveBX] 525 <1> 526 <1> %ifndef BUF2 527 <1> %IF BUFFERFLAG 528 <1> invoke RESTORE_USER_MAP ;AN000;LB. retsore EMS map 529 <1> %ENDIF 530 <1> %endif 531 <1> 532 <1> doscode_leavedos: 533 <1> ASSUME SS:NOTHING ; User routines may misbehave 0 00000744 FA CLI 0 00000745 16 push ss 0 00000746 1F pop ds ; ds => DOSDATA, overwritten soon 0 00000747 FE0E[0000] DEC byte [INDOS] 0 0000074B 8B2E[0000] MOV BP, [user_SP] ; -> user stack 0 0000074F 8E16[0000] MOV SS, [user_SS] 0 00000753 89EC MOV SP, bp ; restore user stack 0 00000755 884600 MOV BYTE PTR [BP + user_AX],AL 0 00000758 A1[0000] MOV AX,[NSP] 0 0000075B A3[0000] MOV [user_SP],AX 0 0000075E A1[0000] MOV AX,[NSS] 0 00000761 A3[0000] MOV [user_SS],AX 0 00000764 E80100 CALL restore_world ; restore all registers 0 00000767 CF IRET 548 <1> EndProc SYSTEM_CALL 549 <1> === Switch to base=001140h -> "DOSDATACODE" 550 <1> section DOSDATACODE ; in DOSDATA 551 <1> extern dosdata_to_doscode 552 <1> entry LEAVEDOS 0 0000123A 2EFF36[0000] push word [cs:dosdata_to_doscode] 0 0000123F BD[A801] mov bp, doscode_leavedos 0 00001242 55 push bp 0 00001243 CB retf 557 <1> === Switch to base=008400h -> "DOSCODECODE" 558 <1> section DOSCODECODE 559 <1> 560 <1> ; 561 <1> ; restore_world restores all registers ('cept SS:SP, CS:IP, flags) from 562 <1> ; the stack prior to giving the user control 563 <1> ; 564 <1> ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING 565 <1> procedure restore_world,NEAR 565 ****************** <1> warning: proc restore_world... [-w+user] 566 <1> 567 <1> lframe -2 568 <1> ; have: es, ds, ..., ax, ip 569 <1> ; want: ip, ds, ..., ax, es 570 <1> lpar word, in_es_out_ip 571 <1> lpar word, ds 572 <1> lpar word, bp 573 <1> lpar word, di 574 <1> lpar word, si 575 <1> lpar word, dx 576 <1> lpar word, cx 577 <1> lpar word, bx 578 <1> lpar word, ax 579 <1> lpar word, in_ip 580 <1> lemit off 581 <1> lenter 0 00000768 89E5 mov bp, sp ; replacement code 0 0000076A 8B4600 mov ax, [bp + ?in_ip] ; ax = ip 0 0000076D 874612 xchg ax, [bp + ?in_es_out_ip] ; ?out_ip = ip, ax = ?in_es 585 <1> lleave ctx 0 00000770 8EC0 mov es, ax ; es = ?in_es 0 00000772 58 pop ax ; discard ?in_ip 0 00000773 58 pop ax 0 00000774 5B pop bx 0 00000775 59 pop cx 0 00000776 5A pop dx 0 00000777 5E pop si 0 00000778 5F pop di 0 00000779 5D pop bp 0 0000077A 1F pop ds 0 0000077B C3 retn 597 <1> EndProc restore_world 598 <1> 599 <1> ; 600 <1> ; save_world saves complete registers on the stack 601 <1> ; 602 <1> ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING 603 <1> procedure save_world,NEAR 603 ****************** <1> warning: proc save_world... [-w+user] 604 <1> lframe 0 605 <1> lpar word, in_ip_out_es 606 <1> lpar word, ds 0 0000077C 1E push ds 0 0000077D 5589E5 lenter ; bp 609 <1> lvar word, di 0 00000780 57 push di 611 <1> lvar word, si 0 00000781 56 push si 613 <1> lvar word, dx 0 00000782 52 push dx 615 <1> lvar word, cx 0 00000783 51 push cx 617 <1> lvar word, bx 0 00000784 53 push bx 619 <1> lvar word, ax 0 00000785 50 push ax 621 <1> lvar word, in_ax_out_ip 0 00000786 50 push ax ; ?in_ax = ax 0 00000787 8CC0 mov ax, es ; = es 0 00000789 874604 xchg ax, word [bp + ?in_ip_out_es] ; ?out_es = es, ax = ip 0 0000078C 8746F2 xchg ax, word [bp + ?in_ax_out_ip] ; ?out_ip = ip, ax = ?in_ax 0 0000078F 8B6E00 mov bp, [bp + ?frame_bp] ; restore bp 627 <1> lleave ctx ; drop context without code 0 00000792 C3 retn 629 <1> EndProc save_world 630 <1> 631 <1> %ifndef BUF2 632 <1> %IF BUFFERFLAG 633 <1> 634 <1> Break ;AN000; 635 <1> ; Inputs: ;AN000; 636 <1> ; none ;AN000; 637 <1> ; Function: ;AN000; 638 <1> ; save map ;AN000; 639 <1> ; Outputs: ;AN000; 640 <1> ; none ;AN000; 641 <1> ; No other registers altered ;AN000; 642 <1> ;AN000; 643 <1> Procedure SAVE_USER_MAP,NEAR ;AN000; 644 <1> ASSUME DS:NOTHING,ES:NOTHING ;AN000; 645 <1> ;AN000; 646 <1> CMP byte [ss:BUF_EMS_MODE],-1 ;LB. EMS support ;AN000; 647 <1> JZ No_user_save ;LB. no ;AN000; 648 <1> CMP byte [ss:SETVECTFLAG], 1 649 <1> jz No_user_save 650 <1> ; MOV [ACT_PAGE],-1 ;LB. invalidate active page ;AN000; 651 <1> ; MOV WORD PTR [LASTBUFFER],-1 ;LB. and last buffer pointer ;AN000; 652 <1> PUSH AX ;LB. save regs ;AN000; 653 <1> PUSH DS ;LB. save regs ;AN000; 654 <1> PUSH ES ;LB. ;AN000; 655 <1> PUSH SI ;LB. ;AN000; 656 <1> PUSH DI ;LB. ;AN000; 657 <1> MOV SI,OFFSET BUF_EMS_SEG_CNT wrt DOSGROUP ;LB. ;AN000; 658 <1> MOV DI,OFFSET BUF_EMS_MAP_USER wrt DOSGROUP ;LB. ;AN000; 659 <1> 660 <1> PUSH ss 661 <1> POP ES 662 <1> PUSH ss ;LB. ds:si -> ems seg cnt ;AN000; 663 <1> POP DS ;LB. ;AN000; 664 <1> 665 <1> MOV AX,4F00H ;LB. save map ;AN000; 666 <1> EnterCrit critDisk ;LB. enter critical section ;AN000; 667 <1> INT 67H ;LB. ;AN000; 668 <1> LeaveCrit critDisk ;LB. leave critical section ;AN000; 669 <1> POP DI ;LB. ;AN000; 670 <1> POP SI ;LB. restore regs ;AN000; 671 <1> POP ES ;LB. ;AN000; 672 <1> POP DS ;LB. ;AN000; 673 <1> POP AX ;LB. restore ;AN000; 674 <1> No_user_save: ;AN000; 675 <1> return ;AN000; 676 <1> EndProc SAVE_USER_MAP ;AN000; 677 <1> ;AN000; 678 <1> 679 <1> Break ;AN000; 680 <1> ; Inputs: ;AN000; 681 <1> ; none ;AN000; 682 <1> ; Function: ;AN000; 683 <1> ; restore_map ;AN000; 684 <1> ; Outputs: ;AN000; 685 <1> ; none ;AN000; 686 <1> ; No other registers altered ;AN000; 687 <1> ;AN000; 688 <1> Procedure RESTORE_USER_MAP,NEAR ;AN000; 689 <1> ASSUME DS:NOTHING,ES:NOTHING ;AN000; 690 <1> 691 <1> CMP byte [ss:BUF_EMS_MODE],-1 ;LB. EMS support ;AN000; 692 <1> JZ No_user_restore ;LB. no ;AN000; 693 <1> CMP byte [ss:SETVECTFLAG], 1 694 <1> jz No_user_restore 695 <1> PUSH AX ;LB. save regs ;AN000; 696 <1> PUSH DS ;LB. save regs ;AN000; 697 <1> PUSH SI ;LB. ;AN000; 698 <1> MOV SI,OFFSET BUF_EMS_MAP_USER wrt DOSGROUP ;LB. ;AN000; 699 <1> 700 <1> PUSH ss 701 <1> POP DS 702 <1> 703 <1> MOV AX,4F01H ;LB. restore map ;AN000; 704 <1> EnterCrit critDisk ;LB. enter critical section ;AN000; 705 <1> INT 67H ;LB. ;AN000; 706 <1> LeaveCrit critDisk ;LB. leave critical section ;AN000; 707 <1> POP SI ;LB. restore regs ;AN000; 708 <1> POP DS ;LB. ;AN000; 709 <1> POP AX ;LB. ;AN000; 710 <1> No_user_restore: ;AN000; 711 <1> return ;AN000; 712 <1> EndProc RESTORE_USER_MAP 713 <1> 714 <1> %ENDIF 715 <1> %endif 716 <1> 717 <1> ; 718 <1> ; get_user_stack returns the user's stack (and hence registers) in DS:SI 719 <1> ; 720 <1> procedure get_user_stack,NEAR 720 ****************** <1> warning: proc get_user_stack... [-w+user] 0 00000793 96 xchg ax, si 0 00000794 E8[0000] call doscode_getdosdata 0 00000797 8ED8 mov ds, ax 0 00000799 96 xchg ax, si 0 0000079A C536[0000] LDS SI,[user_SP] 0 0000079E C3 return 727 <1> EndProc get_user_stack 728 <1> 729 <1> %IFN IBM 730 <1> BREAK 732 <1> D_SET_OEM_HANDLER: 733 <1> ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING 734 <1> 735 <1> ; Inputs: 736 <1> ; User registers, User Stack, INTS disabled 737 <1> ; If CALL F8, DS:DX is new handler address 738 <1> ; Function: 739 <1> ; Process OEM INT 21 extensions 740 <1> ; Outputs: 741 <1> ; Jumps to OEM_HANDLER if appropriate 742 <1> 743 <1> JNE DO_OEM_FUNC ; If above F8 try to jump to handler 744 <1> invalid instruction fixme 745 <1> ; ldos: need segment override 746 <1> MOV WORD PTR [OEM_HANDLER],DX ; Set Handler 747 <1> MOV WORD PTR [OEM_HANDLER+2],DS 748 <1> IRET ; Quick return, Have altered no registers 749 <1> 750 <1> DO_OEM_FUNC: 751 <1> invalid instruction fixme 752 <1> ; ldos: need segment override 753 <1> CMP WORD PTR [OEM_HANDLER],-1 754 <1> JNZ OEM_JMP 755 <1> JMP BADCALL ; Handler not initialized 756 <1> 757 <1> OEM_JMP: 758 <1> invalid instruction fixme 759 <1> ; ldos: need segment override 760 <1> JMP [OEM_HANDLER] 761 <1> %ENDIF 17 ;=== Pop trace listing source 18 END 19 20 === Trace listing source: ../DOS/mscode.lst 1 ; SCCSID = @(#)ibmcode.asm 1.1 85/04/10 2 ;TITLE MISC DOS ROUTINES - Int 25 and 26 handlers and other 3 ;NAME IBMCODE 4 5 ; 6 ; System call dispatch code. 7 ; 8 9 [list -] 9 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 14 15 ;=== Push trace listing source: ms_code.nas 16 %include "ms_code.nas" 1 <1> ; SCCSID = @(#)mscode.asm 1.2 85/07/23 2 <1> ; 3 <1> ; MSCODE.ASM -- MSDOS code 4 <1> ; 5 <1> 6 <1> [list -] 6 ****************** <1> warning: out: ... for DOS Version 4.00 ... [-w+user] 6 ****************** <1> warning: out: BPB.INC... [-w+user] 6 ****************** <1> warning: out: ... CLONE version build switch on ... [-w+user] 6 ****************** <1> warning: out: DEVSYM.INC... [-w+user] 6 ****************** <1> warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi] 14 <2> [list -] 16 <1> %include "lstruct.mac" 1 <2> [list -] 13 <2> [list -] 17 <1> ;.cref 18 <1> [list +] 19 <1> 20 <1> %ifndef Kanji 21 <1> %iassign Kanji 0 22 <1> %endif 23 <1> %ifndef Debug 24 <1> %iassign Debug 0 25 <1> %endif 26 <1> === Switch to base=008400h -> "DOSCODECODE" 27 <1> section DOSCODECODE 28 <1> 29 <1> I_need InDos,BYTE ; TRUE => we are in dos, no interrupt 30 <1> I_need OpenBuf,128 ; temp name buffer 31 <1> I_need ExtErr,WORD ; extended error code 32 <1> I_need User_SS,WORD ; stack segment from user 33 <1> I_need User_SP,WORD ; stack pointer from user 34 <1> I_need DskStack,BYTE ; stack segment inside DOS 35 <1> I_need ThisCDS,DWORD ; Currently referenced CDS pointer 36 <1> I_need ThisDPB,DWORD ; Currently referenced DPB pointer 37 <1> I_need Err_Table_21 ; allowed return map table for errors 38 <1> I_need FailErr,BYTE ; TRUE => system call is being failed 39 <1> I_need ExtErr_Action,BYTE ; recommended action 40 <1> I_need ExtErr_Class,BYTE ; error classification 41 <1> I_need ExtErr_Locus,BYTE ; error location 42 <1> I_need I21_Map_E_Tab,BYTE ; mapping extended error table 43 <1> I_need User_In_AX,WORD ; initial input user AX 44 <1> I_need FOO,WORD ; return address for dos 2f dispatch 45 <1> I_need DTAB,WORD ; dos 2f dispatch table 46 <1> I_need HIGH_SECTOR,WORD ; >32mb 47 <1> I_need IFS_DRIVER_ERR,WORD ; >32mb 48 <1> I_need FastOpenFlg,BYTE ; 49 <1> I_need FastSeekFlg,BYTE ; 50 <1> I_need CURSC_DRIVE,BYTE ; 51 <1> I_need first_hmcb, word 52 <1> === Switch to base=001140h -> "DOSDATACODE" 53 <1> section DOSDATACODE ; in DOSDATA 54 <1> 55 <1> BREAK 56 <1> 57 <1> procedure SNULDEV,FAR 57 ****************** <1> warning: proc SNULDEV... [-w+user] 58 <1> ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING 0 00001244 26814F030001 OR word [ES:BX + REQSTAT],STDON ; Set done bit 60 <1> entry INULDEV 0 0000124A CB RET ; MUST NOT BE A RETURN! 62 <1> EndProc SNULDEV 63 <1> 64 <1> BREAK 65 <1> === Switch to base=008400h -> "DOSCODETABLE" 66 <1> section DOSCODETABLE 67 <1> Public MSC001S,MSC001E 68 <1> MSC001S label byte 69 <1> %IF IBM 70 <1> ; Codes returned by BIOS 71 <1> ERRIN: 0 00000436 02 DB 2 ; NO RESPONSE 0 00000437 06 DB 6 ; SEEK FAILURE 0 00000438 0C DB 12 ; GENERAL ERROR 0 00000439 04 DB 4 ; BAD CRC 0 0000043A 08 DB 8 ; SECTOR NOT FOUND 0 0000043B 00 DB 0 ; WRITE ATTEMPT ON WRITE-PROTECT DISK 78 <1> ERROUT: 79 <1> ; DISK ERRORS RETURNED FROM INT 25 and 26 0 0000043C 80 DB 80H ; NO RESPONSE 0 0000043D 40 DB 40H ; Seek failure 0 0000043E 02 DB 2 ; Address Mark not found 0 0000043F 10 DB 10H ; BAD CRC 0 00000440 04 DB 4 ; SECTOR NOT FOUND 0 00000441 03 DB 3 ; WRITE ATTEMPT TO WRITE-PROTECT DISK 86 <1> 87 <1> NUMERR EQU $-ERROUT 88 <1> %ENDIF 89 <1> MSC001E label byte 90 <1> 91 <1> TABLE ENDS === Switch to base=008400h -> "DOSCODECODE" 92 <1> section DOSCODECODE 93 <1> 94 <1> ; AbsSetup - setup for abs disk functions 95 <1> 96 <1> Procedure AbsSetup,NEAR 96 ****************** <1> warning: proc AbsSetup... [-w+user] 97 <1> ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 98 <1> INDOS equ InDos ; NASM port label 0 0000079F 36FE06[0000] INC byte [ss:INDOS] 0 000007A4 FB STI 0 000007A5 FC CLD 0 000007A6 1E PUSH DS 0 000007A7 161F Context DS 0 000007A9 E8EE00 CALL GETBP_DOS 0 000007AC 7206 JC errdriv ;PM. error drive ;AN000; 0 000007AE 26C7461FFFFF MOV word [ES:BP + dpb_free_cnt],-1 ; do not trust user at all. 107 <1> errdriv: 0 000007B4 1F POP DS 109 <1> ASSUME DS:NOTHING 0 000007B5 7301C3 retc 111 <1> 0 000007B8 36C706[0000]0000 MOV word [ss:HIGH_SECTOR],0 ;>32mb from API ;AN000; 0 000007BF E8EC03 CALL RW32_CONVERT ;>32mb convert 32bit format to 16bit ;AN000; 0 000007C2 72F3 retc 115 <1> 116 <1> %ifndef BUF2 117 <1> invoke SET_RQ_SC_PARMS ;LB. set up SC parms ;AN000; 118 <1> %endif 0 000007C4 1E PUSH DS 0 000007C5 56 PUSH SI 0 000007C6 50 PUSH AX 0 000007C7 161F Context DS 123 <1> OPENBUF equ OpenBuf ; NASM port label 0 000007C9 BE[0000] MOV SI,OFFSET OPENBUF wrt DOSGROUP 0 000007CC 8804 MOV [SI],AL 0 000007CE 800441 ADD BYTE PTR [SI],"A" 0 000007D1 C744013A00 MOV WORD PTR [SI+1],003AH ; ":",0 0 000007D6 B80003 MOV AX,0300H 0 000007D9 F8 CLC 0 000007DA CD2A INT int_IBM ; Will set carry if shared 0 000007DC 58 POP AX 0 000007DD 5E POP SI 0 000007DE 1F POP DS 134 <1> ASSUME DS:NOTHING 0 000007DF 73D6 retnc 0 000007E1 36C706[0000]3200 MOV word [ss:ExtErr],error_not_supported 0 000007E8 C3 return 138 <1> EndProc AbsSetup 139 <1> 140 <1> ; Interrupt 25 handler. Performs absolute disk read. 141 <1> ; Inputs: AL - 0-based drive number 142 <1> ; DS:BX point to destination buffer 143 <1> ; CX number of logical sectors to read 144 <1> ; DX starting logical sector number (0-based) 145 <1> ; Outputs: Original flags still on stack 146 <1> ; Carry set 147 <1> ; AH error from BIOS 148 <1> ; AL same as low byte of DI from INT 24 149 <1> 150 <1> relocated i25 151 <1> procedure ABSDRD,FAR 151 ****************** <1> warning: proc ABSDRD... [-w+user] 152 <1> ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING 153 <1> 154 <1> extern doscode_getdosdata 155 <1> extern temp_var 156 <1> 0 000007E9 FA CLI 0 000007EA 1E push ds 0 000007EB 50 push ax 0 000007EC E8[0000] call doscode_getdosdata 0 000007EF 8ED8 mov ds, ax 0 000007F1 58 pop ax 0 000007F2 8F06[0000] pop word [temp_var] ; rescue user ds 164 <1> 165 <1> user_SS equ User_SS ; NASM port label 0 000007F6 8C16[0000] MOV [user_SS],SS 167 <1> user_SP equ User_SP ; NASM port label 0 000007FA 8926[0000] MOV [user_SP],SP 0 000007FE 1E PUSH ds 0 000007FF 17 POP SS 171 <1> ASSUME SS:DOSGROUP 172 <1> DSKSTACK equ DskStack ; NASM port label 0 00000800 BC[0000] MOV SP,OFFSET DSKSTACK wrt DOSGROUP 0 00000803 8E1E[0000] mov ds, word [temp_var] 0 00000807 E8[0000] invoke Save_World ;>32mb save all regs ;AN000; 0 0000080A 06 PUSH ES 0 0000080B E891FF CALL AbsSetup 0 0000080E 722A JC ILEAVE 179 <1> %ifn IBMCOPYRIGHT 180 <1> ; Here is a gross temporary fix to get around a serious design flaw in 181 <1> ; the secondary cache. The secondary cache does not check for media 182 <1> ; changed (it should). Hence, you can change disks, do an absolute 183 <1> ; read, and get data from the previous disk. To get around this, 184 <1> ; we just won't use the secondary cache for absolute disk reads. 185 <1> ; -mw 8/5/88 0 00000810 E8[0000] EnterCrit critDisk 0 00000813 36C606[0000]FF MOV byte [ss:CURSC_DRIVE],-1 ; invalidate SC ;AN000; 0 00000819 E8[0000] LeaveCrit critDisk 189 <1> %endif 0 0000081C E8[0000] invoke DSKREAD 191 <1> TLEAVE: 0 0000081F 7419 JZ ILEAVE 193 <1> 194 <1> %IF IBM 195 <1> ; Translate the error code to ancient 1.1 codes 0 00000821 06 PUSH ES 0 00000822 0E PUSH CS ; => DOSCODE 0 00000823 07 POP ES 0 00000824 30E4 XOR AH,AH ; Nul error code 0 00000826 B90600 MOV CX,NUMERR ; Number of possible error conditions 0 00000829 BF[0000] MOV DI,OFFSET ERRIN ; Point to error conditions 0 0000082C F2AE REPNE SCASB 0 0000082E 7504 JNZ LEAVECODE ; Not found 0 00000830 268A6505 MOV AH,[ES:DI+NUMERR-1] ; Get translation 205 <1> LEAVECODE: 0 00000834 07 POP ES 207 <1> %ENDIF 0 00000835 36A3[0000] MOV [ss:IFS_DRIVER_ERR],AX ;>32mb save error 0 00000839 F9 STC 210 <1> ILEAVE: 0 0000083A 07 POP ES 0 0000083B E8[0000] invoke Restore_World ;>32mb ;AN000; 0 0000083E FA CLI 0 0000083F 36A1[0000] MOV AX,[ss:IFS_DRIVER_ERR] ;>32mb restore error ;AN000; 0 00000843 36FE0E[0000] DEC byte [ss:INDOS] 0 00000848 1E push ds 0 00000849 56 push si 0 0000084A 36C536[0000] lds si, [ss:user_SP] ; ds:si -> user stack 0 0000084F 4E dec si 0 00000850 4E dec si ; make space for a word on the stack 0 00000851 8F04 pop word [si] ; si 0 00000853 4E dec si 0 00000854 4E dec si 0 00000855 8F04 pop word [si] ; ds 0 00000857 1E push ds 0 00000858 17 pop ss 0 00000859 89F4 mov sp, si 228 <1> ASSUME SS:NOTHING 0 0000085B 1F pop ds ; ds first 0 0000085C 5E pop si ; then si 0 0000085D FB STI 232 <1> 233 <1> entry doscode_retf 0 0000085E CB RET ; This must not be a RETURN! 235 <1> EndProc ABSDRD 236 <1> 237 <1> ; Interrupt 26 handler. Performs absolute disk write. 238 <1> ; Inputs: AL - 0-based drive number 239 <1> ; DS:BX point to source buffer 240 <1> ; CX number of logical sectors to write 241 <1> ; DX starting logical sector number (0-based) 242 <1> ; Outputs: Original flags still on stack 243 <1> ; Carry set 244 <1> ; AH error from BIOS 245 <1> ; AL same as low byte of DI from INT 24 246 <1> 247 <1> relocated i26 248 <1> procedure ABSDWRT,FAR 248 ****************** <1> warning: proc ABSDWRT... [-w+user] 249 <1> ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING 250 <1> 0 0000085F FA CLI 0 00000860 1E push ds 0 00000861 50 push ax 0 00000862 E8[0000] call doscode_getdosdata 0 00000865 8ED8 mov ds, ax 0 00000867 58 pop ax 0 00000868 8F06[0000] pop word [temp_var] ; rescue user ds 258 <1> 0 0000086C 8C16[0000] MOV [user_SS],SS 0 00000870 8926[0000] MOV [user_SP],SP 0 00000874 1E PUSH ds 0 00000875 17 POP SS 263 <1> ASSUME SS:DOSGROUP 0 00000876 BC[0000] MOV SP,OFFSET DSKSTACK wrt DOSGROUP 0 00000879 8E1E[0000] mov ds, word [temp_var] 0 0000087D E8[0000] invoke Save_World ;>32mb save all regs ;AN000; 0 00000880 06 PUSH ES 0 00000881 E81BFF CALL AbsSetup 0 00000884 72B4 JC ILEAVE 270 <1> 0 00000886 E8[0000] EnterCrit critDisk 0 00000889 36C606[0000]FF MOV byte [ss:CURSC_DRIVE],-1 ; invalidate SC ;AN000; 0 0000088F E85603 CALL Fastxxx_Purge ; purge fatopen ;AN000; 0 00000892 E8[0000] LeaveCrit critDisk 275 <1> 0 00000895 E8[0000] invoke DSKWRITE 0 00000898 EB85 JMP TLEAVE 278 <1> EndProc ABSDWRT 279 <1> 280 <1> ; Inputs: 281 <1> ; AL = Logical unit number (A = 0) 282 <1> ; Function: 283 <1> ; Find Drive Parameter Block 284 <1> ; Outputs: 285 <1> ; ES:BP points to DPB 286 <1> ; [THISDPB] = ES:BP 287 <1> ; Carry set if unit number bad or unit is a NET device. 288 <1> ; Later case sets extended error error_I24_not_supported 289 <1> ; No other registers altered 290 <1> 291 <1> Procedure GETBP_DOS,NEAR 291 ****************** <1> warning: proc GETBP_DOS... [-w+user] 292 <1> DOSAssume CS,,"GetBP_DOS" 293 <1> ASSUME ES:NOTHING 294 <1> 0 0000089A 50 PUSH AX 0 0000089B 0401 ADD AL,1 ; No increment; need carry flag 0 0000089D 7216 JC SkipGet 0 0000089F E8[0000] invoke GetThisDrv 0 000008A2 7311 JNC SkipGet ;PM. good drive ;AN000; 0 000008A4 30E4 XOR AH,AH ;DCR. ax= error code ;AN000; 301 <1> error_not_dos_disk equ error_not_DOS_disk ; NASM port equate 0 000008A6 83F81A CMP AX,error_not_dos_disk ;DCR. is unknown media ? ;AN000; 0 000008A9 740A JZ SkipGet ;DCR. yes, let it go ;AN000; 0 000008AB F9 STC ;DCR. ;AN000; 0 000008AC A3[0000] MOV [ExtErr],AX ;PM. invalid drive or Non DOS drive ;AN000; 0 000008AF C706[0000]0102 MOV word [IFS_DRIVER_ERR],0201H ;PM. other errors/unknown unit ;AN000; 307 <1> SkipGet: 0 000008B5 58 POP AX 0 000008B6 7301C3 retc 310 <1> THISCDS equ ThisCDS ; NASM port label 0 000008B9 C42E[0000] LES BP,[THISCDS] 0 000008BD 26F746430080 TEST word [ES:BP + curdir_flags],curdir_isnet ; Clears carry 0 000008C3 7418 JZ GETBP_CDS 0 000008C5 26C46E52 LES BP,[ES:BP + curdir_ifs_hdr] ;IFS. if remote file ;AN000; 315 <1> ifs_attribute equ IFS_ATTRIBUTE ; NASM port label 0 000008C9 26F7460C0008 TEST word [ES:BP + ifs_attribute],IFSREMOTE ;IFS. ;AN000; 0 000008CF C42E[0000] LES BP,[THISCDS] 0 000008D3 7408 JZ GETBP_CDS ;IFS. then error ;AN000; 0 000008D5 C706[0000]3200 MOV word [ExtErr],error_not_supported 0 000008DB F9 STC 0 000008DC C3 return 322 <1> 323 <1> GETBP_CDS: 0 000008DD 26C46E45 LES BP,[ES:BP + curdir_devptr] 325 <1> 326 <1> entry GOTDPB 327 <1> DOSAssume CS,,"GotDPB" 328 <1> ; Load THISDPB from ES:BP 329 <1> 330 <1> THISDPB equ ThisDPB ; NASM port label 0 000008E1 892E[0000] MOV WORD PTR [THISDPB],BP 0 000008E5 8C06[0200] MOV WORD PTR [THISDPB+2],ES 0 000008E9 C3 return 334 <1> EndProc GetBP_DOS 335 <1> 336 <1> BREAK 337 <1> 338 <1> ASSUME SS:DOSGROUP 339 <1> 340 <1> ; 341 <1> ; These are the general system call exit mechanisms. All internal system 342 <1> ; calls will transfer (jump) to one of these at the end. Their sole purpose 343 <1> ; is to set the user's flags and set his AX register for return. 344 <1> ; 345 <1> 346 <1> procedure SYS_RETURN,NEAR 346 ****************** <1> warning: proc SYS_RETURN... [-w+user] 347 <1> ASSUME DS:NOTHING,ES:NOTHING 348 <1> entry SYS_RET_OK 0 000008EA E8[0000] invoke FETCHI_CHECK ; TAG checking for FETCHI 0 000008ED E8[0000] invoke get_user_stack 0 000008F0 836416FE AND word [SI + user_F],~ f_Carry ; turn off user's carry flag 0 000008F4 EB10 JMP SHORT DO_RET ; carry is now clear 353 <1> 354 <1> entry SYS_RET_ERR 0 000008F6 30E4 XOR AH,AH ; hack to allow for smaller error rets 0 000008F8 E86C00 invoke ETAB_LK ; Make sure code is OK, EXTERR gets set 357 <1> ErrorMap equ errorMap ; NASM port label 0 000008FB E81A00 CALL ErrorMap 359 <1> entry From_GetSet 0 000008FE E8[0000] invoke get_user_stack 0 00000901 834C1601 OR word [SI + user_F],f_Carry ; signal carry to user 0 00000905 F9 STC ; also, signal internal error 363 <1> DO_RET: 0 00000906 8904 MOV [SI + user_AX],AX ; Really only sets AH 0 00000908 C3 return 366 <1> 367 <1> entry FCB_RET_OK 368 <1> entry CPMFunc 0 00000909 30C0 XOR AL,AL 0 0000090B C3 return 371 <1> 372 <1> entry FCB_RET_ERR 0 0000090C 30E4 XOR AH,AH 374 <1> exterr equ ExtErr ; NASM port label 0 0000090E 36A3[0000] mov [ss:exterr],AX 0 00000912 E80300 CALL ErrorMap 0 00000915 B0FF MOV AL,-1 0 00000917 C3 return 379 <1> 380 <1> entry errorMap 0 00000918 56 PUSH SI 382 <1> ERR_TABLE_21 equ Err_Table_21 ; NASM port label 0 00000919 BE[0000] MOV SI,OFFSET ERR_TABLE_21 wrt DOSGROUP 384 <1> FAILERR equ FailErr ; NASM port label 0 0000091C 36803E[0000]00 CMP byte [ss:FAILERR],0 ; Check for SPECIAL case. 0 00000922 740A JZ EXTENDED_NORMAL ; All is OK. 387 <1> EXTERR equ ExtErr ; NASM port label 0 00000924 36C706[0000]5300 MOV word [ss:EXTERR],error_FAIL_I24 ; Ooops, this is the REAL reason 0 0000092B BE[0000] MOV SI,OFFSET ERR_TABLE_21 wrt DOSGROUP 390 <1> EXTENDED_NORMAL: 0 0000092E E80200 invoke CAL_LK ; Set CLASS,ACTION,LOCUS for EXTERR 0 00000931 5E POP SI 0 00000932 C3 return 394 <1> 395 <1> EndProc SYS_RETURN 396 <1> 397 <1> ; Inputs: 398 <1> ; SI is OFFSET in DOSGROUP of CLASS,ACTION,LOCUS Table to use 399 <1> ; (DS NEED not be DOSGROUP) 400 <1> ; [EXTERR] is set with error 401 <1> ; Function: 402 <1> ; Look up and set CLASS ACTION and LOCUS values for GetExtendedError 403 <1> ; Outputs: 404 <1> ; [EXTERR_CLASS] set 405 <1> ; [EXTERR_ACTION] set 406 <1> ; [EXTERR_LOCUS] set (EXCEPT on certain errors as determined by table) 407 <1> ; Destroys SI, FLAGS 408 <1> 409 <1> procedure CAL_LK,NEAR 409 ****************** <1> warning: proc CAL_LK... [-w+user] 410 <1> ASSUME DS:NOTHING,ES:NOTHING 411 <1> 0 00000933 1E PUSH DS 0 00000934 50 PUSH AX 0 00000935 53 PUSH BX 0 00000936 161F Context DS ; DS:SI -> Table 0 00000938 8B1E[0000] MOV BX,[EXTERR] ; Get error in BL 417 <1> TABLK1: 0 0000093C AC LODSB 0 0000093D 3CFF CMP AL,0FFH 0 0000093F 7409 JZ GOT_VALS ; End of table 0 00000941 38D8 CMP AL,BL 0 00000943 7405 JZ GOT_VALS ; Got entry 0 00000945 83C603 ADD SI,3 ; Next table entry 0 00000948 EBF2 JMP TABLK1 425 <1> 426 <1> GOT_VALS: 0 0000094A AD LODSW ; AL is CLASS, AH is ACTION 0 0000094B 80FCFF CMP AH,0FFH 0 0000094E 7404 JZ NO_SET_ACT 430 <1> EXTERR_ACTION equ ExtErr_Action ; NASM port label 0 00000950 8826[0000] MOV [EXTERR_ACTION],AH ; Set ACTION 432 <1> NO_SET_ACT: 0 00000954 3CFF CMP AL,0FFH 0 00000956 7403 JZ NO_SET_CLS 435 <1> EXTERR_CLASS equ ExtErr_Class ; NASM port label 0 00000958 A2[0000] MOV [EXTERR_CLASS],AL ; Set CLASS 437 <1> NO_SET_CLS: 0 0000095B AC LODSB ; Get LOCUS 0 0000095C 3CFF CMP AL,0FFH 0 0000095E 7403 JZ NO_SET_LOC 441 <1> EXTERR_LOCUS equ ExtErr_Locus ; NASM port label 0 00000960 A2[0000] MOV [EXTERR_LOCUS],AL 443 <1> NO_SET_LOC: 0 00000963 5B POP BX 0 00000964 58 POP AX 0 00000965 1F POP DS 0 00000966 C3 return 448 <1> EndProc CAL_LK 449 <1> 450 <1> ; Inputs: 451 <1> ; AX is error code 452 <1> ; [USER_IN_AX] has AH value of system call involved 453 <1> ; Function: 454 <1> ; Make sure error code is appropriate to this call. 455 <1> ; Outputs: 456 <1> ; AX MAY be mapped error code 457 <1> ; [EXTERR] = Input AX 458 <1> ; Destroys ONLY AX and FLAGS 459 <1> 460 <1> procedure ETAB_LK,NEAR 460 ****************** <1> warning: proc ETAB_LK... [-w+user] 461 <1> ASSUME DS:NOTHING,ES:NOTHING 462 <1> 0 00000967 1E PUSH DS 0 00000968 56 PUSH SI 0 00000969 51 PUSH CX 0 0000096A 53 PUSH BX 0 0000096B 161F Context DS 0 0000096D A3[0000] MOV [EXTERR],AX ; Set EXTERR with "real" error 469 <1> I21_MAP_E_TAB equ I21_Map_E_Tab ; NASM port label 0 00000970 BE[0000] MOV SI,OFFSET I21_MAP_E_TAB 0 00000973 88C7 MOV BH,AL ; Real code to BH 472 <1> USER_IN_AX equ User_In_AX ; NASM port label 0 00000975 8A1E[0100] MOV BL,BYTE PTR [USER_IN_AX + 1] ; Sys call to BL 474 <1> TABLK2: 0 00000979 2EAD cs LODSW 0 0000097B 3CFF CMP AL,0FFH ; End of table? 0 0000097D 740C JZ NOT_IN_TABLE ; Yes 0 0000097F 38D8 CMP AL,BL ; Found call? 0 00000981 740C JZ GOT_CALL ; Yes 0 00000983 86E0 XCHG AH,AL ; Count to AL 0 00000985 30E4 XOR AH,AH ; Make word for add 0 00000987 01C6 ADD SI,AX ; Next table entry 0 00000989 EBEE JMP TABLK2 484 <1> 485 <1> NOT_IN_TABLE: 0 0000098B 88F8 MOV AL,BH ; Restore original code 0 0000098D EB0C JMP SHORT NO_MAP 488 <1> 489 <1> GOT_CALL: 0 0000098F 88E1 MOV CL,AH 0 00000991 30ED XOR CH,CH ; Count of valid err codes to CX 492 <1> CHECK_CODE: 0 00000993 2EAC cs LODSB 0 00000995 38F8 CMP AL,BH ; Code OK? 0 00000997 7402 JZ NO_MAP ; Yes 0 00000999 E2F8 LOOP CHECK_CODE 497 <1> NO_MAP: 0 0000099B 30E4 XOR AH,AH ; AX is now valid code 0 0000099D 5B POP BX 0 0000099E 59 POP CX 0 0000099F 5E POP SI 0 000009A0 1F POP DS 0 000009A1 C3 return 504 <1> 505 <1> EndProc ETAB_LK 506 <1> 507 <1> BREAK 508 <1> 509 <1> %IF installed 510 <1> 511 <1> ; 512 <1> ; SetBad sets up info for bad functions 513 <1> ; 514 <1> Procedure SetBad,NEAR 514 ****************** <1> warning: proc SetBad... [-w+user] 515 <1> ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING 0 000009A2 E8[0000] call doscode_getdosdata 0 000009A5 1E push ds 0 000009A6 8ED8 mov ds, ax 519 <1> ExtErr_LOCUS equ ExtErr_Locus ; NASM port label 520 <1> errLoc_UNK equ errLOC_Unk ; NASM port equate 0 000009A8 C606[0000]01 MOV byte [ExtErr_LOCUS],errLoc_UNK 0 000009AD 1F pop ds 523 <1> set_ax_1_CY: 0 000009AE B80100 MOV AX,error_invalid_function ; ALL NET REQUESTS get inv func 0 000009B1 F9 STC 0 000009B2 C3 ret 527 <1> EndProc SetBad 528 <1> ; 529 <1> ; BadCall is the initial routine for bad function calls 530 <1> ; 531 <1> relocated badcallentry 532 <1> procedure BadCall,FAR 532 ****************** <1> warning: proc BadCall... [-w+user] 0 000009B3 E8ECFF call SetBad 0 000009B6 CB ret 535 <1> EndProc BadCall 536 <1> ; 537 <1> ; OKCall always sets carry to off. 538 <1> ; 539 <1> relocated okcallentry 540 <1> Procedure OKCall,FAR 540 ****************** <1> warning: proc OKCall... [-w+user] 541 <1> ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING 0 000009B7 F8 CLC 0 000009B8 CB ret 544 <1> EndProc OKCall 545 <1> 546 <1> ; INT 2F handler works as follows: 547 <1> ; PUSH AX 548 <1> ; MOV AX,multiplex:function 549 <1> ; INT 2F 550 <1> ; POP ... 551 <1> ; The handler itself needs to make the AX available for the various routines. 552 <1> 553 <1> relocated i2F 554 <1> Int2F equ INT2F ; NASM port label 555 <1> PUBLIC Int2F 556 <1> INT2F PROC FAR 557 <1> 558 <1> INT2FNT: 559 <1> ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING 0 000009B9 FB STI 561 <1> multNET equ MultNET ; NASM port equate 0 000009BA 80FC11 CMP AH,multNET 0 000009BD 7517 JNZ INT2FSHR 564 <1> TestInstall: 0 000009BF 08C0 OR AL,AL 0 000009C1 7403 JZ Leave2F 567 <1> BadFunc: 0 000009C3 E8DCFF CALL SetBad 569 <1> 570 <1> entry Leave13 ; for msbio/ms96tpi.nas and msbio/msdisk.nas 571 <1> entry Leave2F 0 000009C6 55 push bp 0 000009C7 89E5 mov bp, sp 0 000009C9 50 push ax 0 000009CA 9F lahf 576 <1> ; bp + 0 = saved bp 577 <1> ; bp + 2 = ip 578 <1> ; bp + 4 = cs 579 <1> ; bp + 6 = fl 0 000009CB 886606 mov byte [bp + 6], ah 0 000009CE 58 pop ax 0 000009CF 5D pop bp 0 000009D0 CF iret 584 <1> 585 <1> relocated i31 0 000009D1 E8DAFF call set_ax_1_CY 0 000009D4 EBF0 jmp Leave2F 588 <1> 589 <1> INT2FSHR: 590 <1> multSHARE equ MultSHARE ; NASM port equate 0 000009D6 80FC10 CMP AH,multSHARE ; is this a share request 0 000009D9 74E4 JZ TestInstall ; yes, check for installation 593 <1> 594 <1> INT2FNLS: 0 000009DB 80FC14 CMP AH,NLSFUNC ; is this a DOS 3.3 NLSFUNC request 0 000009DE 74DF JZ TestInstall ; yes check for installation 597 <1> 598 <1> INT2FDOS: 599 <1> ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING 600 <1> multDOS equ MultDOS ; NASM port equate 0 000009E0 80FC12 CMP AH,multDOS 0 000009E3 7406 JZ DispatchDOS 0 000009E5 80FC4A cmp ah, 4Ah 0 000009E8 7428 je hma_access 0 000009EA CF IRET ; This assume that we are at the head 606 <1> ; of the list 607 <1> INT2F ENDP 608 <1> 609 <1> DispatchDOS: 0 000009EB 3C61 cmp al, 61h 0 000009ED 7417 je get_first_umcb ; (NC) 0 000009EF 2EFF36[0000] PUSH word [cs:FOO] ; push return address 613 <1> DTab equ DTAB ; NASM port label 0 000009F4 2EFF36[0000] PUSH word [cs:DTab] ; push table address 0 000009F9 50 PUSH AX ; push index 0 000009FA 55 PUSH BP 0 000009FB 89E5 MOV BP,SP 618 <1> ; stack looks like: 619 <1> ; 0 BP 620 <1> ; 2 DISPATCH 621 <1> ; 4 TABLE 622 <1> ; 6 RETURN 623 <1> ; 8 LONG-RETURN 624 <1> ; c FLAGS 625 <1> ; e AX 626 <1> 0 000009FD 8B460E MOV AX,[BP+0Eh] ; get AX value 0 00000A00 5D POP BP 0 00000A01 E8[0000] Invoke TableDispatch 0 00000A04 EBBD JMP BadFunc ; return indicates invalid function 631 <1> 632 <1> Procedure INT2F_etcetera,NEAR 632 ****************** <1> warning: proc INT2F_etcetera... [-w+user] 633 <1> 634 <1> extern first_umcb 635 <1> 636 <1> get_first_umcb: ; (NC) 0 00000A06 E8[0000] call doscode_getdosdata 0 00000A09 1E push ds 0 00000A0A 8ED8 mov ds, ax 0 00000A0C A1[0000] mov ax, [first_umcb] 0 00000A0F 1F pop ds 0 00000A10 EBB4 jmp Leave2F 643 <1> 644 <1> 645 <1> hma_access: 0 00000A12 3C01 cmp al, 1 0 00000A14 721C jb .iret 0 00000A16 741B je .query 0 00000A18 3C04 cmp al, 4 0 00000A1A 721B jb .access 0 00000A1C 7514 jne .iret 652 <1> ; je .get_first_hmcb 653 <1> 654 <1> .get_first_hmcb: 0 00000A1E 1E push ds 0 00000A1F 53 push bx 0 00000A20 57 push di 0 00000A21 50 push ax 0 00000A22 E86201 call getfirsthmcb 660 <1> ; OUT: ds = FFFFh 661 <1> ; bx = 0 662 <1> ; NC if DOS manages the HMA, 663 <1> ; ds:di -> first HMCB, allocated to DOS (owner = -2) 664 <1> ; A20 is assumed on because our cs is in the HMA 665 <1> ; CHG: ds, di, bx, ax 0 00000A25 7207 jc @F 0 00000A27 31C0 xor ax, ax ; ax = 0 0 00000A29 1E push ds 0 00000A2A 07 pop es ; es:di -> first HMCB 0 00000A2B 5B pop bx ; discard ax 0 00000A2C 5B pop bx ; discard di 0 00000A2D A9 db __TEST_IMM16 ; (skip pop twice) 673 <1> @@: 674 <1> ; if we are not managing the HMA, return 675 <1> ; as if the function is not supported 0 00000A2E 58 pop ax ; restore ax 0 00000A2F 5F pop di ; restore di 0 00000A30 5B pop bx ; unconditionally: restore bx, ds, iret 0 00000A31 1F pop ds 680 <1> .iret: 0 00000A32 CF iret 682 <1> 683 <1> .query: 0 00000A33 E80F01 call find_largest_free_hmcb 0 00000A36 CF iret 686 <1> 687 <1> 688 <1> .access: 0 00000A37 51 push cx 0 00000A38 52 push dx 0 00000A39 3C03 cmp al, 3 ; MS-DOS v7 style access ? 0 00000A3B 7409 je .access_new ; yes, dx and cx as passed --> 693 <1> ; MS-DOS v5 style access, allocate like dl=0 694 <1> ; with owner = int 2Fh caller cs 695 <1> .alloc_legacy: 0 00000A3D 31D2 xor dx, dx ; = function 0 (allocate low) 697 <1> lframe 0 698 <1> lpar word, iret_fl 699 <1> lpar word, iret_cs 700 <1> lpar word, iret_ip 701 <1> lpar word, cx 702 <1> lpar word, dx 0 00000A3F 5589E5 lenter 0 00000A42 8B4E08 mov cx, word [bp + ?iret_cs] 705 <1> ; owner = int 2Fh caller's cs 0 00000A45 5D lleave 707 <1> .access_new: 0 00000A46 50 push ax 0 00000A47 1E push ds 0 00000A48 53 push bx ; must be last here ! hma_alloc modifies this 0 00000A49 80FA02 cmp dl, 2 0 00000A4C 7479 je hma_free 0 00000A4E 720B jb hma_alloc 714 <1> ; unknown function, return bx = unchanged, es:di = all-1s 715 <1> .access_invalid: 0 00000A50 BFFFFF mov di, -1 0 00000A53 8EC7 mov es, di ; es:di = all-1s 718 <1> .access_return: 0 00000A55 5B pop bx ; must be first ! hma_alloc modifies this 0 00000A56 1F pop ds 0 00000A57 58 pop ax 0 00000A58 5A pop dx 0 00000A59 59 pop cx 0 00000A5A CF iret 725 <1> 726 <1> 727 <1> ; INP: dl = 0 if to allocate low 728 <1> ; dl = 1 if to allocate high 729 <1> ; dl is never >= 2 when branched here 730 <1> ; ss:sp -> bx, ds, ax, dx, cx on stack 731 <1> ; (bx must be first !) 732 <1> ; cx = owner to set (if 0, use 1) 733 <1> ; bx = size to allocate (byte granularity) 734 <1> ; OUT: es:di = all-1s if couldn't allocate, 735 <1> ; bx = unmodified 736 <1> ; es:di -> allocated data block if could allocate, 737 <1> ; bx = actually allocated size in bytes, 738 <1> ; rounded up to paragraph boundary 739 <1> ; REM: MS-DOS v7.10 returns bx unchanged if no alloc. 740 <1> hma_alloc: 0 00000A5B E301 jcxz .zero 0 00000A5D A8 db __TEST_IMM8 ; skip inc 743 <1> .zero: 0 00000A5E 41 inc cx ; cx = 1, avoid zero owner 745 <1> 0 00000A5F 8D470F lea ax, [bx + 15] 0 00000A62 83E0F0 and ax, ~15 ; round up to para boundary 748 <1> ; ZR if too large ! 0 00000A65 74E9 jz hma_access.access_invalid 750 <1> ; return bx = unchanged, es:di = all-1s 0 00000A67 E8DB00 call find_largest_free_hmcb 0 00000A6A 72E9 jc hma_access.access_return 753 <1> ; return bx = unchanged, es:di = all-1s 754 <1> 0 00000A6C 39D8 cmp ax, bx ; free block is large enough ? 0 00000A6E 77E0 ja hma_access.access_invalid 757 <1> ; no --> 0 00000A70 1F pop ds ; discard bx on stack (must be first !) 0 00000A71 50 push ax ; push ax instead (actual allocation size) 0 00000A72 06 push es 0 00000A73 1F pop ds ; => HMA, ds:di -> behind HMCB to split 762 <1> 0 00000A74 56 push si 0 00000A75 BE0000 mov si, 0 ; ! preserve flags, si = 0 765 <1> ; ds:di -> low HMCB data, 766 <1> ; size = bx + 16 >= ax + 16 767 <1> ; ax = how much to alloc 768 <1> ; bx = current data size minus 16 769 <1> ; cx = owner to set 770 <1> ; dl = function 771 <1> ; si = 0 0 00000A78 8975F8 mov word [di - HMCB_size + hmcbName], si 0 00000A7B 8975FA mov word [di - HMCB_size + hmcbName + 2], si 0 00000A7E 8975FC mov word [di - HMCB_size + hmcbName + 4], si 0 00000A81 8975FE mov word [di - HMCB_size + hmcbName + 6], si 776 <1> ; clear the name of low HMCB 777 <1> 0 00000A84 7505 jne .split ; NZ if free > requested 0 00000A86 894DF2 mov word [di - HMCB_size + hmcbOwner], cx 780 <1> ; free == requested, just allocate here 781 <1> ; sign, size, and next already set! 0 00000A89 EB39 jmp .full 783 <1> 784 <1> .split: 0 00000A8B 83EB10 sub bx, HMCB_size 0 00000A8E 29C3 sub bx, ax ; bx = current size - 16 - how much to alloc 787 <1> ; = remainder size 0 00000A90 84D2 test dl, dl 0 00000A92 7504 jnz .high 790 <1> .low: 0 00000A94 93 xchg ax, bx ; bx = how much to alloc (no HMCB size) 792 <1> ; ax = remainder size 793 <1> ; di -> behind HMCB 0 00000A95 874DF2 xchg word [di - HMCB_size + hmcbOwner], cx 795 <1> ; allocate it, 796 <1> ; and load cx = 0 (owner meaning free) 797 <1> .high: 798 <1> ; if branched to .high: 799 <1> ; bx = remainder size (size for low HMCB) 800 <1> ; ax = how much to alloc (size for high HMCB) 801 <1> ; cx = owner to set (owner for high MCB) 802 <1> ; have to set es:di -> high HMCB data later 803 <1> ; else if fell through from .low: 804 <1> ; bx = how much to alloc (size for low HMCB) 805 <1> ; ax = remainder size (size for high HMCB) 806 <1> ; cx = 0 (owner for high HMCB) 807 <1> ; es:di -> low HMCB data, to allocate 808 <1> ; common: 809 <1> ; dl = mode (0 if low, 1 if high) 810 <1> ; es:di -> behind low HMCB 811 <1> ; owner of low HMCB set as desired 0 00000A98 53 push bx ; push bx 0 00000A99 8D19 lea bx, [di + bx] ; bx -> new (high) HMCB 0 00000A9B FF75F6 push word [di - HMCB_size + hmcbNext] 815 <1> ; get old next 0 00000A9E C7074D53 mov word [bx + hmcbSignature], "MS" 0 00000AA2 894F02 mov word [bx + hmcbOwner], cx 818 <1> ; set owner (0 if low, input cx if high) 0 00000AA5 894704 mov word [bx + hmcbSize], ax 820 <1> ; set size of high HMCB 0 00000AA8 8F4706 pop word [bx + hmcbNext]; set new next 0 00000AAB 897708 mov word [bx + hmcbName], si 0 00000AAE 89770A mov word [bx + hmcbName + 2], si 0 00000AB1 89770C mov word [bx + hmcbName + 4], si 0 00000AB4 89770E mov word [bx + hmcbName + 6], si 826 <1> ; clear the name 0 00000AB7 895DF6 mov word [di - HMCB_size + hmcbNext], bx 828 <1> ; -> next (created at top of block) 0 00000ABA 8F45F4 pop word [di - HMCB_size + hmcbSize] ; but pop memory 830 <1> ; allocate size of low HMCB 0 00000ABD 84D2 test dl, dl 0 00000ABF 7403 jz @F 0 00000AC1 8D7F10 lea di, [bx + HMCB_size]; -> top HMCB data 834 <1> @@: 835 <1> .full: 0 00000AC4 5E pop si 837 <1> j_hma_access.access_return: 0 00000AC5 EB8E jmp hma_access.access_return 839 <1> 840 <1> 841 <1> hma_free: 0 00000AC7 57 push di 0 00000AC8 E8BC00 call getfirsthmcb 0 00000ACB 723B jc .none 0 00000ACD 57 push di 0 00000ACE 8CC7 mov di, es ; => user es 0 00000AD0 4B dec bx ; = -1 0 00000AD1 39DF cmp di, bx ; match ? 0 00000AD3 5B pop bx 0 00000AD4 7532 jne .none ; no --> 0 00000AD6 5F pop di 0 00000AD7 57 push di 0 00000AD8 F7C70F00 test di, 15 ; valid HMCB ? 0 00000ADC 752A jnz .none ; no --> 0 00000ADE 83EF10 sub di, HMCB_size ; ds:di -> HMCB to free 0 00000AE1 7625 jbe .none ; reject too low HMCB ! 0 00000AE3 813D4D53 cmp word [di + hmcbSignature], "MS" 0 00000AE7 751F jne .none 0 00000AE9 39DF cmp di, bx ; is first HMCB or below ? 860 <1> ; (do not allow to free the first HMCB !) 0 00000AEB 761B jbe .none 862 <1> ; MS-DOS v7.10 has a je here to handle this 863 <1> .loop: 0 00000AED F6C30F test bl, 15 ; valid HMCB ? 0 00000AF0 7516 jnz .none ; no --> 0 00000AF2 813F4D53 cmp word [bx + hmcbSignature], "MS" 0 00000AF6 7510 jne .none 0 00000AF8 8B4706 mov ax, word [bx + hmcbNext] 0 00000AFB 39F8 cmp ax, di 0 00000AFD 740C je .found_below 0 00000AFF 39D8 cmp ax, bx ; next > current ? 0 00000B01 7605 jbe .none ; no --> 0 00000B03 85C0 test ax, ax 0 00000B05 93 xchg bx, ax ; bx -> next HMCB 0 00000B06 75E5 jnz .loop 876 <1> .none: 877 <1> .done: 0 00000B08 5F pop di 0 00000B09 EBBA jmp j_hma_access.access_return 880 <1> 881 <1> .found_below: 0 00000B0B 83650200 and word [di + hmcbOwner], 0 883 <1> ; mark input HMCB as free 0 00000B0F 837F0200 cmp word [bx + hmcbOwner], 0 885 <1> ; is prior free ? 0 00000B13 7502 jne .merge_di_to_next ; no, merge di and subsequent --> 0 00000B15 89DF mov di, bx ; yes, set di from bx and merge subsequent 888 <1> ; (the first iteration will merge input HMCB) 889 <1> .merge_di_to_next: 0 00000B17 8B5D06 mov bx, [di + hmcbNext] ; -> next 0 00000B1A 85DB test bx, bx ; any next ? 0 00000B1C 74EA jz .done ; no, all free ones merged --> 0 00000B1E F6C30F test bl, 15 ; validity 0 00000B21 75E5 jnz .none 0 00000B23 39FB cmp bx, di ; validity 0 00000B25 76E1 jbe .none 0 00000B27 813F4D53 cmp word [bx + hmcbSignature], "MS" 898 <1> ; validity 0 00000B2B 75DB jne .none 0 00000B2D 837F0200 cmp word [bx + hmcbOwner], 0 901 <1> ; is next also free ? 0 00000B31 75D5 jne .done ; no, all free ones merged --> 0 00000B33 8B4704 mov ax, [bx + hmcbSize] 0 00000B36 83C010 add ax, HMCB_size ; = size to add to prior HMCB 0 00000B39 014504 add word [di + hmcbSize], ax 906 <1> ; add to first free HMCB in chain 0 00000B3C 014506 add word [di + hmcbNext], ax 908 <1> ; add, may carry 0 00000B3F 73D6 jnc .merge_di_to_next ; valid next offset --> 0 00000B41 74D4 jz .merge_di_to_next ; valid end of chain indicator --> 0 00000B43 EBC3 jmp .none ; error 912 <1> 913 <1> 914 <1> ; OUT: CY if not managing HMA, 915 <1> ; or <= 16 bytes free, 916 <1> ; or HMCB chain corrupted, 917 <1> ; es:di = FFFFh:FFFFh 918 <1> ; bx = 0 919 <1> ; NC if found >= 16 bytes free, 920 <1> ; es:di -> largest free memory block 921 <1> ; bx = size of block available 922 <1> ; REM: The size returned for MS-DOS v7 is the HMCB memory 923 <1> ; block size minus 16 to allow an optimisation when 924 <1> ; allocating, which is that a new HMCB is always 925 <1> ; created. Unlike that, MS-DOS v5 returns a size 926 <1> ; which spans the entire trailing space up to below 927 <1> ; FFFFh:10000h. lDOS is now reverted to v5 style, 928 <1> ; meaning the full HMCB block size is returned. 929 <1> ; Unlike v5, the free block may still occur in the 930 <1> ; middle of the HMA (not at the very tail) though. 931 <1> ; REM: The returned memory block is the largest free block. 932 <1> ; If multiple free blocks are of the same size, 933 <1> ; the first one is returned. 934 <1> ; CHG: - 935 <1> find_largest_free_hmcb: 0 00000B45 50 push ax 0 00000B46 1E push ds 0 00000B47 51 push cx 0 00000B48 E83C00 call getfirsthmcb 0 00000B4B 722F jc .error 941 <1> .loop: 0 00000B4D F7C70F00 test di, 15 ; valid HMCB ? 0 00000B51 7529 jnz .error ; no --> 0 00000B53 813D4D53 cmp word [di + hmcbSignature], "MS" 0 00000B57 7523 jne .error ; no --> 0 00000B59 837D0200 cmp word [di + hmcbOwner], 0 0 00000B5D 750B jne .next 0 00000B5F 395D04 cmp word [di + hmcbSize], bx 0 00000B62 7606 jbe .next 0 00000B64 8D4510 lea ax, [di + HMCB_size]; -> memory block 0 00000B67 8B5D04 mov bx, word [di + hmcbSize] 952 <1> .next: 0 00000B6A 8B4D06 mov cx, word [di + hmcbNext] 954 <1> ; cx -> next 0 00000B6D E308 jcxz .end ; was last ? --> 0 00000B6F 39F9 cmp cx, di ; valid next offset ? 0 00000B71 7609 jbe .error ; not valid --> 0 00000B73 89CF mov di, cx ; -> next 0 00000B75 EBD6 jmp .loop ; go loop 960 <1> .end: 0 00000B77 97 xchg di, ax ; di -> largest first free HMA memory block 0 00000B78 85DB test bx, bx ; (NC) 0 00000B7A 7505 jnz .done 964 <1> .error: 0 00000B7C 31DB xor bx, bx ; bx = 0 0 00000B7E 8CDF mov di, ds ; es:di will be all-1s 0 00000B80 F9 stc ; signal error 968 <1> .done: 0 00000B81 1E push ds 0 00000B82 07 pop es 0 00000B83 59 pop cx 0 00000B84 1F pop ds 0 00000B85 58 pop ax 0 00000B86 C3 retn 975 <1> 976 <1> 977 <1> ; INP: word [DOSDATA:first_hmcb] set 978 <1> ; and cs == DOSCODE_HMA_SEGMENT 979 <1> ; if DOS manages the HMA 980 <1> ; OUT: ds = FFFFh 981 <1> ; bx = 0 982 <1> ; NC if DOS manages the HMA, 983 <1> ; ds:di -> first HMCB, allocated to DOS (owner = -2) 984 <1> ; A20 is assumed on because our cs is in the HMA 985 <1> ; CHG: ds, di, bx, ax 986 <1> getfirsthmcb: 0 00000B87 E8[0000] call doscode_getdosdata 0 00000B8A 8ED8 mov ds, ax ; => DOSDATA 0 00000B8C 8CCF mov di, cs ; => DOSCODE 0 00000B8E B8FEFF mov ax, DOSCODE_HMA_SEGMENT 991 <1> ; expected DOSCODE segment 0 00000B91 39C7 cmp di, ax ; is it ? 0 00000B93 8B3E[0000] mov di, [first_hmcb] ; ds:di -> first HMCB, if any 0 00000B97 BBFFFF mov bx, -1 0 00000B9A 8EDB mov ds, bx ; => HMA 0 00000B9C 43 inc bx ; = 0, preserve CF ! 0 00000B9D 7203 jb @F ; if not managing HMA --> 0 00000B9F 394502 cmp word [di + hmcbOwner], ax 999 <1> ; NC (ae) if valid, CY (b) if invalid 1000 <1> @@: 0 00000BA2 C3 retn ; CY if DOS is not in the HMA 1002 <1> 1003 <1> 1004 <1> entry DosGetGroup 0 00000BA3 50 push ax 0 00000BA4 E8[0000] call doscode_getdosdata 0 00000BA7 8ED8 mov ds, ax 0 00000BA9 58 pop ax 0 00000BAA C3 return 1010 <1> 1011 <1> entry DOSInstall 0 00000BAB B0FF MOV AL,0FFh 0 00000BAD C3 return 1014 <1> EndProc INT2F_etcetera 1015 <1> 1016 <1> %ENDIF 1017 <1> ;Input: same as ABSDRD and ABSDWRT 1018 <1> ; ES:BP -> DPB 1019 <1> ;Functions: convert 32bit absolute RW input parms to 16bit input parms 1020 <1> ;Output: carry set when CX != -1 and drive is more than 32mb 1021 <1> ; carry clear, parms ok 1022 <1> ; 1023 <1> Procedure RW32_CONVERT,NEAR 1023 ****************** <1> warning: proc RW32_CONVERT... [-w+user] 1024 <1> ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING 0 00000BAE 83F9FF CMP CX,-1 ;>32mb new format ? ;AN000; 0 00000BB1 7423 JZ new32format ;>32mb yes ;AN000; 0 00000BB3 50 PUSH AX ;>32mb save ax ;AN000; 0 00000BB4 52 PUSH DX ;>32mb save dx ;AN000; 0 00000BB5 268B460D MOV AX,[ES:BP + dpb_max_cluster] ;>32mb get max cluster # ;AN000; 0 00000BB9 268A5604 MOV DL,[ES:BP + dpb_cluster_mask] ;>32mb ;AN000; 1031 <1> ; lDOS note: very suspicious, test intended ? 0 00000BBD 80FAFE CMP DL,0FEH ;>32mb removable ? ;AN000; 0 00000BC0 7407 JZ letold ;>32mb yes ;AN000; 0 00000BC2 B600 mov dh, 0 0 00000BC4 42 inc dx ; sectors per cluster 0 00000BC5 F7E2 MUL DX ;>32mb dx:ax= max sector # ;AN000; 0 00000BC7 85D2 test DX,DX ;>32mb > 32mb ? ;AN000; 1038 <1> letold: 0 00000BC9 5A POP DX ;>32mb retore dx ;AN000; 0 00000BCA 58 POP AX ;>32mb restore ax ;AN000; 0 00000BCB 7419 JZ old_style ;>32mb no ;AN000; 0 00000BCD 36C706[0000]0702 MOV word [ss:IFS_DRIVER_ERR],0207H ;>32mb error ;AN000; 0 00000BD4 F9 STC ;>32mb ;AN000; 0 00000BD5 C3 return ;>32mb ;AN000; 1045 <1> new32format: 0 00000BD6 8B5702 MOV DX,WORD PTR [BX + SECTOR_RBA+2];>32mb ;AN000; 0 00000BD9 368916[0000] MOV [ss:HIGH_SECTOR],DX ;>32mb ;AN000; 0 00000BDE 8B17 MOV DX,WORD PTR [BX + SECTOR_RBA] ;>32mb ;AN000; 0 00000BE0 8B4F04 MOV CX,[BX + ABS_RW_COUNT] ;>32mb ;AN000; 0 00000BE3 C55F06 LDS BX,[BX + BUFFER_ADDR] ;>32mb ;AN000; 1051 <1> old_style: ;>32mb ;AN000; 0 00000BE6 F8 CLC ;>32mb ;AN000; 0 00000BE7 C3 return ;>32mb ;AN000; 1054 <1> EndProc RW32_CONVERT 1055 <1> 1056 <1> 1057 <1> ;Input: None 1058 <1> ;Functions: Purge Fastopen/seek Cache Buffers 1059 <1> ;Output: None 1060 <1> ; 1061 <1> ; 1062 <1> Procedure Fastxxx_Purge,NEAR 1062 ****************** <1> warning: proc Fastxxx_Purge... [-w+user] 1063 <1> ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING 0 00000BE8 50 PUSH AX ; save regs. ;AN000; 0 00000BE9 56 PUSH SI ;AN000; 0 00000BEA 52 PUSH DX ;AN000; 1067 <1> FastSeekflg equ FastSeekFlg ; NASM port label 0 00000BEB 36F606[0000]80 TEST byte [ss:FastSeekflg],Fast_yes ; fastseek installed ? ;AN000; 0 00000BF1 7404 JZ topen ; no ;AN000; 0 00000BF3 B402 MOV AH,FastSeek_ID ; set fastseek id ;AN000; 0 00000BF5 EB0A JMP SHORT dofast ; ;AN000; 1072 <1> topen: 1073 <1> FastOpenflg equ FastOpenFlg ; NASM port label 0 00000BF7 36F606[0000]80 TEST byte [ss:FastOpenflg],Fast_yes ; fastopen installed ? ;AN000; 0 00000BFD 740B JZ nofast ; no ;AN000; 0 00000BFF B401 MOV AH,FastOpen_ID ; set fastseek installed ;AN000; 1077 <1> dofast: 0 00000C01 B005 MOV AL,FONC_purge ; purge ;AN000; 0 00000C03 268A5600 MOV DL,[ES:BP + dpb_drive] ; set up drive number ;AN000; 0 00000C07 E8[0000] invoke Fast_Dispatch ; call fastopen/seek ;AN000; 1081 <1> nofast: 0 00000C0A 5A POP DX ;AN000; 0 00000C0B 5E POP SI ; restore regs ;AN000; 0 00000C0C 58 POP AX ; ;AN000; 1085 <1> 0 00000C0D C3 return ; exit ;AN000; 1087 <1> EndProc Fastxxx_Purge 1088 <1> 1089 <1> 1090 <1> 17 ;=== Pop trace listing source 18 END === Trace listing source: ../INC/msdosme.lst 1 ; SCCSID = @(#)ibmdosmes.asm 1.1 85/04/10 2 ; 3 ; Standard device IO for MSDOS (first 12 function calls) 4 ; 5 debug equ 0 6 [list -] 6 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 14 15 ;TITLE IBMDOSMES - DOS OEM dependancies 16 ;NAME IBMDOSMES 17 18 ;=== Push trace listing source: dosmes.nas 19 %include "dosmes.nas" ; NASM included file 1 <1> ; SCCSID = @(#)dosmes.asm 1.7 85/10/23 2 <1> ; SCCSID = @(#)dosmes.asm 1.7 85/10/23 3 <1> ; 4 <1> ; Message file for Internationalized messages. There is 5 <1> ; only one message here available for translation. 6 <1> ; 7 <1> ; 8 <1> ; Revision history 9 <1> ; A000 version 4.00 Jan. 1988 10 <1> ; 11 <1> 12 <1> %IFNdef KANJI 13 <1> %iassign KANJI FALSE 14 <1> %ENDIF 15 <1> 16 <1> %IFNdef Rainbow 17 <1> %iassign Rainbow FALSE 18 <1> %ENDIF 19 <1> 20 <1> [list -] 20 ****************** <1> warning: out: ... for DOS Version 4.00 ... [-w+user] 20 ****************** <1> warning: out: BPB.INC... [-w+user] 20 ****************** <1> warning: out: ... CLONE version build switch on ... [-w+user] 28 <1> === Switch to base=001140h -> "CONSTANTS" 29 <1> section CONSTANTS 30 <1> 31 <1> UserNum equ USERNUM ; NASM port label 32 <1> OEMNum equ OEMNUM ; NASM port label 33 <1> PUBLIC UserNum, OEMNum 34 <1> Public DMES001S,DMES001E 35 <1> DMES001S Label byte 0 000003B2 ???? USERNUM DW ? ; 24 bit user number 0 000003B4 ?? DB ? 38 <1> OEMNUM: 39 <1> %if 0 40 <1> %IF IBM 41 <1> %IF IBMCOPYRIGHT 42 <1> DB 0 ; 8 bit OEM number 43 <1> %ELSE 44 <1> DB 0FFH ; 8 bit OEM number 45 <1> %ENDIF 46 <1> %ELSE 47 <1> DB 0FFH 48 <1> %ENDIF 49 <1> %else 0 000003B5 26 db 26h ; lDOS OEM number = 26h 51 <1> %endif 52 <1> 53 <1> DMES001E label byte 54 <1> ; (no prior section) ; CONSTANTS ENDS 55 <1> === Switch to base=001140h -> "TABLE" 56 <1> section TABLE ; in DOSDATA 57 <1> Public DMES002S 58 <1> DMES002S label byte 59 <1> 60 <1> 61 <1> ; The following table is used for DOS 3.3 62 <1> ;DOS country and code page information is defined here for DOS 3.3. 63 <1> ;The initial value for ccDosCountry is 1 (USA). 64 <1> ;The initial value for ccDosCodepage is 850. 65 <1> ; 66 <1> ; 67 <1> PUBLIC COUNTRY_CDPG,UCASE_TAB,FILE_UCASE_TAB 68 <1> PUBLIC FILE_CHAR_TAB 69 <1> ; 70 <1> ; country and code page infomation 71 <1> ; 72 <1> COUNTRY_CDPG label byte 73 <1> 0 00000F20 0000000000000000 db 0,0,0,0,0,0,0,0 ; reserved words 0 00000F28 5C434F554E5452592E db '\COUNTRY.SYS',0 ; path name of country.sys 0 00000F31 53595300 76 00000015 <1> db 51 dup (?) 0 00000F68 B501 dw 437 ; system code page id 0 00000F6A 0600 dw 6 ; number of entries 0 00000F6C 02 db SetUcase ; Ucase type 0 00000F6D [8E00] dw OFFSET UCASE_TAB wrt DOSGROUP ;pointer to upper case table 0 00000F6F 0000 dw 0 ; segment of poiter 0 00000F71 04 db SetUcaseFile ; Ucase file char type 0 00000F72 [1001] dw OFFSET FILE_UCASE_TAB wrt DOSGROUP ;pointer to file upper case table 0 00000F74 0000 dw 0 ; segment of poiter 0 00000F76 05 db SetFileList ; valid file chars type 0 00000F77 [9201] dw OFFSET FILE_CHAR_TAB wrt DOSGROUP ;pointer to valid file char tab 0 00000F79 0000 dw 0 ; segment of poiter 0 00000F7B 06 db SetCollate ; collate type 0 00000F7C [C201] dw OFFSET COLLATE_TAB wrt DOSGROUP ;pointer to collate table 0 00000F7E 0000 dw 0 ; segment of poiter 0 00000F80 07 db SetDBCS ;AN000; DBCS Ev 2/12/KK 0 00000F81 [C402] dw OFFSET DBCS_TAB wrt DOSGROUP ;AN000;;pointer to DBCS Ev table 2/12/KK 0 00000F83 0000 dw 0 ;AN000; segment of poiter 2/12/KK 0 00000F85 01 db SetCountryInfo ; country info type 0 00000F86 2600 dw NEW_COUNTRY_SIZE ; extended country info size 0 00000F88 0100 dw 1 ; USA country id 0 00000F8A B501 dw 437 ; USA system code page id 0 00000F8C 0000 dw 0 ; date format 0 00000F8E 2400000000 db '$',0,0,0,0 ; currency symbol 0 00000F93 2C00 db ',',0 ; thousand separator 0 00000F95 2E00 db '.',0 ; decimal separator 0 00000F97 2D00 db '-',0 ; date separator 0 00000F99 3A00 db ':',0 ; time separator 0 00000F9B 00 db 0 ; currency format flag 0 00000F9C 02 db 2 ; # of disgit in currency 0 00000F9D 00 db 0 ; time format 0 00000F9E [A004] dw casemap + DOSENTRYADJUSTOFFSET ;mono case routine entry point 0 00000FA0 [0000] dw DOSENTRY - DOSENTRYADJUSTSEGMENT ; segment of entry point 0 00000FA2 2C00 db ',',0 ; data list separator 0 00000FA4 000000000000000000 dw 0,0,0,0,0 ; reserved 0 00000FAD 00 111 <1> 112 <1> 113 <1> 114 <1> ; 115 <1> ; 116 <1> ; 117 <1> ; 118 <1> ; 119 <1> ; upper case table 120 <1> ; 121 <1> UCASE_TAB label byte 0 00000FAE 8000 dw 128 0 00000FB0 809A45418E418F80 db 128,154,069,065,142,065,143,128 0 00000FB8 4545454949498E8F db 069,069,069,073,073,073,142,143 0 00000FC0 9092924F994F5555 db 144,146,146,079,153,079,085,085 0 00000FC8 59999A9B9C9D9E9F db 089,153,154,155,156,157,158,159 0 00000FD0 41494F55A5A5A6A7 db 065,073,079,085,165,165,166,167 0 00000FD8 A8A9AAABACADAEAF db 168,169,170,171,172,173,174,175 0 00000FE0 B0B1B2B3B4B5B6B7 db 176,177,178,179,180,181,182,183 0 00000FE8 B8B9BABBBCBDBEBF db 184,185,186,187,188,189,190,191 0 00000FF0 C0C1C2C3C4C5C6C7 db 192,193,194,195,196,197,198,199 0 00000FF8 C8C9CACBCCCDCECF db 200,201,202,203,204,205,206,207 0 00001000 D0D1D2D3D4D5D6D7 db 208,209,210,211,212,213,214,215 0 00001008 D8D9DADBDCDDDEDF db 216,217,218,219,220,221,222,223 0 00001010 E0E1E2E3E4E5E6E7 db 224,225,226,227,228,229,230,231 0 00001018 E8E9EAEBECEDEEEF db 232,233,234,235,236,237,238,239 0 00001020 F0F1F2F3F4F5F6F7 db 240,241,242,243,244,245,246,247 0 00001028 F8F9FAFBFCFDFEFF db 248,249,250,251,252,253,254,255 139 <1> 140 <1> ; 141 <1> ; file upper case table 142 <1> ; 143 <1> FILE_UCASE_TAB label byte 0 00001030 8000 dw 128 0 00001032 809A45418E418F80 db 128,154,069,065,142,065,143,128 0 0000103A 4545454949498E8F db 069,069,069,073,073,073,142,143 0 00001042 9092924F994F5555 db 144,146,146,079,153,079,085,085 0 0000104A 59999A9B9C9D9E9F db 089,153,154,155,156,157,158,159 0 00001052 41494F55A5A5A6A7 db 065,073,079,085,165,165,166,167 0 0000105A A8A9AAABACADAEAF db 168,169,170,171,172,173,174,175 0 00001062 B0B1B2B3B4B5B6B7 db 176,177,178,179,180,181,182,183 0 0000106A B8B9BABBBCBDBEBF db 184,185,186,187,188,189,190,191 0 00001072 C0C1C2C3C4C5C6C7 db 192,193,194,195,196,197,198,199 0 0000107A C8C9CACBCCCDCECF db 200,201,202,203,204,205,206,207 0 00001082 D0D1D2D3D4D5D6D7 db 208,209,210,211,212,213,214,215 0 0000108A D8D9DADBDCDDDEDF db 216,217,218,219,220,221,222,223 0 00001092 E0E1E2E3E4E5E6E7 db 224,225,226,227,228,229,230,231 0 0000109A E8E9EAEBECEDEEEF db 232,233,234,235,236,237,238,239 0 000010A2 F0F1F2F3F4F5F6F7 db 240,241,242,243,244,245,246,247 0 000010AA F8F9FAFBFCFDFEFF db 248,249,250,251,252,253,254,255 161 <1> 162 <1> ; 163 <1> ; file char list 164 <1> ; 165 <1> FILE_CHAR_TAB label byte 0 000010B2 1600 dw 22 ; length 0 000010B4 0100FF db 1,0,255 ; include all 0 000010B7 000020 db 0,0,20h ; exclude 0 - 20h 0 000010BA 020E2E222F5C5B5D3A db 2,14,'."/\[]:|<>+=;,' ; exclude 14 special 0 000010C3 7C3C3E2B3D3B2C 170 000001AA <1> db 24 dup (?) ; reserved 171 <1> ; 172 <1> ; collate table 173 <1> ; 174 <1> COLLATE_TAB label byte 0 000010E2 0001 dw 256 0 000010E4 0001020304050607 db 0,1,2,3,4,5,6,7 0 000010EC 08090A0B0C0D0E0F db 8,9,10,11,12,13,14,15 0 000010F4 1011121314151617 db 16,17,18,19,20,21,22,23 0 000010FC 18191A1B1C1D1E1F db 24,25,26,27,28,29,30,31 0 00001104 2021222324252627 db " ","!",'"',"#","$","%","&","'" 0 0000110C 28292A2B2C2D2E2F db "(",")","*","+",",","-",".","/" 0 00001114 3031323334353637 db "0","1","2","3","4","5","6","7" 0 0000111C 38393A3B3C3D3E3F db "8","9",":",";","<","=",">","?" 0 00001124 4041424344454647 db "@","A","B","C","D","E","F","G" 0 0000112C 48494A4B4C4D4E4F db "H","I","J","K","L","M","N","O" 0 00001134 5051525354555657 db "P","Q","R","S","T","U","V","W" 0 0000113C 58595A5B5C5D5E5F db "X","Y","Z","[","\","]","^","_" 0 00001144 6041424344454647 db "`","A","B","C","D","E","F","G" 0 0000114C 48494A4B4C4D4E4F db "H","I","J","K","L","M","N","O" 0 00001154 5051525354555657 db "P","Q","R","S","T","U","V","W" 0 0000115C 58595A7B7C7D7E7F db "X","Y","Z","{","|","}","~",127 0 00001164 4355454141414143 db "C","U","E","A","A","A","A","C" 0 0000116C 4545454949494141 db "E","E","E","I","I","I","A","A" 0 00001174 4541414F4F4F5555 db "E","A","A","O","O","O","U","U" 0 0000117C 594F552424242424 db "Y","O","U","$","$","$","$","$" 0 00001184 41494F554E4EA6A7 db "A","I","O","U","N","N",166,167 0 0000118C 3FA9AAABAC212222 db "?",169,170,171,172,"!",'"','"' 0 00001194 B0B1B2B3B4B5B6B7 db 176,177,178,179,180,181,182,183 0 0000119C B8B9BABBBCBDBEBF db 184,185,186,187,188,189,190,191 0 000011A4 C0C1C2C3C4C5C6C7 db 192,193,194,195,196,197,198,199 0 000011AC C8C9CACBCCCDCECF db 200,201,202,203,204,205,206,207 0 000011B4 D0D1D2D3D4D5D6D7 db 208,209,210,211,212,213,214,215 0 000011BC D8D9DADBDCDDDEDF db 216,217,218,219,220,221,222,223 0 000011C4 E053 db 224,"S" 0 000011C6 E2E3E4E5E6E7 db 226,227,228,229,230,231 0 000011CC E8E9EAEBECEDEEEF db 232,233,234,235,236,237,238,239 0 000011D4 F0F1F2F3F4F5F6F7 db 240,241,242,243,244,245,246,247 0 000011DC F8F9FAFBFCFDFEFF db 248,249,250,251,252,253,254,255 209 <1> ; 210 <1> ; dbcs is not supported in DOS 3.3 211 <1> ; DBCS_TAB CC_DBCS <> 212 <1> ; 213 <1> ; DBCS for DOS 4.00 2/12/KK 214 <1> PUBLIC DBCS_TAB 215 <1> DBCS_TAB label byte ;AN000; 2/12/KK 0 000011E4 0000 dw 0 ;AN000; 2/12/KK max number 0 000011E6 000000000000000000 db 16 dup(0) ;AN000; 2/12/KK 0 000011EF 00000000000000 218 <1> 219 <1> ; dw 6 ; 2/12/KK 220 <1> ; db 081h,09fh ; 2/12/KK 221 <1> ; db 0e0h,0fch ; 2/12/KK 222 <1> ; db 0,0 ; 2/12/KK 223 <1> ; 224 <1> ; 225 <1> === Switch to base=008400h -> "DOSCODETABLE" 226 <1> section DOSCODETABLE 227 <1> 228 <1> ;=== Push trace listing source: divmes.nas 229 <1> %include "divmes.nas" ; NASM included file 1 <2> ; THIS IS THE ONLY DOS "MESSAGE". IT DOES NOT NEED A TERMINATOR. 2 <2> PUBLIC DIVMES 3 <2> Public DIVM001S,DIVM001E 4 <2> DIVM001S label byte 5 <2> 6 <2> ;=== Push trace listing source: msdos.cl1 7 <2> %include "msdos.cl1" ; NASM included file 1 <3> ; msdos.cl1 2 <3> 3 <3> 4 <3> ;_______________________ 5 <3> 0 00000442 0D0A44697669646520 DIVMES DB 13,10,"Divide overflow",13,10 0 0000044B 6F766572666C6F770D 0 00000454 0A 8 <2> ;=== Pop trace listing source 9 <2> 10 <2> PUBLIC DivMesLen 11 <2> DivMes equ DIVMES ; NASM port label 0 00000455 1300 DivMesLen DW $-DivMes ; Length of the above message in bytes 13 <2> DIVM001E label byte 14 <2> 230 <1> ;=== Pop trace listing source 231 <1> === Switch to base=001140h -> "TABLE" 232 <1> section TABLE ; in DOSDATA 233 <1> 234 <1> ;=== Push trace listing source: yesno.nas 235 <1> %include "yesno.nas" ; NASM included file 1 <2> ; This is for contry Yes and No 2 <2> PUBLIC NLS_YES,NLS_yes2,NLS_NO,NLS_no2 3 <2> ;=== Push trace listing source: msdos.cl3 4 <2> %include "msdos.cl3" ; NASM included file 1 <3> ; msdos.cl3 2 <3> 3 <3> 4 <3> ;_______________________ 5 <3> 0 000011F6 59 NLS_YES DB "Y" 7 <3> 8 <3> ;_______________________ 9 <3> 0 000011F7 4E NLS_NO DB "N" 11 <3> 12 <3> ;_______________________ 13 <3> 0 000011F8 79 NLS_yes2 DB "y" 15 <3> 16 <3> ;_______________________ 17 <3> 0 000011F9 6E NLS_no2 DB "n" 5 <2> ;=== Pop trace listing source 6 <2> 236 <1> ;=== Pop trace listing source 237 <1> 238 <1> 239 <1> %ifndef DONOBITS 240 <1> === Switch to base=008400h -> "DOSCODECODE" 241 <1> section DOSCODECODE 242 <1> 243 <1> extern doscode_getdosdata 244 <1> 245 <1> relocated casemap 0 00000C0E 50 push ax 0 00000C0F E8[0000] call doscode_getdosdata 0 00000C12 50 push ax 0 00000C13 B8[0000] mov ax, MAP_CASE 0 00000C16 50 push ax 0 00000C17 CB retf 252 <1> 253 <1> === Switch to base=001140h -> "DOSDATACODE" 254 <1> section DOSDATACODE ; in DOSDATA 255 <1> ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING 256 <1> 257 <1> ;CASE MAPPER ROUTINE FOR 80H-FFH character range, DOS 3.3 258 <1> ; ENTRY: AL = Character to map 259 <1> ; EXIT: AL = The converted character 260 <1> ; Alters no registers except AL and flags. 261 <1> ; The routine should do nothing to chars below 80H. 262 <1> ; 263 <1> ; Example: 264 <1> 265 <1> Procedure MAP_CASE,FAR 265 ****************** <1> warning: proc MAP_CASE... [-w+user] 0 0000124B 58 pop ax 0 0000124C 3C80 CMP AL,80H 0 0000124E 7301 JAE Map1 ;Map no chars below 80H ever 0 00001250 CB RET 270 <1> Map1: 0 00001251 2C80 SUB AL,80H ;Turn into index value 0 00001253 1E PUSH DS 0 00001254 53 PUSH BX 0 00001255 BB[9000] MOV BX,OFFSET UCASE_TAB + 2 wrt DOSGROUP 275 <1> FINISH: 0 00001258 0E PUSH CS ;Move to DS 0 00001259 1F POP DS 0 0000125A D7 xlatb ;Get upper case character 0 0000125B 5B POP BX 0 0000125C 1F POP DS 0 0000125D CB L_RET: RET 282 <1> EndProc MAP_CASE 283 <1> 284 <1> ;SUBTTL EDIT FUNCTION ASSIGNMENTS AND HEADERS 285 <1> ;PAGE 286 <1> ; The following two tables implement the current buffered input editing 287 <1> ; routines. The tables are pairwise associated in reverse order for ease 288 <1> ; in indexing. That is; The first entry in ESCTAB corresponds to the last 289 <1> ; entry in ESCFUNC, and the last entry in ESCTAB to the first entry in ESCFUNC. 290 <1> 291 <1> %endif ; DONOBITS 292 <1> 293 <1> === Switch to base=001140h -> "TABLE" 294 <1> section TABLE ; in DOSDATA 295 <1> PUBLIC CANCHAR 0 000011FA 1B CANCHAR DB CANCEL ;Cancel line character 297 <1> PUBLIC ESCCHAR 0 000011FB 00 ESCCHAR DB ESCCH ;Lead-in character for escape sequences 299 <1> === Switch to base=008400h -> "DOSCODETABLE" 300 <1> section DOSCODETABLE 301 <1> %IFN Rainbow 302 <1> ESCTAB LABEL BYTE 303 <1> %IFN IBM 304 <1> %IF WANG 305 <1> DB 0C0h ; ^Z inserter 306 <1> DB 0C1H ; Copy one char 307 <1> DB 0C1H ; Copy one char 308 <1> DB 0C7H ; Skip one char 309 <1> DB 08AH ; Copy to char 310 <1> DB 088H ; Skip to char 311 <1> DB 09AH ; Copy line 312 <1> DB 0CBH ; Kill line (no change in template) 313 <1> DB 08BH ; Reedit line (new template) 314 <1> DB 0C3H ; Backspace 315 <1> DB 0C6H ; Enter insert mode 316 <1> DB 0D6H ; Exit insert mode 317 <1> DB 0C6H ; Escape character 318 <1> DB 0C6H ; End of table 319 <1> %ELSE 320 <1> ; VT52 equivalences 321 <1> DB "Z" ; ^Z inserter 322 <1> DB "S" ; F1 Copy one char 323 <1> DB "S" ; F1 Copy one char 324 <1> DB "V" ; F4 Skip one char 325 <1> DB "T" ; F2 Copy to char 326 <1> DB "W" ; F5 Skip to char 327 <1> DB "U" ; F3 Copy line 328 <1> DB "E" ; SHIFT ERASE Kill line (no change in template) 329 <1> DB "J" ; ERASE Reedit line (new template) 330 <1> DB "D" ; LEFT Backspace 331 <1> DB "P" ; BLUE Enter insert mode 332 <1> DB "Q" ; RED Exit insert mode 333 <1> DB "R" ; GRAY Escape character 334 <1> DB "R" ; End of table 335 <1> %ENDIF 336 <1> %ENDIF 337 <1> %IF IBM 0 00000457 40 DB 64 ; Ctrl-Z - F6 0 00000458 4D DB 77 ; Copy one char - --> 0 00000459 3B DB 59 ; Copy one char - F1 0 0000045A 53 DB 83 ; Skip one char - DEL 0 0000045B 3C DB 60 ; Copy to char - F2 0 0000045C 3E DB 62 ; Skip to char - F4 0 0000045D 3D DB 61 ; Copy line - F3 0 0000045E 3D DB 61 ; Kill line (no change to template ) - Not used 0 0000045F 3F DB 63 ; Reedit line (new template) - F5 0 00000460 4B DB 75 ; Backspace - <-- 0 00000461 52 DB 82 ; Enter insert mode - INS (toggle) 0 00000462 52 DB 82 ; Exit insert mode - INS (toggle) 0 00000463 41 DB 65 ; Escape character - F7 0 00000464 41 DB 65 ; End of table 352 <1> %ENDIF 353 <1> ESCEND LABEL BYTE 354 <1> ESCTABLEN EQU ESCEND-ESCTAB 355 <1> === Switch to base=001140h -> "DOSDATATABLE" 356 <1> section DOSDATATABLE ; in DOSDATA 357 <1> 358 <1> align 2, db 0 359 <1> ESCFUNC LABEL WORD 0 000011FC [0000] short_addr GETCH ; Ignore the escape sequence 0 000011FE [0000] short_addr TWOESC 0 00001200 [0000] short_addr EXITINS 0 00001202 [0000] short_addr ENTERINS 0 00001204 [0000] short_addr BACKSP 0 00001206 [0000] short_addr REEDIT 0 00001208 [0000] short_addr KILNEW 0 0000120A [0000] short_addr COPYLIN 0 0000120C [0000] short_addr SKIPSTR 0 0000120E [0000] short_addr COPYSTR 0 00001210 [0000] short_addr SKIPONE 0 00001212 [0000] short_addr COPYONE 0 00001214 [0000] short_addr COPYONE 0 00001216 [0000] short_addr CTRLZ 374 <1> %ENDIF 375 <1> 376 <1> %ifndef DONOBITS 377 <1> === Switch to base=008400h -> "DOSCODECODE" 378 <1> section DOSCODECODE ; TABLE ENDS 379 <1> 380 <1> ; 381 <1> ; OEMFunction key is expected to process a single function 382 <1> ; key input from a device and dispatch to the proper 383 <1> ; routines leaving all registers UNTOUCHED. 384 <1> ; 385 <1> ; Inputs: CS, SS are DOSGROUP 386 <1> ; Outputs: None. This function is expected to JMP to one of 387 <1> ; the following labels: 388 <1> ; 389 <1> ; GetCh - ignore the sequence 390 <1> ; TwoEsc - insert an ESCChar in the buffer 391 <1> ; ExitIns - toggle insert mode 392 <1> ; EnterIns - toggle insert mode 393 <1> ; BackSp - move backwards one space 394 <1> ; ReEdit - reedit the line with a new template 395 <1> ; KilNew - discard the current line and start from scratch 396 <1> ; CopyLin - copy the rest of the template into the line 397 <1> ; SkipStr - read the next character and skip to it in the template 398 <1> ; CopyStr - read next char and copy from template to line until char 399 <1> ; SkipOne - advance position in template one character 400 <1> ; CopyOne - copy next character in template into line 401 <1> ; CtrlZ - place a ^Z into the template 402 <1> ; Registers that are allowed to be modified by this function are: 403 <1> ; AX, CX, BP 404 <1> 405 <1> Procedure OEMFunctionKey,NEAR 405 ****************** <1> warning: proc OEMFunctionKey... [-w+user] 406 <1> ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP 407 <1> %IF DBCS ;AN000; 408 <1> extrn intCNE0:near ;AN000; 2/17/KK 409 <1> CALL intCNE0 ;AN000; 2/17/KK 410 <1> %ELSE ;AN000; 0 00000C18 E8[0000] invoke D_std_con_input_no_echo ; Get the second byte of the sequence 412 <1> %ENDIF ;AN000; 413 <1> %IFN Rainbow 0 00000C1B B10E MOV CL,ESCTABLEN ; length of table for scan 0 00000C1D 06 push es 0 00000C1E 57 PUSH DI ; save DI (cannot change it!) 0 00000C1F 0E push cs 0 00000C20 07 pop es 0 00000C21 BF[1500] MOV DI,OFFSET ESCTAB ; offset of second byte table 0 00000C24 F2AE REPNE SCASB ; Look it up in the table 0 00000C26 5F POP DI ; restore DI 0 00000C27 07 pop es 0 00000C28 D1E1 SHL CX,1 ; convert byte offset to word 0 00000C2A 89CD MOV BP,CX ; move to indexable register 0 00000C2C FFA6[0000] JMP [BP+OFFSET ESCFUNC wrt DOSGROUP] ; Go to the right routine 426 <1> %ENDIF 427 <1> %IF Rainbow 428 <1> 429 <1> TransferIf MACRO value,address 430 <1> local a 431 <1> CMP AL,[value] 432 <1> JNZ a 433 <1> transfer address 434 <1> a: 435 <1> ENDM 436 <1> 437 <1> CMP AL,'[' ; is it second lead char 438 <1> JZ EatParm ; yes, go walk tree 439 <1> GoGetCh: 440 <1> transfer GetCh ; no, ignore sequence 441 <1> EatParm: 442 <1> invoke D_std_con_input_no_echo ; get argument 443 <1> CMP AL,'A' ; is it alphabetic arg? 444 <1> JAE EatAlpha ; yes, go snarf one up 445 <1> XOR BP,BP ; init digit counter 446 <1> JMP InDigit ; jump into internal eat digit routine 447 <1> EatNum: 448 <1> invoke D_std_con_input_no_echo ; get next digit 449 <1> InDigit: 450 <1> CMP AL,'9' ; still a digit? 451 <1> JA CheckNumEnd ; no, go check for end char 452 <1> SUB AL,'0' ; turn into potential digit 453 <1> JL GoGetCh ; oops, not a digit, ignore 454 <1> MOV CX,BP ; save BP for 10 multiply 455 <1> CBW ; make AL into AX 456 <1> SHL BP,1 ; 2*BP 457 <1> SHL BP,1 ; 4*BP 458 <1> ADD BP,CX ; 5*BP 459 <1> SHL BP,1 ; 10*BP 460 <1> ADD BP,AX ; 10*BP + digit 461 <1> JMP EatNum ; continue with number 462 <1> CheckNumEnd: 463 <1> CMP AL,7Eh ; is it end char ~ 464 <1> JNZ GoGetCh ; nope, ignore key sequence 465 <1> MOV AX,BP 466 <1> transferIf 1,SkipStr ; FIND key 467 <1> transferIf 2,EnterIns ; INSERT HERE key 468 <1> transferIf 3,SkipOne ; REMOVE 469 <1> transferIf 4,CopyStr ; SELECT 470 <1> transferIf 17,TwoEsc ; INTERRUPT 471 <1> transferIf 18,ReEdit ; RESUME 472 <1> transferIf 19,KilNew ; CANCEL 473 <1> transferIf 21,CtrlZ ; EXIT 474 <1> transferIf 29,CopyLin ; DO 475 <1> JMP GoGetCh 476 <1> EatAlpha: 477 <1> CMP AL,'O' ; is it O? 478 <1> JA GoGetCh ; no, after assume bogus 479 <1> JZ EatPQRS ; eat the rest of the bogus key 480 <1> transferIf 'C',CopyOne ; RIGHT 481 <1> transferIf 'D',BackSp ; LEFT 482 <1> JMP GoGetCh 483 <1> EatPQRS: 484 <1> invoke D_std_con_input_no_echo ; eat char after O 485 <1> JMP GoGetCh 486 <1> %ENDIF 487 <1> 488 <1> EndProc OEMFunctionKey 489 <1> 490 <1> ; (no prior section) ; DOSCODECODE ENDS 491 <1> 492 <1> %endif ; DONOBITS 493 <1> 494 <1> END 20 ;=== Pop trace listing source 21 === Trace listing source: ../DOS/time.lst 1 ; SCCSID = @(#)time.asm 1.1 85/04/10 2 ;TITLE TIME - time and date functions 3 ;NAME TIME 4 ; 5 ; System Calls and low level routines for DATE and TIME 6 ; 7 ; $GET_DATE 8 ; $SET_DATE 9 ; $GET_TIME 10 ; $SET_TIME 11 ; DATE16 12 ; READTIME 13 ; DSLIDE 14 ; SETYEAR 15 ; DODATE 16 ; DSUM 17 ; 18 ; Modification history: 19 ; 20 ; Created: ARR 30 March 1983 21 ; 22 23 [list -] === Switch to base=008400h -> "DOSCODECODE" 30 section DOSCODECODE 31 [list -] 31 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 31 ****************** warning: out: BPB.INC... [-w+user] 31 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 31 ****************** warning: out: DEVSYM.INC... [-w+user] 38 39 40 i_need DAY,BYTE 41 i_need MONTH,BYTE 42 i_need YEAR,WORD 43 i_need WEEKDAY,BYTE 44 i_need TIMEBUF,6 45 i_need BCLOCK,DWORD 46 i_need DAYCNT_DOS,WORD 47 i_need YRTAB,8 48 i_need MONTAB,12 49 i_need DATE_FLAG,WORD 50 51 FOURYEARS equ 3*365 + 366 52 53 ;SUBTTL DATE AND TIME - SYSTEM CALLS 42,43,44,45 54 ;PAGE 55 procedure D_GET_DATE,NEAR 55 ****************** warning: proc D_GET_DATE... [-w+user] 56 ASSUME DS:NOTHING,ES:NOTHING 57 58 ; Inputs: 59 ; None 60 ; Function: 61 ; Return current date 62 ; Returns: 63 ; Date in CX:DX 64 0 00000C30 161F Context DS 0 00000C32 E8B700 CALL READTIME ;Check for rollover to next day 0 00000C35 A1[0000] MOV AX,[YEAR] 68 ; 69 ; WARNING!!!! DAY and MONTH must be adjacently allocated! 70 ; 0 00000C38 8B1E[0000] MOV BX,WORD PTR [DAY] ; fetch both day and month 0 00000C3C E8[0000] invoke get_user_stack ;Get pointer to user registers 73 ASSUME DS:NOTHING 0 00000C3F 895C06 MOV [SI + user_DX],BX ;DH=month, DL=day 0 00000C42 05BC07 ADD AX,1980 ;Put bias back 0 00000C45 894404 MOV [SI + user_CX],AX ;CX=year 0 00000C48 36A0[0000] MOV AL,BYTE PTR [ss:WEEKDAY] 0 00000C4C C3 return 79 EndProc D_GET_DATE 80 81 procedure D_SET_DATE,NEAR ;System call 43 81 ****************** warning: proc D_SET_DATE... [-w+user] 82 ASSUME DS:NOTHING,ES:NOTHING 83 84 ; Inputs: 85 ; CX:DX valid date 86 ; Function: 87 ; Set current date 88 ; Returns: 89 ; AL = -1 date bad, = 0 OK 90 0 00000C4D B0FF MOV AL,-1 ;Be ready to flag error 0 00000C4F 81E9BC07 SUB CX,1980 ;Fix bias in year 0 00000C53 72F7 retc ;Error if not big enough 0 00000C55 83F977 CMP CX,119 ;Year must be less than 2100 0 00000C58 7712 JA RET24 0 00000C5A 08F6 OR DH,DH 0 00000C5C 74EE retz 0 00000C5E 08D2 OR DL,DL 0 00000C60 74EA retz ;Error if either month or day is 0 0 00000C62 80FE0C CMP DH,12 ;Check against max. month 0 00000C65 7705 JA RET24 0 00000C67 161F Context DS 0 00000C69 E81001 invoke DODATE 0 00000C6C C3 RET24: return 105 EndProc D_SET_DATE 106 107 procedure D_GET_TIME,NEAR ;System call 44 107 ****************** warning: proc D_GET_TIME... [-w+user] 108 ASSUME DS:NOTHING,ES:NOTHING 109 110 ; Inputs: 111 ; None 112 ; Function: 113 ; Get current time 114 ; Returns: 115 ; Time in CX:DX 116 0 00000C6D 161F Context DS 0 00000C6F E87A00 CALL READTIME 0 00000C72 E8[0000] invoke get_user_stack ;Get pointer to user registers 0 00000C75 895406 MOV [SI + user_DX],DX 0 00000C78 894C04 MOV [SI + user_CX],CX 0 00000C7B 30C0 XOR AL,AL 0 00000C7D C3 RET26: return 124 EndProc D_GET_TIME 125 126 procedure D_SET_TIME,NEAR ;System call 45 126 ****************** warning: proc D_SET_TIME... [-w+user] 127 ASSUME DS:NOTHING,ES:NOTHING 128 129 ; Inputs: 130 ; CX:DX = Time 131 ; Function: 132 ; Set time 133 ; Returns: 134 ; AL = -1 time bad, = 0 OK 135 0 00000C7E B0FF MOV AL,-1 ;Flag in case of error 0 00000C80 80FD18 CMP CH,24 ;Check hours 0 00000C83 73F8 JAE RET26 0 00000C85 80F93C CMP CL,60 ;Check minutes 0 00000C88 73F3 JAE RET26 0 00000C8A 80FE3C CMP DH,60 ;Check seconds 0 00000C8D 73EE JAE RET26 0 00000C8F 80FA64 CMP DL,100 ;Check 1/100's 0 00000C92 73E9 JAE RET26 0 00000C94 51 PUSH CX 0 00000C95 52 PUSH DX 0 00000C96 161F Context DS 0 00000C98 BB[0000] MOV BX,OFFSET TIMEBUF wrt DOSGROUP 0 00000C9B B90600 MOV CX,6 0 00000C9E 31D2 XOR DX,DX 0 00000CA0 89D0 MOV AX,DX 0 00000CA2 53 PUSH BX 0 00000CA3 E8[0000] invoke SETREAD 154 DOSAssume CS,,"TIME/SetRead" 0 00000CA6 1E PUSH DS 0 00000CA7 C536[0000] LDS SI,[BCLOCK] 157 ASSUME DS:NOTHING 0 00000CAB E8[0000] invoke DEVIOCALL2 ;Get correct day count 0 00000CAE 1F POP DS 160 DOSAssume CS,,"TIME/DevIOCall2" 0 00000CAF 5B POP BX 0 00000CB0 E8[0000] invoke SETWRITE 0 00000CB3 8F06[0400] POP WORD PTR [TIMEBUF+4] 0 00000CB7 8F06[0200] POP WORD PTR [TIMEBUF+2] 0 00000CBB C536[0000] LDS SI,[BCLOCK] 166 ASSUME DS:NOTHING 0 00000CBF E8[0000] invoke DEVIOCALL2 ;Set the time 0 00000CC2 30C0 XOR AL,AL 0 00000CC4 C3 return 170 EndProc D_SET_TIME 171 172 ;SUBTTL DATE16, READTIME, DODATE -- GUTS OF TIME AND DATE 173 ;PAGE 174 175 ; 176 ; Date16 returns the current date in AX, current time in DX 177 ; AX - YYYYYYYMMMMDDDDD years months days 178 ; DX - HHHHHMMMMMMSSSSS hours minutes seconds/2 179 ; 180 ; DS = DOSGROUP on output 181 182 procedure DATE16,NEAR 182 ****************** warning: proc DATE16... [-w+user] 0 00000CC5 161F Context DS 184 ASSUME ES:NOTHING 0 00000CC7 51 PUSH CX 0 00000CC8 06 PUSH ES 0 00000CC9 E82000 CALL READTIME 0 00000CCC 07 POP ES 0 00000CCD D0E1 SHL CL,1 ;Minutes to left part of byte 0 00000CCF D0E1 SHL CL,1 0 00000CD1 D1E1 SHL CX,1 ;Push hours and minutes to left end 0 00000CD3 D1E1 SHL CX,1 0 00000CD5 D1E1 SHL CX,1 0 00000CD7 D0EE SHR DH,1 ;Count every two seconds 0 00000CD9 08F1 OR CL,DH ;Combine seconds with hours and minutes 0 00000CDB 89CA MOV DX,CX 197 ; 198 ; WARNING! MONTH and YEAR must be adjacently allocated 199 ; 0 00000CDD A1[0000] MOV AX,WORD PTR [MONTH] ;Fetch month and year 0 00000CE0 B104 MOV CL,4 0 00000CE2 D2E0 SHL AL,CL ;Push month to left to make room for day 0 00000CE4 D1E0 SHL AX,1 0 00000CE6 59 POP CX 0 00000CE7 0A06[0000] OR AL,[DAY] 0 00000CEB C3 return 207 EndProc DATE16 208 209 ;Gets time in CX:DX. Figures new date if it has changed. 210 ;Uses AX, CX, DX. 211 212 procedure READTIME,NEAR 212 ****************** warning: proc READTIME... [-w+user] 213 DOSAssume CS,,"ReadTime" 214 ASSUME ES:NOTHING 215 0 00000CEC C706[0000]0000 MOV word [DATE_FLAG],0 ; reset date flag for CPMIO 0 00000CF2 56 PUSH SI 0 00000CF3 53 PUSH BX 0 00000CF4 BB[0000] MOV BX,OFFSET TIMEBUF wrt DOSGROUP 0 00000CF7 B90600 MOV CX,6 0 00000CFA 31D2 XOR DX,DX 0 00000CFC 89D0 MOV AX,DX 0 00000CFE E8[0000] invoke SETREAD 0 00000D01 1E PUSH DS 0 00000D02 C536[0000] LDS SI,[BCLOCK] 226 ASSUME DS:NOTHING 0 00000D06 E8[0000] invoke DEVIOCALL2 ;Get correct date and time 0 00000D09 1F POP DS 229 DOSAssume CS,,"ReadTime/DevIOCall2" 0 00000D0A 5B POP BX 0 00000D0B 5E POP SI 0 00000D0C A1[0000] MOV AX,WORD PTR [TIMEBUF] 0 00000D0F 8B0E[0200] MOV CX,WORD PTR [TIMEBUF+2] 0 00000D13 8B16[0400] MOV DX,WORD PTR [TIMEBUF+4] 0 00000D17 3B06[0000] CMP AX,[DAYCNT_DOS] ;See if day count is the same 0 00000D1B 74CE retz 0 00000D1D 3D36AB CMP AX,FOURYEARS*30 ;Number of days in 120 years 0 00000D20 733D JAE RET22 ;Ignore if too large 0 00000D22 A3[0000] MOV [DAYCNT_DOS],AX 0 00000D25 56 PUSH SI 0 00000D26 51 PUSH CX 0 00000D27 52 PUSH DX ;Save time 0 00000D28 31D2 XOR DX,DX 0 00000D2A B9B505 MOV CX,FOURYEARS ;Number of days in 4 years 0 00000D2D F7F1 DIV CX ;Compute number of 4-year units 0 00000D2F D1E0 SHL AX,1 0 00000D31 D1E0 SHL AX,1 0 00000D33 D1E0 SHL AX,1 ;Multiply by 8 (no. of half-years) 0 00000D35 89C1 MOV CX,AX ;<240 implies AH=0 0 00000D37 BE[0000] MOV SI,OFFSET YRTAB wrt DOSGROUP;Table of days in each year 0 00000D3A E82300 CALL DSLIDE ;Find out which of four years we're in 0 00000D3D D1E9 SHR CX,1 ;Convert half-years to whole years 0 00000D3F 7304 JNC SK ;Extra half-year? 0 00000D41 81C2C800 ADD DX,200 255 SK: 0 00000D45 E82400 CALL SETYEAR 0 00000D48 B101 MOV CL,1 ;At least at first month in year 0 00000D4A BE[0000] MOV SI,OFFSET MONTAB wrt DOSGROUP ;Table of days in each month 0 00000D4D E81000 CALL DSLIDE ;Find out which month we're in 0 00000D50 880E[0000] MOV [MONTH],CL 0 00000D54 42 INC DX ;Remainder is day of month (start with one) 0 00000D55 8816[0000] MOV [DAY],DL 0 00000D59 E89100 CALL WKDAY ;Set day of week 0 00000D5C 5A POP DX 0 00000D5D 59 POP CX 0 00000D5E 5E POP SI 0 00000D5F C3 RET22: return 268 EndProc READTIME 269 270 procedure DSLIDE,NEAR 270 ****************** warning: proc DSLIDE... [-w+user] 0 00000D60 B400 MOV AH,0 272 DSLIDE1: 0 00000D62 AC LODSB ;Get count of days 0 00000D63 39C2 CMP DX,AX ;See if it will fit 0 00000D65 72F8 retc ;If not, done 0 00000D67 29C2 SUB DX,AX 0 00000D69 41 INC CX ;Count one more month/year 0 00000D6A EBF6 JMP SHORT DSLIDE1 279 EndProc DSLIDE 280 281 procedure SETYEAR,NEAR 281 ****************** warning: proc SETYEAR... [-w+user] 282 ;Set year with value in CX. Adjust length of February for this year. 0 00000D6C 880E[0000] MOV BYTE PTR [YEAR],CL 284 285 CHKYR: 0 00000D70 F6C103 TEST CL,3 ;Check for leap year 0 00000D73 B01C MOV AL,28 0 00000D75 7501 JNZ SAVFEB ;28 days if no leap year 0 00000D77 40 inc ax ;Add leap day 290 SAVFEB: 0 00000D78 A2[0100] MOV [MONTAB+1],AL ;Store for February 0 00000D7B C3 RET23: return 293 EndProc SETYEAR 294 295 procedure DODATE,NEAR 295 ****************** warning: proc DODATE... [-w+user] 296 DOSAssume CS,,"DoDate" 297 ASSUME ES:NOTHING 0 00000D7C E8F1FF CALL CHKYR ;Set Feb. up for new year 0 00000D7F 88F0 MOV AL,DH 0 00000D81 BB[FFFF] MOV BX,OFFSET MONTAB-1 wrt DOSGROUP 0 00000D84 D7 xlatb;Look up days in month 0 00000D85 38D0 CMP AL,DL 0 00000D87 B0FF MOV AL,-1 ;Restore error flag, just in case 0 00000D89 72F0 retc ;Error if too many days 0 00000D8B E8DEFF CALL SETYEAR 306 ; 307 ; WARNING! DAY and MONTH must be adjacently allocated 308 ; 0 00000D8E 8916[0000] MOV WORD PTR [DAY],DX ;Set both day and month 0 00000D92 D1E9 SHR CX,1 0 00000D94 D1E9 SHR CX,1 0 00000D96 B8B505 MOV AX,FOURYEARS 0 00000D99 89D3 MOV BX,DX 0 00000D9B F7E1 MUL CX 0 00000D9D 8A0E[0000] MOV CL,BYTE PTR [YEAR] 0 00000DA1 80E103 AND CL,3 0 00000DA4 BE[0000] MOV SI,OFFSET YRTAB wrt DOSGROUP 0 00000DA7 89C2 MOV DX,AX 0 00000DA9 D1E1 SHL CX,1 ;Two entries per year, so double count 0 00000DAB E85200 CALL DSUM ;Add up the days in each year 0 00000DAE 88F9 MOV CL,BH ;Month of year 0 00000DB0 BE[0000] MOV SI,OFFSET MONTAB wrt DOSGROUP 0 00000DB3 49 DEC CX ;Account for months starting with one 0 00000DB4 E84900 CALL DSUM ;Add up days in each month 0 00000DB7 88D9 MOV CL,BL ;Day of month 0 00000DB9 49 DEC CX ;Account for days starting with one 0 00000DBA 01CA ADD DX,CX ;Add in to day total 0 00000DBC 92 XCHG AX,DX ;Get day count in AX 0 00000DBD A3[0000] MOV [DAYCNT_DOS],AX 0 00000DC0 56 PUSH SI 0 00000DC1 53 PUSH BX 0 00000DC2 50 PUSH AX 0 00000DC3 BB[0000] MOV BX,OFFSET TIMEBUF wrt DOSGROUP 0 00000DC6 B90600 MOV CX,6 0 00000DC9 31D2 XOR DX,DX 0 00000DCB 89D0 MOV AX,DX 0 00000DCD 53 PUSH BX 0 00000DCE E8[0000] invoke SETREAD 339 DOSAssume CS,,"DoDate/SetRead" 0 00000DD1 1E PUSH DS 0 00000DD2 C536[0000] LDS SI,[BCLOCK] 342 ASSUME DS:NOTHING 0 00000DD6 E8[0000] invoke DEVIOCALL2 ;Get correct date and time 0 00000DD9 1F POP DS 0 00000DDA 5B POP BX 346 DOSAssume CS,,"DoDate/DevIOCall2" 0 00000DDB E8[0000] invoke SETWRITE 0 00000DDE 8F06[0000] POP WORD PTR [TIMEBUF] 0 00000DE2 1E PUSH DS 0 00000DE3 C536[0000] LDS SI,[BCLOCK] 351 ASSUME DS:NOTHING 0 00000DE7 E8[0000] invoke DEVIOCALL2 ;Set the date 0 00000DEA 1F POP DS 354 DOSAssume CS,,"DoDate/DevIOCall2(second)" 0 00000DEB 5B POP BX 0 00000DEC 5E POP SI 357 WKDAY: 0 00000DED A1[0000] MOV AX,[DAYCNT_DOS] 0 00000DF0 31D2 XOR DX,DX 0 00000DF2 B90700 MOV CX,7 0 00000DF5 40 INC AX 0 00000DF6 40 INC AX ;First day was Tuesday 0 00000DF7 F7F1 DIV CX ;Compute day of week 0 00000DF9 8816[0000] MOV [WEEKDAY],DL 0 00000DFD 30C0 XOR AL,AL ;Flag OK 0 00000DFF C3 Ret25: return 367 EndProc DODATE 368 369 procedure DSUM,NEAR 369 ****************** warning: proc DSUM... [-w+user] 0 00000E00 B400 MOV AH,0 371 RET25 equ Ret25 ; NASM port label 0 00000E02 E3FB JCXZ RET25 373 DSUM1: 0 00000E04 AC LODSB 0 00000E05 01C2 ADD DX,AX 0 00000E07 E2FB LOOP DSUM1 0 00000E09 C3 return 378 EndProc DSUM 379 380 END 381 382 === Trace listing source: ../DOS/getset.lst 1 ; SCCSID = @(#)getset.asm 1.2 85/07/23 2 ;TITLE GETSET - GETting and SETting MS-DOS system calls 3 ;NAME GETSET 4 ; 5 ; System Calls which get and set various things 6 ; 7 ; $GET_VERSION 8 ; $GET_VERIFY_ON_WRITE 9 ; $SET_VERIFY_ON_WRITE 10 ; $INTERNATIONAL 11 ; $GET_DRIVE_FREESPACE 12 ; $GET_DMA 13 ; $SET_DMA 14 ; $GET_DEFAULT_DRIVE 15 ; $SET_DEFAULT_DRIVE 16 ; $GET_INTERRUPT_VECTOR 17 ; $SET_INTERRUPT_VECTOR 18 ; RECSET 19 ; $CHAR_OPER 20 ; $GetExtendedError DOS 3.3 21 ; Get_Global_CdPg DOS 4.0 22 ; $ECS_CALL DOS 4.0 23 ; 24 ; Revision history: 25 ; 26 ; Created: ARR 30 March 1983 27 ; 28 ; A000 version 4.0 Jan. 1988 29 ; A006 D503-- fake version for IBMCACHE 30 ; A008 P4070- faske version for MS WINDOWS 31 32 [list -] === Switch to base=008400h -> "DOSCODECODE" 43 section DOSCODECODE 44 [list -] 44 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 44 ****************** warning: out: BPB.INC... [-w+user] 44 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 44 ****************** warning: out: DEVSYM.INC... [-w+user] 52 53 i_need USERNUM,WORD 54 i_need MSVERS,WORD 55 I_need doslocation3001, byte 56 i_need VERFLG,BYTE 57 i_need CNTCFLAG,BYTE 58 i_need DMAADD,DWORD 59 i_need CURDRV,BYTE 60 i_need chSwitch,BYTE 61 i_need COUNTRY_CDPG,byte ;DOS 3.3 62 I_need CDSCount,BYTE 63 I_need ThisCDS,DWORD 64 i_need EXTERR,WORD 65 i_need EXTERR_ACTION,BYTE 66 i_need EXTERR_CLASS,BYTE 67 i_need EXTERR_LOCUS,BYTE 68 i_need EXTERRPT,DWORD 69 i_need UCASE_TAB,BYTE 70 i_need FILE_UCASE_TAB,BYTE 71 i_need InterCon,BYTE 72 i_need CURRENTPDB,WORD 73 i_need DBCS_TAB,BYTE ;AN000; 74 i_need Special_version,WORD ;AN006; 75 i_need Fake_Count,BYTE ;AN008; 76 i_need NLS_YES,BYTE ;AN000; 77 i_need NLS_yes2,BYTE ;AN000; 78 i_need NLS_NO,BYTE ;AN000; 79 i_need NLS_no2,BYTE ;AN000; 80 81 82 BREAK <$Get_Version -- Return DOS version number> 83 procedure D_GET_VERSION,NEAR 83 ****************** warning: proc D_GET_VERSION... [-w+user] 84 ASSUME DS:NOTHING,ES:NOTHING 85 86 ; Inputs: 87 ; None 88 ; Function: 89 ; Return DOS version number 90 ; Outputs: 91 ; OEM number in BH 92 ; User number in BL:CX (24 bits) 93 ; Version number as AL.AH in binary 94 ; NOTE: On pre 1.28 DOSs AL will be zero 95 0 00000E0A 161F context DS 0 00000E0C 8B1E[0200] MOV BX,[USERNUM + 2] 0 00000E10 8B0E[0000] MOV CX,[USERNUM] 0 00000E14 3C01 cmp al, 1 0 00000E16 7504 jne .use_oem_id 0 00000E18 8A3E[0000] mov bh, [doslocation3001] 102 .use_oem_id: 0 00000E1C A1[0000] MOV AX,[MSVERS] 0 00000E1F E8[0000] invoke get_user_stack 105 ASSUME DS:NOTHING 0 00000E22 895C02 MOV [SI + user_BX],BX 0 00000E25 894C04 MOV [SI + user_CX],CX 0 00000E28 36803E[0000]FF CMP byte [ss:Fake_Count],0FFH ;AN008; 0 00000E2E 740D JZ reg ;AN008; 0 00000E30 36803E[0000]00 CMP byte [ss:Fake_Count],0 ;AN008; 0 00000E36 7411 JZ usual ;AN008; 0 00000E38 36FE0E[0000] DEC byte [ss:Fake_Count] ;AN008; 113 reg: ;AN008; 0 00000E3D 36833E[0000]00 CMP word [ss:Special_version],0 ;AN006; 0 00000E43 7404 JZ usual ;AN006; 0 00000E45 36A1[0000] MOV AX,[ss:Special_version] ;AN006; 117 usual: ;AN006; 0 00000E49 8904 MOV [SI + user_AX],AX ; Really only sets AH 0 00000E4B C3 return 120 EndProc D_GET_VERSION 121 122 BREAK <$Get_Verify_on_Write - return verify-after-write flag> 123 procedure D_GET_VERIFY_ON_WRITE,NEAR 123 ****************** warning: proc D_GET_VERIFY_ON_WRITE... [-w+user] 124 ASSUME DS:NOTHING,ES:NOTHING 125 126 ; Inputs: 127 ; none. 128 ; Function: 129 ; returns flag 130 ; Returns: 131 ; AL = value of VERIFY flag 132 0 00000E4C 36A0[0000] MOV AL,[ss:VERFLG] 0 00000E50 C3 return 135 EndProc D_GET_VERIFY_ON_WRITE 136 137 BREAK <$Set_Verify_on_Write - Toggle verify-after-write flag> 138 procedure D_SET_VERIFY_ON_WRITE,NEAR 138 ****************** warning: proc D_SET_VERIFY_ON_WRITE... [-w+user] 139 ASSUME DS:NOTHING,ES:NOTHING 140 141 ; Inputs: 142 ; AL = desired value of VERIFY flag 143 ; Function: 144 ; Sets flag 145 ; Returns: 146 ; None 147 0 00000E51 2401 AND AL,1 0 00000E53 36A2[0000] MOV [ss:VERFLG],AL 0 00000E57 C3 return 151 EndProc D_SET_VERIFY_ON_WRITE 152 153 BREAK <$International - return country-dependent information> 154 ; 155 ; Inputs: 156 ; MOV AH,International 157 ; MOV AL,country (al = 0 => current country) 158 ; [MOV BX,country] 159 ; LDS DX,block 160 ; INT 21 161 ; Function: 162 ; give users an idea of what country the application is running 163 ; Outputs: 164 ; IF DX != -1 on input (get country) 165 ; AL = 0 means return current country table. 166 ; 0 internat_block_max, 177 ; in the correct order for being returned by the 178 ; INTERNATIONAL call as follows: 179 ; WORD Date format 0=mdy, 1=dmy, 2=ymd 180 ; 5 BYTE Currency symbol null terminated 181 ; 2 BYTE thousands separator null terminated 182 ; 2 BYTE Decimal point null terminated 183 ; 2 BYTE Date separator null terminated 184 ; 2 BYTE Time separator null terminated 185 ; 1 BYTE Bit field. Currency format. 186 ; Bit 0. =0 $ before # =1 $ after # 187 ; Bit 1. no. of spaces between # and $ (0 or 1) 188 ; 1 BYTE No. of significant decimal digits in currency 189 ; 1 BYTE Bit field. Time format. 190 ; Bit 0. =0 12 hour clock =1 24 hour 191 ; DWORD Call address of case conversion routine 192 ; 2 BYTE Data list separator null terminated. 193 ; Carry: 194 ; Register AX has the error code. 195 ; IF DX = -1 on input (set current country) 196 ; AL = 0 is an error 197 ; 0 292 ; 293 ; Inputs: 294 ; if AL >= 20H 295 ; AL= 20H capitalize single char, DL= char 296 ; 21H capitalize string ,CX= string length 297 ; 22H capitalize ASCIIZ string 298 ; 23H YES/NO check, DL=1st char DH= 2nd char (DBCS) 299 ; 80H bit 0 = use normal upper case table 300 ; 1 = use file upper case table 301 ; DS:DX points to string 302 ; 303 ; else 304 ; 305 ; MOV AH,GetExtCntry ; DOS 3.3 306 ; MOV AL,INFO_ID ( info type,-1 selects all) 307 ; MOV BX,CODE_PAGE ( -1 = active code page ) 308 ; MOV DX,COUNTRY_ID ( -1 = active country ) 309 ; MOV CX,SIZE ( amount of data to return) 310 ; LES DI,COUNTRY_INFO ( buffer for returned data ) 311 ; INT 21 312 ; Function: 313 ; give users extended country dependent information 314 ; or capitalize chars 315 ; Outputs: 316 ; No Carry: 317 ; extended country info is succesfully returned 318 ; Carry: 319 ; Register AX has the error code. 320 ; AX=0, NO for YES/NO CHECK 321 ; 1, YES 322 323 324 procedure D_GetExtCntry,NEAR ; DOS 3.3 324 ****************** warning: proc D_GetExtCntry... [-w+user] 325 ASSUME DS:NOTHING,ES:NOTHING 0 00000EDF 3C20 CMP AL,CAP_ONE_CHAR ;AN000;MS. < 20H ? 0 00000EE1 7303 JAE capcap ;AN000;MS. 0 00000EE3 EB6B JMP notcap ;AN000;MS. yes 0 00000EE5 90 nop ; identicalise 330 capcap: ;AN000; 0 00000EE6 A880 TEST AL,UPPER_TABLE ;AN000;MS. which upper case table 0 00000EE8 7505 JNZ fileupper ;AN000;MS. file upper case 0 00000EEA BB[0200] MOV BX,OFFSET UCASE_TAB+2 wrt DOSGROUP ;AN000;MS. get normal upper case 0 00000EED EB03 JMP SHORT capit ;AN000;MS. 335 fileupper: ;AN000; 0 00000EEF BB[0200] MOV BX,OFFSET FILE_UCASE_TAB+2 wrt DOSGROUP;AN000;MS. get file upper case 337 capit: ;AN000; 0 00000EF2 3C20 CMP AL,CAP_ONE_CHAR ;AN000;;MS.cap one char ? 0 00000EF4 750D JNZ chkyes ;AN000;;MS. no 0 00000EF6 88D0 MOV AL,DL ;AN000;;MS. set up AL 0 00000EF8 E8[0000] invoke GETLET3 ;AN000;;MS. upper case it 0 00000EFB E8[0000] invoke get_user_stack ;AN000;;MS. get user stack 0 00000EFE 884406 MOV byte ptr [SI + user_DX],AL;AN000;;MS. user's DL=AL 0 00000F01 EB24 JMP SHORT nono ;AN000;;MS. done 345 chkyes: ;AN000; 0 00000F03 3C23 CMP AL,CHECK_YES_NO ;AN000;;MS. check YES or NO ? 0 00000F05 7522 JNZ capstring ;AN000;;MS. no 0 00000F07 31C0 XOR AX,AX ;AN000;;MS. presume NO 349 %IF DBCS ;AN000; 350 PUSH AX ;AN000;;MS. 351 MOV AL,DL ;AN000;;MS. 352 invoke TESTKANJ ;AN000;;MS. DBCS ? 353 POP AX ;AN000;;MS. 354 JNZ dbcs_char ;AN000;;MS. yes, return error 355 %ENDIF ;AN000; 356 ;AN000; 0 00000F09 363A16[0000] CMP DL,[ss:NLS_YES] ;AN000;;MS. is 'Y' ? 0 00000F0E 7416 JZ yesyes ;AN000;;MS. yes 0 00000F10 363A16[0000] CMP DL,[ss:NLS_yes2] ;AN000;;MS. is 'y' ? 0 00000F15 740F JZ yesyes ;AN000;;MS. yes 0 00000F17 363A16[0000] CMP DL,[ss:NLS_NO] ;AN000;;MS. is 'N'? 0 00000F1C 7409 JZ nono ;AN000;;MS. no 0 00000F1E 363A16[0000] CMP DL,[ss:NLS_no2] ;AN000;;MS. is 'n' ? 0 00000F23 7402 JZ nono ;AN000;;MS. no 365 dbcs_char: ;AN000; 0 00000F25 40 INC AX ;AN000;;MS. not YES or NO 367 yesyes: ;AN000' 0 00000F26 40 INC AX ;AN000;;MS. return 1 369 nono: ;AN000; 0 00000F27 EBA0 transfer SYS_RET_OK ;AN000;;MS. done 371 capstring: ;AN000; 0 00000F29 89D6 MOV SI,DX ;AN000;;MS. si=dx 0 00000F2B 3C21 CMP AL,CAP_STRING ;AN000;;MS. cap string ? 0 00000F2D 7510 JNZ capascii ;AN000;;MS. no 0 00000F2F 83F900 CMP CX,0 ;AN000;;MS. check count 0 0 00000F32 74F3 JZ nono ;AN000;;MS. yes finished 377 concap: ;AN000; 0 00000F34 AC LODSB ;AN000;;MS. get char 379 %IF DBCS ;AN000;;MS. 380 invoke TESTKANJ ;AN000;;MS. DBCS ? 381 JZ notdbcs ;AN000;;MS. no 382 INC SI ;AN000;;MS. skip 2 chars 383 DEC CX ;AN000;;MS. bad input, one DBCS char at end 384 JZ nono ;AN000;;MS. yes 385 JMP SHORT next99 ;AN000;;MS. 386 notdbcs: ;AN000; 387 %ENDIF ;AN000; 388 0 00000F35 E8[0000] invoke GETLET3 ;AN000;;MS. upper case it 0 00000F38 8844FF MOV byte ptr [SI-1],AL ;AN000;;MS. store back 391 next99: ;AN000; 0 00000F3B E2F7 LOOP concap ;AN000;;MS. continue 0 00000F3D EBE8 JMP nono ;AN000;;MS. done 394 capascii: ;AN000; 0 00000F3F 3C22 CMP AL,CAP_ASCIIZ ;AN000;;MS. cap ASCIIZ string ? 0 00000F41 7545 JNZ capinval ;AN000;;MS. no 397 concap2: ;AN000; 0 00000F43 AC LODSB ;AN000;;MS. get char 0 00000F44 3C00 CMP AL,0 ;AN000;;MS. end of string ? 0 00000F46 74DF JZ nono ;AN000;;MS. yes 401 %IF DBCS ;AN000;;MS. 402 invoke TESTKANJ ;AN000;;MS. DBCS ? 403 JZ notdbcs2 ;AN000;;MS. no 404 CMP BYTE PTR [SI],0 ;AN000;;MS. bad input, one DBCS char at end 405 JZ nono ;AN000;;MS. yes 406 INC SI ;AN000;;MS. skip 2 chars 407 JMP concap2 ;AN000;;MS. 408 notdbcs2: ;AN000; 409 %ENDIF ;AN000; 0 00000F48 E8[0000] invoke GETLET3 ;AN000;;MS. upper case it 0 00000F4B 8844FF MOV byte ptr [SI-1],AL ;AN000;;MS. store back 0 00000F4E EBF3 JMP concap2 ;AN000;;MS. continue 413 414 415 notcap: 0 00000F50 83F905 CMP CX,5 ; minimum size is 5 0 00000F53 7278 JB sizeerror 0 00000F55 161F context DS 0 00000F57 BE[0000] MOV SI,OFFSET COUNTRY_CDPG wrt DOSGROUP 0 00000F5A 83FAFF CMP DX,-1 ; active country ? 0 00000F5D 7503 JNZ GETCDPG ; no 0 00000F5F 8B5468 MOV DX,[SI + ccDosCountry] ; get active country id 423 GETCDPG: 0 00000F62 83FBFF CMP BX,-1 ; active code page? 0 00000F65 7503 JNZ CHKAGAIN ; no, check again 0 00000F67 8B5C6A MOV BX,[SI + ccDosCodePage] ; get active code page id 427 CHKAGAIN: 0 00000F6A 3B5468 CMP DX,[SI + ccDosCountry] ; same as active country id? 0 00000F6D 7551 JNZ CHKNLS ; no 0 00000F6F 3B5C6A CMP BX,[SI + ccDosCodePage] ; same as active code page id? 0 00000F72 754C JNZ CHKNLS ; no 432 CHKTYPE: 0 00000F74 8B5C48 MOV BX,[SI + ccSysCodePage] ; bx = sys code page id 434 ; CMP AL,SetALL ; select all? 435 ; JNZ SELONE 436 ; MOV SI,OFFSET COUNTRY_CDPG + ccNumber_of_entries wrt DOSGROUP 437 SELONE: 0 00000F77 51 PUSH CX ; save cx 0 00000F78 8B4C4A MOV CX,[SI + ccNumber_of_entries] 0 00000F7B BE[4C00] MOV SI,OFFSET COUNTRY_CDPG + ccSetUcase wrt DOSGROUP 441 NXTENTRY: 0 00000F7E 3A04 CMP AL,[SI] ; compare info type 0 00000F80 740B JZ FOUNDIT 0 00000F82 83C605 ADD SI,5 ; next entry 0 00000F85 E2F7 LOOP NXTENTRY 0 00000F87 59 POP CX 447 capinval: 0 00000F88 B001E9[0000] error error_Invalid_Function ; info type not found 449 FOUNDIT: 0 00000F8D A4 MOVSB ; move info id byte 0 00000F8E 59 POP CX ; retsore char count 0 00000F8F 3C01 CMP AL,SetCountryInfo ; select country info type ? 0 00000F91 7414 JZ setsize 0 00000F93 B90400 MOV CX,4 ; 4 bytes will be moved 0 00000F96 B80500 MOV AX,5 ; 5 bytes will be returned in CX 456 OK_RETN: 0 00000F99 F3A4 REP MOVSB ; copy info 0 00000F9B 89C1 MOV CX,AX ; CX = actual length returned 0 00000F9D 89D8 MOV AX,BX ; return sys code page in ax 460 GETDONE: 0 00000F9F E8[0000] invoke get_user_stack ; return actual length to user's CX 0 00000FA2 894C04 MOV [SI + user_CX],CX 0 00000FA5 EB80 transfer SYS_RET_OK 464 setsize: 0 00000FA7 83E903 SUB CX,3 ; size after length field 0 00000FAA 390C CMP WORD PTR [SI],CX ; less than table size 0 00000FAC 7302 JAE setsize2 ; no 0 00000FAE 8B0C MOV CX,WORD PTR [SI] ; truncate to table size 469 setsize2: 0 00000FB0 26890D MOV [ES:DI],CX ; copy actual length to user's 0 00000FB3 83C702 ADD DI,2 ; update index 0 00000FB6 83C602 ADD SI,2 0 00000FB9 89C8 MOV AX,CX 0 00000FBB 83C003 ADD AX,3 ; AX has the actual length 0 00000FBE EBD9 JMP OK_RETN ; go move it 476 CHKNLS: 0 00000FC0 30E4 XOR AH,AH 0 00000FC2 50 PUSH AX ; save info type 0 00000FC3 5D POP BP ; bp = info type 0 00000FC4 B80014CD2F CallInstall NLSInstall,NLSFUNC,0 ; check if NLSFUNC in memory 0 00000FC9 3CFF CMP AL,0FFH 0 00000FCB 7404 JZ NLSNXT ; in memory 483 sizeerror: 0 00000FCD B001EBB9 error error_Invalid_Function 0 00000FD1 B80214CD2F NLSNXT: CallInstall GetExtInfo,NLSFUNC,2 ;get extended info 0 00000FD6 3C00 CMP AL,0 ; success ? 0 00000FD8 7505 JNZ NLSERROR 0 00000FDA 8B4448 MOV AX,[SI + ccSysCodePage] ; ax = sys code page id 0 00000FDD EBC0 JMP GETDONE 490 NLSERROR: 0 00000FDF EBEE transfer SYS_RET_ERR ; return what is got from NLSFUNC 492 493 EndProc D_GetExtCntry 494 495 BREAK <$GetSetCdPg - get or set global code page> 496 ; 497 ; Inputs: 498 ; MOV AH,GetSetCdPg ; DOS 3.3 499 ; MOV AL,n ; n = 1 : get code page, n = 2 : set code page 500 ; MOV BX,CODE_PAGE ( set code page only) 501 ; INT 21 502 ; Function: 503 ; get or set the global code page 504 ; Outputs: 505 ; No Carry: 506 ; global code page is set (set global code page) 507 ; BX = active code page id (get global code page) 508 ; DX = system code page id (get global code page) 509 ; Carry: 510 ; Register AX has the error code. 511 512 513 procedure D_GetSetCdPg,NEAR ; DOS 3.3 513 ****************** warning: proc D_GetSetCdPg... [-w+user] 514 ASSUME DS:NOTHING,ES:NOTHING 0 00000FE1 161F context DS 0 00000FE3 BE[0000] MOV SI,OFFSET COUNTRY_CDPG wrt DOSGROUP 0 00000FE6 3C01 CMP AL,1 ; get global code page 0 00000FE8 7511 JNZ setglpg ; set global cod epage 0 00000FEA 8B5C6A MOV BX,[SI + ccDosCodePage] ; get active code page id 0 00000FED 8B5448 MOV DX,[SI + ccSysCodePage] ; get sys code page id 0 00000FF0 E8[0000] invoke get_user_stack 522 ASSUME DS:NOTHING 0 00000FF3 895C02 MOV [SI + user_BX],BX ; update returned bx 0 00000FF6 895406 MOV [SI + user_DX],DX ; update returned dx 525 OK_RETURN: 0 00000FF9 EBAA transfer SYS_RET_OK 527 ASSUME DS:DOSGROUP 528 setglpg: 0 00000FFB 3C02 CMP AL,2 0 00000FFD 7533 JNZ nomem 531 ;;;;;;; CMP BX,[SI.ccDosCodePage] ; same as active code page 532 ;;;;;;; JZ OK_RETURN ; yes 0 00000FFF 8B5468 MOV DX,[SI + ccDosCountry] 0 00001002 B80014CD2F CallInstall NLSInstall,NLSFUNC,0 ; check if NLSFUNC in memory 0 00001007 3CFF CMP AL,0FFH 0 00001009 7527 JNZ nomem ; not in memory 0 0000100B B80114CD2F CallInstall SetCodePage,NLSFUNC,1 ;set the code page 0 00001010 3C00 CMP AL,0 ; success ? 0 00001012 74E5 JZ OK_RETURN ; yes 0 00001014 3C41 CMP AL,65 ; set device code page failed 0 00001016 7518 JNZ seterr 0 00001018 B84100 MOV AX,65 0 0000101B A3[0000] MOV [EXTERR],AX 0 0000101E C606[0000]06 MOV byte [EXTERR_ACTION],errACT_Ignore 0 00001023 C606[0000]05 MOV byte [EXTERR_CLASS],errCLASS_HrdFail 0 00001028 C606[0000]04 MOV byte [EXTERR_LOCUS],errLOC_SerDev 0 0000102D E9[0000] transfer From_GetSet 548 549 seterr: 0 00001030 EBAD transfer SYS_RET_ERR 551 nomem: 0 00001032 B001EBFA error error_Invalid_Function ; function not defined 553 ; 554 EndProc D_GetSetCdPg 555 556 557 558 559 BREAK <$Get_Drive_Freespace -- Return bytes of free disk space on a drive> 560 procedure D_GET_DRIVE_FREESPACE,NEAR 560 ****************** warning: proc D_GET_DRIVE_FREESPACE... [-w+user] 561 ASSUME DS:NOTHING,ES:NOTHING 562 563 ; Inputs: 564 ; DL = Drive number 565 ; Function: 566 ; Return number of free allocation units on drive 567 ; Outputs: 568 ; BX = Number of free allocation units 569 ; DX = Total Number of allocation units on disk 570 ; CX = Sector size 571 ; AX = Sectors per allocation unit 572 ; = -1 if bad drive specified 573 ; This call returns the same info in the same registers (except for FAT pointer) 574 ; as the old FAT pointer calls 575 0 00001036 161F context DS 0 00001038 88D0 MOV AL,DL 0 0000103A E8[0000] invoke GetThisDrv ; Get drive 579 SET_AX_RET: 0 0000103D 721A JC BADFDRV 0 0000103F E8[0000] invoke DISK_INFO 0 00001042 87D3 XCHG DX,BX 0 00001044 72F7 JC SET_AX_RET ; User FAILed to I 24 0 00001046 48 dec ax 0 00001047 30E4 XOR AH,AH ; Chuck Fat ID byte 0 00001049 40 inc ax ; translate EDR-DOS 0 to 256 587 DoSt: 0 0000104A E8[0000] invoke get_user_stack 589 ASSUME DS:NOTHING 0 0000104D 895406 MOV [SI + user_DX],DX 0 00001050 894C04 MOV [SI + user_CX],CX 0 00001053 895C02 MOV [SI + user_BX],BX 0 00001056 8904 MOV [SI + user_AX],AX 0 00001058 C3 return 595 BADFDRV: 596 ; MOV AL,error_invalid_drive ; Assume error 0 00001059 E8[0000] invoke FCB_RET_ERR 0 0000105C B8FFFF MOV AX,-1 0 0000105F EBE9 JMP DoSt 600 EndProc D_GET_DRIVE_FREESPACE 601 602 BREAK <$Get_DMA, $Set_DMA -- Get/Set current DMA address> 603 procedure D_GET_DMA,NEAR 603 ****************** warning: proc D_GET_DMA... [-w+user] 604 ASSUME DS:NOTHING,ES:NOTHING 605 606 ; Inputs: 607 ; None 608 ; Function: 609 ; Get DISK TRANSFER ADDRESS 610 ; Returns: 611 ; ES:BX is current transfer address 612 0 00001061 368B1E[0000] MOV BX,WORD PTR [ss:DMAADD] 0 00001066 368B0E[0200] MOV CX,WORD PTR [ss:DMAADD+2] 0 0000106B E8[0000] invoke get_user_stack 0 0000106E 895C02 MOV [SI + user_BX],BX 0 00001071 894C10 MOV [SI + user_ES],CX 0 00001074 C3 return 619 EndProc D_GET_DMA 620 621 procedure D_SET_DMA,NEAR 621 ****************** warning: proc D_SET_DMA... [-w+user] 622 ASSUME DS:NOTHING,ES:NOTHING 623 624 ; Inputs: 625 ; DS:DX is desired new disk transfer address 626 ; Function: 627 ; Set DISK TRANSFER ADDRESS 628 ; Returns: 629 ; None 630 0 00001075 368916[0000] MOV WORD PTR [ss:DMAADD],DX 0 0000107A 368C1E[0200] MOV WORD PTR [ss:DMAADD+2],DS 0 0000107F C3 return 634 EndProc D_SET_DMA 635 636 BREAK <$Get_Default_Drive, $Set_Default_Drive -- Set/Get default drive> 637 procedure D_GET_DEFAULT_DRIVE,NEAR 637 ****************** warning: proc D_GET_DEFAULT_DRIVE... [-w+user] 638 ASSUME DS:NOTHING,ES:NOTHING 639 640 ; Inputs: 641 ; None 642 ; Function: 643 ; Return current drive number 644 ; Returns: 645 ; AL = drive number 646 0 00001080 36A0[0000] MOV AL,[ss:CURDRV] 0 00001084 C3 return 649 EndProc D_GET_DEFAULT_DRIVE 650 651 procedure D_SET_DEFAULT_DRIVE,NEAR 651 ****************** warning: proc D_SET_DEFAULT_DRIVE... [-w+user] 652 ASSUME DS:NOTHING,ES:NOTHING 653 654 ; Inputs: 655 ; DL = Drive number for new default drive 656 ; Function: 657 ; Set the default drive 658 ; Returns: 659 ; AL = Number of drives, NO ERROR RETURN IF DRIVE NUMBER BAD 660 0 00001085 88D0 MOV AL,DL 0 00001087 FEC0 INC AL ; A=1, b=2... 0 00001089 E8[0000] invoke GetVisDrv ; see if visible drive 0 0000108C 7204 JC SETRET ; errors do not set 665 ; LDS SI,ThisCDS ; get CDS 666 ; TEST [SI].curdir_flags,curdir_splice ; was it spliced? 667 ; JNZ SetRet ; yes, do not set 0 0000108E 36A2[0000] MOV [ss:CURDRV],AL ; no, set 669 SETRET: 670 CDSCOUNT equ CDSCount ; NASM port label 0 00001092 36A0[0000] MOV AL,[ss:CDSCOUNT] ; let user see what the count really is 0 00001096 C3 RET17: return 673 EndProc D_SET_DEFAULT_DRIVE 674 675 BREAK <$Get_Interrupt_Vector - Get/Set interrupt vectors> 676 procedure D_GET_INTERRUPT_VECTOR,NEAR 676 ****************** warning: proc D_GET_INTERRUPT_VECTOR... [-w+user] 677 ASSUME DS:NOTHING,ES:NOTHING 678 679 ; Inputs: 680 ; AL = interrupt number 681 ; Function: 682 ; Get the interrupt vector 683 ; Returns: 684 ; ES:BX is current interrupt vector 685 0 00001097 E81A00 CALL RECSET 0 0000109A 26C41F LES BX,[ES:BX] 0 0000109D E8[0000] invoke get_user_stack 0 000010A0 895C02 MOV [SI + user_BX],BX 0 000010A3 8C4410 MOV [SI + user_ES],ES 0 000010A6 C3 return 692 EndProc D_GET_INTERRUPT_VECTOR 693 694 procedure D_SET_INTERRUPT_VECTOR,NEAR 694 ****************** warning: proc D_SET_INTERRUPT_VECTOR... [-w+user] 695 ASSUME DS:NOTHING,ES:NOTHING 696 697 ; Inputs: 698 ; AL = interrupt number 699 ; DS:DX is desired new interrupt vector 700 ; Function: 701 ; Set the interrupt vector 702 ; Returns: 703 ; None 704 0 000010A7 E80A00 CALL RECSET 0 000010AA FA CLI ; Watch out!!!!! Folks sometimes use 0 000010AB 268917 MOV [ES:BX],DX ; this for hardware ints (like timer). 0 000010AE 268C5F02 MOV [ES:BX+2],DS 0 000010B2 FB STI 0 000010B3 C3 return 711 EndProc D_SET_INTERRUPT_VECTOR 712 713 %IF ALTVECT 714 invalid instruction fixme 715 ; ldos: section ? 716 === Switch to base=001140h -> "TABLE" 717 section TABLE 718 VECIN: 719 ; INPUT VECTORS 720 Public GSET001S,GSET001E 721 GSET001S label byte 722 DB 22H ; Terminate 723 DB 23H ; ^C 724 DB 24H ; Hard error 725 DB 28H ; Spooler 726 LSTVEC DB ? ; ALL OTHER 727 728 VECOUT: 729 ; GET MAPPED VECTOR 730 DB int_terminate 731 DB int_ctrl_c 732 DB int_fatal_abort 733 DB int_spooler 734 LSTVEC2 DB ? ; Map to itself 735 736 NUMVEC equ VECOUT-VECIN 737 GSET001E label byte === Switch to base=008400h -> "DOSCODECODE" 738 TABLE ENDS 739 %ENDIF 740 741 procedure RECSET,NEAR 741 ****************** warning: proc RECSET... [-w+user] 742 743 %IF ALTVECT 744 context ES 745 MOV [LSTVEC],AL ; Terminate list with real vector 746 MOV [LSTVEC2],AL ; Terminate list with real vector 747 MOV CX,NUMVEC ; Number of possible translations 748 MOV DI,OFFSET VECIN wrt DOSGROUP ; Point to vectors 749 REPNE SCASB 750 MOV AL,[ES:DI+NUMVEC-1] ; Get translation 751 %ENDIF 752 0 000010B4 31DB XOR BX,BX 0 000010B6 8EC3 MOV ES,BX 0 000010B8 88C3 MOV BL,AL 0 000010BA D1E3 SHL BX,1 0 000010BC D1E3 SHL BX,1 0 000010BE C3 return 759 EndProc recset 760 761 BREAK <$Char_Oper - hack on paths, switches so that xenix can look like PCDOS> 762 ; 763 ; input: AL = function: 764 ; 0 - read switch char 765 ; 1 - set switch char (char in DL) 766 ; 2 - read device availability 767 ; Always returns available 768 ; 3 - set device availability 769 ; No longer supported (NOP) 770 ; output: (get) DL - character/flag 771 ; 772 procedure D_CHAR_OPER,NEAR 772 ****************** warning: proc D_CHAR_OPER... [-w+user] 773 ASSUME DS:NOTHING,ES:NOTHING 0 000010BF 161F context DS 0 000010C1 3C01 CMP AL,1 0 000010C3 720B JB CharGetSw 0 000010C5 740F JZ CharSetSw 0 000010C7 3C03 CMP AL,3 0 000010C9 7210 JB CharGetDev 0 000010CB 7416 JZ CharSetDev 0 000010CD B0FF MOV AL,-1 0 000010CF C3 return 783 CharGetSw: 0 000010D0 8A16[0000] MOV DL,[chSwitch] 0 000010D4 EB07 JMP SHORT CharSet 786 CharSetSw: 0 000010D6 8816[0000] MOV [chSwitch],DL 0 000010DA C3 return 789 CharGetDev: 0 000010DB B2FF MOV DL,-1 791 CharSet: 0 000010DD E8[0000] Invoke Get_User_Stack 793 ASSUME DS:NOTHING 794 User_DX equ user_DX ; NASM port label 0 000010E0 895406 MOV [SI + User_DX],DX 796 CharSetDev: 0 000010E3 C3 return 798 EndProc D_CHAR_OPER 799 800 BREAK <$GetExtendedError - Return Extended DOS error code> 801 ; 802 ; input: None 803 ; output: AX = Extended error code (0 means no extended error) 804 ; BL = recommended action 805 ; BH = class of error 806 ; CH = locus of error 807 ; ES:DI = may be pointer 808 ; 809 procedure D_GetExtendedError,NEAR 809 ****************** warning: proc D_GetExtendedError... [-w+user] 810 ASSUME DS:NOTHING,ES:NOTHING 0 000010E4 161F Context DS 0 000010E6 A1[0000] MOV AX,[EXTERR] 0 000010E9 C43E[0000] LES DI,[EXTERRPT] 0 000010ED 8B1E[0000] MOV BX,WORD PTR [EXTERR_ACTION] ; BL = Action, BH = Class 0 000010F1 8A2E[0000] MOV CH,[EXTERR_LOCUS] 0 000010F5 E8[0000] invoke get_user_stack 817 ASSUME DS:NOTHING 0 000010F8 897C0A MOV [SI + user_DI],DI 0 000010FB 8C4410 MOV [SI + user_ES],ES 0 000010FE 895C02 MOV [SI + user_BX],BX 0 00001101 894C04 MOV [SI + user_CX],CX 0 00001104 E9[0000] transfer SYS_RET_OK 823 EndProc D_GetExtendedError 824 825 BREAK <$Get_Global_CdPg - Return Global Code Page> 826 ; 827 ; input: None 828 ; output: AX = Global Code Page 829 ; 830 procedure Get_Global_CdPg,NEAR 830 ****************** warning: proc Get_Global_CdPg... [-w+user] 831 ASSUME DS:NOTHING,ES:NOTHING 0 00001107 56 PUSH SI 0 00001108 BE[0000] MOV SI,OFFSET COUNTRY_CDPG wrt DOSGROUP 0 0000110B 368B446A MOV AX,[ss:SI + ccDosCodePage] 0 0000110F 5E POP SI 0 00001110 C3 return 837 EndProc Get_Global_CdPg 838 839 ;-------------------------------Start of DBCS 2/13/KK 840 BREAK 841 842 ASSUME DS:NOTHING, ES:NOTHING 843 844 procedure D_ECS_call,NEAR 844 ****************** warning: proc D_ECS_call... [-w+user] 845 846 ; Inputs: 847 ; AL = 0 get lead byte table 848 ; on return DS:SI has the table location 849 ; 850 ; AL = 1 set / reset interim console flag 851 ; DL = flag (00H or 01H) 852 ; no return 853 ; 854 ; AL = 2 get interim console flag 855 ; on return DL = current flag value 856 ; 857 ; AL = OTHER then error, and returns with: 858 ; AX = error_invalid_function 859 ; 860 ; NOTE: THIS CALL DOES GUARANTEE THAT REGISTER OTHER THAN 861 ; SS:SP WILL BE PRESERVED! 862 863 %IF DBCS ;AN000; 864 ;AN000; 865 or al, al ; AL = 0 (get table)? ;AN000; 866 je get_lbt ;AN000; 867 cmp al, SetInterimMode ; AL = 1 (set / reset interim flag)? ;AN000; 868 je set_interim ;AN000; 869 cmp al, GetInterimMode ; AL = 2 (get interim flag)? ;AN000; 870 je get_interim ;AN000; 871 error error_invalid_function ;AN000; 872 ;AN000; 873 get_lbt: ; get lead byte table ;AN000; 874 push ax ;AN000; 875 push bx ;AN000; 876 push ds ;AN000; 877 context DS ;AN000; 878 MOV BX,offset COUNTRY_CDPG + ccSetDBCS wrt DOSGROUP ;AN000; 879 MOV AX,[BX+1] ; set EV address to DS:SI ;AN000; 880 MOV BX,[BX+3] ;AN000; 881 ADD AX,2 ; Skip Lemgth ;AN000; 882 invoke get_user_stack ;AN000; 883 assume ds:nothing ;AN000; 884 MOV [SI + user_SI], AX ;AN000; 885 MOV [SI + user_DS], BX ;AN000; 886 pop ds ;AN000; 887 pop bx ;AN000; 888 pop ax ;AN000; 889 transfer SYS_RET_OK ;AN000; 890 891 set_interim: ; Set interim console flag ;AN000; 892 push dx ;AN000; 893 and dl,01 ; isolate bit 1 ;AN000; 894 mov [InterCon], dl ;AN000; 895 push ds ;AN000; 896 CurrentPDB equ CURRENTPDB ; NASM port label 897 mov ds, [CurrentPDB] ;AN000; 898 mov byte ptr [PDB_InterCon], dl ; update value in pdb ;AN000; 899 pop ds ;AN000; 900 pop dx ;AN000; 901 transfer SYS_RET_OK ;AN000; 902 903 get_interim: ;AN000; 904 push dx ;AN000; 905 push ds ;AN000; 906 mov dl,[InterCon] ;AN000; 907 invoke get_user_stack ; get interim console flag ;AN000; 908 assume ds:nothing ;AN000; 909 mov [SI + user_DX],DX ;AN000; 910 pop ds ;AN000; 911 pop dx ;AN000; 912 transfer SYS_RET_OK ;AN000; 913 %ELSE ;AN000; 0 00001111 08C0 or al, al ; AL = 0 (get table)? ;AN000; 0 00001113 750B jnz okok ;AN000; 916 get_lbt: ;AN000; 0 00001115 E8[0000] invoke get_user_stack ;AN000; 918 assume ds:nothing ;AN000; 919 Dosgroup equ DOSGROUP ; NASM port equate 0 00001118 C74408[0200] MOV word [SI + user_SI], Offset DBCS_TAB+2 wrt Dosgroup ;AN000; 0 0000111D 8C540E MOV [SI + user_DS], ss ;AN000; 922 okok: ;AN000; 0 00001120 EBE2 transfer SYS_RET_OK ; ;AN000; 924 925 %ENDIF ;AN000; 926 927 D_ECS_call endp ;AN000; 928 929 END === Trace listing source: ../DOS/parse.lst 1 ; SCCSID = @(#)parse.asm 1.2 85/07/23 2 ;TITLE PARSE - Parsing system calls for MS-DOS 3 ;NAME PARSE 4 ; 5 ; System calls for parsing command lines 6 ; 7 ; $PARSE_FILE_DESCRIPTOR 8 ; 9 ; Modification history: 10 ; 11 ; Created: ARR 30 March 1983 12 ; EE PathParse 10 Sept 1983 13 ; 14 15 [list -] === Switch to base=008400h -> "DOSCODECODE" 22 section DOSCODECODE 23 [list -] 23 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 23 ****************** warning: out: BPB.INC... [-w+user] 23 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 23 ****************** warning: out: DEVSYM.INC... [-w+user] 30 31 BOGUS equ FALSE 32 ;.lall 33 I_Need chSwitch,BYTE 34 35 BREAK <$Parse_File_Descriptor -- Parse an arbitrary string into an FCB> 36 37 ; Inputs: 38 ; DS:SI Points to a command line 39 ; ES:DI Points to an empty FCB 40 ; Bit 0 of AL = 1 At most one leading separator scanned off 41 ; = 0 Parse stops if separator encountered 42 ; Bit 1 of AL = 1 If drive field blank in command line - leave FCB 43 ; = 0 " " " " " " - put 0 in FCB 44 ; Bit 2 of AL = 1 If filename field blank - leave FCB 45 ; = 0 " " " - put blanks in FCB 46 ; Bit 3 of AL = 1 If extension field blank - leave FCB 47 ; = 0 " " " - put blanks in FCB 48 ; Function: 49 ; Parse command line into FCB 50 ; Returns: 51 ; AL = 1 if '*' or '?' in filename or extension, 0 otherwise 52 ; DS:SI points to first character after filename 53 54 procedure D_PARSE_FILE_DESCRIPTOR,NEAR 54 ****************** warning: proc D_PARSE_FILE_DESCRIPTOR... [-w+user] 55 ASSUME DS:NOTHING,ES:NOTHING 56 0 00001122 E8[0000] invoke MAKEFCB 0 00001125 56 PUSH SI 0 00001126 E8[0000] invoke get_user_stack 0 00001129 8F4408 POP word [SI + user_SI] 0 0000112C C3 return 62 EndProc D_PARSE_FILE_DESCRIPTOR 63 64 65 %IF BOGUS 66 BREAK <$PathParse - Parse a string> 67 68 ;------------------------------------------------------------------------------ 69 ; 70 ; Parse is a string parser. It copies the next token into a buffer, updates 71 ; the string pointer, and builds a flag word which describes the token. 72 ; 73 ; ENTRY 74 ; DS:SI - Points to the beginning of the string to be parsed 75 ; ES:DI - Points to the buffer which will hold the new token 76 ; 77 ; EXIT 78 ; AX - Flag word 79 ; DS:SI - String pointer updated to point past the token just found 80 ; All other registers are unchanged. 81 ; 82 ; All of the isXXXX procedures called by the main routine test a character 83 ; to see if it is of a particular type. If it is, they store the character 84 ; and return with the ZF set. 85 ; 86 ; CALLS 87 ; isswit issep ispchr ispsep isinval isdot ischrnull dirdot pasep 88 ; 89 ; 90 ; INTERNAL REGISTER USAGE 91 ; AH - FF/00 to indicate whether a path token can terminated with a 92 ; slash or not. 93 ; AL - Used with lodsb/stosb to transfer and test chars from DS:SI 94 ; BX - Holds flag word 95 ; CX - Used with loop/rep and as a work var 96 ; DX - Used to test the length of names and extensions 97 ; 98 ; EFFECTS 99 ; The memory pointed to by DI has the next token copied into it. 100 ; 101 ; WARNINGS 102 ; It is the caller's responsibility to make sure DS:SI does not point 103 ; to a null string. If it does, SI is incremented, a null byte is 104 ; stored at ES:DI, and the routine returns. 105 ; 106 ;------------------------------------------------------------------------------ 107 ParseClassMask equ 1110000000000000b ; Token class mask 108 ParseSwitch equ 1000000000000000b ; Switch class 109 ParseSeparators equ 0100000000000000b ; Separator class 110 ParsePathName equ 0010000000000000b ; Path class 111 ParsePathNameData equ 0000000000001111b ; Path token data mask 112 ParsePathSynErr equ 0000000000000001b ; Path has syntax error 113 ParsePathWild equ 0000000000000010b ; Path has wildcards 114 ParsePathSeparators equ 0000000000000100b ; Path has pseparators 115 ParseInvalidDrive equ 0000000000001000b ; Path has invald drive 116 117 118 ; Sepchars is a string containing all of the token separator characters 119 ; and is used to test for separators. 120 === Switch to base=008400h -> "DOSCODETABLE" 121 section DOSCODETABLE 122 Public PRS001S,PRS001E 123 PRS001S label byte 124 sepchrs db 9,10,13,' ','+',',',';','=' ; tab cr lf sp + , ; = 125 seplen equ $-sepchrs 126 PRS001E label byte === Switch to base=008400h -> "DOSCODECODE" 127 section DOSCODECODE ; DOSCODETABLE ends 128 129 Procedure D_PathParse,NEAR 130 assume ds:nothing,es:nothing 131 xor ah,ah ; initialize registers and flags 132 xor bx,bx 133 cld 134 lodsb ; used the first byte of the token to 135 call isswit ; determine its type and call the routine to 136 je switch ; parse it 137 call issep 138 je separ 139 call ispchr 140 je path 141 call ispsep 142 je path 143 call isdot 144 je path 145 call isinval 146 je inval 147 stosb 148 jmp done 149 150 inval: or bx,ParsePathName ; an invalid character/path token 151 or bx,ParsePathSynErr ; was found, set the appropriate 152 call issep ; flag bits and parse the rest of 153 jne icont ; the token 154 dec di 155 icont: dec si 156 jmp ptosep 157 158 switch: mov bx,ParseSwitch ; found a switch, set flag and parse 159 jmp ptosep ; the rest of it 160 161 separ: mov bx,ParseSeparators ; found separator, set flag and parse 162 seloop: lodsb ; everything up to the next non 163 call issep ; separator character 164 je seloop 165 jmp bksi 166 167 path: or bx,ParsePathName ; found path, set flag 168 mov cx,8 ; set up to parse a file name 169 mov dx,8 170 call pasep ; if the token began with a path 171 jne pcont1 ; separator or . call rcont which 172 not ah ; handles checksfor . and .. 173 jmp rcont 174 pcont1: cmp al,'.' 175 jne pcont2 176 dec si 177 dec di 178 jmp rcont 179 pcont2: cmp al,'A' ; if token may start with a drive 180 jge drive ; designator, go to drive. otherwise 181 jmp name1 ; parse a file name. 182 183 drive: cmp byte ptr [si],':' ; if there is a drive designator, parse 184 jne name1 ; and verify it. otherwise parse a file 185 not ah ; name. 186 cmp al,'Z' 187 jle dcont1 188 sub al,' ' 189 dcont1: sub al,'@' 190 invoke GetthisDrv 191 lodsb 192 stosb 193 jc dcont2 194 jmp dcont3 195 dcont2: or bx,ParseInvalidDrive 196 dcont3: dec cx 197 lodsb 198 call ispsep 199 je rcont 200 dec si 201 202 repeat: mov al,byte ptr [si-2] ; repeat and rcont test for //, \\, ., 203 call pasep ; and .. and repeatedly calls name 204 jne rcont ; and ext until a path token has 205 inc si ; been completely parsed. 206 jmp inval 207 rcont: call dirdot 208 je done 209 jc inval 210 mov cx,8 211 mov dx,8 212 jmp name 213 214 name1: dec cx 215 name: lodsb ; parse and verify a file name 216 call ispchr 217 jne ncheck 218 xor ah,ah 219 nloop: loop name 220 lodsb 221 222 ncheck: cmp ah,0 223 jne ncont 224 cmp cx,dx 225 jne ncont 226 jmp inval 227 ncont: call isdot 228 je ext 229 jmp dcheck 230 231 ext: mov cx,3 ; parse and verify a file extension 232 mov dx,3 233 extl: lodsb 234 call ispchr 235 jne echeck 236 eloop: loop extl 237 lodsb 238 239 echeck: cmp cx,dx 240 jne dcheck 241 jmp inval 242 243 dcheck: call ispsep ; do the checks need to make sure 244 je repeat ; a file name or extension ended 245 call issep ; correctly and checks to see if 246 je bkboth ; we're done 247 call ischrnull 248 je done 249 jmp inval 250 251 ptosep: lodsb ; parse everything to the next separator 252 call issep 253 je bkboth 254 call ischrnull 255 je done 256 call isinval 257 jne ptcont 258 or bx,ParsePathSynErr 259 ptcont: stosb 260 jmp ptosep 261 262 bkboth: dec di ; clean up when the end of the token 263 bksi: dec si ; is found, stick a terminating null 264 done: xor al,al ; byte at the end of buf, and exit 265 stosb 266 push si 267 invoke Get_user_stack 268 mov [si + user_AX],bx 269 pop word [si + user_SI] 270 Transfer sys_ret_ok 271 272 Endproc D_PathParse 273 274 ; Is current character the beginning of a switch? 275 276 isswit proc near 277 cmp al,[ss:chSwitch] 278 jne swret 279 stosb 280 swret: ret 281 isswit endp 282 283 284 ; Is the current character a separator? 285 286 issep proc near 287 push cx 288 push di 289 push es 290 push cs 291 pop es 292 mov cx,seplen 293 dosgroup equ DOSGROUP ; NASM port equate 294 mov di,offset sepchrs 295 repne scasb 296 pop es 297 pop di 298 jne sepret 299 sepyes: stosb 300 sepret: pop cx 301 ret 302 issep endp 303 304 305 ; Is the current character a path character? If it is a wildcard char too, 306 ; set that flag. 307 308 ispchr proc near 309 cmp al,'!' 310 je pcyes 311 cmp al,'#' 312 jl pcret 313 cmp al,'*' 314 je pcwild 315 jl pcyes 316 cmp al,'-' 317 je pcyes 318 cmp al,'0' 319 jl pcret 320 cmp al,'9' 321 jle pcyes 322 cmp al,'?' 323 je pcwild 324 jl pcret 325 cmp al,'Z' 326 jle pcyes 327 cmp al,'^' 328 jl pcret 329 cmp al,'{' 330 jle pcyes 331 cmp al,'}' 332 je pcyes 333 cmp al,'~' 334 je pcyes 335 jmp pcret 336 pcwild: or bx,ParsePathWild 337 pcyes: stosb 338 cmp al,al 339 pcret: ret 340 ispchr endp 341 342 343 ; Is the current character a path separator? If so, set that flag after 344 ; storing the byte. 345 346 ispsep proc near 347 call pasep 348 jne psret 349 stosb 350 or bx,ParsePathSeparators 351 cmp al,al 352 psret: ret 353 ispsep endp 354 355 356 ; Set ZF if the character in AL is a path separator. 357 358 pasep proc near 359 cmp byte [ss:chSwitch],'/' 360 je bkslash 361 cmp al,'/' 362 retz 363 bkslash:cmp al,'\' 364 ret 365 pasep endp 366 367 368 ; Is the current character invalid? 369 370 isinval proc near 371 cmp al,1 372 jl inret 373 cmp al,8 374 jle inyes 375 cmp al,11 376 jl inret 377 cmp al,13 378 jne incont 379 cmp al,0 380 ret 381 incont: cmp al,31 382 jle inyes 383 cmp al,'[' 384 je inyes 385 cmp al,']' 386 je inyes 387 ret 388 inyes: cmp al,al 389 inret: ret 390 isinval endp 391 392 393 ; Is the current character a dot? 394 395 isdot proc near 396 cmp al,'.' 397 jne dotret 398 stosb 399 dotret: ret 400 isdot endp 401 402 403 ; Is the current character null? If so, update SI for exiting. 404 405 ischrnull proc near 406 cmp al,0 407 jne nulret 408 dec si 409 cmp al,al 410 nulret: ret 411 ischrnull endp 412 413 414 ; Check for . and .. Before returning, CF and ZF are set to indicate whether 415 ; the token is invalid (found . or .. followed by an invalid char - CF on), 416 ; we're done (found . or .. followed by null or a separator - ZF on), or the 417 ; token continues (. and .. not found or found and followed by a path 418 ; separator - both flags off). 419 420 dirdot proc near 421 cmp byte ptr [si], '.' 422 jne diretc 423 lodsb 424 stosb 425 cmp byte ptr [si],'.' 426 jne dicont 427 lodsb 428 stosb 429 dicont: lodsb 430 call ispsep 431 je diretc 432 call issep 433 je dibk 434 call ischrnull 435 je diretd 436 direti: stc ; Invalid return 437 ret 438 dibk: dec si 439 dec di 440 diretd: cmp al,al ; Done return 441 ret 442 diretc: cmp ah,1 ; Continue return 443 clc 444 ret 445 dirdot endp 446 %ENDIF 447 448 END === Trace listing source: ../DOS/misc.lst 1 ; SCCSID = @(#)misc.asm 1.1 85/04/10 2 ;TITLE MISC - Miscellanious routines for MS-DOS 3 ;NAME MISC 4 ; 5 ; Miscellaneous system calls most of which are CAVEAT 6 ; 7 ; $SLEAZEFUNC 8 ; $SLEAZEFUNCDL 9 ; $GET_INDOS_FLAG 10 ; $GET_IN_VARS 11 ; $GET_DEFAULT_DPB 12 ; $GET_DPB 13 ; $DISK_RESET 14 ; $SETDPB 15 ; $Dup_PDB 16 ; $CREATE_PROCESS_DATA_BLOCK 17 ; SETMEM 18 ; FETCHI_CHECK 19 ; $GSetMediaID 20 ; 21 ; Revision history: 22 ; 23 ; Created: ARR 30 March 1983 24 ; 25 ; A000 version 4.00 Jan. 1988 26 ; A001 D490 -- Change IOCTL subfunctions from 63h, 43h to 66h , 46h 27 28 [list -] === Switch to base=008400h -> "DOSCODECODE" 35 section DOSCODECODE 36 [list -] 36 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 36 ****************** warning: out: BPB.INC... [-w+user] 36 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 36 ****************** warning: out: DEVSYM.INC... [-w+user] 43 44 ENTRYPOINTSEG EQU 0CH 45 MAXDIF EQU 0FFFH 46 SAVEXIT EQU 10 47 48 i_need LASTBUFFER,DWORD 49 i_need BuffHead,DWORD 50 i_need INDOS,BYTE 51 i_need SYSINITVAR,BYTE 52 i_need CurrentPDB,WORD 53 i_need CreatePDB,BYTE 54 i_need FATBYTE,BYTE 55 i_need THISCDS,DWORD 56 i_need THISSFT,DWORD 57 i_need FETCHI_TAG,WORD ; for TAG CHECK 58 i_need BUF_HASH_COUNT,WORD ;AN000; number of Hash Entries 59 i_need HIGH_SECTOR,WORD ;AN000; high word of sector # 60 i_need DOS34_FLAG,WORD ;AN000; 61 %if debug 62 I_need BugLev,WORD 63 I_need BugTyp,WORD 64 %include "bugtyp.nas" 65 %endif 66 67 BREAK 68 69 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 70 ; C A V E A T P R O G R A M M E R ; 71 ; ; 72 ; Inputs: 73 ; None 74 ; Function: 75 ; Return Stuff sort of like old get fat call 76 ; Outputs: 77 ; DS:BX = Points to FAT ID byte (IBM only) 78 ; GOD help anyone who tries to do ANYTHING except 79 ; READ this ONE byte. 80 ; DX = Total Number of allocation units on disk 81 ; CX = Sector size 82 ; AL = Sectors per allocation unit 83 ; = -1 if bad drive specified 84 85 procedure D_SLEAZEFUNC,NEAR 85 ****************** warning: proc D_SLEAZEFUNC... [-w+user] 86 ASSUME DS:NOTHING,ES:NOTHING 87 0 0000112D B200 MOV DL,0 89 90 entry D_SLEAZEFUNCDL 91 ;Same as above except drive passed in DL (0=default, 1=A, 2=B, ...) 92 0 0000112F 161F context DS 0 00001131 88D0 MOV AL,DL 0 00001133 E8[0000] invoke GETTHISDRV ; Get CDS structure 96 SET_AL_RET: 97 ; MOV AL,error_invalid_drive ; Assume error ;AC000; 0 00001136 721E JC BADSLDRIVE 0 00001138 E8[0000] invoke DISK_INFO 0 0000113B 72F9 JC SET_AL_RET ; User FAILed to I 24 0 0000113D 8826[0000] MOV [FATBYTE],AH 102 ; NOTE THAT A FIXED MEMORY CELL IS USED --> THIS CALL IS NOT 103 ; RE-ENTRANT. USERS BETTER GET THE ID BYTE BEFORE THEY MAKE THE 104 ; CALL AGAIN 0 00001141 BF[0000] MOV DI,OFFSET FATBYTE wrt DOSGROUP 0 00001144 30E4 XOR AH,AH ; AL has sectors/cluster 107 ; Does not handle EDR-DOS 256 SpC, 108 ; what does EDR-DOS do? 109 ; A: EDR-DOS returns 0 in al. 0 00001146 E8[0000] invoke get_user_stack 111 ASSUME DS:NOTHING 0 00001149 894C04 MOV [SI + user_CX],CX 0 0000114C 895C06 MOV [SI + user_DX],BX 0 0000114F 897C02 MOV [SI + user_BX],DI 0 00001152 8C540E MOV [SI + user_DS], ss ; stash correct pointer 0 00001155 C3 return 117 BADSLDRIVE: 0 00001156 E9[0000] transfer FCB_Ret_ERR 119 EndProc D_SLEAZEFUNC 120 ; ; 121 ; C A V E A T P R O G R A M M E R ; 122 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 123 124 BREAK <$Get_INDOS_Flag -- Return location of DOS critical-section flag> 125 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 126 ; C A V E A T P R O G R A M M E R ; 127 ; ; 128 ; Inputs: 129 ; None 130 ; Function: 131 ; Returns location of DOS status for interrupt routines 132 ; Returns: 133 ; Flag location in ES:BX 134 135 procedure D_GET_INDOS_FLAG,NEAR 135 ****************** warning: proc D_GET_INDOS_FLAG... [-w+user] 136 ASSUME DS:NOTHING,ES:NOTHING 137 0 00001159 E8[0000] invoke get_user_stack 0 0000115C C74402[0000] MOV word [SI + user_BX],OFFSET INDOS wrt DOSGROUP 0 00001161 8C5410 MOV [SI + user_ES],SS 0 00001164 C3 return 142 EndProc D_GET_INDOS_FLAG 143 ; ; 144 ; C A V E A T P R O G R A M M E R ; 145 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 146 147 BREAK <$Get_IN_VARS -- Return a pointer to DOS variables> 148 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 149 ; C A V E A T P R O G R A M M E R ; 150 ; ; 151 ; Return a pointer to interesting DOS variables This call is version 152 ; dependent and is subject to change without notice in future versions. 153 ; Use at risk. 154 procedure D_GET_IN_VARS,NEAR 154 ****************** warning: proc D_GET_IN_VARS... [-w+user] 0 00001165 E8[0000] invoke get_user_stack 0 00001168 C74402[0000] MOV word [SI + user_BX],OFFSET SYSINITVAR wrt DOSGROUP 0 0000116D 8C5410 MOV [SI + user_ES],SS 0 00001170 C3 return 159 EndProc D_GET_IN_VARS 160 ; ; 161 ; C A V E A T P R O G R A M M E R ; 162 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 163 164 165 BREAK <$Get_Default_DPB,$Get_DPB -- Return pointer to DPB> 166 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 167 ; C A V E A T P R O G R A M M E R ; 168 ; ; 169 ; Inputs: 170 ; None 171 ; Function: 172 ; Return pointer to drive parameter table for default drive 173 ; Returns: 174 ; DS:BX points to the DPB 175 ; AL = 0 If OK, = -1 if bad drive (call 50 only) 176 177 procedure D_GET_DEFAULT_DPB,NEAR 177 ****************** warning: proc D_GET_DEFAULT_DPB... [-w+user] 178 ASSUME DS:NOTHING,ES:NOTHING 179 0 00001171 B200 MOV DL,0 181 182 entry D_GET_DPB 183 ; Same as above only drive passed in DL (0=default, 1=A, 2=B, ...) 184 0 00001173 161F context DS 0 00001175 88D0 MOV AL,DL 0 00001177 E8[0000] invoke GETTHISDRV ; Get CDS structure 0 0000117A 7223 JC ISNODRV ; no valid drive 0 0000117C C43E[0000] LES DI,[THISCDS] ; check for net CDS 0 00001180 26F745430080 TEST word [ES:DI + curdir_flags],curdir_isnet 0 00001186 7517 JNZ ISNODRV ; No DPB to point at on NET stuff 0 00001188 E8[0000] EnterCrit CritDisk 0 0000118B E8[0000] invoke FATRead_CDS ; Force Media Check and return DPB 0 0000118E E8[0000] LeaveCrit CritDisk 0 00001191 720C JC ISNODRV ; User FAILed to I 24, only error we 196 ; have. 0 00001193 E8[0000] invoke get_user_stack 198 ASSUME DS:NOTHING 0 00001196 896C02 MOV [SI + user_BX],BP 0 00001199 8C440E MOV [SI + user_DS],ES 0 0000119C 30C0 XOR AL,AL 0 0000119E C3 return 203 204 ISNODRV: 0 0000119F B0FF MOV AL,-1 0 000011A1 C3 return 207 EndProc D_GET_Default_dpb 208 ; ; 209 ; C A V E A T P R O G R A M M E R ; 210 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 211 212 213 BREAK <$Disk_Reset -- Flush out all dirty buffers> 214 215 procedure D_DISK_RESET,NEAR 215 ****************** warning: proc D_DISK_RESET... [-w+user] 216 ASSUME DS:NOTHING,ES:NOTHING 217 218 ; Inputs: 219 ; None 220 ; Function: 221 ; Flush and invalidate all buffers 222 ; Returns: 223 ; Nothing 224 0 000011A2 B0FF MOV AL,-1 226 entry D_DISK_RESET2 0 000011A4 161F context DS 0 000011A6 E8[0000] EnterCrit critDisk 0 000011A9 830E[0000]04 OR word [DOS34_FLAG],FROM_DISK_RESET ;AN000; 0 000011AE E8[0000] invoke FLUSHBUF 0 000011B1 8326[0000]FB AND word [DOS34_FLAG],NO_FROM_DISK_RESET ;AN000; 232 ; 233 ; We will "ignore" any errors on the flush, and go ahead and invalidate. This 234 ; call doesn't return any errors and it is supposed to FORCE a known state, so 235 ; let's do it. 236 ; 237 ; Invalidate 'last-buffer' used 238 ; 0 000011B6 BBFFFF MOV BX,-1 0 000011B9 891E[0200] MOV WORD PTR [LASTBUFFER+2],BX 0 000011BD 891E[0000] MOV WORD PTR [LASTBUFFER],BX 242 ; 243 ; TEST [DOS34_FLAG],IFS_DRIVE_RESET ;AN000;;IFS. from ifs call back ? 244 ; JZ FreeDone ;AN000;;IFS. no 245 ; AND [DOS34_FLAG],NO_IFS_DRIVE_RESET ;AN000;;IFS. clear the flag 246 ; LeaveCrit critDisk ;AN000;;IFS. 247 ; return ;AN000;;IFS. return 248 FreeDone: 0 000011C1 E8[0000] LeaveCrit critDisk 0 000011C4 B8FFFF MOV AX,-1 251 multNET equ MultNET ; NASM port equate 0 000011C7 B82011CD2F CallInstall NetFlushBuf,multNET,32 0 000011CC C3 return 254 EndProc D_DISK_RESET 255 256 BREAK <$SetDPB - Create a valid DPB from a user-specified BPB> 257 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 258 ; C A V E A T P R O G R A M M E R ; 259 ; ; 260 procedure D_SETDPB,NEAR 260 ****************** warning: proc D_SETDPB... [-w+user] 261 ASSUME DS:NOTHING,ES:NOTHING 262 263 ; Inputs: 264 ; ES:BP Points to DPB 265 ; DS:SI Points to BPB 266 ; Function: 267 ; Build a correct DPB from the BPB 268 ; Outputs: 269 ; ES:BP and DS preserved all others destroyed 270 0 000011CD 89EF MOV DI,BP 0 000011CF AF scasw ; Skip over dpb_drive and dpb_UNIT 0 000011D0 AD LODSW 0 000011D1 AB STOSW ; dpb_sector_size 0 000011D2 85C0 test ax, ax 0 000011D4 7406 jz .nonfat 0 000011D6 807C0300 CMP BYTE PTR [SI + BPFTCNT-2],0 ; FAT file system drive ;AN000; 0 000011DA 7508 JNZ yesfat ; yes ;AN000; 279 .nonfat: 0 000011DC 26C6450400 MOV BYTE PTR [ES:DI + dpb_FAT_count-4],0 0 000011E1 EB74 JMP setend ; NO ;AN000; 0 000011E3 90 nop ; identicalise 283 yesfat: 0 000011E4 89C2 MOV DX,AX 0 000011E6 AC LODSB ; get amount clusters (0 means 256) 0 000011E7 48 dec ax 0 000011E8 AA STOSB ; dpb_cluster_mask 0 000011E9 B400 mov ah, 0 0 000011EB 40 inc ax ; translate EDR-DOS 0 to 256 0 000011EC B300 mov bl, 0 ; bl = shift count 291 LOG2LOOP: 0 000011EE A801 TEST AL,1 0 000011F0 7506 JNZ SAVLOG 0 000011F2 FEC3 inc bl ; increment shift count 0 000011F4 D1E8 shr ax, 1 ; shift right amount clusters 0 000011F6 EBF6 JMP SHORT LOG2LOOP 297 SAVLOG: 0 000011F8 88D8 mov al, bl ; bl = al = shift count 0 000011FA AA STOSB ; dpb_cluster_shift 0 000011FB A5 MOVSW ; dpb_first_FAT Start of FAT (# of reserved sectors) 0 000011FC AC LODSB 0 000011FD AA STOSB ; dpb_FAT_count Number of FATs 303 ; OR AL,AL ; NONFAT ? ;AN000; 304 ; JZ setend ; yes, don't do anything ;AN000; 0 000011FE 88C7 MOV BH,AL 0 00001200 AD LODSW 0 00001201 AB STOSW ; dpb_root_entries Number of directory entries 0 00001202 B105 MOV CL,5 0 00001204 D3EA SHR DX,CL ; Directory entries per sector 0 00001206 48 DEC AX 0 00001207 01D0 ADD AX,DX ; Cause Round Up 0 00001209 89D1 MOV CX,DX 0 0000120B 31D2 XOR DX,DX 0 0000120D F7F1 DIV CX 0 0000120F 89C1 MOV CX,AX ; Number of directory sectors 0 00001211 47 INC DI 0 00001212 47 INC DI ; Skip dpb_first_sector 0 00001213 A5 MOVSW ; Total number of sectors in DSKSIZ (temp as dpb_max_cluster) 0 00001214 AC LODSB 0 00001215 26884617 MOV [ES:BP + dpb_media],AL ; Media byte 0 00001219 AD LODSW ; Number of sectors in a FAT 0 0000121A AB STOSW ;AC000;;>32mb dpb_FAT_size 0 0000121B 88FA MOV DL,BH ;AN000;;>32mb 0 0000121D 30F6 XOR DH,DH ;AN000;;>32mb 0 0000121F F7E2 MUL DX ;AC000;;>32mb Space occupied by all FATs 0 00001221 26034606 ADD AX,[ES:BP + dpb_first_FAT] 0 00001225 AB STOSW ; dpb_dir_sector 0 00001226 01C8 ADD AX,CX ; Add number of directory sectors 0 00001228 2689460B MOV [ES:BP + dpb_first_sector],AX 330 0 0000122C 88D9 mov cl, bl ; cluster size shift count 0 0000122E 26837E0D00 CMP WORD PTR [ES:BP + DSKSIZ],0 ;F.C. >32mb ;AN000; 0 00001233 751A JNZ normal_dpb ;F.C. >32mb ;AN000; 0 00001235 30ED XOR CH,CH ;F.C. >32mb ;AN000; 335 BPB_BigTotalSectors equ BPB_BIGTOTALSECTORS ; NASM port label 336 BPB_SectorsPerTrack equ BPB_SECTORSPERTRACK ; NASM port label 0 00001237 8B5C08 MOV BX,WORD PTR [SI+BPB_BigTotalSectors-BPB_SectorsPerTrack] ;AN000; 0 0000123A 8B540A MOV DX,WORD PTR [SI+BPB_BigTotalSectors-BPB_SectorsPerTrack+2] ;AN000; 0 0000123D 29C3 SUB BX,AX ;AN000;;F.C. >32mb 0 0000123F 83DA00 SBB DX,0 ;AN000;;F.C. >32mb 0 00001242 E306 jcxz norot ;AN000;;F.C. >32mb 342 rott: ;AN000;;F.C. >32mb 0 00001244 D1EA shr DX,1 ;AN000;;F.C. >32mb 0 00001246 D1DB RCR BX,1 ;AN000;;F.C. >32mb 0 00001248 E2FA LOOP rott ;AN000;;F.C. >32mb 346 norot: ;AN000; 0 0000124A 89D8 MOV AX,BX ;AN000;;F.C. >32mb 0 0000124C EB09 JMP setend ;AN000;;F.C. >32mb 0 0000124E 90 nop ; identicalise 350 normal_dpb: 0 0000124F 262B460D SUB AX,[ES:BP + DSKSIZ] 0 00001253 F7D8 NEG AX ; Sectors in data area 353 ;; MOV CL,BL ; dpb_cluster_shift 0 00001255 D3E8 SHR AX,CL ; Div by sectors/cluster 355 setend: 0 00001257 40 INC AX 0 00001258 2689460D MOV [ES:BP + dpb_max_cluster],AX 0 0000125C 26C7461D0000 MOV word [ES:BP + dpb_next_free],0 ; Init so first ALLOC starts at 359 ; begining of FAT 0 00001262 26C7461FFFFF MOV word [ES:BP + dpb_free_cnt],-1 ; current count is invalid. 0 00001268 C3 return 362 EndProc D_SETDPB 363 ; ; 364 ; C A V E A T P R O G R A M M E R ; 365 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 366 367 BREAK <$Create_Process_Data_Block,SetMem -- Set up process data block> 368 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 369 ; C A V E A T P R O G R A M M E R ; 370 ; ; 371 ; 372 ; Inputs: DX is new segment address of process 373 ; SI is end of new allocation block 374 ; 375 procedure D_Dup_PDB,NEAR 375 ****************** warning: proc D_Dup_PDB... [-w+user] 376 ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING 0 00001269 36C606[0000]FF MOV byte [ss:CreatePDB],0FFH ; indicate a new process 0 0000126F 368E1E[0000] MOV DS,[ss:CurrentPDB] 0 00001274 56 PUSH SI 0 00001275 EB0A JMP SHORT CreateCopy 381 EndProc D_Dup_PDB 382 383 procedure D_CREATE_PROCESS_DATA_BLOCK,NEAR 383 ****************** warning: proc D_CREATE_PROCESS_DATA_BLOCK... [-w+user] 384 ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING 385 386 ; Inputs: 387 ; DX = Segment number of new base 388 ; Function: 389 ; Set up program base and copy term and ^C from int area 390 ; Returns: 391 ; None 392 ; Called at DOS init 393 0 00001277 E8[0000] CALL get_user_stack 0 0000127A 8E5C14 MOV DS,[SI + user_CS] 396 PDB_Block_len equ PDB_block_len ; NASM port label 0 0000127D FF360200 PUSH word [PDB_Block_len] 398 CreateCopy: 0 00001281 8EC2 MOV ES,DX 0 00001283 31F6 XOR SI,SI ; copy all 80h bytes 0 00001285 89F7 MOV DI,SI 0 00001287 B98000 MOV CX,80H 0 0000128A F3A5 REP MOVSW 404 ; DOS 3.3 7/9/86 405 0 0000128C B91400 MOV CX,FilPerProc ; copy handles in case of 0 0000128F BF1800 MOV DI,offset PDB_JFN_Table ; Set Handle Count has been issued 0 00001292 1E PUSH DS 0 00001293 C5363400 LDS SI,[PDB_JFN_Pointer] 0 00001297 F3A4 REP MOVSB 0 00001299 1F POP DS 412 413 ; DOS 3.3 7/9/86 0 0000129A 36F606[0000]FF TEST byte [ss:CreatePDB],0FFh; Shall we create a process? 0 000012A0 744B JZ Create_PDB_cont ; nope, old style call 416 ; 417 ; Here we set up for a new process... 418 ; 419 0 000012A2 16 PUSH ss 0 000012A3 1F POP DS 422 DOSAssume CS,,"MISC/Create_Copy" 0 000012A4 31DB XOR BX,BX ; dup all jfns 0 000012A6 B91400 MOV CX,FilPerProc ; only 20 of them 425 426 Create_dup_jfn: 0 000012A9 06 PUSH ES ; save new PDB 0 000012AA E8[0000] invoke SFFromHandle ; get sf pointer 0 000012AD B0FF MOV AL,-1 ; unassigned JFN 0 000012AF 7225 JC CreateStash ; file was not really open 0 000012B1 26F745050010 TEST word [ES:DI + sf_flags],sf_no_inherit 0 000012B7 751D JNZ CreateStash ; if no-inherit bit is set, skip dup. 433 ; 434 ; We do not inherit network file handles. 435 ; 0 000012B9 268A6502 MOV AH,BYTE PTR [ES:DI + sf_mode] 0 000012BD 80E4F0 AND AH,sharing_mask 438 sharing_net_fcb equ sharing_net_FCB ; NASM port equate 0 000012C0 80FC70 CMP AH,sharing_net_fcb 0 000012C3 7411 jz CreateStash 441 ; 442 ; The handle we have found is duplicatable (and inheritable). Perform 443 ; duplication operation. 444 ; 0 000012C5 893E[0000] MOV WORD PTR [THISSFT],DI 0 000012C9 8C06[0200] MOV WORD PTR [THISSFT+2],ES 0 000012CD E8[0000] invoke DOS_DUP ; signal duplication 448 ; 449 ; get the old sfn for copy 450 ; 0 000012D0 E8[0000] invoke pJFNFromHandle ; ES:DI is jfn 0 000012D3 268A05 MOV AL,[ES:DI] ; get sfn 453 ; 454 ; Take AL (old sfn or -1) and stash it into the new position 455 ; 456 CreateStash: 0 000012D6 07 POP ES 0 000012D7 26884718 MOV [ES:BX + PDB_JFN_Table],AL; copy into new place! 0 000012DB 43 INC BX ; next jfn... 460 create_dup_jfn equ Create_dup_jfn ; NASM port label 0 000012DC E2CB LOOP create_dup_jfn 462 0 000012DE 8B1E[0000] MOV BX,[CurrentPDB] ; get current process 0 000012E2 26891E1600 MOV [ES:PDB_Parent_PID],BX ; stash in child 0 000012E7 8C06[0000] MOV [CurrentPDB],ES 466 ASSUME DS:NOTHING 0 000012EB 8EDB MOV DS,BX 468 ; 469 ; end of new process create 470 ; 471 Create_PDB_cont: 0 000012ED 36C606[0000]00 MOV BYTE PTR [ss:CreatePDB],0h ; reset flag 0 000012F3 58 POP AX 474 475 entry SETMEM ; called from NEARDOSINIT, ss != DOSDATA 476 ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING 477 478 ; Inputs: 479 ; AX = Size of memory in paragraphs 480 ; DX = Segment 481 ; Function: 482 ; Completely prepares a program base at the 483 ; specified segment. 484 ; Called at DOS init 485 ; Outputs: 486 ; DS = DX 487 ; ES = DX 488 ; [0] has INT int_abort 489 ; [2] = First unavailable segment 490 ; [5] to [9] form a long call to the entry point 491 ; [10] to [13] have exit address (from int_terminate) 492 ; [14] to [17] have ctrl-C exit address (from int_ctrl_c) 493 ; [18] to [21] have fatal error address (from int_fatal_abort) 494 ; DX,BP unchanged. All other registers destroyed. 495 0 000012F4 31C9 XOR CX,CX 0 000012F6 8ED9 MOV DS,CX 0 000012F8 8EC2 MOV ES,DX 0 000012FA BE8800 MOV SI,addr_int_terminate 0 000012FD BF0A00 MOV DI,SAVEXIT 0 00001300 B90600 MOV CX,6 0 00001303 F3A5 REP MOVSW 0 00001305 26A30200 MOV [ES:2],AX 0 00001309 29D0 SUB AX,DX 0 0000130B 3DFF0F CMP AX,MAXDIF 0 0000130E 7603 JBE HAVDIF 0 00001310 B8FF0F MOV AX,MAXDIF 508 HAVDIF: 0 00001313 83E810 SUB AX,10H ; Allow for 100h byte "stack" 0 00001316 BB0C00 MOV BX,ENTRYPOINTSEG ; in .COM files 0 00001319 29C3 SUB BX,AX 0 0000131B B104 MOV CL,4 0 0000131D D3E0 SHL AX,CL 0 0000131F 8EDA MOV DS,DX 0 00001321 A30600 MOV WORD PTR [PDB_CPM_Call+1],AX 0 00001324 891E0800 MOV WORD PTR [PDB_CPM_Call+3],BX 0 00001328 C7060000CD20 MOV word [PDB_Exit_Call],(int_abort << 8) + mi_INT 0 0000132E C60605009A MOV BYTE PTR [PDB_CPM_Call],mi_Long_CALL 519 PDB_Call_System equ PDB_Call_system ; NASM port label 0 00001333 C7065000CD21 MOV WORD PTR [PDB_Call_System],(int_command << 8) + mi_INT 0 00001339 C6065200CB MOV BYTE PTR [PDB_Call_System+2],mi_Long_RET 0 0000133E C70634001800 MOV WORD PTR [PDB_JFN_Pointer],PDB_JFN_Table 0 00001344 8C1E3600 MOV WORD PTR [PDB_JFN_Pointer+2],DS 0 00001348 C70632001400 MOV WORD PTR [PDB_JFN_Length],FilPerProc 525 ; 526 ; The server runs several PDB's without creating them VIA EXEC. We need to 527 ; enumerate all PDB's at CPS time in order to find all references to a 528 ; particular SFT. We perform this by requiring that the server link together 529 ; for us all sub-PDB's that he creates. The requirement for us, now, is to 530 ; initialize this pointer. 531 ; 0 0000134E C7063800FFFF MOV word ptr [PDB_Next_PDB],-1 0 00001354 C7063A00FFFF MOV word ptr [PDB_Next_PDB+2],-1 0 0000135A C3 return 535 536 EndProc D_CREATE_PROCESS_DATA_BLOCK 537 538 ; ; 539 ; C A V E A T P R O G R A M M E R ; 540 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 541 procedure FETCHI_CHECK,NEAR 541 ****************** warning: proc FETCHI_CHECK... [-w+user] 542 ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING 0 0000135B 9C PUSHF 0 0000135C 36813E[0000]7258 CMP word [ss:FETCHI_TAG],22642 0 00001363 7403 JZ TAG_OK 0 00001365 E8[0000] invoke DOSINIT ; go to hell 547 TAG_OK: 0 00001368 9D POPF 0 00001369 C3 return 550 EndProc FETCHI_CHECK 551 552 BREAK <$GSetMediaID -- get set media ID> 553 ; Inputs: 554 ; BL= drive number as defined in IOCTL 555 ; AL= 0 get media ID 556 ; 1 set media ID 557 ; DS:DX= buffer containing information 558 ; DW 0 info level (set on input) 559 ; DD ? serial # 560 ; DB 11 dup(?) volume id 561 ; DB 8 dup(?) file system type 562 ; Function: 563 ; Get or set media ID 564 ; Returns: 565 ; carry clear, DS:DX is filled 566 ; carry set, error 567 568 procedure D_GSetMediaID,NEAR ;AN000; 568 ****************** warning: proc D_GSetMediaID... [-w+user] 569 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 570 0 0000136A B96608 MOV CX,0866H ;AN000;MS.; assume get for IOCTL 0 0000136D 3C00 CMP AL,0 ;AN001;MS.; get ? 0 0000136F 7407 JZ doioctl ;AN000;MS.; yes 0 00001371 3C01 CMP AL,1 ;AN000;MS.; set ? 0 00001373 7509 JNZ errorfunc ;AN000;MS.; no 0 00001375 B94608 MOV CX,0846H ;AN001;MS.; 577 doioctl: ;AN000; 0 00001378 B00D MOV AL,0DH ;AN000;MS.; generic IOCTL 0 0000137A E8[0000] invoke D_IOCTL ;AN000;MS.; let IOCTL take care of it 0 0000137D C3 return ;AN000;MS.; 581 errorfunc: ;AN000; 0 0000137E B001E9[0000] error error_invalid_function;AN000;MS. ; invalid function 583 EndProc D_GSetMediaID ;AN000; 584 585 END === Trace listing source: ../DOS/misc2.lst 1 ; SCCSID = @(#)misc2.asm 1.1 85/04/10 2 ;TITLE MISC2 - Miscellanious routines for MS-DOS 3 ;NAME MISC2 4 ; 5 ; Miscellaneous useful routines 6 ; 7 ; StrCpy 8 ; StrCmp 9 ; Ucase 10 ; StrLen 11 ; DStrLen 12 ; Idle 13 ; TableDispatch 14 ; FastInit ; DOS 4.0 15 ; FastRet ; DOS 4.0 16 ; NLS_OPEN ; DOS 4.0 17 ; NLS_LSEEK ; DOS 4.0 18 ; Fake_User_Stack ; DOS 4.0 19 ; GetDevList ; DOS 4.0 20 ; NLS_IOCTL ; DOS 4.0 21 ; NLS_GETEXT ; DOS 4.0 22 ; MSG_RETRIEVAL ; DOS 4.0 23 ; Fake_Version ; DOS 4.0 24 ; 25 ; Revision history: 26 ; 27 ; Created: ARR 30 March 1983 28 ; 29 ; A000 version 4.0 Jan. 1988 30 ; A001 DCR 486 - Share installation for >32mb drives 31 ; A006 DCR 503 - fake version number for IBMCACHE 32 33 [list -] 41 === Switch to base=008400h -> "DOSCODECODE" 42 section DOSCODECODE 43 [list -] 43 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 43 ****************** warning: out: BPB.INC... [-w+user] 43 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 51 52 i_need THISCDS,DWORD 53 I_Need RetryLoop,WORD 54 I_need fSharing,BYTE ; TRUE => server-issued call 55 I_need FastTable,BYTE ;AN000; 56 I_need FastFlg,BYTE ;AN000; 57 I_need User_SP_2F,WORD ;AN000; 58 I_need User_SP,WORD ;AN000; 59 I_need User_SS,WORD ;AN000; 60 I_need SysInitTable,BYTE ;AN000; 61 I_need EXTERR,WORD ;AN000; 62 I_need MSG_EXTERROR,DWORD ;AN000; 63 I_need fshare,byte ;AN001; 64 I_need Special_version,WORD ;AN006; 65 %if debug 66 I_need BugLev,WORD 67 I_need BugTyp,WORD 68 %include "bugtyp.nas" 69 %endif 70 71 Break 72 73 ; 74 ; Strcmp - compare ASCIZ DS:SI to ES:DI. Case INSENSITIVE. '/' = '\' 75 ; Strings of different lengths don't match. 76 ; Inputs: DS:SI - pointer to source string ES:DI - pointer to dest string 77 ; Outputs: Z if strings same, NZ if different 78 ; Registers modified: NONE 79 80 Procedure StrCmp,NEAR 80 ****************** warning: proc StrCmp... [-w+user] 81 ASSUME CS:DOSGroup,SS:DOSGroup,DS:NOTHING,ES:NOTHING 0 00001383 565750 SaveReg 83 Cmplp: 0 00001386 AC LODSB 85 %IF DBCS ;AN000; 86 invoke testkanj ;AN000;; 2/13/KK 87 jz notkanj1 ;AN000;; 2/13/KK 88 dec si ;AN000;; Do source again 2/13/KK 89 cmpsb ;AN000;; First byte 2/13/KK 90 JNZ PopRet ;AN000;; Strings dif 2/13/KK 91 cmpsb ;AN000;; Second byte of kanji char 2/13/KK 92 JNZ PopRet ;AN000;; Strings dif 2/13/KK 93 mov al,byte ptr [SI-1] ;AN000;; Need last byte in AL 2/13/KK 94 jmp short Tend ;AN000; 95 notkanj1: ;AN000;; 2/13/KK 96 %ENDIF ;AN000; 0 00001387 E83300 CALL uCase ; convert to upper case 0 0000138A E8[0000] Invoke PathChrCmp ; convert / to \. 0 0000138D 88C4 MOV AH,AL 0 0000138F 268A05 MOV AL,[ES:DI] 0 00001392 47 INC DI 0 00001393 E82700 CALL uCase ; convert to upper case 0 00001396 E8[0000] Invoke PathChrCmp ; convert / to \. 0 00001399 38C4 CMP AH,AL 0 0000139B 7504 JNZ PopRet ; Strings dif 106 Tend: 0 0000139D 08C0 OR AL,AL 0 0000139F 75E5 JNZ Cmplp ; More string 109 PopRet: 0 000013A1 585F5E RestoreReg 0 000013A4 C3 return 112 EndProc StrCmp 113 114 Break 115 116 ; 117 ; Strcpy - copy an ASCIZ string from DS:SI to ES:DI and make uppercase 118 ; FStrcpy - copy an ASCIZ string from DS:SI to ES:DI. no modification of 119 ; characters. 120 ; 121 ; Inputs: DS:SI - pointer to source string 122 ; ES:DI - pointer to destination string 123 ; Outputs: ES:DI point byte after nul byte at end of dest string 124 ; DS:SI point byte after nul byte at end of source string 125 ; Registers modified: SI,DI 126 127 Procedure StrCpy,NEAR 127 ****************** warning: proc StrCpy... [-w+user] 128 ASSUME CS:DOSGroup,SS:DOSGroup,DS:NOTHING,ES:NOTHING 0 000013A5 50 SaveReg 130 CPYLoop: 0 000013A6 AC LODSB 132 %IF DBCS ;AN000; 133 invoke testkanj ;AN000;; 2/13/KK 134 jz notkanj2 ;AN000;; 2/13/KK 135 STOSB ;AN000;; 2/13/KK 136 LODSB ;AN000;; 2/13/KK 137 STOSB ;AN000;; 2/13/KK 138 jmp short CPYLoop ;AN000;; 3/31/KK 139 140 notkanj2: ;AN000;; 2/13/KK 141 %ENDIF ;AN000; 0 000013A7 E81300 CALL uCase ; convert to upper case 0 000013AA E8[0000] Invoke PathChrCmp ; convert / to \. 0 000013AD AA STOSB 145 Tend2: 0 000013AE 08C0 OR AL,AL 0 000013B0 75F4 JNZ CPYLoop 0 000013B2 58 RestoreReg 0 000013B3 C3 return 150 EndProc StrCpy 151 152 Procedure FStrCpy,NEAR 152 ****************** warning: proc FStrCpy... [-w+user] 153 ASSUME CS:DOSGroup,SS:DOSGroup,DS:NOTHING,ES:NOTHING 0 000013B4 50 SaveReg 155 FCPYLoop: 0 000013B5 AC LODSB 0 000013B6 AA STOSB 0 000013B7 08C0 OR AL,AL 0 000013B9 75FA JNZ FCPYLoop 0 000013BB 58 RestoreReg 0 000013BC C3 return 162 EndProc FStrCpy 163 164 ; 165 ; Upper case the letter in AL. Most chars are non lowercase. 166 ; 167 Procedure uCase,NEAR 167 ****************** warning: proc uCase... [-w+user] 168 ; CMP AL,'a' 169 ; JAE Maybe 170 ; return 171 ;Maybe: 172 ; CMP AL,'z' 173 ; JA CaseRet 174 ; ADD AL,'A'-'a' 175 ;CaseRet: 176 ;;; 10/31/86 let's do file upper case for all DOS file names 0 000013BD E8[0000] invoke GetLet2 178 ;;; 10/31/86 let's do file upper case for all DOS file names 0 000013C0 C3 return 180 EndProc uCase 181 182 Break 183 184 ; 185 ; StrLen - Compute length of string ES:DI 186 ; Inputs: ES:DI - pointer to string 187 ; Outputs: CX is size of string INCLUDING the NUL 188 ; Registers modified: CX 189 190 Procedure StrLen,NEAR 190 ****************** warning: proc StrLen... [-w+user] 191 ASSUME CS:DOSGroup,SS:DOSGroup,DS:NOTHING,ES:NOTHING 0 000013C1 57 PUSH DI 0 000013C2 50 PUSH AX 0 000013C3 B9FFFF MOV CX,-1 0 000013C6 30C0 XOR AL,AL 0 000013C8 F2AE REPNE SCASB 0 000013CA F7D1 NOT CX 0 000013CC 58 POP AX 0 000013CD 5F POP DI 0 000013CE C3 return 201 EndProc StrLen 202 203 ; 204 ; DStrLen - Compute length of string DS:SI 205 ; Inputs: DS:SI - pointer to string 206 ; Outputs: CX is size of string INCLUDING the NUL 207 ; Registers modified: CX 208 Procedure DStrLen,NEAR 208 ****************** warning: proc DStrLen... [-w+user] 0 000013CF E80700 CALL XCHGP 0 000013D2 E8ECFF CALL StrLen 0 000013D5 E80100 CALL XCHGP 0 000013D8 C3 return 213 EndProc DStrLen 214 215 Break 216 217 Procedure XCHGP,NEAR 217 ****************** warning: proc XCHGP... [-w+user] 0 000013D9 1E06 SaveReg 0 000013DB 1F07 RestoreReg 0 000013DD 87F7 XCHG SI,DI 0 000013DF C3 return 222 EndProc XCHGP 223 224 Break 225 226 ; 227 ; Idle - when retrying an operation due to a lock/sharing violation, we spin 228 ; until RetryLoop is exhausted. 229 ; 230 ; Inputs: RetryLoop is the number of times we spin 231 ; Outputs: Wait 232 ; Registers modified: none 233 234 Procedure Idle,NEAR 234 ****************** warning: proc Idle... [-w+user] 235 ASSUME CS:DOSGroup,SS:DOSGROUP,DS:NOTHING,ES:NOTHING 0 000013E0 36F606[0000]FF TEST byte [ss:fSharing],-1 0 000013E6 75F7 retnz 0 000013E8 51 SaveReg 0 000013E9 368B0E[0000] MOV CX,[ss:RetryLoop] 0 000013EE E308 JCXZ Idle3 0 000013F0 51 Idle1: PUSH CX 0 000013F1 31C9 XOR CX,CX 0 000013F3 E2FE Idle2: LOOP Idle2 0 000013F5 59 POP CX 0 000013F6 E2F8 LOOP Idle1 0 000013F8 59 Idle3: RestoreReg 0 000013F9 C3 return 248 EndProc Idle 249 250 Break 251 252 ; 253 ; TableDispatch - given a table and an index, jmp to the approptiate 254 ; routine. Preserve all input registers to the routine. 255 ; 256 ; Inputs: Push return address 257 ; Push Table address 258 ; Push index (byte) 259 ; Outputs: appropriate routine gets jumped to. 260 ; return indicates invalid index 261 ; Registers modified: none. 262 263 TableFrame STRUC 0 00001383 ???? OldBP DW ? 0 00001385 ???? OldRet DW ? 0 00001387 ?? Index DB ? 0 00001388 ?? Pad DB ? 0 00001389 ???? Tab DW ? 0 0000138B ???? NewRet DW ? 270 TableFrame ENDS 271 272 procedure TableDispatch,NEAR 272 ****************** warning: proc TableDispatch... [-w+user] 273 ASSUME CS:DOSGroup,DS:NOTHING,SS:NOTHING,SS:NOTHING 0 000013FA 55 PUSH BP 0 000013FB 89E5 MOV BP,SP 0 000013FD 53 PUSH BX ; save BX 0 000013FE 8B5E06 MOV BX,[BP + Tab] ; get pointer to table 0 00001401 2E8A1F MOV BL,[CS:BX] ; maximum index 0 00001404 385E04 CMP [BP + Index],BL ; table error? 0 00001407 7317 JAE TableError ; yes 0 00001409 8A5E04 MOV BL,[BP + Index] ; get desired table index 0 0000140C 30FF XOR BH,BH ; convert to word 0 0000140E D1E3 SHL BX,1 ; convert to word pointer 0 00001410 43 INC BX ; point past first length byte 0 00001411 035E06 ADD BX,[BP + Tab] ; get real offset 0 00001414 2E8B1F MOV BX,[CS:BX] ; get contents of table entry 0 00001417 895E06 MOV [BP + Tab],BX ; put table entry into return address 0 0000141A 5B POP BX ; restore BX 0 0000141B 5D POP BP ; restore BP 0 0000141C 83C404 ADD SP,4 ; clean off Index and our return addr 0 0000141F C3 return ; do operation 292 TableError: 0 00001420 5B POP BX ; restore BX 0 00001421 5D POP BP ; restore BP 0 00001422 C20600 RET 6 ; clean off Index, Table and RetAddr 296 EndProc TableDispatch 297 298 Break 299 300 ; 301 ; TestNet - examine CDS pointed to by ThisCDS and see if it indicates a 302 ; network CDS. This will handle NULL cds also. 303 ; 304 ; Inputs: ThisCDS points to CDS or NULL 305 ; Outputs: ES:DI = ThisCDS 306 ; carry Set => network 307 ; carry Clear => local 308 ; Registers modified: none. 309 310 Procedure TestNet,NEAR 310 ****************** warning: proc TestNet... [-w+user] 311 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING 312 ThisCDS equ THISCDS ; NASM port label 0 00001425 97 xchg ax, di 314 extern doscode_getdosdata 0 00001426 E8[0000] call doscode_getdosdata 0 00001429 8EC0 mov es, ax 0 0000142B 26C406[0000] LES ax,[es:ThisCDS] 0 00001430 83F8FF CMP ax,-1 0 00001433 97 xchg ax, di 0 00001434 7408 je .CMCRet ; UNC? carry is clear 0 00001436 26F745430080 TEST word [ES:DI + curdir_flags],curdir_isnet 0 0000143C 7401 jz .ret ; --> NC 323 .CMCRet: 0 0000143E F5 CMC ; CY if networked 0 0000143F C3 .ret: return 326 327 EndProc TestNet 328 329 Break 330 331 ; 332 ; IsSFTNet - examine SF pointed to by ES:DI and see if it indicates a 333 ; network file. 334 ; 335 ; Inputs: ES:DI point to SFT 336 ; Outputs: Zero set if not network sft 337 ; zero reset otherwise 338 ; Carry CLEAR!!! 339 ; Registers modified: none. 340 341 Procedure IsSFTNet,NEAR 341 ****************** warning: proc IsSFTNet... [-w+user] 342 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING 0 00001440 26F745050080 TEST word [ES:DI + sf_flags],sf_isnet 0 00001446 C3 return 345 EndProc IsSFTNet 346 347 Break 348 349 ; 2F.122A multDOS function 350 ; DOS 4.00 2/9/87 351 ; FastInit - initialize the FASTXXX routine entry 352 ; in the FastTable 353 ; 354 ; Inputs: BX = FASTXXX ID ( 1=fastopen, 2=fastseek,,,,) 355 ; DS:SI = address of FASTXXX routine entry 356 ; SI = -1 for query only 357 ; Outputs: Carry flag clear, if success 358 ; Carry flag set, if failure 359 ; 360 ; 361 362 extern doscode_getdosdata 363 364 Procedure FastInit,NEAR ;AN000; 364 ****************** warning: proc FastInit... [-w+user] 365 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING ;AN000; 366 0 00001447 06 push es 0 00001448 E8[0000] call doscode_getdosdata 0 0000144B 8EC0 mov es, ax 370 0 0000144D BF[0200] MOV DI,OFFSET FastTable + 2 wrt DOSGROUP ;AN000;FO. points to fastxxx entry 0 00001450 4B DEC BX ;AN000;FO.;; decrement index 0 00001451 83FB02 cmp bx, 2 0 00001454 7317 jae fastinitinvalid 0 00001456 89DA MOV DX,BX ;AN000;FO.;; save bx 0 00001458 D1E3 SHL BX,1 ;AN000;FO.;; times 4 , each entry is DWORD 0 0000145A D1E3 SHL BX,1 ;AN000;FO. 0 0000145C 01DF ADD DI,BX ;AN000;FO. index to the entry 0 0000145E 268B4502 MOV AX,WORD PTR [es:DI+2] ;AN000;FO. get entry segment 380 fcheck: ;AN000; 0 00001462 B9[0000] MOV CX, DOSENTRY ;AN000;FO.;; get DOS segment ; => DOSENTRY 0 00001465 39C8 CMP AX,CX ;AN000;FO.;; first time installed ? 0 00001467 7407 JZ ok_install ;AN000;FO.;; yes 0 00001469 85C0 test ax, ax ;AN000;FO.; 0 0000146B 7403 JZ ok_install ;AN000;FO.; 386 fastinitinvalid: 0 0000146D F9 STC ;AN000;FO.;; already installed ! 0 0000146E EB19 JMP SHORT FSret ;AN000;FO. set carry 389 ok_install: ;AN000; 0 00001470 83FEFF CMP SI,-1 ;AN000;FO.; Query only ? 0 00001473 7414 JZ FSret ;AN000;FO.; yes (NC) 0 00001475 8CD9 MOV CX,DS ;AN000;FO.; get FASTXXX entry segment 0 00001477 8CD9 MOV CX,DS ;AN000;FO.;; get FASTXXX entry segment 0 00001479 26894D02 MOV WORD PTR [es:DI+2],CX ;AN000;FO.;; initialize routine entry 0 0000147D 268935 MOV WORD PTR [es:DI],SI ;AN000;FO.;; initialize routine offset 0 00001480 BF[0000] MOV DI,OFFSET FastFlg wrt DOSGROUP ;AN000;FO.; get addr of FASTXXX flags 0 00001483 01D7 ADD DI,DX ;AN000;FO.; index to a FASTXXX flag 0 00001485 26800D80 OR byte ptr [es:DI],Fast_yes ;AN000;FO.; indicate installed 399 ; (NC) 400 FSret: ;AN000; 0 00001489 07 pop es 0 0000148A C3 return ;AN000;FO. 403 EndProc FastInit ;AN000;FO. 404 405 Break 406 407 ; DOS 3.3 6/10/86 408 ; FastRet - indicate FASTXXXX not in memory 409 ; 410 ; Inputs: None 411 ; Outputs: AX = -1 and carry flag set 412 ; 413 ; Registers modified: none. 414 415 relocated fastentry 416 Procedure FastRet,FAR 416 ****************** warning: proc FastRet... [-w+user] 417 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING 0 0000148B B8FFFF MOV AX,-1 0 0000148E F9 STC 0 0000148F CB RET 421 EndProc FastRet 422 423 Break 424 425 ; DOS 3.3 6/10/86 426 ; NLS_OPEN - call $OPEN for NLSFUNC 427 ; 428 ; Inputs: Same input as $OPEN except CL = mode 429 ; Outputs: same output as $OPEN 430 ; 431 432 Procedure NLS_OPEN,NEAR 432 ****************** warning: proc NLS_OPEN... [-w+user] 433 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING 434 435 ; MOV BL,[CPSWFLAG] ; disable code page matching logic 436 ; MOV [CPSWFLAG],0 437 ; PUSH BX ; save current state 438 0 00001490 88C8 MOV AL,CL ; set up correct interface for $OPEN 0 00001492 E8[0000] invoke D_OPEN 441 442 ; POP BX ; restore current state 443 ; MOV [CPSWFLAG],BL 0 00001495 C3 RET 445 EndProc NLS_OPEN 446 447 Break 448 449 ; DOS 3.3 6/10/86 450 ; NLS_LSEEK - call $LSEEK for NLSFUNC 451 ; 452 ; Inputs: BP = open mode 453 ; Outputs: same output as $LSEEK 454 ; 455 456 Procedure NLS_LSEEK,NEAR 456 ****************** warning: proc NLS_LSEEK... [-w+user] 457 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING 458 459 user_SP equ User_SP ; NASM port label 0 00001496 36FF36[0000] PUSH word [ss:user_SP] ; save user stack 461 user_SS equ User_SS ; NASM port label 0 0000149B 36FF36[0000] PUSH word [ss:user_SS] 0 000014A0 E81000 CALL Fake_User_Stack 0 000014A3 89E8 MOV AX,BP ; set up correct interface for $LSEEK 0 000014A5 E8[0000] invoke D_LSEEK 0 000014A8 368F06[0000] POP word [ss:user_SS] ; restore user stack 0 000014AD 368F06[0000] POP word [ss:user_SP] 0 000014B2 C3 RET 469 EndProc NLS_LSEEK 470 471 472 Break 473 474 475 ; DOS 3.3 6/10/86 476 ; Fake_User_Stack - save user stack pointer 477 ; 478 479 Procedure Fake_User_Stack,NEAR 479 ****************** warning: proc Fake_User_Stack... [-w+user] 480 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING 481 0 000014B3 36A1[0000] MOV AX,[ss:User_SP_2F] ; replace with INT 2F stack 0 000014B7 36A3[0000] MOV [ss:user_SP],AX 0 000014BB 368C16[0000] MOV [ss:user_SS],ss ; DOSGROUP 485 0 000014C0 C3 RET 487 EndProc Fake_User_Stack 488 489 ; 490 Break 491 492 493 ; DOS 3.3 7/25/86 494 ; GetDevList - get device header list pointer 495 ; 496 ; Output: AX:BX points to the device header list 497 498 Procedure GetDevList,NEAR 498 ****************** warning: proc GetDevList... [-w+user] 499 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 500 501 extern SYSINITVAR 502 0 000014C1 E8[0000] call doscode_getdosdata 0 000014C4 8ED8 mov ds, ax 0 000014C6 BE[0000] mov si, SYSINITVAR 0 000014C9 8B4422 MOV AX,WORD PTR [SI + SYSI_DEV] 0 000014CC 8B5C24 MOV BX,WORD PTR [SI + SYSI_DEV+2] 508 0 000014CF C3 RET 510 EndProc GetDevList 511 512 Break 513 514 ; DOS 3.3 7/25/86 515 ; NLS_IOCTL - call $IOCTL for NLSFUNC 516 ; 517 ; Inputs: BP = function code 0CH 518 ; Outputs: same output as generic $IOCTL 519 ; 520 521 Procedure NLS_IOCTL,NEAR 521 ****************** warning: proc NLS_IOCTL... [-w+user] 522 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING 523 0 000014D0 36FF36[0000] PUSH word [ss:user_SP] ; save user stack 0 000014D5 36FF36[0000] PUSH word [ss:user_SS] 0 000014DA E8D6FF CALL Fake_User_Stack 0 000014DD 89E8 MOV AX,BP ; set up correct interface for $LSEEK 0 000014DF E8[0000] invoke D_IOCTL 0 000014E2 368F06[0000] POP word [ss:user_SS] ; restore user stack 0 000014E7 368F06[0000] POP word [ss:user_SP] 0 000014EC C3 RET 532 EndProc NLS_IOCTL 533 534 Break 535 536 ; DOS 3.3 7/25/86 537 ; NLS_GETEXT - 538 ; 539 ; Inputs: none 540 ; Outputs: AX = extended error 541 ; 542 543 Procedure NLS_GETEXT,NEAR 543 ****************** warning: proc NLS_GETEXT... [-w+user] 544 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING 545 0 000014ED 1E push ds 0 000014EE E8[0000] call doscode_getdosdata 0 000014F1 8ED8 mov ds, ax 0 000014F3 A1[0000] mov ax, [EXTERR] ; return extended error 0 000014F6 1F pop ds 0 000014F7 C3 RET 552 EndProc NLS_GETEXT 553 554 Break 555 556 ; DOS 4.00 557 ; 558 ; Inputs: DL=0 get extended error message addr 559 ; =1 set extended error message addr 560 ; =2 get parser error message addr 561 ; =3 set parser error message addr 562 ; =4 get critical error message addr 563 ; =5 set critical error message addr 564 ; =6 get file system error message addr 565 ; =7 set file system error message addr 566 ; =8 get address for code reduction 567 ; =9 set address for code reduction 568 ; Function: get/set message address 569 ; Outputs: ES:DI points to addr when get 570 ; 571 572 Procedure MSG_RETRIEVAL,NEAR ;AN000; 572 ****************** warning: proc MSG_RETRIEVAL... [-w+user] 573 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING ;AN000; 574 0 000014F8 50 PUSH AX ;AN000;;MS. save regs 0 000014F9 56 PUSH SI ;AN000;;MS. save regs 0 000014FA 1E push ds 0 000014FB E8[0000] call doscode_getdosdata 0 000014FE 8ED8 mov ds, ax 0 00001500 89D0 MOV AX,DX ;AN000;;MS. 0 00001502 BE[0000] MOV SI,OFFSET MSG_EXTERROR wrt DOSGROUP ;AN000;;MS. 0 00001505 A801 TEST AL,1 ;AN000;;MS. get ? 0 00001507 7401 JZ toget ;AN000;;MS. yes 0 00001509 48 DEC ax ;AN000;;MS. 585 toget: ;AN000; 0 0000150A 3C0A cmp al, 10 0 0000150C 7312 jae .invalid 0 0000150E D0E0 SHL AL,1 ;AN000;;MS. times 2 0 00001510 30E4 XOR AH,AH ;AN000;;MS. 0 00001512 01C6 ADD SI,AX ;AN000;;MS. position to the entry 0 00001514 F6C201 TEST DL,1 ;AN000;;MS. get ? (NC) 0 00001517 7414 JZ getget ;AN000;;MS. yes 0 00001519 893C MOV WORD PTR [SI],DI ;AN000;;MS. set MSG 0 0000151B 8C4402 MOV WORD PTR [SI+2],ES ;AN000;;MS. address to ES:DI 0 0000151E EB0F JMP SHORT MSGret ;AN000;;MS. exit 596 .invalid: 0 00001520 F6C201 test dl, 1 0 00001523 7505 jnz .invalidset 0 00001525 BFFFFF mov di, -1 0 00001528 8EC7 mov es, di 601 .invalidset: 0 0000152A F9 stc 0 0000152B EB02 jmp MSGret 604 getget: ;AN000; 0 0000152D C43C LES DI,[SI] ;AN000;;MS. get msg addr 606 MSGret: ;AN000; 0 0000152F 1F pop ds 0 00001530 5E POP SI ;AN000;;MS. 0 00001531 58 POP AX ;AN000;;MS. 0 00001532 C3 return ;AN000;;MS. exit 611 612 EndProc MSG_RETRIEVAL ;AN000; 613 614 615 Break 616 617 ; 618 ; Inputs: DL=0 current version number 619 ; <>0 special version number 620 ; Function: set special version number 621 ; Outputs: version number is changed 622 ; 623 624 Procedure Fake_version,NEAR ;AN000; 624 ****************** warning: proc Fake_version... [-w+user] 625 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING ;AN000; 626 0 00001533 1E push ds 0 00001534 50 push ax 0 00001535 E8[0000] call doscode_getdosdata 0 00001538 8ED8 mov ds, ax 0 0000153A 58 pop ax 0 0000153B 8916[0000] MOV [Special_version],DX ;AN006;MS. 0 0000153F 1F pop ds 0 00001540 C3 return ;AN006;;MS. exit 635 636 EndProc Fake_version ;AN006;;MS. 637 638 END === Trace listing source: ../DOS/crit.lst 1 ; SCCSID = @(#)crit.asm 1.1 85/04/10 2 ;TITLE CRIT - Critical Section Routines 3 ;NAME CRIT 4 ; 5 ; Critical Section Routines 6 ; 7 ; Critical section handlers 8 ; 9 ; Modification history: 10 ; 11 ; Created: ARR 30 March 1983 12 ; 13 14 [list -] 14 ****************** warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi] 14 <1> [list -] 19 %include "dosseg.nas" 1 <1> ; SCCSID = @(#)dosseg.asm 1.1 85/04/10 2 <1> ; SCCSID = @(#)dosseg.asm 1.1 85/04/10 3 <1> ; 4 <1> ; segment ordering for MSDOS 5 <1> ; 6 <1> 7 <1> %include "ddataseg.nas" 1 <2> === Switch to base=001140h -> "DOSSTART" 2 <2> section DOSSTART align=16 PUBLIC class=DOSSTART 3 <2> ; (no prior section) ; DOSSTART ENDS 4 <2> === Switch to base=001140h -> "START" 5 <2> section START align=1 PUBLIC class=START 6 <2> ; (no prior section) ; START ENDS 7 <2> === Switch to base=001140h -> "CONSTANTS" 8 <2> section CONSTANTS align=2 PUBLIC class=CONST 9 <2> ; (no prior section) ; CONSTANTS ENDS 10 <2> === Switch to base=001140h -> "DATA" 11 <2> section DATA align=2 PUBLIC class=DATA 12 <2> ; (no prior section) ; DATA ENDS 13 <2> === Switch to base=001140h -> "TABLE" 14 <2> section TABLE align=2 PUBLIC class=TABLE 15 <2> ; (no prior section) ; TABLE ENDS 16 <2> === Switch to base=001140h -> "CODE" 17 <2> section CODE align=1 PUBLIC class=CODE 18 <2> ; (no prior section) ; CODE ENDS 19 <2> === Switch to base=001140h -> "DOSDATATABLE" 20 <2> section DOSDATATABLE align=2 PUBLIC class=DOSDATACODE 21 <2> ; (no prior section) ; DOSDATATABLE ENDS 22 <2> === Switch to base=001140h -> "DOSDATACODE" 23 <2> section DOSDATACODE align=1 PUBLIC class=DOSDATACODE 24 <2> ; (no prior section) ; DOSDATACODE ENDS 25 <2> === Switch to base=001140h -> "LAST" 26 <2> section LAST align=16 PUBLIC class=LAST 27 <2> ; (no prior section) ; LAST ENDS 28 <2> 29 <2> group DOSGROUP DOSSTART START CONSTANTS DATA TABLE CODE DOSDATATABLE DOSDATACODE LAST 8 <1> 9 <1> %include "dcodeseg.nas" 1 <2> 2 <2> %ifndef DCODESEGNAS 3 <2> %assign DCODESEGNAS 1 4 <2> === Switch to base=008400h -> "DOSCODETABLE" 5 <2> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <2> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=008400h -> "DOSCODECODE" 7 <2> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <2> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=008400h -> "DOSBIOCODE" 9 <2> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=008400h -> "BIOCODE" 10 <2> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <2> 12 <2> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <2> 14 <2> %endif 10 <1> === Switch to base=001140h -> "LAST" 11 <1> section LAST 12 <1> ; (no prior section) ; LAST ENDS 20 21 [list +] === Switch to base=008400h -> "DOSCODECODE" 22 section DOSCODECODE 23 24 global ECritDisk 25 global ECritMem 26 global ECritSFT 27 global LCritDisk 28 global LCritMem 29 global LCritSFT 30 31 ECritDisk: 32 ECritMem: 33 ECritSFT: 0 00001541 53 push bx 0 00001542 BB[0100] mov bx, patch_dosdata_EcritDisk 0 00001545 EB10 jmp transfer_doscode_to_dosdata 37 38 LCritDisk: 39 LCritMem: 40 LCritSFT: 0 00001547 53 push bx 0 00001548 BB[0900] mov bx, patch_dosdata_LcritDisk 0 0000154B EB0A jmp transfer_doscode_to_dosdata 44 45 global ECritDevice 46 global LCritDevice 47 48 ECritDevice: 0 0000154D 53 push bx 0 0000154E BB[1100] mov bx, patch_dosdata_EcritDevice 0 00001551 EB04 jmp transfer_doscode_to_dosdata 52 53 LCritDevice: 0 00001553 53 push bx 0 00001554 BB[1900] mov bx, patch_dosdata_LcritDevice 56 57 global transfer_doscode_to_dosdata 58 59 transfer_doscode_to_dosdata: 60 lframe 0 61 lpar word, in_ip_out_cs 62 lpar word, in_bx_out_ip 63 lpar word, in_ax_out_dosdata_retf 0 00001557 50 push ax ; ?in_ax = ax 0 00001558 E81500 call doscode_getdosdata 66 lpar dword, transferto 0 0000155B 50 push ax ; ?transferto + 2 = DOSDATA 0 0000155C 53 push bx ; ?transferto = entrypoint 0 0000155D 5589E5 lenter 0 00001560 8CCB mov bx, cs 0 00001562 875E0A xchg bx, [bp + ?in_ip_out_cs] ; ?out_cs = cs 0 00001565 875E08 xchg bx, [bp + ?in_bx_out_ip] ; ?out_ip = ip 73 ; bx = ?in_bx 0 00001568 B8[0000] mov ax, dosdata_retf 0 0000156B 874606 xchg ax, [bp + ?in_ax_out_dosdata_retf] 76 ; ?out_dosdata_retf = dosdata_retf 77 ; ax = ?in_ax 0 0000156E 5D lleave , optimiserestoresp 0 0000156F CB retf ; branch to ?transferto, 80 ; ?out_dosdata_retf and ?out_csip on stack 81 82 global doscode_getdosdata 83 doscode_getdosdata: 0 00001570 1E push ds 0 00001571 B80000 mov ax, 0 0 00001574 8ED8 mov ds, ax ; ds => IVT 0 00001576 A1C600 mov ax, [31h * 4 + 2] ; ds => DOSDATA 0 00001579 1F pop ds 0 0000157A C3 retn 90 91 === Switch to base=001140h -> "DOSDATACODE" 92 section DOSDATACODE ; in DOSDATA 93 94 dosdata_retf: 0 0000125E CB retf 96 97 [list -] 97 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 97 ****************** warning: out: BPB.INC... [-w+user] 97 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 103 104 I_need User_In_AX,WORD 105 i_need CurrentPDB,WORD 106 %if debug 107 I_need BugLev,WORD 108 I_need BugTyp,WORD 109 %include "bugtyp.nas" 110 %endif 111 112 Break 113 114 ; 115 ; Each handler must leave everything untouched; including flags! 116 ; 117 ; Sleaze for time savings: first instruction is a return. This is patched 118 ; by the sharer to be a PUSH AX to complete the correct routines. 119 ; 120 121 global patch_dosdata_EcritDisk 122 patch_dosdata_EcritDisk: 0 0000125F C3 RETn 124 ; PUSH AX 125 fmt TypSect,LevReq,<"PDB $x entering $x">, 0 00001260 B80180 MOV AX,8000h+critDisk 127 int_ibm equ int_IBM ; NASM port equate 0 00001263 CD2A INT int_ibm 0 00001265 58 POP AX 0 00001266 C3 retn 131 132 global patch_dosdata_LcritDisk 133 patch_dosdata_LcritDisk: 0 00001267 C3 RETn 135 ; PUSH AX 136 fmt TypSect,LevReq,<"PDB $x entering $x">, 0 00001268 B80181 MOV AX,8100h+critDisk 0 0000126B CD2A INT int_ibm 0 0000126D 58 POP AX 0 0000126E C3 retn 141 142 global patch_dosdata_EcritDevice 143 patch_dosdata_EcritDevice: 0 0000126F C3 RETn 145 ; PUSH AX 146 fmt TypSect,LevReq,<"PDB $x entering $x">, 0 00001270 B80280 MOV AX,8000h+critDevice 0 00001273 CD2A INT int_ibm 0 00001275 58 POP AX 0 00001276 C3 retn 151 152 global patch_dosdata_LcritDevice 153 patch_dosdata_LcritDevice: 0 00001277 C3 RETn 155 ; PUSH AX 0 00001278 B80281 MOV AX,8100h+critDevice 0 0000127B CD2A INT int_ibm 0 0000127D 58 POP AX 0 0000127E C3 retn 160 161 END === Trace listing source: ../DOS/cpmio.lst 1 ; SCCSID = @(#)cpmio.asm 1.1 85/04/10 2 ;TITLE CPMIO - device IO for MSDOS 3 ;NAME CPMIO 4 ; 5 ; Standard device IO for MSDOS (first 12 function calls) 6 ; 7 8 [list -] 13 14 ; 15 ; Old style CP/M 1-12 system calls to talk to reserved devices 16 ; 17 ; $Std_Con_Input_No_Echo 18 ; $Std_Con_String_Output 19 ; $Std_Con_String_Input 20 ; $RawConIO 21 ; $RawConInput 22 ; RAWOUT 23 ; RAWOUT2 24 ; 25 ; Revision history: 26 ; 27 ; A000 version 4.00 - Jan 1988 28 ; A002 PTM -- dir >lpt3 hangs 29 ; 30 ; 31 ; 32 ; 33 ; 34 ; 35 ; 36 ; 37 ; 38 ; 39 === Switch to base=008400h -> "DOSCODECODE" 40 section DOSCODECODE 41 42 ;.xcref 43 [list -] 43 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 43 ****************** warning: out: BPB.INC... [-w+user] 43 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 43 ****************** warning: out: DEVSYM.INC... [-w+user] 48 ;.cref 49 50 %ifndef KANJI 51 %iassign KANJI 0 ;FALSE 52 %endif 53 54 ; The following routines form the console I/O group (funcs 1,2,6,7,8,9,10,11). 55 ; They assume ES and DS NOTHING, while not strictly correct, this forces data 56 ; references to be SS or CS relative which is desired. 57 58 i_need CARPOS,BYTE 59 i_need STARTPOS,BYTE 60 i_need INBUF,128 61 i_need INSMODE,BYTE 62 i_need user_SP,WORD 63 EXTRN EscChar:BYTE ; lead byte for function keys 64 EXTRN CanChar:BYTE ; Cancel character 65 EXTRN OUTCHA:NEAR ;AN000 char out with status check 2/11/KK 66 i_need Printer_Flag,BYTE 67 i_need SCAN_FLAG,BYTE 68 i_need DATE_FLAG,WORD 69 i_need Packet_Temp,WORD ; temporary packet used by readtime 70 i_need DEVCALL,DWORD 71 i_need InterChar,BYTE ;AN000;interim char flag ( 0 = regular char) 72 i_need InterCon,BYTE ;AN000;console flag ( 1 = in interim mode ) 73 i_need SaveCurFlg,BYTE ;AN000;console out ( 1 = print and do not advance) 74 i_need COUNTRY_CDPG,byte ;AN000; 2/12/KK 75 i_need TEMP_VAR,WORD ;AN000; 2/12/KK 76 i_need DOS34_FLAG,WORD ;AN000; 2/12/KK 77 i_need FETCHI_TAG, word 78 79 80 Break 81 %IF DBCS ;AN000; 82 83 ;-------------------------------- Start of Korean Support 2/11/KK 84 procedure D_STD_CON_INPUT_NO_ECHO,NEAR ;System call 8 ;AN000; 85 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 86 87 StdCILop: ;AN000; 88 invoke INTER_CON_INPUT_NO_ECHO ;AN000; 89 transfer InterApRet ; go to return fuction ;AN000; 90 91 EndProc D_STD_CON_INPUT_NO_ECHO ;AN000; 92 93 procedure INTER_CON_INPUT_NO_ECHO,NEAR ;AN000; 94 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 95 ;-----------------------------------End of Korean Support 2/11/KK 96 97 ; Inputs: 98 ; None 99 ; Function: 100 ; Same as $STD_CON_INPUT_NO_ECHO but uses interim character read from 101 ; the device. 102 ; Returns: 103 ; AL = character 104 ; Zero flag SET if interim character, RESET otherwise 105 106 %ELSE ;AN000; 107 108 109 ; 110 ; Inputs: 111 ; None 112 ; Function: 113 ; Input character from console, no echo 114 ; Returns: 115 ; AL = character 116 117 procedure D_STD_CON_INPUT_NO_ECHO,NEAR ;System call 8 117 ****************** warning: proc D_STD_CON_INPUT_NO_ECHO... [-w+user] 118 ASSUME DS:NOTHING,ES:NOTHING 119 120 %ENDIF 0 0000157B 1E PUSH DS 0 0000157C 56 PUSH SI 123 INTEST: 0 0000157D E8[0000] invoke STATCHK 0 00001580 7547 JNZ Get 126 ;************************************************************************* 0 00001582 36803E[0000]00 cmp byte [ss:Printer_Flag],0 ; is printer idle? 0 00001588 7505 jnz no_sys_wait 0 0000158A B405 mov ah,5 ; get input status with system wait 0 0000158C E8[0000] invoke IOFUNC 131 no_sys_wait: 132 ;************************************************************************** 0 0000158F B484 MOV AH,84h 0 00001591 CD2A INT int_IBM 135 136 ;;; 7/15/86 update the date in the idle loop 137 ;;; Dec 19, 1986 D.C.L. changed following CMP to Byte Ptr from Word Ptr 138 ;;;; to shorten loop in consideration of the PC Convertible 139 0 00001593 36803E[0000]FF CMP byte ptr [ss:DATE_FLAG],-1 ; date is updated may be every 0 00001599 7527 JNZ NoUpdate ; 65535 x ? ms if no one calls 0 0000159B 50 PUSH AX 0 0000159C 53 PUSH BX ; following is tricky, 0 0000159D 51 PUSH CX ; it may be called by critical handler 0 0000159E 52 PUSH DX ; at that time, DEVCALL is used by 146 ; other's READ or WRITE 0 0000159F 1E PUSH DS ; save DS = SFT's sgement 0 000015A0 16 PUSH ss ; READTIME must use DS=CS 0 000015A1 1F POP DS 150 0 000015A2 B80000 MOV AX,0 ; therefore, we save DEVCALL 0 000015A5 E8DC02 CALL Save_Restore_Packet ; save DEVCALL packet 0 000015A8 E8[0000] invoke READTIME ; readtime 0 000015AB B80100 MOV AX,1 0 000015AE E8D302 CALL Save_Restore_Packet ; restore DEVCALL packet 156 0 000015B1 36813E[0000]7258 CMP word ptr [ss:FETCHI_TAG],22642 0 000015B8 7403 JZ check_ok 0 000015BA E8[0000] invoke DOSINIT ; should never come here 160 check_ok: 161 0 000015BD 1F POP DS ; restore DS 0 000015BE 5A POP DX 0 000015BF 59 POP CX 0 000015C0 5B POP BX 0 000015C1 58 POP AX 167 NoUpdate: 0 000015C2 36FF06[0000] INC word [ss:DATE_FLAG] 169 170 ;;; 7/15/86 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 171 Intest equ INTEST ; NASM port label 0 000015C7 EBB4 JMP Intest 173 Get: 0 000015C9 30E4 XOR AH,AH 0 000015CB E8[0000] invoke IOFUNC 0 000015CE 5E POP SI 0 000015CF 1F POP DS 178 ;;; 7/15/86 0 000015D0 36C606[0000]00 MOV BYTE PTR [ss:SCAN_FLAG],0 0 000015D6 3C00 CMP AL,0 ; extended code ( AL ) 0 000015D8 7506 JNZ noscan 0 000015DA 36C606[0000]01 MOV BYTE PTR [ss:SCAN_FLAG],1 ; set this flag for ALT_Q key 183 184 noscan: 185 ;;; 7/15/86 186 %IF DBCS ;AN000; 187 cmp byte [ss:InterChar],1 ;AN000; set the zero flag if the character3/31/KK ;AN000; 188 %ENDIF ;AN000; 0 000015E0 C3 return 190 %IF DBCS ;AN000; 191 EndProc INTER_CON_INPUT_NO_ECHO ;AN000; ;2/11/KK ;AN000; 192 %ELSE ;AN000; 193 EndProc D_STD_CON_INPUT_NO_ECHO 194 %ENDIF ;AN000; 195 196 Break 197 198 ; Inputs: 199 ; DS:DX Point to output string '$' terminated 200 ; Function: 201 ; Print the string on the console device 202 ; Returns: 203 ; None 204 205 procedure D_STD_CON_STRING_OUTPUT,NEAR ;System call 9 205 ****************** warning: proc D_STD_CON_STRING_OUTPUT... [-w+user] 206 ASSUME DS:NOTHING,ES:NOTHING 207 0 000015E1 89D6 MOV SI,DX 209 STRING_OUT1: 0 000015E3 AC LODSB 211 %IF DBCS ;AN000; 212 invoke TESTKANJ ;AN000; 2/11/KK ;AN000; 213 jz SBCS00 ;AN000; 2/11/KK ;AN000; 214 invoke OUTT ;AN000; 2/11/KK ;AN000; 215 LODSB ;AN000; 2/11/KK ;AN000; 216 JMP NEXT_STR1 ;AN000; 2/11/KK ;AN000; 217 SBCS00: ;AN000; 2/11/KK ;AN000; 218 %ENDIF ;AN000; 0 000015E4 3C24 CMP AL,'$' 0 000015E6 74F8 retz 221 NEXT_STR1: 0 000015E8 E8[0000] invoke OUTT 0 000015EB EBF6 JMP STRING_OUT1 224 225 EndProc D_STD_CON_STRING_OUTPUT 226 227 %IF DBCS ;AN000; 228 ;=== Push trace listing source: kstrin.nas 229 %include "kstrin.nas" ;AN000; 230 ;=== Pop trace listing source 231 %ELSE ;AN000; 232 ;=== Push trace listing source: strin.nas 233 %include "strin.nas" 1 <1> ; SCCSID = @(#)strin.asm 1.2 85/04/18 2 <1> Break 3 <1> 4 <1> ; Inputs: 5 <1> ; DS:DX Point to an input buffer 6 <1> ; Function: 7 <1> ; Fill buffer from console input until CR 8 <1> ; Returns: 9 <1> ; None 10 <1> 11 <1> procedure D_STD_CON_STRING_INPUT,NEAR ;System call 10 11 ****************** <1> warning: proc D_STD_CON_STRING_INPUT... [-w+user] 12 <1> ASSUME DS:NOTHING,ES:NOTHING 13 <1> 0 000015ED 8CD0 MOV AX,SS 0 000015EF 8EC0 MOV ES,AX 0 000015F1 89D6 MOV SI,DX 0 000015F3 30ED XOR CH,CH 0 000015F5 AD LODSW 19 <1> ; 20 <1> ; AL is the buffer length 21 <1> ; AH is the template length 22 <1> ; 0 000015F6 08C0 OR AL,AL 0 000015F8 74E6 retz ;Buffer is 0 length!!? 0 000015FA 88E3 MOV BL,AH ;Init template counter 0 000015FC 88EF MOV BH,CH ;Init template counter 27 <1> ; 28 <1> ; BL is the number of bytes in the template 29 <1> ; 0 000015FE 38D8 CMP AL,BL 0 00001600 7605 JBE NOEDIT ;If length of buffer inconsistent with contents 0 00001602 80380D CMP BYTE PTR [BX+SI],c_CR 0 00001605 7402 JZ EDITON ;If CR correctly placed EDIT is OK 34 <1> ; 35 <1> ; The number of chars in the template is >= the number of chars in buffer or 36 <1> ; there is no CR at the end of the template. This is an inconsistant state 37 <1> ; of affairs. Pretend that the template was empty: 38 <1> ; 39 <1> NOEDIT: 0 00001607 88EB MOV BL,CH ;Reset buffer 41 <1> EDITON: 0 00001609 88C2 MOV DL,AL 0 0000160B 4A DEC DX ;DL is # of bytes we can put in the buffer 44 <1> ; 45 <1> ; Top level. We begin to read a line in. 46 <1> ; 47 <1> NEWLIN: 0 0000160C 36A0[0000] MOV AL,[ss:CARPOS] 0 00001610 36A2[0000] MOV [ss:STARTPOS],AL ;Remember position in raw buffer 0 00001614 56 PUSH SI 0 00001615 BF[0000] MOV DI,OFFSET INBUF wrt DOSGROUP ;Build the new line here 0 00001618 36882E[0000] MOV [ss:INSMODE],CH ;Insert mode off 0 0000161D 88EF MOV BH,CH ;No chars from template yet 0 0000161F 88EE MOV DH,CH ;No chars to new line yet 0 00001621 E857FF invoke D_STD_CON_INPUT_NO_ECHO ;Get first char 0 00001624 3C0A CMP AL,c_LF ;Linefeed 0 00001626 7503 JNZ GOTCH ;Filter out LF so < works 58 <1> ; 59 <1> ; This is the main loop of reading in a character and processing it. 60 <1> ; 61 <1> ; BH is the index of the next byte in the template 62 <1> ; BL is the length of the template 63 <1> ; DH is the number of bytes in the buffer 64 <1> ; DL is the length of the buffer 65 <1> ; 66 <1> entry GETCH 0 00001628 E850FF invoke D_STD_CON_INPUT_NO_ECHO 68 <1> GOTCH: 69 <1> ; 70 <1> ; Brain-damaged TP ignored ^F in case his BIOS did not flush the 71 <1> ; input queue. 72 <1> ; 0 0000162B 3C06 CMP AL,"F"-"@" 0 0000162D 74F9 JZ GETCH 75 <1> ; 76 <1> ; If the leading char is the function-key lead byte 77 <1> ; 78 <1> ESCCHAR equ EscChar ; NASM port label 0 0000162F 363A06[0000] CMP AL,[ss:ESCCHAR] 0 00001634 7443 JZ ESCape ;change reserved keyword DBM 5-7-87 81 <1> ; 82 <1> ; Rubout and ^H are both destructive backspaces. 83 <1> ; 0 00001636 3C7F CMP AL,c_DEL 0 00001638 7436 JZ BACKSPJ 0 0000163A 3C08 CMP AL,c_BS 0 0000163C 7432 JZ BACKSPJ 88 <1> ; 89 <1> ; ^W deletes backward once and then backs up until a letter is before the 90 <1> ; cursor 91 <1> ; 0 0000163E 3C17 CMP AL,"W" - "@" 93 <1> ; The removal of the comment characters before the jump statement will 94 <1> ; cause ^W to backup a word. 95 <1> ;*** JZ WordDel 0 00001640 90 NOP 0 00001641 90 NOP 0 00001642 3C15 CMP AL,"U" - "@" 99 <1> ; The removal of the comment characters before the jump statement will 100 <1> ; cause ^U to clear a line. 101 <1> ;*** JZ LineDel 0 00001644 90 NOP 0 00001645 90 NOP 104 <1> 105 <1> ; 106 <1> ; CR terminates the line. 107 <1> ; 0 00001646 3C0D CMP AL,c_CR 0 00001648 7432 JZ ENDLIN 110 <1> ; 111 <1> ; LF goes to a new line and keeps on reading. 112 <1> ; 0 0000164A 3C0A CMP AL,c_LF 0 0000164C 7444 JZ PHYCRLF 115 <1> ; 116 <1> ; ^X (or ESC) deletes the line and starts over 117 <1> ; 118 <1> CANCHAR equ CanChar ; NASM port label 0 0000164E 363A06[0000] CMP AL,[ss:CANCHAR] 0 00001653 746B JZ KILNEW 121 <1> ; 122 <1> ; Otherwise, we save the input character. 123 <1> ; 124 <1> SAVCH: 0 00001655 38D6 CMP DH,DL 0 00001657 7319 JAE BUFFUL ; buffer is full. 0 00001659 AA STOSB 0 0000165A FEC6 INC DH ; increment count in buffer. 0 0000165C E8[0000] invoke BUFOUT ;Print control chars nicely 0 0000165F 36803E[0000]00 CMP BYTE PTR [ss:INSMODE],0 0 00001665 75C1 JNZ GETCH ; insertmode => don't advance template 0 00001667 38DF CMP BH,BL 0 00001669 73BD JAE GETCH ; no more characters in template 0 0000166B 46 INC SI ; Skip to next char in template 0 0000166C FEC7 INC BH ; remember position in template 0 0000166E EBB8 JMP SHORT GETCH 137 <1> 138 <1> BACKSP equ BackSp ; NASM port label 0 00001670 EB61 BACKSPJ: JMP SHORT BACKSP 140 <1> 141 <1> BUFFUL: 0 00001672 B007 MOV AL,7 ; Bell to signal full buffer 0 00001674 E8[0000] invoke OUTT 0 00001677 EBAF JMP SHORT GETCH 145 <1> 146 <1> ESCape: ;change reserved keyword DBM 5-7-87 0 00001679 E9[0000] transfer OEMFunctionKey ; let the OEM's handle the key dispatch 148 <1> 149 <1> ENDLIN: 0 0000167C AA STOSB ; Put the CR in the buffer 0 0000167D E8[0000] invoke OUTT ; Echo it 0 00001680 5F POP DI ; Get start of user buffer 0 00001681 8875FF MOV [DI-1],DH ; Tell user how many bytes 0 00001684 FEC6 INC DH ; DH is length including CR 155 <1> entry COPYNEW 0 00001686 1E06 SaveReg 0 00001688 1F07 RestoreReg ; XCHG ES,DS 0 0000168A BE[0000] MOV SI,OFFSET INBUF wrt DOSGROUP 0 0000168D 88F1 MOV CL,DH ; set up count 0 0000168F F3A4 REP MOVSB ; Copy final line to user buffer 0 00001691 C3 return 162 <1> ; 163 <1> ; Output a CRLF to the user screen and do NOT store it into the buffer 164 <1> ; 165 <1> PHYCRLF: 0 00001692 E84B01 invoke CRLF 0 00001695 EB91 JMP GETCH 168 <1> 169 <1> ; 170 <1> ; Delete the previous line 171 <1> ; 172 <1> LineDel: 0 00001697 08F6 OR DH,DH 174 <1> GetCh equ GETCH ; NASM port label 0 00001699 748D JZ GetCh 0 0000169B E83B00 Call BackSpace 0 0000169E EBF7 JMP LineDel 178 <1> 179 <1> ; 180 <1> ; delete the previous word. 181 <1> ; 182 <1> WordDel: 183 <1> WordLoop: 0 000016A0 E83600 Call BackSpace ; backspace the one spot 0 000016A3 08F6 OR DH,DH 0 000016A5 7416 JZ GetChJ 0 000016A7 268A45FF MOV AL,[ES:DI-1] 0 000016AB 3C30 cmp al,'0' 189 <1> GetChj equ GetChJ ; NASM port label 0 000016AD 720E jb GetChj 0 000016AF 3C39 cmp al,'9' 0 000016B1 76ED jbe WordLoop 0 000016B3 0C20 OR AL,20h 0 000016B5 3C61 CMP AL,'a' 0 000016B7 7204 JB GetChJ 0 000016B9 3C7A CMP AL,'z' 0 000016BB 76E3 JBE WordLoop 198 <1> GetChJ: 0 000016BD E968FF JMP GetCh 200 <1> ; 201 <1> ; The user wants to throw away what he's typed in and wants to start over. We 202 <1> ; print the backslash and then go to the next line and tab to the correct spot 203 <1> ; to begin the buffered input. 204 <1> ; 205 <1> entry KILNEW 0 000016C0 B05C MOV AL,"\" 0 000016C2 E8[0000] invoke OUTT ;Print the CANCEL indicator 0 000016C5 5E POP SI ;Remember start of edit buffer 209 <1> PUTNEW: 0 000016C6 E81701 invoke CRLF ;Go to next line on screen 0 000016C9 36A0[0000] MOV AL,[ss:STARTPOS] 0 000016CD E8[0000] invoke TAB ;Tab over 0 000016D0 E939FF JMP NEWLIN ;Start over again 214 <1> 215 <1> 216 <1> ; 217 <1> ; Destructively back up one character position 218 <1> ; 219 <1> entry BackSp 0 000016D3 E80300 Call BackSpace 0 000016D6 E94FFF JMP GetCh 222 <1> 223 <1> BackSpace: 0 000016D9 08F6 OR DH,DH 0 000016DB 7419 JZ OLDBAK ;No chars in line, do nothing to line 0 000016DD E85800 CALL BACKUP ;Do the backup 0 000016E0 268A05 MOV AL,[ES:DI] ;Get the deleted char 0 000016E3 3C20 CMP AL," " 0 000016E5 730F JAE OLDBAK ;Was a normal char 0 000016E7 3C09 CMP AL,c_HT 0 000016E9 741B JZ BAKTAB ;Was a tab, fix up users display 232 <1> ;; 9/27/86 fix for ctrl-U backspace 0 000016EB 3C15 CMP AL,"U"-"@" ; ctrl-U is a section symbol not ^U 0 000016ED 7407 JZ OLDBAK 0 000016EF 3C14 CMP AL,"T"-"@" ; ctrl-T is a paragraphs symbol not ^T 0 000016F1 7403 JZ OLDBAK 237 <1> ;; 9/27/86 fix for ctrl-U backspace 0 000016F3 E84500 CALL BACKMES ;Was a control char, zap the '^' 239 <1> OLDBAK: 0 000016F6 36803E[0000]00 CMP BYTE PTR [ss:INSMODE],0 0 000016FC 7593 retnz ;In insert mode, done 0 000016FE 08FF OR BH,BH 0 00001700 748F retz ;Not advanced in template, stay where we are 0 00001702 FECF DEC BH ;Go back in template 0 00001704 4E DEC SI 0 00001705 C3 return 247 <1> 248 <1> BAKTAB: 0 00001706 57 PUSH DI 0 00001707 4F DEC DI ;Back up one char 0 00001708 FD STD ;Go backward 0 00001709 88F1 MOV CL,DH ;Number of chars currently in line 0 0000170B B020 MOV AL," " 0 0000170D 53 PUSH BX 0 0000170E B307 MOV BL,7 ;Max 0 00001710 E30E JCXZ FIGTAB ;At start, do nothing 257 <1> FNDPOS: 0 00001712 AE SCASB ;Look back 0 00001713 7609 JNA CHKCNT 0 00001715 26807D0109 CMP BYTE PTR [ES:DI+1],9 0 0000171A 7409 JZ HAVTAB ;Found a tab 0 0000171C FECB DEC BL ;Back one char if non tab control char 263 <1> CHKCNT: 0 0000171E E2F2 LOOP FNDPOS 265 <1> FIGTAB: 0 00001720 362A1E[0000] SUB BL,[ss:STARTPOS] 267 <1> HAVTAB: 0 00001725 28F3 SUB BL,DH 0 00001727 00D9 ADD CL,BL 0 00001729 80E107 AND CL,7 ;CX has correct number to erase 0 0000172C FC CLD ;Back to normal 0 0000172D 5B POP BX 0 0000172E 5F POP DI 0 0000172F 74C5 JZ OLDBAK ;Nothing to erase 275 <1> TABBAK: 0 00001731 E80700 invoke BACKMES 0 00001734 E2FB LOOP TABBAK ;Erase correct number of chars 0 00001736 EBBE JMP SHORT OLDBAK 279 <1> 280 <1> BACKUP: 0 00001738 FECE DEC DH ;Back up in line 0 0000173A 4F DEC DI 283 <1> BACKMES: 0 0000173B B008 MOV AL,c_BS ;Backspace 0 0000173D E8[0000] invoke OUTT 0 00001740 B020 MOV AL," " ;Erase 0 00001742 E8[0000] invoke OUTT 0 00001745 B008 MOV AL,c_BS ;Backspace 0 00001747 E9[0000] JMP OUTT ;Done 290 <1> 291 <1> ;User really wants an ESC character in his line 292 <1> entry TwoEsc 0 0000174A 36A0[0000] MOV AL,[ss:ESCCHAR] 0 0000174E E904FF JMP SAVCH 295 <1> 296 <1> ;Copy the rest of the template 297 <1> entry COPYLIN 0 00001751 88D9 MOV CL,BL ;Total size of template 0 00001753 28F9 SUB CL,BH ;Minus position in template, is number to move 0 00001755 EB07 JMP SHORT COPYEACH 301 <1> 302 <1> entry CopyStr 0 00001757 E83400 invoke FINDOLD ;Find the char 0 0000175A EB02 JMP SHORT COPYEACH ;Copy up to it 305 <1> 306 <1> ;Copy one char from template to line 307 <1> entry COPYONE 0 0000175C B101 MOV CL,1 309 <1> ;Copy CX chars from template to line 310 <1> COPYEACH: 0 0000175E 36C606[0000]00 MOV BYTE PTR [ss:INSMODE],0 ;All copies turn off insert mode 0 00001764 38D6 CMP DH,DL 0 00001766 740F JZ GETCH2 ;At end of line, can't do anything 0 00001768 38DF CMP BH,BL 0 0000176A 740B JZ GETCH2 ;At end of template, can't do anything 0 0000176C AC LODSB 0 0000176D AA STOSB 0 0000176E E8[0000] invoke BUFOUT 0 00001771 FEC7 INC BH ;Ahead in template 0 00001773 FEC6 INC DH ;Ahead in line 0 00001775 E2E7 LOOP COPYEACH 322 <1> GETCH2: 0 00001777 E9AEFE JMP GETCH 324 <1> 325 <1> ;Skip one char in template 326 <1> entry SKIPONE 0 0000177A 38DF CMP BH,BL 0 0000177C 74F9 JZ GETCH2 ;At end of template 0 0000177E FEC7 INC BH ;Ahead in template 0 00001780 46 INC SI 0 00001781 E9A4FE JMP GETCH 332 <1> 333 <1> entry SKIPSTR 0 00001784 E80700 invoke FINDOLD ;Find out how far to go 0 00001787 01CE ADD SI,CX ;Go there 0 00001789 00CF ADD BH,CL 0 0000178B E99AFE JMP GETCH 338 <1> 339 <1> ;Get the next user char, and look ahead in template for a match 340 <1> ;CX indicates how many chars to skip to get there on output 341 <1> ;NOTE: WARNING: If the operation cannot be done, the return 342 <1> ; address is popped off and a jump to GETCH is taken. 343 <1> ; Make sure nothing extra on stack when this routine 344 <1> ; is called!!! (no PUSHes before calling it). 345 <1> FINDOLD: 0 0000178E E8EAFD invoke D_STD_CON_INPUT_NO_ECHO 0 00001791 363A06[0000] CMP AL,[ss:ESCCHAR] ; did he type a function key? 0 00001796 7506 JNZ FindSetup ; no, set up for scan 0 00001798 E8E0FD invoke D_STD_CON_INPUT_NO_ECHO ; eat next char 350 <1> NotFnd equ NOTFND ; NASM port label 0 0000179B EB1E JMP NotFnd ; go try again 0 0000179D 90 nop ; identicalise 353 <1> FindSetup: 0 0000179E 88D9 MOV CL,BL 0 000017A0 28F9 SUB CL,BH ;CX is number of chars to end of template 0 000017A2 7417 JZ NOTFND ;At end of template 0 000017A4 49 DEC CX ;Cannot point past end, limit search 0 000017A5 7414 JZ NOTFND ;If only one char in template, forget it 0 000017A7 06 PUSH ES 0 000017A8 1E PUSH DS 0 000017A9 07 POP ES 0 000017AA 57 PUSH DI 0 000017AB 89F7 MOV DI,SI ;Template to ES:DI 0 000017AD 47 INC DI 0 000017AE F2AE REPNE SCASB ;Look 0 000017B0 5F POP DI 0 000017B1 07 POP ES 0 000017B2 7507 JNZ NOTFND ;Didn't find the char 0 000017B4 F6D1 NOT CL ;Turn how far to go into how far we went 0 000017B6 00D9 ADD CL,BL ;Add size of template 0 000017B8 28F9 SUB CL,BH ;Subtract current pos, result distance to skip 0 000017BA C3 return 373 <1> 374 <1> NOTFND: 0 000017BB 5D POP BP ;Chuck return address 0 000017BC E969FE JMP GETCH 377 <1> 378 <1> entry REEDIT 0 000017BF B040 MOV AL,"@" ;Output re-edit character 0 000017C1 E8[0000] invoke OUTT 0 000017C4 5F POP DI 0 000017C5 57 PUSH DI 0 000017C6 06 PUSH ES 0 000017C7 1E PUSH DS 0 000017C8 E8BBFE invoke COPYNEW ;Copy current line into template 0 000017CB 1F POP DS 0 000017CC 07 POP ES 0 000017CD 5E POP SI 0 000017CE 88F3 MOV BL,DH ;Size of line is new size template 0 000017D0 E9F3FE JMP PUTNEW ;Start over again 391 <1> 392 <1> entry EXITINS 393 <1> entry ENTERINS 0 000017D3 36F616[0000] NOT BYTE PTR [ss:INSMODE] 0 000017D8 E94DFE JMP GETCH 396 <1> 397 <1> ;Put a real live ^Z in the buffer (embedded) 398 <1> entry CTRLZ 0 000017DB B01A MOV AL,"Z"-"@" 0 000017DD E975FE JMP SAVCH 401 <1> 402 <1> ;Output a CRLF 403 <1> entry CRLF 0 000017E0 B00D MOV AL,c_CR 0 000017E2 E8[0000] invoke OUTT 0 000017E5 B00A MOV AL,c_LF 0 000017E7 E9[0000] JMP OUTT 408 <1> 409 <1> EndProc D_STD_CON_STRING_INPUT 410 <1> 411 <1> 234 ;=== Pop trace listing source 235 %ENDIF ;AN000; 236 237 Break 238 239 ; Inputs: 240 ; DL = -1 if input 241 ; else DL is output character 242 ; Function: 243 ; Input or output raw character from console, no echo 244 ; Returns: 245 ; AL = character 246 247 procedure D_RAW_CON_IO,NEAR ; System call 6 247 ****************** warning: proc D_RAW_CON_IO... [-w+user] 248 ASSUME DS:NOTHING,ES:NOTHING 249 0 000017EA 88D0 MOV AL,DL 0 000017EC 3CFF CMP AL,-1 0 000017EE 7403 JZ RAW22 ;AN000; 0 000017F0 EB43 JMP RAWOUT ;AN000; 0 000017F2 90 nop ; identicalise 255 RAW22: ;AN000; 0 000017F3 36C43E[0000] LES DI,[ss:user_SP] ; Get pointer to register save area 0 000017F8 31DB XOR BX,BX 0 000017FA E8[0000] invoke GET_IO_SFT 0 000017FD 72BB retc 260 %IF DBCS ;AN000; 261 Intercon equ InterCon ; NASM port label 262 push word ptr [Intercon] ;AN000; 263 mov byte [Intercon],0 ;AN000; disable interim characters 264 %ENDIF ;AN000; 0 000017FF B401 MOV AH,1 0 00001801 E8[0000] invoke IOFUNC 0 00001804 750B JNZ RESFLG 268 %IF DBCS ;AN000; 269 pop word ptr [InterCon] ;AN000; restore interim flag 270 %ENDIF ;AN000; 0 00001806 E8[0000] invoke SPOOLINT 0 00001809 26804D1640 OR BYTE PTR [ES:DI + user_F],40H ; Set user's zero flag 0 0000180E 30C0 XOR AL,AL 0 00001810 C3 return 275 276 RESFLG: 0 00001811 26806516BF AND BYTE PTR [ES:DI + user_F],0FFH-40H ; Reset user's zero flag 278 %IF DBCS ;AN000; 279 XOR AH,AH ;AN000; 280 invoke IOFUNC ;AN000; get the character 281 pop word ptr [InterCon] ;AN000; 282 return ;AN000; 283 %ENDIF ;AN000; ;AN000; 284 285 RILP: 0 00001816 E8[0000] invoke SPOOLINT 287 288 ; Inputs: 289 ; None 290 ; Function: 291 ; Input raw character from console, no echo 292 ; Returns: 293 ; AL = character 294 295 entry D_RAW_CON_INPUT ; System call 7 296 0 00001819 53 PUSH BX 0 0000181A 31DB XOR BX,BX 0 0000181C E8[0000] invoke GET_IO_SFT 0 0000181F 5B POP BX 0 00001820 72EE retc 0 00001822 B401 MOV AH,1 0 00001824 E8[0000] invoke IOFUNC 0 00001827 7506 JNZ Got 0 00001829 B484 MOV AH,84h 0 0000182B CD2A INT int_IBM 0 0000182D EBE7 JMP RILP 308 Got: 0 0000182F 30E4 XOR AH,AH 0 00001831 E8[0000] invoke IOFUNC 311 %IF DBCS ;AN000; 312 cmp byte [InterChar],1 ;AN000; 2/11/KK 313 ; 2/11/KK 314 ; Sets the application zero flag depending on the 2/11/KK 315 ; zero flag upon entry to this routine. Then returns 2/11/KK 316 ; from system call. 2/11/KK 317 ; 2/11/KK 318 entry InterApRet ;AN000; 2/11/KK ;AN000; 319 pushf ;AN000; 3/16/KK 320 push ds ;AN000; 3/16/KK 321 push bx ;AN000; 3/16/KK 322 Context DS ;AN000; 3/16/KK 323 MOV BX,offset COUNTRY_CDPG.ccDosCodePage wrt DOSGROUP 324 cmp word ptr [bx],934 ;AN000; 3/16/KK korean code page ? 325 pop bx ;AN000; 3/16/KK 326 pop ds ;AN000; 3/16/KK 327 je do_koren ;AN000; 3/16/KK 328 popf ;AN000; 3/16/KK 329 return ;AN000; 3/16/KK 330 do_koren: ;AN000; 3/16/KK 331 popf ;AN000; 332 LES DI,[user_SP] ;AN000; Get pointer to register save area KK 333 jnz sj0 ;AN000; 2/11/KK 334 OR BYTE PTR [ES:DI + user_F],40H ;AN000; Set user's zero flag 2/11/KK 335 return ;AN000; 2/11/KK 336 sj0: ;AN000; 2/11/KK 337 AND BYTE PTR [ES:DI + user_F],0FFH-40H ;AN000; Reset user's zero flag 2/KK 338 %ENDIF ;AN000; 0 00001834 C3 return ;AN000; 340 ; 341 ; Output the character in AL to stdout 342 ; 343 entry RAWOUT 344 0 00001835 53 PUSH BX 0 00001836 BB0100 MOV BX,1 347 0 00001839 E8[0000] invoke GET_IO_SFT 0 0000183C 721B JC RAWRET1 350 0 0000183E 8B5C05 MOV BX,[SI + sf_flags] 352 353 ; 354 ; If we are a network handle OR if we are not a local device then go do the 355 ; output the hard way. 356 ; 357 358 sf_isNet equ sf_isnet ; NASM port equate 0 00001841 81E38080 AND BX,sf_isNet + devid_device 0 00001845 81FB8000 CMP BX,devid_device 361 RawNorm equ RAWNORM ; NASM port label 0 00001849 7510 JNZ RawNorm 363 %IF DBCS ;AN000; 364 TEST byte [SaveCurFlg],01H ;AN000; print but no cursor adv? 365 JNZ RAWNORM ;AN000; 2/11/KK 366 %ENDIF ;AN000; 367 368 ; TEST BX,sf_isnet ; output to NET? 369 ; JNZ RAWNORM ; if so, do normally 370 ; TEST BX,devid_device ; output to file? 371 ; JZ RAWNORM ; if so, do normally 372 0 0000184B 1E PUSH DS 0 0000184C C55C07 LDS BX,[SI + sf_devptr] ; output to special? 0 0000184F F6470410 TEST BYTE PTR [BX+SDEVATT],ISSPEC 0 00001853 1F POP DS 0 00001854 7405 JZ RAWNORM ; if not, do normally 0 00001856 CD29 INT int_fastcon ; quickly output the char 379 RAWRET: 0 00001858 F8 CLC 381 RAWRET1: 0 00001859 5B POP BX 0 0000185A C3 return 384 RAWNORM: 0 0000185B E80700 CALL RAWOUT3 0 0000185E EBF8 JMP RAWRET 387 388 ; 389 ; Output the character in AL to handle in BX 390 ; 391 entry RAWOUT2 392 0 00001860 E8[0000] invoke GET_IO_SFT 0 00001863 72F5 retc 395 RAWOUT3: 0 00001865 50 PUSH AX 0 00001866 EB0D JMP SHORT RAWOSTRT 398 ROLP: 0 00001868 E8[0000] invoke SPOOLINT 0 0000186B 36810E[0000]0002 OR word [ss:DOS34_FLAG],CTRL_BREAK_FLAG ;AN002; set control break 0 00001872 E8[0000] invoke DSKSTATCHK ;AN002; check control break 402 RAWOSTRT: 0 00001875 B403 MOV AH,3 0 00001877 E8[0000] invoke IOFUNC 0 0000187A 74EC JZ ROLP 0 0000187C 58 POP AX 0 0000187D B402 MOV AH,2 0 0000187F E8[0000] invoke IOFUNC 0 00001882 F8 CLC ; Clear carry indicating successful 0 00001883 C3 return 411 EndProc D_RAW_CON_IO 412 413 ; Inputs: 414 ; AX=0 save the DEVCALL request packet 415 ; =1 restore the DEVCALL request packet 416 ; Function: 417 ; save or restore the DEVCALL packet 418 ; Returns: 419 ; none 420 421 procedure Save_Restore_Packet,NEAR 421 ****************** warning: proc Save_Restore_Packet... [-w+user] 422 ASSUME DS:NOTHING,ES:NOTHING 423 0 00001884 1E PUSH DS 0 00001885 06 PUSH ES 0 00001886 56 PUSH SI 0 00001887 57 PUSH DI 0 00001888 83F800 CMP AX,0 ; save packet 0 0000188B 7409 JZ save_packet 430 restore_packet: 0 0000188D BE[0000] MOV SI,OFFSET Packet_Temp wrt DOSGROUP ;sourec 0 00001890 BF[0000] MOV DI,OFFSET DEVCALL wrt DOSGROUP ;destination 0 00001893 EB07 JMP set_seg 0 00001895 90 nop ; identicalise 435 save_packet: 0 00001896 BF[0000] MOV DI,OFFSET Packet_Temp wrt DOSGROUP ;destination 0 00001899 BE[0000] MOV SI,OFFSET DEVCALL wrt DOSGROUP ;source 438 set_seg: 0 0000189C 8CD0 MOV AX,ss ; set DS,ES to DOSGROUP 0 0000189E 8ED8 MOV DS,AX 0 000018A0 8EC0 MOV ES,AX 0 000018A2 B90B00 MOV CX,11 ; 11 words to move 0 000018A5 F3A5 REP MOVSW 444 0 000018A7 5F POP DI 0 000018A8 5E POP SI 0 000018A9 07 POP ES 0 000018AA 1F POP DS 0 000018AB C3 return 450 EndProc Save_Restore_Packet 451 452 END === Trace listing source: ../DOS/cpmio2.lst 1 ; SCCSID = @(#)cpmio2.asm 1.1 85/04/11 2 ;TITLE CPMIO2 - device IO for MSDOS 3 ;NAME CPMIO2 4 5 [list -] 10 11 ; 12 ; Old style CP/M 1-12 system calls to talk to reserved devices 13 ; 14 ; $Std_Con_Input 15 ; $Std_Con_Output 16 ; OUTT 17 ; TAB 18 ; BUFOUT 19 ; $Std_Aux_Input 20 ; $Std_Aux_Output 21 ; $Std_Printer_Output 22 ; $Std_Con_Input_Status 23 ; $Std_Con_Input_Flush 24 ; 25 ; Revision History: 26 ; 27 ; AN000 version 4.00 - Jan. 1988 28 ; 29 === Switch to base=008400h -> "DOSCODECODE" 30 section DOSCODECODE 31 32 ;.xcref 33 [list -] 33 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 33 ****************** warning: out: BPB.INC... [-w+user] 33 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 33 ****************** warning: out: DEVSYM.INC... [-w+user] 37 ;.cref 38 39 ; The following routines form the console I/O group (funcs 1,2,6,7,8,9,10,11). 40 ; They assume ES and DS NOTHING, while not strictly correct, this forces data 41 ; references to be SS or CS relative which is desired. 42 43 i_need CARPOS,BYTE 44 i_need CHARCO,BYTE 45 i_need PFLAG,BYTE 46 i_need CurrentPDB,WORD ;AN000; 47 i_need InterCon,BYTE ;AN000; 48 i_need SaveCurFlg,BYTE ;AN000; 49 50 51 Break 52 53 ; Inputs: 54 ; None 55 ; Function: 56 ; Input character from console, echo 57 ; Returns: 58 ; AL = character 59 60 procedure D_STD_CON_INPUT,NEAR ;System call 1 60 ****************** warning: proc D_STD_CON_INPUT... [-w+user] 61 ASSUME DS:NOTHING,ES:NOTHING 62 63 %IF DBCS ;AN000; 64 push word ptr [InterCon] ;AN000; 65 mov byte [InterCon],01H ;AN000; 66 invoke INTER_CON_INPUT_NO_ECHO ;AN000; 67 pop word ptr [InterCon] ;AN000; 68 pushf ;AN000; 69 push AX ;AN000; 70 mov byte [SaveCurFlg],0 ;AN000; 71 jnz sj0 ;AN000; 72 mov byte [SaveCurFlg],1 ;AN000; 73 sj0: ;AN000; 74 invoke OUTT ;AN000; 75 SaveCurFLg equ SaveCurFlg ; NASM port label 76 mov byte [SaveCurFLg],0 ;AN000; 77 pop AX ;AN000; 78 popf ;AN000; 79 jz D_STD_CON_INPUT ;AN000; 80 %ELSE ;AN000; 0 000018AC E8[0000] invoke D_STD_CON_INPUT_NO_ECHO 0 000018AF 50 PUSH AX 0 000018B0 E80400 invoke OUTT 0 000018B3 58 POP AX 85 %ENDIF ;AN000; 0 000018B4 C3 return 87 EndProc D_STD_CON_INPUT 88 89 Break 90 91 ; Inputs: 92 ; DL = character 93 ; Function: 94 ; Output character to console 95 ; Returns: 96 ; None 97 98 procedure D_STD_CON_OUTPUT,NEAR ;System call 2 98 ****************** warning: proc D_STD_CON_OUTPUT... [-w+user] 99 public OUTCHA ;AN000; 100 ASSUME DS:NOTHING,ES:NOTHING 101 0 000018B5 88D0 MOV AL,DL 103 104 entry OUTT 0 000018B7 3C20 CMP AL,20H 0 000018B9 725F JB CTRLOUT 0 000018BB 3C7F CMP AL,c_DEL 0 000018BD 7405 JZ OUTCH 109 OUTCHA: ;AN000; 0 000018BF 36FE06[0000] INC BYTE PTR [ss:CARPOS] 111 OUTCH: 0 000018C4 1E PUSH DS 0 000018C5 56 PUSH SI 0 000018C6 36FE06[0000] INC BYTE PTR [ss:CHARCO] ;invoke statchk... 0 000018CB 368026[0000]3F AND BYTE PTR [ss:CHARCO],00111111B ;AN000; every 64th char 0 000018D1 7505 JNZ OUTSKIP 0 000018D3 50 PUSH AX 0 000018D4 E8[0000] invoke STATCHK 0 000018D7 58 POP AX 120 OUTSKIP: 0 000018D8 E8[0000] invoke RAWOUT ;output the character 0 000018DB 5E POP SI 0 000018DC 1F POP DS 124 %IF DBCS ;AN000; 125 TEST byte [SaveCurFlg],01H ;AN000;print but no cursor adv? 2/13/KK 126 retnz ;AN000;if so then do not send to prt2/13/KK 127 %ENDIF 0 000018DD 36F606[0000]FF TEST BYTE PTR [ss:PFLAG],-1 0 000018E3 74CF retz 0 000018E5 53 PUSH BX 0 000018E6 1E PUSH DS 0 000018E7 56 PUSH SI 0 000018E8 BB0100 MOV BX,1 0 000018EB E8[0000] invoke GET_IO_SFT 0 000018EE 7224 JC TRIPOPJ 0 000018F0 8B5C05 MOV BX,[SI + sf_flags] 0 000018F3 F7C30080 TEST BX,sf_isnet ; output to NET? 0 000018F7 751B JNZ TRIPOPJ ; if so, no echo 0 000018F9 F7C38000 TEST BX,devid_device ; output to file? 0 000018FD 7415 JZ TRIPOPJ ; if so, no echo 0 000018FF BB0400 MOV BX,4 0 00001902 E8[0000] invoke GET_IO_SFT 0 00001905 720D JC TRIPOPJ 0 00001907 F744050008 TEST word [SI + sf_flags],sf_net_spool ; StdPrn redirected? 0 0000190C 7409 JZ LISSTRT2J ; No, OK to echo 0 0000190E 36C606[0000]00 MOV BYTE PTR [ss:PFLAG],0 ; If a spool, NEVER echo 147 TRIPOPJ: 0 00001914 E98B00 JMP TRIPOP 149 150 LISSTRT2J: 0 00001917 E98500 JMP LISSTRT2 152 153 CTRLOUT: 0 0000191A 3C0D CMP AL,c_CR 0 0000191C 7420 JZ ZERPOS 0 0000191E 3C08 CMP AL,c_BS 0 00001920 7428 JZ BACKPOS 0 00001922 3C09 CMP AL,c_HT 0 00001924 759E JNZ OUTCH 0 00001926 36A0[0000] MOV AL,[ss:CARPOS] 0 0000192A 0CF8 OR AL,0F8H 0 0000192C F6D8 NEG AL 163 164 entry TAB 165 0 0000192E 51 PUSH CX 0 0000192F 88C1 MOV CL,AL 0 00001931 B500 MOV CH,0 0 00001933 E307 JCXZ POPTAB 170 TABLP: 0 00001935 B020 MOV AL," " 0 00001937 E87DFF invoke OUTT 0 0000193A E2F9 LOOP TABLP 174 POPTAB: 0 0000193C 59 POP CX 0 0000193D C3 return 177 178 ZERPOS: 0 0000193E 36C606[0000]00 MOV BYTE PTR [ss:CARPOS],0 0 00001944 E97DFF JMP OUTCH 0 00001947 E96DFF OUTJ: JMP OUTT 182 183 BACKPOS: 0 0000194A 36FE0E[0000] DEC BYTE PTR [ss:CARPOS] 0 0000194F E972FF JMP OUTCH 186 187 entry BUFOUT 0 00001952 3C20 CMP AL," " 0 00001954 73F1 JAE OUTJ ;Normal char 0 00001956 3C09 CMP AL,9 0 00001958 74ED JZ OUTJ ;OUT knows how to expand tabs 192 193 ;DOS 3.3 7/14/86 0 0000195A 3C15 CMP AL,"U"-"@" ; turn ^U to section symbol 0 0000195C 740D JZ CTRLU 0 0000195E 3C14 CMP AL,"T"-"@" ; turn ^T to paragraph symbol 0 00001960 7409 JZ CTRLU 198 NOT_CTRLU: 199 ;DOS 3.3 7/14/86 200 0 00001962 50 PUSH AX 0 00001963 B05E MOV AL,"^" 0 00001965 E84FFF invoke OUTT ;Print '^' before control chars 0 00001968 58 POP AX 0 00001969 0C40 OR AL,40H ;Turn it into Upper case mate 206 CTRLU: 0 0000196B E849FF invoke OUTT 0 0000196E C3 return 209 EndProc D_STD_CON_OUTPUT 210 211 Break 212 213 ; Inputs: 214 ; None 215 ; Function: 216 ; Returns character from aux input 217 ; Returns: 218 ; Character in AL 219 220 procedure D_STD_AUX_INPUT,NEAR ;System call 3 220 ****************** warning: proc D_STD_AUX_INPUT... [-w+user] 221 ASSUME DS:NOTHING,ES:NOTHING 222 0 0000196F E8[0000] invoke STATCHK 0 00001972 BB0300 MOV BX,3 0 00001975 E8[0000] invoke GET_IO_SFT 0 00001978 72F4 retc 0 0000197A EB03 JMP SHORT TAISTRT 228 AUXILP: 0 0000197C E8[0000] invoke SPOOLINT 230 TAISTRT: 0 0000197F B401 MOV AH,1 0 00001981 E8[0000] invoke IOFUNC 0 00001984 74F6 JZ AUXILP 0 00001986 30E4 XOR AH,AH 0 00001988 E8[0000] invoke IOFUNC 0 0000198B C3 return 237 EndProc D_STD_AUX_INPUT 238 239 Break 240 241 ; Inputs: 242 ; Character in DL 243 ; Function: 244 ; Output character to aux output 245 ; Returns: 246 ; Nothing 247 248 procedure D_STD_AUX_OUTPUT,NEAR ;System call 4 248 ****************** warning: proc D_STD_AUX_OUTPUT... [-w+user] 249 ASSUME DS:NOTHING,ES:NOTHING 250 0 0000198C 53 PUSH BX 0 0000198D BB0300 MOV BX,3 0 00001990 EB04 JMP SHORT SENDOUT 254 255 EndProc D_STD_AUX_OUTPUT 256 257 Break 258 259 ; Inputs: 260 ; DL = Character 261 ; Function: 262 ; Output the character to the list device 263 ; Returns: 264 ; None 265 266 procedure D_STD_PRINTER_OUTPUT,NEAR ;System call 5 266 ****************** warning: proc D_STD_PRINTER_OUTPUT... [-w+user] 267 ASSUME DS:NOTHING,ES:NOTHING 268 0 00001992 53 PUSH BX 0 00001993 BB0400 MOV BX,4 271 272 SENDOUT: 0 00001996 88D0 MOV AL,DL 0 00001998 50 PUSH AX 0 00001999 E8[0000] invoke STATCHK 0 0000199C 58 POP AX 0 0000199D 1E PUSH DS 0 0000199E 56 PUSH SI 279 LISSTRT2: 0 0000199F E8[0000] invoke RAWOUT2 281 TRIPOP: 0 000019A2 5E POP SI 0 000019A3 1F POP DS 0 000019A4 5B POP BX 0 000019A5 C3 return 286 EndProc D_STD_PRINTER_OUTPUT 287 288 Break 289 290 ; Inputs: 291 ; None 292 ; Function: 293 ; Check console input status 294 ; Returns: 295 ; AL = -1 character available, = 0 no character 296 297 procedure D_STD_CON_INPUT_STATUS,NEAR ;System call 11 297 ****************** warning: proc D_STD_CON_INPUT_STATUS... [-w+user] 298 ASSUME DS:NOTHING,ES:NOTHING 299 0 000019A6 E8[0000] invoke STATCHK 0 000019A9 B000 MOV AL,0 ; no xor!! 0 000019AB 74F8 retz 0 000019AD 0CFF OR AL,-1 0 000019AF C3 return 305 EndProc D_STD_CON_INPUT_STATUS 306 307 Break 308 309 ; Inputs: 310 ; AL = DOS function to be called after flush (1,6,7,8,10) 311 ; Function: 312 ; Flush console input buffer and perform call in AL 313 ; Returns: 314 ; Whatever call in AL returns or AL=0 if AL was not 1,6,7,8 or 10 315 316 procedure D_STD_CON_INPUT_FLUSH,NEAR ;System call 12 316 ****************** warning: proc D_STD_CON_INPUT_FLUSH... [-w+user] 317 ASSUME DS:NOTHING,ES:NOTHING 318 0 000019B0 50 PUSH AX 0 000019B1 52 PUSH DX 0 000019B2 31DB XOR BX,BX 0 000019B4 E8[0000] invoke GET_IO_SFT 0 000019B7 7205 JC BADJFNCON 0 000019B9 B404 MOV AH,4 0 000019BB E8[0000] invoke IOFUNC 326 327 BADJFNCON: 0 000019BE 5A POP DX 0 000019BF 58 POP AX 0 000019C0 88C4 MOV AH,AL 0 000019C2 3C01 CMP AL,1 0 000019C4 7413 JZ REDISPJ 0 000019C6 3C06 CMP AL,6 0 000019C8 740F JZ REDISPJ 0 000019CA 3C07 CMP AL,7 0 000019CC 740B JZ REDISPJ 0 000019CE 3C08 CMP AL,8 0 000019D0 7407 JZ REDISPJ 0 000019D2 3C0A CMP AL,10 0 000019D4 7403 JZ REDISPJ 0 000019D6 B000 MOV AL,0 0 000019D8 C3 return 343 344 REDISPJ: 345 %IF DBCS ;AN000; 346 mov ds,[CurrentPDB] ;AN000; 347 ;AN000; set DS same as one from COMMAND entry 348 %ENDIF 0 000019D9 FA CLI 0 000019DA E9[0000] transfer REDISP 351 EndProc D_STD_CON_INPUT_FLUSH 352 353 END === Trace listing source: ../DOS/fcbio.lst 1 ; SCCSID = @(#)fcbio.asm 1.5 85/07/30 2 ; SCCSID = @(#)fcbio.asm 1.5 85/07/30 3 ;TITLE FCBIO - FCB system calls 4 ;NAME FCBIO 5 6 ; 7 ; Ancient 1.0 1.1 FCB system calls 8 ; regen save 9 ; $GET_FCB_POSITION written none none 10 ; $FCB_DELETE written none none 11 ; $GET_FCB_FILE_LENGTH written none none 12 ; $FCB_CLOSE written close none 13 ; $FCB_RENAME written none none 14 ; SaveFCBInfo 15 ; ResetLRU 16 ; SetOpenAge 17 ; LRUFCB 18 ; FCBRegen 19 ; BlastSFT 20 ; CheckFCB 21 ; SFTFromFCB 22 ; FCBHardErr 23 ; 24 ; Revision history: 25 ; 26 ; Created: ARR 4 April 1983 27 ; MZ 6 June 1983 completion of functions 28 ; MZ 15 Dec 1983 Brain damaged programs close FCBs multiple 29 ; times. Change so successive closes work by 30 ; always returning OK. Also, detect I/O to 31 ; already closed FCB and return EOF. 32 ; MZ 16 Jan 1984 More braindamage. Need to separate info 33 ; out of sft into FCB for reconnection 34 ; 35 ; A000 version 4.00 Jan. 1988 36 ; 37 [list -] === Switch to base=008400h -> "DOSCODECODE" 44 section DOSCODECODE 45 [list -] 45 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 45 ****************** warning: out: BPB.INC... [-w+user] 45 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 45 ****************** warning: out: DEVSYM.INC... [-w+user] 53 54 %ifndef Kanji 55 %iassign Kanji 0 56 %endif 57 58 I_need OpenBuf,128 ; buffer for translating paths 59 I_need RenBuf,128 ; buffer for rename paths 60 i_need THISDPB,DWORD 61 i_need EXTERR,WORD 62 i_need ALLOWED,BYTE 63 I_need ThisSFT,DWORD ; SFT in use 64 I_need WFP_start,WORD ; pointer to canonical name 65 I_need Ren_WFP,WORD ; pointer to canonical name 66 I_need Attrib,BYTE ; Attribute for match attributes 67 I_need sftFCB,DWORD ; pointer to SFTs for FCB cache 68 I_need FCBLRU,WORD ; least recently used count 69 I_need Proc_ID,WORD ; current process ID 70 I_Need Name1,14 ; place for device names 71 I_need DEVPT,DWORD ; device pointer 72 I_need OpenLRU,WORD ; open age 73 I_need KeepCount,WORD ; number of fcbs to keep 74 I_need User_In_AX,WORD ; user input system call. 75 I_need JShare,DWORD ; share jump table 76 I_need FastOpenTable,BYTE ; DOS 3.3 fastopen 77 %if debug 78 I_need BugLev,WORD 79 I_need BugTyp,WORD 80 %include "bugtyp.nas" 81 %endif 82 83 84 Break <$Get_FCB_Position - set random record fields to current pos> 85 86 ; 87 ; $Get_FCB_Position - look at an FCB, retrieve the current position from the 88 ; extent and next record field and set the random record field to point 89 ; to that record 90 ; 91 ; Inputs: DS:DX point to a possible extended FCB 92 ; Outputs: The random record field of the FCB is set to the current record 93 ; Registers modified: all 94 95 Procedure D_Get_FCB_Position,NEAR 95 ****************** warning: proc D_Get_FCB_Position... [-w+user] 96 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 000019DD E8[0000] invoke GetExtended ; point to FCB 0 000019E0 E8[0000] invoke GetExtent ; DX:AX is current record 0 000019E3 894421 MOV WORD PTR [SI + fcb_RR],AX ; drop in low order piece 0 000019E6 885423 MOV [SI+fcb_RR+2],DL ; drop in high order piece 0 000019E9 837C0E40 CMP word [SI + fcb_RECSIZ],64 0 000019ED 7303 JAE GetFCBBye 0 000019EF 887424 MOV [SI+fcb_RR+2+1],DH ; Set 4th byte only if record size < 64 104 GetFCBBye: 0 000019F2 E9[0000] transfer FCB_Ret_OK 106 EndProc D_GET_FCB_POSITION 107 108 Break <$FCB_Delete - remove several files that match the input FCB> 109 110 ; 111 ; $FCB_delete - given an FCB, remove all directory entries in the current 112 ; directory that have names that match the FCB's ? marks. 113 ; 114 ; Inputs: DS:DX - point to an FCB 115 ; Outputs: directory entries matching the FCB are deleted 116 ; AL = FF if no entries were deleted. 117 ; Registers modified: all 118 119 Procedure D_FCB_Delete,NEAR 119 ****************** warning: proc D_FCB_Delete... [-w+user] 120 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup 121 DOSGroup equ DOSGROUP ; NASM port equate 0 000019F5 BF[0000] MOV DI,OFFSET OpenBuf wrt DOSGroup ; appropriate place 0 000019F8 E8[0000] invoke TransFCB ; convert FCB to path 0 000019FB 7209 JC BadPath ; signal no deletions 0 000019FD 161F Context DS 0 000019FF E8[0000] invoke DOS_Delete ; wham 0 00001A02 7202 JC BadPath 128 GoodPath: 0 00001A04 EBEC transfer FCB_Ret_OK ; do a good return 130 BadPath: 131 ; 132 133 ; Error code is in AX 134 ; 0 00001A06 E9[0000] transfer FCB_Ret_Err ; let someone else signal the error 136 EndProc D_FCB_DELETE 137 138 Break <$Get_FCB_File_Length - return the length of a file> 139 140 ; 141 ; $Get_FCB_File_Length - set the random record field to the length of the 142 ; file in records (rounded up if partial). 143 ; 144 ; Inputs: DS:DX - point to a possible extended FCB 145 ; Outputs: Random record field updated to reflect the number of records 146 ; Registers modified: all 147 148 Procedure D_Get_FCB_File_Length,NEAR 148 ****************** warning: proc D_Get_FCB_File_Length... [-w+user] 149 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 00001A09 E8[0000] invoke GetExtended ; get real FCB pointer 151 ; DX points to Input FCB 0 00001A0C BF[0000] MOV DI,OFFSET OpenBuf wrt DOSGroup ; appropriate buffer 0 00001A0F 1E56 SaveReg ; save pointer to true FCB 0 00001A11 E8[0000] Invoke TransFCB ; Trans name DS:DX, sets SATTRIB 0 00001A14 5E1F RestoreReg 0 00001A16 72EE JC BadPath 0 00001A18 1E56 SaveReg ; save pointer 0 00001A1A 161F Context DS 0 00001A1C E8[0000] invoke Get_File_Info ; grab the info 0 00001A1F 5E1F RestoreReg ; get pointer back 0 00001A21 72E3 JC BadPath ; invalid something 0 00001A23 89DA MOV DX,BX ; get high order size 0 00001A25 89F8 MOV AX,DI ; get low order size 0 00001A27 8B5C0E MOV BX,[SI + fcb_RECSIZ] ; get his record size 0 00001A2A 09DB OR BX,BX ; empty record => 0 size for file 0 00001A2C 7503 JNZ GetSize ; not empty 0 00001A2E BB8000 MOV BX,128 168 GetSize: 0 00001A31 89C7 MOV DI,AX ; save low order word 0 00001A33 89D0 MOV AX,DX ; move high order for divide 0 00001A35 31D2 XOR DX,DX ; clear out high 0 00001A37 F7F3 DIV BX ; wham 0 00001A39 50 PUSH AX ; save dividend 0 00001A3A 89F8 MOV AX,DI ; get low order piece 0 00001A3C F7F3 DIV BX ; wham 0 00001A3E 89D1 MOV CX,DX ; save remainder 0 00001A40 5A POP DX ; get high order dividend 0 00001A41 E306 JCXZ LengthStore ; no roundup 0 00001A43 83C001 ADD AX,1 0 00001A46 83D200 ADC DX,0 ; 32-bit increment 181 LengthStore: 182 FCB_RR equ fcb_RR ; NASM port label 0 00001A49 894421 MOV WORD PTR [SI + FCB_RR],AX ; store low order 0 00001A4C 885423 MOV [SI + FCB_RR+2],DL ; store high order 0 00001A4F 08F6 OR DH,DH 0 00001A51 74B1 JZ GoodPath ; not storing insignificant zero 0 00001A53 887424 MOV [SI + FCB_RR+3],DH ; save that high piece 188 GoodRet: 0 00001A56 EBAC transfer FCB_Ret_OK 190 EndProc D_GET_FCB_FILE_LENGTH 191 192 Break <$FCB_Close - close a file> 193 194 ; 195 ; $FCB_Close - given an FCB, look up the SFN and close it. Do not free it 196 ; as the FCB may be used for further I/O 197 ; 198 ; Inputs: DS:DX point to FCB 199 ; Outputs: AL = FF if file was not found on disk 200 ; Registers modified: all 201 202 Procedure D_FCB_Close,NEAR 202 ****************** warning: proc D_FCB_Close... [-w+user] 203 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 00001A58 30C0 XOR AL,AL ; default search attributes 0 00001A5A E8[0000] invoke GetExtended ; DS:SI point to real FCB 0 00001A5D 7403 JZ NoAttr ; not extended 0 00001A5F 8A44FF MOV AL,[SI-1] ; get attributes 208 NoAttr: 0 00001A62 36A2[0000] MOV [ss:Attrib],AL ; stash away found attributes 0 00001A66 E8F803 invoke SFTFromFCB 0 00001A69 72EB JC GoodRet ; MZ 16 Jan Assume death 212 ; 213 ; If the sharer is present, then the SFT is not regenable. Thus, there is 214 ; no need to set the SFT's attribute. 215 ; 216 ;;; 9/8/86 F.C. save SFT attribute and restore it back when close is done 0 00001A6B 268A4504 MOV AL,[ES:DI + sf_attr] 0 00001A6F 30E4 XOR AH,AH 0 00001A71 50 PUSH AX 220 ;;; 9/8/86 F.C. save SFT attribute and restore it back when close is done 0 00001A72 E8[0000] invoke CheckShare 0 00001A75 7508 JNZ NoStash 0 00001A77 36A0[0000] MOV AL,[ss:Attrib] 0 00001A7B 26884504 MOV [ES:DI + sf_attr],AL ; attempted attribute for close 225 NoStash: 226 FCB_FDATE equ fcb_FDATE ; NASM port label 0 00001A7F 8B4414 MOV AX,[SI + FCB_FDATE] ; move in the time and date 0 00001A82 2689450F MOV [ES:DI + sf_date],AX 229 FCB_FTIME equ fcb_FTIME ; NASM port label 0 00001A86 8B4416 MOV AX,[SI + FCB_FTIME] 0 00001A89 2689450D MOV [ES:DI + sf_time],AX 232 FCB_FilSiz equ fcb_FILSIZ ; NASM port label 0 00001A8D 8B4410 MOV AX,[SI + FCB_FilSiz] 0 00001A90 26894511 MOV WORD PTR [ES:DI + sf_size],AX 0 00001A94 8B4412 MOV AX,[SI + FCB_FilSiz + 2] 0 00001A97 26894513 MOV WORD PTR [ES:DI + sf_size + 2],AX 237 sf_Flags equ sf_flags ; NASM port label 0 00001A9B 26814D050040 OR word [ES:DI + sf_Flags],sf_close_nodate 0 00001AA1 161F Context DS ; let Close see variables 0 00001AA3 E8[0000] invoke DOS_Close ; wham 0 00001AA6 C43E[0000] LES DI,[ThisSFT] 242 ;;; 9/8/86 F.C. restore SFT attribute 0 00001AAA 59 POP CX 0 00001AAB 26884D04 MOV [ES:DI + sf_attr],CL 245 ;;; 9/8/86 F.C. restore SFT attribute 0 00001AAF 9C PUSHF 0 00001AB0 26F705FFFF TEST word [ES:DI + sf_ref_count],-1 ; zero ref count gets blasted 0 00001AB5 7507 JNZ CloseOK 0 00001AB7 50 PUSH AX 0 00001AB8 B04D MOV AL,'M' 0 00001ABA E8D202 invoke BlastSFT 0 00001ABD 58 POP AX 253 CloseOK: 0 00001ABE 9D POPF 0 00001ABF 7395 JNC GoodRet 0 00001AC1 3C06 CMP AL,error_invalid_handle 0 00001AC3 7491 JZ GoodRet 0 00001AC5 B002 MOV AL,error_file_not_found 0 00001AC7 E9[0000] transfer FCB_Ret_Err 260 EndProc D_FCB_CLOSE 261 262 Break <$FCB_Rename - change names in place> 263 264 ; 265 ; $FCB_Rename - rename a file in place within a directory. Renames multiple 266 ; files copying from the meta characters. 267 ; 268 ; Inputs: DS:DX point to an FCB. The normal name field is the source 269 ; name of the files to be renamed. Starting at offset 11h 270 ; in the FCB is the destination name. 271 ; Outputs: AL = 0 -> no error occurred and all files were renamed 272 ; AL = FF -> some files may have been renamed but: 273 ; rename to existing file or source file not found 274 ; Registers modified: all 275 276 Procedure D_FCB_Rename,NEAR 276 ****************** warning: proc D_FCB_Rename... [-w+user] 277 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 00001ACA E8[0000] invoke GetExtended ; get pointer to real FCB 0 00001ACD 52 SaveReg 0 00001ACE 8A04 MOV AL,[SI] ; get drive byte 0 00001AD0 83C610 ADD SI,10h ; point to destination 0 00001AD3 BF[0000] MOV DI,OFFSET RenBuf wrt DOSGroup ; point to destination buffer 0 00001AD6 FF341E56 SaveReg <,DS,SI> ; save source pointer for TransFCB 0 00001ADA 8804 MOV [SI],AL ; drop in real drive 0 00001ADC 89F2 MOV DX,SI ; let TransFCB know where the FCB is 0 00001ADE E8[0000] invoke TransFCB ; munch this pathname 0 00001AE1 5E1F8F04 RestoreReg > ; get path back 0 00001AE5 5A RestoreReg ; Original FCB pointer 0 00001AE6 721A JC BadRen ; bad path -> error 290 WFP_Start equ WFP_start ; NASM port label 0 00001AE8 368B36[0000] MOV SI,[ss:WFP_Start] ; get pointer 0 00001AED 368936[0000] MOV [ss:Ren_WFP],SI ; stash it 0 00001AF2 BF[0000] MOV DI,OFFSET OpenBuf wrt DOSGroup ; appropriate spot 0 00001AF5 E8[0000] invoke TransFCB ; wham 295 ; NOTE that this call is pointing 296 ; back to the ORIGINAL FCB so 297 ; SATTRIB gets set correctly 0 00001AF8 7208 JC BadRen ; error 0 00001AFA E8[0000] invoke DOS_Rename 0 00001AFD 7203 JC BadRen 0 00001AFF E9[0000] transfer FCB_Ret_OK 302 BadRen: 303 ; 304 ; AL has error code 305 ; 0 00001B02 EBC3 transfer FCB_Ret_Err 307 308 EndProc D_FCB_RENAME 309 310 Break 311 312 ; 313 ; FCBs suffer from several problems. First, they are maintained in the 314 ; user's space so he may move them at will. Second, they have a small 315 ; reserved area that may be used for system information. Third, there was 316 ; never any "rules for behavior" for FCBs; there was no protocol for their 317 ; usage. 318 ; 319 ; This results in the following misbehavior: 320 ; 321 ; infinite opens of the same file: 322 ; 323 ; While (TRUE) { While (TRUE) { 324 ; FCBOpen (FCB); FCBOpen (FCB); 325 ; Read (FCB); Write (FCB); 326 ; } } 327 ; 328 ; infinite opens of different files: 329 ; 330 ; While (TRUE) { While (TRUE) { 331 ; FCBOpen (FCB[i++]); FCBOpen (FCB[i++]); 332 ; Read (FCB); Write (FCB); 333 ; } } 334 ; 335 ; multiple closes of the same file: 336 ; 337 ; FCBOpen (FCB); 338 ; while (TRUE) 339 ; FCBClose (FCB); 340 ; 341 ; I/O after closing file: 342 ; 343 ; FCBOpen (FCB); 344 ; while (TRUE) { 345 ; FCBWrite (FCB); 346 ; FCBClose (FCB); 347 ; } 348 ; 349 ; The following is am implementation of a methodology for emulating the 350 ; above with the exception of I/O after close. We are NOT attempting to 351 ; resolve that particular misbehavior. We will enforce correct behaviour in 352 ; FCBs when they refer to a network file or when there is file sharing on 353 ; the local machine. 354 ; 355 ; The reserved fields of the FCB (10 bytes worth) is divided up into various 356 ; structures depending on the file itself and the state of operations of the 357 ; OS. The information contained in this reserved field is enough to 358 ; regenerate the SFT for the local non-shared file. It is assumed that this 359 ; regeneration procedure may be expensive. The SFT for the FCB is 360 ; maintained in a LRU cache as the ONLY performance inprovement. 361 ; 362 ; No regeneration of SFTs is attempted for network FCBs. 363 ; 364 ; To regenerate the SFT for a local FCB, it is necessary to determine if the 365 ; file sharer is working. If the file sharer is present then the SFT is not 366 ; regenerated. 367 ; 368 ; Finally, if there is no local sharing, the full name of the file is no 369 ; longer available. We can make up for this by using the following 370 ; information: 371 ; 372 ; The Drive number (from the DPB). 373 ; The physical sector of the directory that contains the entry. 374 ; The relative position of the entry in the sector. 375 ; The first cluster field. 376 ; The last used SFT. 377 ; OR In the case of a device FCB 378 ; The low 6 bits of sf_flags (indicating device type) 379 ; The pointer to the device header 380 ; 381 ; 382 ; We read in the particular directory sector and examine the indicated 383 ; directory entry. If it matches, then we are kosher; otherwise, we fail. 384 ; 385 ; Some key items need to be remembered: 386 ; 387 ; Even though we are caching SFTs, they may contain useful sharing 388 ; information. We enforce good behavior on the FCBs. 389 ; 390 ; Network support must not treat FCBs as impacting the ref counts on 391 ; open VCs. The VCs may be closed only at process termination. 392 ; 393 ; If this is not an installed version of the DOS, file sharing will 394 ; always be present. 395 ; 396 ; We MUST always initialize lstclus to = firclus when regenerating a 397 ; file. Otherwise we start allocating clusters up the wazoo. 398 ; 399 ; Always initialize, during regeneration, the mode field to both isFCB 400 ; and open_for_both. This is so the FCB code in the sharer can find the 401 ; proper OI record. 402 ; 403 ; The test bits are: 404 ; 405 ; 00 -> local file 406 ; 40 -> sharing local 407 ; 80 -> network 408 ; C0 -> local device 409 410 Break 411 412 ; 413 ; SaveFCBInfo - given an FCB and its associated SFT, copy the relevant 414 ; pieces of information into the FCB to allow for subsequent 415 ; regeneration. Poke LRU also. 416 ; 417 ; Inputs: ThisSFT points to a complete SFT. 418 ; DS:SI point to the FCB (not an extended one) 419 ; Outputs: The relevant reserved fields in the FCB are filled in. 420 ; DS:SI preserved 421 ; ES:DI point to sft 422 ; Registers modified: All 423 ; 424 425 Procedure SaveFCBInfo,NEAR 425 ****************** warning: proc SaveFCBInfo... [-w+user] 426 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 00001B04 36C43E[0000] LES DI,[ss:ThisSFT] 428 Assert ISSFT,,"SaveFCBInfo" 0 00001B09 E8[0000] invoke IsSFTNet 0 00001B0C 740B JZ SaveLocal ; if not network then save local info 431 ; 432 ;----- In net support ----- 433 ; 0 00001B0E 268B450B MOV AX,WORD PTR [ES:DI + sf_serial_ID] ;AN000;;IFS. save IFS ID 0 00001B12 89441C MOV WORD PTR [SI + FCB_netID],ax ;AN000;;IFS. 436 ; SaveReg 437 ; LES DI,DWORD PTR [ES:DI].sf_netid 438 ; MOV WORD PTR [SI].FCB_netID,DI ; save net ID 439 ; MOV WORD PTR [SI].FCB_netID+2,ES 440 ; RestoreReg 0 00001B15 B380 MOV BL,FCBNETWORK 442 ; 443 ;----- END In net support ----- 444 ; 445 %IF debug 446 JMP SaveSFN 447 %ELSE 0 00001B17 EB4E JMP SHORT SaveSFN 449 %ENDIF 450 SaveLocal: 451 %IF Installed 0 00001B19 E8[0000] Invoke CheckShare 0 00001B1C 7403 JZ SaveNoShare ; no sharer 0 00001B1E EB42 JMP SaveShare ; sharer present 0 00001B20 90 nop ; identicalise 456 457 SaveNoShare: 0 00001B21 26F745058000 TEST word [ES:DI + sf_flags],devid_device 0 00001B27 7527 JNZ SaveNoShareDev ; Device 460 ; 461 ; Save no sharing local file information 462 ; 0 00001B29 268B451B MOV AX,WORD PTR [ES:DI + sf_dirsec] ; get directory sector F.C. 0 00001B2D 89441D MOV [SI + fcb_nsl_dirsec],AX 0 00001B30 268A451F MOV AL,[ES:DI + sf_dirpos] ; location in sector 0 00001B34 88441F MOV [SI + fcb_nsl_dirpos],AL 0 00001B37 268B450B MOV AX,[ES:DI + sf_firclus] ; first cluster 0 00001B3B 89441B MOV [SI + fcb_nsl_firclus],AX 0 00001B3E B300 MOV BL,00 470 ; 471 ; Create the bits field from the dirty/device bits of the flags word and the 472 ; mode byte 473 ; 474 SetFCBBits: 0 00001B40 268B4505 MOV AX,[ES:DI + sf_flags] 0 00001B44 24C0 AND AL,0C0h ; mask off drive bits 0 00001B46 260A4502 OR AL,BYTE PTR [ES:DI + sf_mode] ; stick in open mode 0 00001B4A 88441A MOV [SI + fcb_nsl_bits],AL ; save dirty info 0 00001B4D EB18 JMP SaveSFN ; go and save SFN 0 00001B4F 90 nop ; identicalise 481 482 ; 483 ; Save no sharing local device information 484 ; 485 SaveNoShareDev: 0 00001B50 268B4507 MOV AX,WORD PTR [ES:DI + sf_devptr] 0 00001B54 89441A MOV WORD PTR [SI + FCB_nsld_drvptr],AX 0 00001B57 268B4509 MOV AX,WORD PTR [ES:DI + sf_devptr + 2] 0 00001B5B 89441C MOV WORD PTR [SI + FCB_nsld_drvptr + 2],AX 0 00001B5E B340 MOV BL,FCBDEVICE 0 00001B60 EBDE JMP SetFCBBits ; go and save SFN 492 493 SaveShare: 494 %ENDIF 495 ; 496 ;----- In share support ----- 497 ; 498 %if installed 0 00001B62 36FF1E[2800] Call far [ss:JShare + 10 * 4] 500 %else 501 Call ShSave 502 %endif 503 ; 504 ;----- end in share support ----- 505 ; 506 SaveSFN: 0 00001B67 268B4505 MOV AX,[ES:DI + sf_flags] 0 00001B6B 243F AND AL,3Fh ; get real drive 0 00001B6D 08D8 OR AL,BL 0 00001B6F 884419 MOV [SI + fcb_l_drive],AL 0 00001B72 8D45FA LEA AX,[DI-SFTable] 512 ; 513 ; Adjust for offset to table. 514 ; 515 SftFCB equ sftFCB ; NASM port label 0 00001B75 362B06[0000] SUB AX,WORD PTR [ss:SftFCB] 0 00001B7A B33B MOV BL,sf_entry_struc_size 0 00001B7C F6F3 DIV BL 0 00001B7E 884418 MOV [SI + FCB_sfn],AL ; last used SFN 0 00001B81 36A1[0000] MOV AX,[ss:FCBLRU] ; get lru count 0 00001B85 40 INC AX 0 00001B86 26894515 MOV WORD PTR [ES:DI + sf_LRU],AX 0 00001B8A 7506 JNZ SimpleStuff 524 ; 525 ; lru flag overflowed. Run through all FCB sfts and adjust: LRU < 8000h 526 ; get set to 0. Others -= 8000h. This LRU = 8000h 527 ; 0 00001B8C BB1500 MOV BX, offset sf_position 0 00001B8F E80500 invoke ResetLRU 530 ; 531 ; Set new LRU to AX 532 ; 533 SimpleStuff: 0 00001B92 36A3[0000] MOV [ss:FCBLRU],AX 0 00001B96 C3 return 536 EndProc SaveFCBInfo 537 538 Break 539 540 ; 541 ; ResetLRU - during lru updates, we may wrap at 64K. We must walk the 542 ; entire set of SFTs and subtract 8000h from their lru counts and truncate 543 ; at 0. 544 ; 545 ; Inputs: BX is offset into SFT field where lru firld is kept 546 ; ES:DI point to SFT currently being updated 547 ; Outputs: All FCB SFTs have their lru fields truncated 548 ; AX has 8000h 549 ; Registers modified: none 550 551 Procedure ResetLRU,NEAR 551 ****************** warning: proc ResetLRU... [-w+user] 552 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING 553 Assert ISSFT,,"ResetLRU" 0 00001B97 B80080 MOV AX,8000h 0 00001B9A 0657 SaveReg 0 00001B9C 36C43E[0000] LES DI,[ss:sftFCB] ; get pointer to head 557 sfCount equ SFCount ; NASM port label 0 00001BA1 268B4D04 MOV CX,[ES:DI + sfCount] 559 sfTable equ SFTable ; NASM port label 0 00001BA5 8D7D06 LEA DI,[DI + sfTable] ; point at table 561 ovScan: 0 00001BA8 262901 SUB WORD PTR [ES:DI+BX],AX ; decrement lru count 0 00001BAB 7703 JA ovLoop 0 00001BAD 268901 MOV WORD PTR [ES:DI + BX],AX ; truncate at 0 565 ovLoop: 566 SF_Entry_struc_size equ sf_entry_struc_size ; NASM port equate 0 00001BB0 83C73B ADD DI,SF_Entry_struc_size ; advance to next 0 00001BB3 E2F3 LOOP ovScan 0 00001BB5 5F07 RestoreReg 0 00001BB7 268901 MOV [ES:DI+BX],AX 0 00001BBA C3 return 572 EndProc ResetLRU 573 574 Break 575 576 ; 577 ; SetOpenAge - In order to maintain the first N open files in the FCB cache, 578 ; we keep the 'open age' or an LRU count based on opens. We update the 579 ; count here and fill in the appropriate field. 580 ; 581 ; Inputs: ES:DI point to SFT 582 ; Outputs: ES:DI has the open age field filled in. 583 ; If open age has wraparound, we will have subtracted 8000h 584 ; from all open ages. 585 ; Registers modified: AX 586 ; 587 588 Procedure SetOpenAge,NEAR 588 ****************** warning: proc SetOpenAge... [-w+user] 589 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING 590 Assert ISSFT,,"SetOpenAge" 0 00001BBB 36A1[0000] MOV AX,[ss:OpenLRU] 0 00001BBF 40 INC AX 0 00001BC0 26894517 MOV [ES:DI + sf_OpenAge],AX 0 00001BC4 7506 JNZ SetDone 595 sf_Position equ sf_position ; NASM port label 0 00001BC6 BB1700 MOV BX, offset sf_Position+2 0 00001BC9 E8CBFF invoke ResetLRU 598 SetDone: 0 00001BCC 36A3[0000] MOV [ss:OpenLRU],AX 0 00001BD0 C3 return 601 EndProc SetOpenAge 602 603 Break 604 605 ; 606 ; LRUFCB - find LRU fcb in cache. Set ThisSFT and return it. We preserve 607 ; the first keepcount sfts if they are network sfts or if sharing is 608 ; loaded. If carry is set then NO BLASTING is NECESSARY. 609 ; 610 ; Inputs: none 611 ; Outputs: ES:DI point to SFT 612 ; ThisSFT points to SFT 613 ; SFT is zeroed 614 ; Carry set of closes failed 615 ; Registers modified: none 616 ; 617 618 Procedure LRUFCB,NEAR 618 ****************** warning: proc LRUFCB... [-w+user] 619 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING 0 00001BD1 E8[0000] Invoke Save_World 621 ; 622 ; Find nth oldest NET/SHARE FCB. We want to find its age for the second scan 623 ; to find the lease recently used one that is younger than the open age. We 624 ; operate be scanning the list n times finding the least age that is greater 625 ; or equal to the previous minimum age. 626 ; 627 ; BP is the count of times we need to go through this loop. 628 ; AX is the current acceptable minimum age to consider 629 ; 0 00001BD4 368B2E[0000] mov bp,[ss:KeepCount] ; k = keepcount; 0 00001BD9 31C0 XOR AX,AX ; low = 0; 632 ; 633 ; If we've scanned the table n times, then we are done. 634 ; 635 lru1: 0 00001BDB 83FD00 CMP bp,0 ; while (k--) { 0 00001BDE 7452 JZ lru75 0 00001BE0 4D DEC bp 639 ; 640 ; Set up for scan. 641 ; 642 ; AX is the minimum age for consideration 643 ; BX is the minimum age found during the scan 644 ; SI is the position of the entry that corresponds to BX 645 ; 0 00001BE1 BBFFFF MOV BX,-1 ; min = 0xffff; 0 00001BE4 89DE MOV si,BX ; pos = 0xffff; 648 SFTFCB equ sftFCB ; NASM port label 0 00001BE6 36C43E[0000] LES DI,[ss:SFTFCB] ; for (CX=FCBCount; CX>0; CX--) 0 00001BEB 268B4D04 MOV CX,[ES:DI + sfCount] 0 00001BEF 8D7D06 LEA DI,[DI + sfTable] 652 ; 653 ; Innermost loop. If the current entry is free, then we are done. Or, if the 654 ; current entry is busy (indicating a previous aborted allocation), then we 655 ; are done. In both cases, we use the found entry. 656 ; 657 lru2: 0 00001BF2 26833D00 cmp word [es:di + sf_ref_count],0 0 00001BF6 7406 jz lru25 0 00001BF8 26833DFF cmp word [es:di + sf_ref_count],sf_busy 0 00001BFC 7505 jnz lru3 662 ; 663 ; The entry is usable without further scan. Go and use it. 664 ; 665 lru25: 0 00001BFE 89FE MOV si,DI ; pos = i; 0 00001C00 EB6A JMP lru11 ; goto got; 0 00001C02 90 nop ; identicalise 669 ; 670 ; See if the entry is for the network or for the sharer. 671 ; 672 ; If for the sharer or network then 673 ; if the age < current minimum AND >= allowed minimum then 674 ; this entry becomes current minimum 675 ; 676 lru3: 0 00001C03 26F745050080 TEST word [ES:DI + sf_flags],sf_isnet ; if (!net[i] 0 00001C09 7505 JNZ lru35 679 %if installed 0 00001C0B E8[0000] Invoke CheckShare ; && !sharing) 0 00001C0E 7410 JZ lru5 ; else 682 %ENDIF 683 ; 684 ; This SFT is for the net or is for the sharer. See if it less than the 685 ; current minimum. 686 ; 687 lru35: 0 00001C10 268B5517 MOV DX,[ES:DI + sf_OpenAge] 0 00001C14 39C2 CMP DX,AX ; if (age[i] >= low && 0 00001C16 7208 JB lru5 0 00001C18 39DA CMP DX,BX 0 00001C1A 7304 JAE lru5 ; age[i] < min) { 693 ; 694 ; entry is new minimum. Remember his age. 695 ; 0 00001C1C 89D3 mov bx,DX ; min = age[i]; 0 00001C1E 89FE mov si,di ; pos = i; 698 ; 699 ; End of loop. gp back for more 700 ; 701 lru5: 0 00001C20 83C73B add di,sf_entry_struc_size 0 00001C23 E2CD loop lru2 ; } 704 ; 705 ; The scan is complete. If we have successfully found a new minimum (pos != -1) 706 ; set then threshold value to this new minimum + 1. Otherwise, the scan is 707 ; complete. Go find LRU. 708 ; 0 00001C25 83FEFF lru6: cmp si,-1 ; position not -1? 0 00001C28 7408 jz lru75 ; no, done with everything 0 00001C2A 8D4701 lea ax,[bx+1] ; set new threshold age 0 00001C2D EBAC jmp lru1 ; go and loop for more 0 00001C2F F9 lru65: stc 714 lruDead equ LRUDead ; NASM port label 0 00001C30 EB70 jmp short lruDead ; return -1; 716 ; 717 ; Main loop is done. We have AX being the age+1 of the nth oldest sharer or 718 ; network entry. We now make a second pass through to find the LRU entry 719 ; that is local-no-share or has age >= AX 720 ; 721 lru75: 0 00001C32 BBFFFF mov bx,-1 ; min = 0xffff; 0 00001C35 89DE mov si,bx ; pos = 0xffff; 0 00001C37 36C43E[0000] LES DI,[ss:SFTFCB] ; for (CX=FCBCount; CX>0; CX--) 0 00001C3C 268B4D04 MOV CX,[ES:DI + sfCount] 0 00001C40 8D7D06 LEA DI,[DI + sfTable] 727 ; 728 ; If this is is local-no-share then go check for LRU else if age >= threshold 729 ; then check for lru. 730 ; 731 lru8: 0 00001C43 26F745050080 TEST word [ES:DI + sf_flags],sf_isnet 0 00001C49 7505 jnz lru85 ; is for network, go check age 0 00001C4B E8[0000] invoke CheckShare ; sharer here? 0 00001C4E 7406 jz lru86 ; no, go check lru 736 ; 737 ; Network or sharer. Check age 738 ; 739 lru85: 0 00001C50 26394517 cmp [es:di + sf_OpenAge],ax 0 00001C54 720C jb lru9 ; age is before threshold, skip it 742 ; 743 ; Check LRU 744 ; 745 lru86: 0 00001C56 26395D15 cmp [es:di + sf_LRU],bx ; is LRU less than current LRU? 0 00001C5A 7306 jae lru9 ; no, skip this 0 00001C5C 89FE mov si,di ; remember position 0 00001C5E 268B5D15 mov bx,[es:di + sf_LRU] ; remember new minimum LRU 750 ; 751 ; Done with this entry, go back for more. 752 ; 753 lru9: 0 00001C62 83C73B add di,sf_entry_struc_size 0 00001C65 E2DC loop lru8 756 ; 757 ; Scan is complete. If we found NOTHING that satisfied us then we bomb 758 ; out. The conditions here are: 759 ; 760 ; No local-no-shares AND all net/share entries are older than threshold 761 ; 762 lru10: 0 00001C67 83FEFF cmp si,-1 ; if no one f 0 00001C6A 74C3 jz lru65 ; return -1; 765 lru11: 0 00001C6C 89F7 mov di,si 0 00001C6E 36893E[0000] MOV WORD PTR [ss:ThisSFT],DI ; set thissft 0 00001C73 368C06[0200] MOV WORD PTR [ss:ThisSFT+2],ES 769 ; 770 ; If we have sharing or thisSFT is a net sft, then close it until ref count 771 ; is 0. 772 ; 773 sf_isNet equ sf_isnet ; NASM port equate 0 00001C78 26F745050080 TEST word [ES:DI + sf_flags],sf_isNet 0 00001C7E 7505 JNZ LRUClose 776 %IF INSTALLED 0 00001C80 E8[0000] Invoke CheckShare 0 00001C83 7418 JZ LRUDone 779 %ENDIF 780 ; 781 ; Repeat close until ref count is 0 782 ; 783 LRUClose: 0 00001C85 161F Context DS 0 00001C87 C43E[0000] LES DI,[ThisSFT] 0 00001C8B 26833D00 CMP word [ES:DI + sf_ref_count],0 ; is ref count still <> 0? 0 00001C8F 740C JZ LRUDone ; nope, all done 788 789 ; Message 1,"LRUFCB: closing " 790 ; MessageNum 791 ; Message 1,":" 792 ; MessageNum 793 0 00001C91 E8[0000] Invoke DOS_Close 0 00001C94 73EF jnc LRUClose ; no error => clean up 0 00001C96 3C06 cmp al,error_invalid_handle 0 00001C98 74EB jz LRUClose 0 00001C9A F9 stc 0 00001C9B EB05 JMP short LRUDead 800 LRUDone: 0 00001C9D 30C0 XOR AL,AL 0 00001C9F E8ED00 invoke BlastSFT ; fill SFT with 0 (AL) 803 LRUDead: 0 00001CA2 E8[0000] Invoke Restore_World 805 ASSUME DS:NOTHING 0 00001CA5 36C43E[0000] LES DI,[ss:ThisSFT] 807 Assert ISSFT,,"LRUFCB return" 0 00001CAA 7201C3 retnc 0 00001CAD B023 MOV AL,error_FCB_unavailable 0 00001CAF C3 return 811 EndProc LRUFCB 812 813 Break 814 815 ; 816 ; FCBRegen - examine reserved field of FCB and attempt to generate the SFT 817 ; from it. 818 ; 819 ; Inputs: DS:SI point to FCB 820 ; Outputs: carry clear Filled in SFT 821 ; Carry set unrecoverable error 822 ; Registers modified: all 823 824 Procedure FCBRegen,NEAR 824 ****************** warning: proc FCBRegen... [-w+user] 825 ASSUME DS:NOTHING,ES:NOTHING 826 ; 827 ; General data filling. Mode is sf_isFCB + open_for_both, date/time we do 828 ; not fill, size we do no fill, position we do not fill, 829 ; bit 14 of flags = TRUE, other bits = FALSE 830 ; 0 00001CB0 8A4419 MOV AL,[SI + fcb_l_drive] 832 ; 833 ; We discriminate based on the first two bits in the reserved field. 834 ; 0 00001CB3 A880 TEST AL,FCBSPECIAL ; check for no sharing test 0 00001CB5 741C JZ RegenNoSharing ; yes, go regen from no sharing 837 ; 838 ; The FCB is for a network or a sharing based system. At this point we have 839 ; already closed the SFT for this guy and reconnection is impossible. 840 ; 841 ; Remember that he may have given us a FCB with bogus information in it. 842 ; Check to see if sharing is present or if the redir is present. If either is 843 ; around, presume that we have cycled out the FCB and give the hard error. 844 ; Otherwise, just return with carry set. 845 ; 0 00001CB7 E8[0000] invoke CheckShare ; test for sharer 0 00001CBA 7509 JNZ RegenFail ; yep, fail this. 848 multNet equ MultNET ; NASM port equate 0 00001CBC B80011 MOV AX,multNet << 8 ; install check on multnet 0 00001CBF CD2F INT 2FH 0 00001CC1 08C0 OR AL,AL ; is it there? 0 00001CC3 740C JZ RegenDead ; no, just fail the operation 853 RegenFail: 0 00001CC5 36A1[0000] MOV AX,[ss:User_In_AX] 855 fcb_close equ FCB_Close ; NASM port equate 0 00001CC9 80FC10 cmp AH,fcb_close 0 00001CCC 7403 jz RegenDead 0 00001CCE E8C501 invoke FCBHardErr ; massive hard error. 859 RegenDead: 0 00001CD1 F9 STC 0 00001CD2 C3 return ; carry set 862 ; 863 ; Local FCB without sharing. Check to see if sharing is loaded. If so 864 ; fail the operation. 865 ; 866 RegenNoSharing: 0 00001CD3 E8[0000] invoke CheckShare ; Sharing around? 0 00001CD6 75ED JNZ RegenFail 869 ; 870 ; Find an SFT for this guy. 871 ; 0 00001CD8 E8[0000] invoke LRUFcb 0 00001CDB 72F5 retc 874 SF_IsFCB equ sf_isfcb ; NASM port equate 0 00001CDD 26C745020280 MOV word [ES:DI + sf_mode],SF_IsFCB + open_for_both + sharing_compat 0 00001CE3 243F AND AL,3Fh ; get drive number for flags 0 00001CE5 98 CBW 878 sf_close_noDate equ sf_close_nodate ; NASM port equate 0 00001CE6 0D0040 OR AX,sf_close_noDate ; normal FCB operation 880 ; 881 ; The bits field consists of the upper two bits (dirty and device) from the 882 ; SFT and the low 4 bits from the open mode. 883 ; 0 00001CE9 8A4C1A MOV CL,[SI + FCB_nsl_bits] ; stick in dirty bits. 0 00001CEC 88CD MOV CH,CL 0 00001CEE 80E5C0 AND CH,0C0h ; mask off the dirty/device bits 0 00001CF1 08E8 OR AL,CH 0 00001CF3 80E10F AND CL,access_mask ; get the mode bits 0 00001CF6 26884D02 MOV BYTE PTR [ES:DI + sf_mode],CL 0 00001CFA 26894505 MOV [ES:DI + sf_flags],AX ; initial flags 0 00001CFE 36A1[0000] MOV AX,[ss:Proc_ID] 0 00001D02 26894531 MOV [ES:DI + sf_PID],AX 0 00001D06 1E560657 SaveReg 0 00001D0A 1607 Context ES 0 00001D0C BF[0000] MOV DI,OFFSET Name1 wrt DOSGroup 0 00001D0F B90800 MOV CX,8 0 00001D12 46 INC SI ; Skip past drive byte to name in FCB 898 RegenCopyName2: 0 00001D13 AC LODSB 900 901 %IF DBCS ;AN000; 902 invoke testkanj ;AN000; 903 jz notkanj9 ;AN000; 904 STOSB ;AN000; 905 DEC CX ;AN000; 906 JCXZ DoneNam2 ;AN000; ; Ignore split kanji char error 907 LODSB ;AN000; 908 jmp short StuffChar2 ;AN000; 909 ;AN000; 910 notkanj9: ;AN000; 911 %ENDIF ;AN000; 912 0 00001D14 E8[0000] Invoke UCase 914 StuffChar2: 0 00001D17 AA STOSB 0 00001D18 E2F9 LOOP RegenCopyName2 917 DoneNam2: 0 00001D1A 161F Context DS 919 ATTRIB equ Attrib ; NASM port label 0 00001D1C C606[0000]16 MOV byte [ATTRIB],attr_hidden + attr_system + attr_directory 921 ; Must set this to something interesting 922 ; to call DEVNAME. 0 00001D21 E8[0000] Invoke DevName ; check for device 924 ASSUME DS:NOTHING,ES:NOTHING 0 00001D24 5F075E1F RestoreReg 0 00001D28 7219 JC RegenFileNoSharing ; not found on device list => file 927 ; 928 ; Device found. We can ignore disk-specific info 929 ; 0 00001D2A 26887D05 MOV BYTE PTR [ES:DI + sf_flags],BH ; device parms 0 00001D2E 26C6450400 MOV byte [ES:DI + sf_attr],0 ; attribute 0 00001D33 36C536[0000] LDS SI,[ss:DEVPT] ; get device driver 0 00001D38 26897507 MOV WORD PTR [ES:DI + sf_devptr],SI 0 00001D3C 268C5D09 MOV WORD PTR [ES:DI + sf_devptr + 2],DS 0 00001D40 C3 return ; carry is clear 936 937 RegenDeadJ: 0 00001D41 EB8E JMP RegenDead 939 ; 940 ; File found. Just copy in the remaining pieces. 941 ; 942 RegenFileNoSharing: 0 00001D43 268B4505 MOV AX,[ES:DI + sf_flags] 0 00001D47 83E03F AND AX,03Fh 0 00001D4A 1E56 SaveReg 0 00001D4C E8[0000] Invoke Find_DPB 0 00001D4F 26897507 MOV WORD PTR [ES:DI + sf_devptr],SI 0 00001D53 268C5D09 MOV WORD PTR [ES:DI + sf_devptr + 2],DS 0 00001D57 5E1F RestoreReg 0 00001D59 72E6 jc RegenDeadJ ; if find DPB fails, then drive 951 ; indicator was bogus 0 00001D5B 8B441D MOV AX,[SI + FCB_nsl_dirsec] 0 00001D5E 2689451B MOV WORD PTR [ES:DI + sf_dirsec],AX 0 00001D62 26C7451D0000 MOV WORD PTR [ES:DI + sf_dirsec + 2],0 ;AN000;>32mb 0 00001D68 8B441B MOV AX,[SI + FCB_nsl_firclus] 0 00001D6B 2689450B MOV [ES:DI + sf_firclus],AX 0 00001D6F 26894535 MOV [ES:DI + sf_lstclus],AX 0 00001D73 8A441F MOV AL,[SI + FCB_nsl_dirpos] 0 00001D76 2688451F MOV [ES:DI + sf_dirpos],AL 0 00001D7A 26FF05 INC word [ES:DI + sf_ref_count] ; Increment reference count. 961 ; Existing FCB entries would be 962 ; flushed unnecessarily because of 963 ; check in CheckFCB of the ref_count. 964 ; July 22/85 - BAS 965 FCB_name equ fcb_name ; NASM port label 0 00001D7D 8D7401 LEA SI,[SI + FCB_name] 0 00001D80 8D7D20 LEA DI,[DI + sf_name] 968 fcb_extent equ fcb_EXTENT ; NASM port label 0 00001D83 B90B00 MOV CX,fcb_extent-fcb_name 970 RegenCopyName: 0 00001D86 AC LODSB 972 973 %IF DBCS ;AN000; 974 invoke testkanj 975 jz notkanj1 976 STOSB 977 DEC CX 978 JCXZ DoneNam ; Ignore split kanji char error 979 LODSB 980 jmp short StuffChar 981 982 notkanj1: 983 %ENDIF ;AN000; 984 0 00001D87 E8[0000] Invoke UCase 986 StuffChar: 0 00001D8A AA STOSB 0 00001D8B E2F9 LOOP RegenCopyName 989 DoneNam: 0 00001D8D F8 clc 0 00001D8E C3 return 992 EndProc FCBRegen 993 994 ; 995 ; BlastSFT - fill SFT with garbage 996 ; 997 ; Inputs: ES:DI point to SFT 998 ; AL has fill 999 ; Outputs: SFT is filled with nonsense 1000 ; *FLAGS PRESERVED* 1001 ; Registers modified: CX 1002 1003 Procedure BlastSFT,NEAR 1003 ****************** warning: proc BlastSFT... [-w+user] 0 00001D8F 57 SaveReg 0 00001D90 B93B00 MOV CX,sf_entry_struc_size 0 00001D93 F3AA REP STOSB 0 00001D95 5F RestoreReg 0 00001D96 26C7050000 MOV word [ES:DI + sf_ref_count],0 ; set ref count 0 00001D9B 26C745150000 MOV word [ES:DI + sf_LRU],0 ; set lru 0 00001DA1 26C74517FFFF MOV word [ES:DI + sf_OpenAge],-1 ; Set open age 0 00001DA7 C3 return 1012 EndProc BlastSFT 1013 1014 Break 1015 1016 ; CheckFCB - examine an FCB and its contents to see if it needs to be 1017 ; regenerated. 1018 ; 1019 ; Inputs: DS:SI point to FCB (not extended) 1020 ; AL is SFT index 1021 ; Outputs: Carry Set - FCB needs to be regened 1022 ; Carry clear - FCB is OK. ES:DI point to SFT 1023 ; Registers modified: AX and BX 1024 1025 Procedure CheckFCB,NEAR 1025 ****************** warning: proc CheckFCB... [-w+user] 1026 ASSUME DS:NOTHING,ES:NOTHING 0 00001DA8 36C43E[0000] LES DI,[ss:sftFCB] 0 00001DAD 26384504 CMP BYTE PTR [ES:DI + SFCount],AL 0 00001DB1 7244 JC BadSFT 0 00001DB3 B33B MOV BL,sf_entry_struc_size 0 00001DB5 F6E3 MUL BL 1032 sftable equ SFTable ; NASM port label 0 00001DB7 8D7D06 LEA DI,[DI + sftable] 0 00001DBA 01C7 ADD DI,AX 0 00001DBC 36A1[0000] MOV AX,[ss:Proc_ID] 0 00001DC0 26394531 CMP [ES:DI + sf_PID],AX 0 00001DC4 7531 JNZ BadSFT ; must match process 0 00001DC6 26833D00 CMP word [ES:DI + sf_ref_count],0 0 00001DCA 742B JZ BadSFT ; must also be in use 0 00001DCC 8A4419 MOV AL,[SI + FCB_l_Drive] 0 00001DCF A880 TEST AL,FCBSPECIAL ; a special FCB? 0 00001DD1 7430 JZ CheckNoShare ; No. try local or device 1043 ; 1044 ; Since we are a special FCB, try NOT to use a bogus test instruction. 1045 ; FCBSHARE is a superset of FCBNETWORK. 1046 ; 0 00001DD3 50 PUSH AX 0 00001DD4 24C0 AND AL,FCBMASK 0 00001DD6 3CC0 CMP AL,FCBSHARE ; net FCB? 0 00001DD8 58 POP AX 0 00001DD9 751E JNZ CheckNet ; yes 1052 ; 1053 ;----- In share support ----- 1054 ; 1055 %if installed 0 00001DDB 36FF1E[2C00] Call far [ss:JShare + 11 * 4] 1057 %else 1058 Call ShChk 1059 %endif 0 00001DE0 7215 JC BadSFT 0 00001DE2 EB06 JMP SHORT CheckD 1062 ; 1063 ;----- End in share support ----- 1064 ; 1065 CheckFirClus: 0 00001DE4 263B5D0B CMP BX,[ES:DI + sf_firclus] 0 00001DE8 750D JNZ BadSFT 0 00001DEA 243F CheckD: AND AL,3Fh 0 00001DEC 268A6505 MOV AH,BYTE PTR [ES:DI + sf_flags] 0 00001DF0 80E43F AND AH,3Fh 0 00001DF3 38C4 CMP AH,AL 0 00001DF5 74B0 retz ; carry is clear 0 00001DF7 F9 BadSFT: STC 0 00001DF8 C3 return ; carry is clear 1075 CheckNet: 1076 ; 1077 ;----- In net support ----- 1078 ; 1079 ; MOV AX,[SI].FCB_net_handle 1080 ; CMP AX,WORD PTR [ES:DI].sf_NETID+4 1081 ; JNZ BadSFT 1082 ; MOV AX,WORD PTR [SI].FCB_netID 1083 ; CMP AX,WORD PTR [ES:DI].sf_netid 1084 ; JNZ BadSFT 0 00001DF9 8B441C MOV AX,WORD PTR [SI + FCB_netID] ;AN000;IFS.DOS 4.00 0 00001DFC 263B450B CMP AX,WORD PTR [ES:DI + sf_serial_ID] ;AN000;IFS.DOS 4.00 0 00001E00 75F5 JNZ BadSFT 1088 ; 1089 ;----- END In net support ----- 1090 ; 0 00001E02 C3 return 1092 1093 CheckNoShare: 0 00001E03 A840 TEST AL,FCBDEVICE ; Device? 0 00001E05 7546 JNZ CheckNoShareDev ; Yes 1096 ; 1097 ; Check no sharing local file 1098 ; 0 00001E07 8B5C1D MOV BX,[SI + FCB_nsl_Dirsec] 0 00001E0A 26837D1D00 CMP WORD PTR [ES:DI + sf_dirsec + 2],0 ;AN000;F.C. >32mb 1101 BadSFt equ BadSFT ; NASM port label 0 00001E0F 75E6 JNZ BadSFt ;AN000;F.C. >32mb 1103 0 00001E11 263B5D1B CMP BX,WORD PTR [ES:DI + sf_dirsec] ;AN000;F.C. >32mb 0 00001E15 75E0 JNZ BadSFT 0 00001E17 8A5C1F MOV BL,[SI + FCB_nsl_Dirpos] 0 00001E1A 263A5D1F CMP BL,[ES:DI + sf_dirpos] 0 00001E1E 75D7 JNZ BadSFt 1109 ; 1110 ; Since the bits field comes from two different spots, compare them separately. 1111 ; 0 00001E20 8A5C1A MOV BL,[SI + FCB_nsl_bits] 0 00001E23 268A7D05 MOV BH,BYTE PTR [ES:DI + sf_flags] 0 00001E27 30DF XOR BH,BL 0 00001E29 80E7C0 AND BH,0C0h 0 00001E2C 75C9 JNZ BadSFT ; dirty/device bits are different 0 00001E2E 26325D02 XOR BL,BYTE PTR [ES:DI + sf_mode] 0 00001E32 80E30F AND BL,access_mask 0 00001E35 75C0 JNZ BadSFT ; access modes are different 1120 ; Make sure that the names are the same in the FCB and the SFT 1121 ; This case can appear under the following scenario: 1122 ; Create FOO 1123 ; Rename FOO -> BAR 1124 ; Open BAR 1125 ; The SFT will still contain the name for the old file name. 1126 ; July 30/85 - BAS 0 00001E37 57 PUSH DI 0 00001E38 56 PUSH SI 0 00001E39 8D7D20 LEA DI,[DI + sf_name] 0 00001E3C 8D7401 LEA SI,[SI + fcb_name] 0 00001E3F B90B00 MOV CX,11 0 00001E42 F3A6 REPE CMPSB 0 00001E44 5E POP SI 0 00001E45 5F POP DI 0 00001E46 75AF JNZ BadSFT 0 00001E48 8B5C1B MOV BX,[SI + FCB_nsl_firclus] 0 00001E4B EB97 JMP CheckFirClus 1138 1139 CheckNoShareDev: 0 00001E4D 8B5C1A MOV BX,WORD PTR [SI + FCB_nsld_drvptr] 0 00001E50 263B5D07 CMP BX,WORD PTR [ES:DI + sf_devptr] 0 00001E54 75A1 JNZ BadSFT 0 00001E56 8B5C1C MOV BX,WORD PTR [SI + FCB_nsld_drvptr + 2] 0 00001E59 263B5D09 CMP BX,WORD PTR [ES:DI + sf_devptr + 2] 0 00001E5D 7598 JNZ BadSFT 0 00001E5F EB89 JMP CheckD 1147 1148 EndProc CheckFCB 1149 1150 Break 1151 1152 ; 1153 ; SFTFromFCB - the workhorse of this compatability crap. Check to see if 1154 ; the SFT for the FCB is Good. If so, make ThisSFT point to it. If not 1155 ; good, get one from the cache and regenerate it. Overlay the LRU field 1156 ; with PID 1157 ; 1158 ; Inputs: DS:SI point to FCB 1159 ; Outputs: ThisSFT point to appropriate SFT 1160 ; Carry clear -> OK ES:DI -> SFT 1161 ; Carry set -> error in ax 1162 ; Registers modified: ES,DI, AX 1163 1164 Procedure SFTFromFCB,NEAR 1164 ****************** warning: proc SFTFromFCB... [-w+user] 1165 ASSUME DS:NOTHING,ES:NOTHING 0 00001E61 5053 SaveReg 0 00001E63 8A4418 MOV AL,[SI + fcb_sfn] ; set SFN for check 0 00001E66 E83FFF invoke CheckFCB 0 00001E69 5B58 RestoreReg 0 00001E6B 36893E[0000] MOV WORD PTR [ss:ThisSFT],DI ; set thissft 0 00001E70 368C06[0200] MOV WORD PTR [ss:ThisSFT+2],ES 0 00001E75 7310 JNC SetSFT ; no problems, just set thissft 1173 1174 fmt typFCB,LevCheck,<"FCB $x:$x does not match SFT $x:$x\n">, 1175 0 00001E77 E8[0000] Invoke Save_World 0 00001E7A E833FE invoke FCBRegen 0 00001E7D E8[0000] Invoke Restore_World ; restore world 0 00001E80 36A1[0000] MOV AX,[ss:EXTERR] 0 00001E84 7301C3 retc 1181 1182 ; Message 1,<"FCBRegen Succeeded",13,10> 1183 0 00001E87 36C43E[0000] SetSFT: LES DI,[ss:ThisSFT] 0 00001E8C 36FF36[0000] PUSH word [ss:Proc_ID] ; set process id 0 00001E91 268F4531 POP word [ES:DI + sf_PID] 0 00001E95 C3 return ; carry is clear 1188 EndProc SFTFromFCB 1189 1190 Break 1191 1192 ; 1193 ; FCBHardErr - signal to a user app that he is trying to use an 1194 ; unavailable FCB. 1195 ; 1196 ; Inputs: none. 1197 ; Outputs: none. 1198 ; Registers modified: all 1199 ; 1200 1201 Procedure FCBHardErr,NEAR 1201 ****************** warning: proc FCBHardErr... [-w+user] 1202 ASSUME DS:NOTHING,ES:NOTHING 1203 error_FCB_Unavailable equ error_FCB_unavailable ; NASM port equate 0 00001E96 B82300 MOV AX,error_FCB_Unavailable 1205 allowed_FAIL equ Allowed_FAIL ; NASM port equate 0 00001E99 36C606[0000]08 MOV byte [ss:ALLOWED],allowed_FAIL 0 00001E9F 36C42E[0000] LES BP,[ss:THISDPB] 0 00001EA4 BF0100 MOV DI,1 ; Fake some registers 0 00001EA7 89F9 MOV CX,DI 0 00001EA9 268B560B MOV DX,[ES:BP + dpb_first_sector] 0 00001EAD E8[0000] invoke HARDERR_DOS 0 00001EB0 F9 STC 0 00001EB1 C3 return 1214 EndProc FCBHardErr 1215 1216 END === Trace listing source: ../DOS/fcbio2.lst 1 ; SCCSID = @(#)fcbio2.asm 1.2 85/07/23 2 ; SCCSID = @(#)fcbio2.asm 1.2 85/07/23 3 ;TITLE FCBIO2 - FCB system calls 4 ;NAME FCBIO2 5 6 ; 7 ; Ancient 1.0 1.1 FCB system calls 8 ; regen save 9 ; GetRR 10 ; GetExtent 11 ; SetExtent 12 ; GetExtended 13 ; GetRecSize 14 ; FCBIO 15 ; $FCB_OPEN written ACC ACC 16 ; $FCB_CREATE written ACC ACC 17 ; $FCB_RANDOM_WRITE_BLOCK written fcbio fcbio 18 ; $FCB_RANDOM_READ_BLOCK written fcbio fcbio 19 ; $FCB_SEQ_READ written fcbio fcbio 20 ; $FCB_SEQ_WRITE written fcbio fcbio 21 ; $FCB_RANDOM_READ written fcbio fcbio 22 ; $FCB_RANDOM_WRITE written fcbio fcbio 23 ; 24 ; Revision history: 25 ; 26 ; Created: ARR 4 April 1983 27 ; MZ 6 June 1983 completion of functions 28 ; MZ 15 Dec 1983 Brain damaged programs close FCBs multiple 29 ; times. Change so successive closes work by 30 ; always returning OK. Also, detect I/O to 31 ; already closed FCB and return EOF. 32 ; MZ 16 Jan 1984 More braindamage. Need to separate info 33 ; out of sft into FCB for reconnection 34 ; 35 ; A000 version 4.00 Jan. 1988 36 ; 37 [list -] === Switch to base=008400h -> "DOSCODECODE" 44 section DOSCODECODE 45 [list -] 45 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 45 ****************** warning: out: BPB.INC... [-w+user] 45 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 45 ****************** warning: out: DEVSYM.INC... [-w+user] 45 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 53 54 EXTRN DOS_Read:NEAR, DOS_Write:NEAR 55 EXTRN DOS_Open:NEAR, DOS_Create:NEAR 56 57 I_need DMAAdd,DWORD ; current user's DMA address 58 I_need OpenBuf,128 ; buffer for translating paths 59 I_need ThisSFT,DWORD ; SFT in use 60 I_need sftFCB,DWORD ; pointer to SFTs for FCB cache 61 I_need FCBLRU,WORD ; least recently used count 62 I_need DISK_FULL,BYTE ; flag for disk full 63 %if debug 64 I_need BugLev,WORD 65 I_need BugTyp,WORD 66 %include "bugtyp.nas" 67 %endif 68 69 %ifndef BUF2 70 %IF BUFFERFLAG 71 I_need BUF_EMS_MODE,BYTE 72 I_need BUF_EMS_LAST_PAGE,DWORD 73 I_need BUF_EMS_FIRST_PAGE,DWORD 74 I_need BUF_EMS_SAFE_FLAG,BYTE 75 I_need BUF_EMS_NPA640,WORD 76 I_need BUF_EMS_PAGE_FRAME,WORD 77 I_need BUF_EMS_PFRAME,WORD 78 I_need LASTBUFFER,DWORD 79 80 extrn restore_user_map:near 81 extrn Setup_EMS_Buffers:near 82 %ENDIF 83 %endif 84 85 ; Defintions for FCBOp flags 86 87 Random equ 2 ; random operation 88 FCBRead equ 4 ; doing a read 89 Block equ 8 ; doing a block I/O 90 91 Break 92 93 ; 94 ; GetRR - correctly load DX:AX with the random record field (3 or 4 bytes) 95 ; from the FCB pointed to by DS:SI 96 ; 97 ; Inputs: DS:SI point to an FCB 98 ; BX has record size 99 ; Outputs: DX:AX contain the contents of the random record field 100 ; Registers modified: none 101 102 Procedure GetRR,NEAR 102 ****************** warning: proc GetRR... [-w+user] 103 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 104 FCB_RR equ fcb_RR ; NASM port label 0 00001EB2 8B4421 MOV AX,WORD PTR [SI + FCB_RR] ; get low order part 0 00001EB5 8B5423 MOV DX,WORD PTR [SI + FCB_RR+2] ; get high order part 0 00001EB8 83FB40 CMP BX,64 ; ignore MSB of RR if recsiz > 64 0 00001EBB 7202 JB GetRRBye 0 00001EBD 30F6 XOR DH,DH 110 GetRRBye: 0 00001EBF C3 return 112 EndProc GetRR 113 114 Break 115 116 ; 117 ; GetExtent - Construct the next record to perform I/O from the EXTENT and 118 ; NR fields in the FCB. 119 ; 120 ; Inputs: DS:SI - point to FCB 121 ; Outputs: DX:AX contain the contents of the random record field 122 ; Registers modified: none 123 124 Procedure GetExtent,NEAR 124 ****************** warning: proc GetExtent... [-w+user] 125 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 0 00001EC0 8A4420 MOV AL,[SI + fcb_NR] ; get low order piece 0 00001EC3 8B540C MOV DX,[SI + fcb_EXTENT] ; get high order piece 0 00001EC6 D0E0 SHL AL,1 0 00001EC8 D1EA SHR DX,1 0 00001ECA D0D8 RCR AL,1 ; move low order bit of DL to high order of AH 0 00001ECC 88D4 MOV AH,DL 0 00001ECE 88F2 MOV DL,DH 0 00001ED0 30F6 XOR DH,DH 0 00001ED2 C3 return 135 EndProc GetExtent 136 137 Break 138 139 ; 140 ; SetExtent - change the position of an FCB by filling in the extent/NR 141 ; fields 142 ; 143 ; Inputs: DS:SI point to FCB 144 ; DX:AX is a record location in file 145 ; Outputs: Extent/NR fields are filled in 146 ; Registers modified: CX 147 148 Procedure SetExtent,NEAR 148 ****************** warning: proc SetExtent... [-w+user] 149 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 00001ED3 5052 SaveReg 0 00001ED5 89C1 MOV CX,AX 0 00001ED7 247F AND AL,7FH ; next rec field 0 00001ED9 884420 MOV [SI + fcb_NR],AL 0 00001EDC 80E180 AND CL,80H ; save upper bit 0 00001EDF D1E1 SHL CX,1 0 00001EE1 D1D2 RCL DX,1 ; move high bit of CX to low bit of DX 0 00001EE3 88E8 MOV AL,CH 0 00001EE5 88D4 MOV AH,DL 0 00001EE7 89440C MOV [SI + fcb_EXTENT],AX ; all done 0 00001EEA 5A58 RestoreReg 0 00001EEC C3 return 162 EndProc SetExtent 163 164 Break 165 166 ; 167 ; GetExtended - Make DS:SI point to FCB from DS:DX 168 ; 169 ; Inputs: DS:DX point to a possible extended FCB 170 ; Outputs: DS:SI point to the FCB part 171 ; zeroflag set if not extended fcb 172 ; Registers modified: SI 173 174 Procedure GetExtended,NEAR 174 ****************** warning: proc GetExtended... [-w+user] 175 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 0 00001EED 89D6 MOV SI,DX ; point to Something 0 00001EEF 803CFF CMP BYTE PTR [SI],-1 ; look for extention 0 00001EF2 7503 JNZ GetBye ; not there 0 00001EF4 83C607 ADD SI,7 ; point to FCB 180 GetBye: 0 00001EF7 39D6 CMP SI,DX ; set condition codes 0 00001EF9 C3 return 183 EndProc GetExtended 184 185 Break 186 187 ; 188 ; GetRecSize - return in BX the record size from the FCB at DS:SI 189 ; 190 ; Inputs: DS:SI point to a non-extended FCB 191 ; Outputs: BX contains the record size 192 ; Registers modified: None 193 194 Procedure GetRecSize,NEAR 194 ****************** warning: proc GetRecSize... [-w+user] 195 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 00001EFA 8B5C0E MOV BX,[SI + fcb_RECSIZ] ; get his record size 0 00001EFD 09DB OR BX,BX ; is it nul? 0 00001EFF 75F8 retnz 0 00001F01 BB8000 MOV BX,128 ; use default size 0 00001F04 895C0E MOV [SI + fcb_RECSIZ],BX ; stuff it back 0 00001F07 C3 return 202 EndProc GetRecSize 203 204 BREAK 205 206 ; 207 ; FCBIO - look at FCBOP and merge all FCB operations into a single routine. 208 ; 209 ; Inputs: FCBOP flags which operations need to be performed 210 ; DS:DX point to FCB 211 ; CX may have count of number of records to xfer 212 ; Outputs: AL has error code 213 ; Registers modified: all 214 215 Procedure FCBIO,NEAR 215 ****************** warning: proc FCBIO... [-w+user] 216 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup 217 PUBLIC FCBIO001S,FCBIO001E 218 FCBIO001S: 219 LocalVar FCBErr,BYTE 220 LocalVar cRec,WORD 221 LocalVar RecPos,DWORD 222 LocalVar RecSize,WORD 223 LocalVar bPos,DWORD 224 LocalVar cByte,WORD 225 LocalVar cResult,WORD 226 LocalVar cRecRes,WORD 227 LocalVar FCBOp,BYTE 228 FCBIO001E: 0 00001F08 5589E583EC14 Enter 230 231 FEOF EQU 1 232 FTRIM EQU 2 0 00001F0E 8846EC MOV [FCBOp],AL 0 00001F11 C646FF00 MOV byte [FCBErr],0 ; FCBErr = 0; 0 00001F15 E8D5FF invoke GetExtended ; FCB = GetExtended (); 236 BLOCK equ Block ; NASM port equate 0 00001F18 F646EC08 TEST byte [FCBOp],BLOCK ; if ((OP&BLOCK) == 0) 0 00001F1C 7503 JNZ GetPos 0 00001F1E B90100 MOV CX,1 ; cRec = 1; 240 GetPos: 0 00001F21 894EFD MOV [cRec],CX ;*Tail coalesce 0 00001F24 E899FF invoke GetExtent ; RecPos = GetExtent (); 0 00001F27 E8D0FF invoke GetRecSize ; RecSize = GetRecSize (); 0 00001F2A 895EF7 MOV [RecSize],BX 245 RANDOM equ Random ; NASM port equate 0 00001F2D F646EC02 TEST byte [FCBOp],RANDOM ; if ((OP&RANDOM) <> 0) 0 00001F31 7403 JZ GetRec 0 00001F33 E87CFF invoke GetRR ; RecPos = GetRR (); 249 GetRec: 0 00001F36 8946F9 MOV [RecPosL],AX ;*Tail coalesce 0 00001F39 8956FB MOV [RecPosH],DX 0 00001F3C E894FF invoke SetExtent ; SetExtent (RecPos); 0 00001F3F 8B46FB MOV AX,[RecPosH] ; bPos = RecPos * RecSize; 0 00001F42 F7E3 MUL BX 0 00001F44 89C7 MOV DI,AX 0 00001F46 8B46F9 MOV AX,[RecPosL] 0 00001F49 F7E3 MUL BX 0 00001F4B 01FA ADD DX,DI 0 00001F4D 8946F3 MOV [bPosL],AX 0 00001F50 8956F5 MOV [bPosH],DX 0 00001F53 8B46FD MOV AX,[cRec] ; cByte = cRec * RecSize; 0 00001F56 F7E3 MUL BX 0 00001F58 8946F1 MOV [cByte],AX 0 00001F5B 360306[0000] ADD AX,WORD PTR [ss:DMAAdd] ; if (cByte+DMA > 64K) { 0 00001F60 83D200 ADC DX,0 0 00001F63 7419 JZ DoOper 0 00001F65 C646FF02 MOV byte [FCBErr],FTRIM ; FCBErr = FTRIM; 0 00001F69 36A1[0000] MOV AX,WORD PTR [ss:DMAAdd] ; cRec = (64K-DMA)/RecSize; 0 00001F6D F7D8 NEG AX 0 00001F6F 7501 JNZ DoDiv 0 00001F71 48 DEC AX 272 DoDiv: 0 00001F72 31D2 XOR DX,DX 0 00001F74 F7F3 DIV BX 0 00001F76 8946FD MOV [cRec],AX 0 00001F79 F7E3 MUL BX ; cByte = cRec * RecSize; 0 00001F7B 8946F1 MOV [cByte],AX ; } 278 DoOper: 0 00001F7E 31DB XOR BX,BX 0 00001F80 895EEF MOV [cResult],BX ; cResult = 0; 0 00001F83 395EF1 CMP [cByte],BX ; if (cByte <> 0 || 0 00001F86 7508 JNZ DoGetExt 0 00001F88 F646FF02 TEST byte [FCBErr],FTRIM ; (FCBErr&FTRIM) == 0) { 284 %IF debug 285 JZ DoGetExt 286 JMP SkipOp 287 %ELSE 0 00001F8C 7402 JZ SKP_SkipOp 0 00001F8E EB76 JMP SkipOp 290 SKP_SkipOp: 291 %ENDIF 292 DoGetExt: 0 00001F90 E8[0000] invoke SFTFromFCB ; if (!SFTFromFCB (SFT,FCB)) 0 00001F93 730F JNC ContinueOp 295 FCBDeath: 0 00001F95 E8[0000] invoke FCB_Ret_Err ; signal error, map for extended 0 00001F98 C746ED0000 MOV word [cRecRes],0 ; no bytes transferred 0 00001F9D C646FF01 MOV byte [FCBErr],FEOF ; return FTRIM; 0 00001FA1 E9F000 JMP FCBSave ; bam! 300 ContinueOp: 301 Assert ISSFT,,"ContinueOP" 302 fcb_filsiz equ fcb_FILSIZ ; NASM port label 0 00001FA4 8B4410 MOV AX,WORD PTR [SI + fcb_filsiz] 0 00001FA7 26894511 MOV WORD PTR [ES:DI + sf_size],AX 0 00001FAB 8B4412 MOV AX,WORD PTR [SI + fcb_filsiz + 2] 0 00001FAE 26894513 MOV WORD PTR [ES:DI + sf_size + 2],AX 0 00001FB2 8B46F3 MOV AX,[bPosL] 0 00001FB5 8B56F5 MOV DX,[bPosH] 0 00001FB8 26894515 MOV WORD PTR [ES:DI + sf_position],AX 0 00001FBC 26875517 XCHG WORD PTR [ES:DI + sf_position+2],DX 0 00001FC0 52 PUSH DX ; save away Open age. 0 00001FC1 8B4EF1 MOV CX,[cByte] ; cResult = 313 314 ; int 3 315 316 DOSGroup equ DOSGROUP ; NASM port equate 0 00001FC4 BF[0000] MOV DI,OFFSET DOS_Read ; *(OP&FCBRead ? DOS_Read 0 00001FC7 F646EC04 TEST byte [FCBOp],FCBRead ; : DOS_Write)(cRec); 0 00001FCB 7503 JNZ DoContext 0 00001FCD BF[0000] MOV DI,OFFSET DOS_Write 321 DoContext: 0 00001FD0 551E56 SaveReg 0 00001FD3 161F Context DS 324 ;; Fix for disk full 0 00001FD5 FFD7 CALL DI 0 00001FD7 5E1F5D RestoreReg 327 ASSUME DS:NOTHING 328 329 %ifndef BUF2 330 %IF BUFFERFLAG 331 pushf 332 push ax 333 push bx 334 335 cmp byte [ss:BUF_EMS_MODE], -1 336 jz dos_fcb_call_done 337 call restore_user_map 338 mov ax, word ptr [ss:BUF_EMS_LAST_PAGE] 339 cmp [ss:BUF_EMS_PFRAME], ax 340 je dos_fcb_call_done 341 mov word ptr [ss:LASTBUFFER], -1 342 mov [ss:BUF_EMS_PFRAME], ax 343 mov ax, word ptr [ss:BUF_EMS_LAST_PAGE+2] 344 mov [ss:BUF_EMS_PAGE_FRAME], ax 345 mov byte [ss:BUF_EMS_SAFE_FLAG], 1 346 call Setup_EMS_Buffers 347 348 dos_fcb_call_done: 349 pop bx 350 pop ax 351 popf 352 %ENDIF 353 %endif 354 0 00001FDA 72B9 JC FCBDeath 356 0 00001FDC 36803E[0000]00 CMP BYTE PTR [ss:DISK_FULL],0 ; treat disk full as error 0 00001FE2 740A JZ NODSKFULL 0 00001FE4 36C606[0000]00 MOV BYTE PTR [ss:DISK_FULL],0 ; clear the flag 0 00001FEA C646FF01 MOV byte [FCBerr],FEOF ; set disk full flag 361 NODSKFULL: 362 ;; Fix for disk full 0 00001FEE 894EEF MOV [cResult],CX 0 00001FF1 E8[0000] invoke SaveFCBInfo ; SaveFCBInfo (FCB); 365 Assert ISSFT,,"FCBIO/SaveFCBInfo" 366 %warning out: WARNING!!! Make sure sf_position+2 is OpenAGE 366 ****************** warning: out: WARNING!!! Make sure sf_position+2 is OpenAGE [-w+user] 367 sf_Position equ sf_position ; NASM port label 0 00001FF4 268F4517 POP WORD PTR [ES:DI + sf_Position + 2] ; restore open age 0 00001FF8 268B4511 MOV AX,WORD PTR [ES:DI + sf_size] 0 00001FFC 894410 MOV WORD PTR [SI + fcb_filsiz],AX 0 00001FFF 268B4513 MOV AX,WORD PTR [ES:DI + sf_size + 2] 0 00002003 894412 MOV WORD PTR [SI + fcb_filsiz + 2],AX 373 ; } 374 SkipOp: 0 00002006 8B46EF MOV AX,[cResult] ; cRecRes = cResult / RecSize; 0 00002009 31D2 XOR DX,DX 0 0000200B F776F7 DIV word [RecSize] 0 0000200E 8946ED MOV [cRecRes],AX 0 00002011 0146F9 ADD [RecPosL],AX ; RecPos += cRecResult; 0 00002014 8356FB00 ADC word [RecPosH],0 381 ; 382 ; If we have not gotten the expected number of records, we signal an EOF 383 ; condition. On input, this is EOF. On output this is usually disk full. 384 ; BUT... Under 2.0 and before, all device output IGNORED this condition. So 385 ; do we. 386 ; 0 00002018 3B46FD CMP AX,[cRec] ; if (cRecRes <> cRec) 0 0000201B 7412 JZ TryBlank 0 0000201D F646EC04 TEST byte [FCBOp],FCBRead ; if (OP&FCBRead || !DEVICE) 0 00002021 7508 JNZ SetEOF 0 00002023 26F745058000 TEST word [ES:DI + sf_flags],devid_device 0 00002029 7504 JNZ TryBlank 393 SetEOF: 0 0000202B C646FF01 MOV byte [FCBErr],FEOF ; FCBErr = FEOF; 395 TryBlank: ; 0 0000202F 09D2 OR DX,DX ; if (cResult%RecSize <> 0) { 0 00002031 7426 JZ SetExt 0 00002033 8346F901 ADD word [RecPosL],1 ; RecPos++; 0 00002037 8356FB00 ADC word [RecPosH],0 0 0000203B F646EC04 TEST byte [FCBOp],FCBRead ; if(OP&FCBRead) <> 0) { 0 0000203F 7418 JZ SetExt 0 00002041 FF46ED INC word [cRecRes] ; cRecRes++; 0 00002044 C646FF03 MOV byte [FCBErr],FTRIM + FEOF ; FCBErr = FTRIM | FEOF; 0 00002048 8B4EF7 MOV CX,[RecSize] ; Blank (RecSize-cResult%RecSize, 0 0000204B 29D1 SUB CX,DX ; DMA+cResult); 0 0000204D 30C0 XOR AL,AL 0 0000204F 36C43E[0000] LES DI,[ss:DMAAdd] 0 00002054 037EEF ADD DI,[cResult] 0 00002057 F3AA REP STOSB ; } } 410 SetExt: 0 00002059 8B56FB MOV DX,[RecPosH] 0 0000205C 8B46F9 MOV AX,[RecPosL] 0 0000205F F646EC02 TEST byte [FCBOp],RANDOM ; if ((OP&Random) == 0 || 0 00002063 7406 JZ DoSetExt 0 00002065 F646EC08 TEST byte [FCBOp],BLOCK ; (OP&BLOCK) <> 0) 0 00002069 7403 JZ TrySetRR 417 DoSetExt: 0 0000206B E865FE invoke SetExtent ; SetExtent (RecPos, FCB); 419 TrySetRR: 0 0000206E F646EC08 TEST byte [FCBOp],BLOCK ; if ((op&BLOCK) <> 0) 0 00002072 740F JZ TryReturn 0 00002074 894421 MOV WORD PTR [SI + FCB_RR],AX ; FCB->RR = RecPos; 0 00002077 885423 MOV BYTE PTR [SI + FCB_RR+2],DL 0 0000207A 837C0E40 CMP word [SI + fcb_RECSIZ],64 0 0000207E 7303 JAE TryReturn 0 00002080 887424 MOV [SI+fcb_RR+2+1],DH ; Set 4th byte only if record size < 64 427 TryReturn: 0 00002083 F646EC04 TEST byte [FCBOP],FCBRead ; if (!(FCBOP & FCBREAD)) { 0 00002087 750B JNZ FCBSave 0 00002089 1E SaveReg ; FCB->FDate = date; 0 0000208A E8[0000] Invoke Date16 ; FCB->FTime = time; 0 0000208D 1F RestoreReg 433 FCB_FDate equ fcb_FDATE ; NASM port label 0 0000208E 894414 MOV [SI + FCB_FDate],AX 435 FCB_FTime equ fcb_FTIME ; NASM port label 0 00002091 895416 MOV [SI + FCB_FTime],DX ; } 437 FCBSave: 0 00002094 F646EC08 TEST byte [FCBOp],BLOCK ; if ((op&BLOCK) <> 0) 0 00002098 7409 JZ DoReturn 0 0000209A 8B4EED MOV CX,[cRecRes] ; user_CX = cRecRes; 0 0000209D E8[0000] invoke Get_User_Stack 442 User_CX equ user_CX ; NASM port label 0 000020A0 894C04 MOV [SI + User_CX],CX 444 DoReturn: 0 000020A3 8A46FF MOV AL,[FCBErr] ; return (FCBERR); 0 000020A6 89EC5D Leave 0 000020A9 C3 return 448 EndProc FCBIO 449 450 Break <$FCB_Open - open an old-style FCB> 451 452 ; 453 ; $FCB_Open - CPM compatability file open. The user has formatted an FCB 454 ; for us and asked to have the rest filled in. 455 ; 456 ; Inputs: DS:DX point to an unopenned FCB 457 ; Outputs: AL indicates status 0 is ok FF is error 458 ; FCB has the following fields filled in: 459 ; Time/Date Extent/NR Size 460 461 Procedure D_FCB_Open,NEAR 461 ****************** warning: proc D_FCB_Open... [-w+user] 462 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 463 sharing_Compat equ sharing_compat ; NASM port equate 464 Open_For_Both equ open_for_both ; NASM port equate 0 000020AA B80200 MOV AX,sharing_Compat+Open_For_Both 0 000020AD B9[0000] MOV CX,OFFSET DOS_Open 467 ; 468 ; The following is common code for Creation and openning of FCBs. AX is 469 ; either attributes (for create) or open mode (for open)... DS:DX points to 470 ; the FCB 471 ; 472 DoAccess: 0 000020B0 1E525150 SaveReg ; save FCB pointer away 0 000020B4 BF[0000] MOV DI,OFFSET OpenBuf wrt DOSGroup 0 000020B7 E8[0000] invoke TransFCB ; crunch the fcb 0 000020BA 58595A1F RestoreReg ; get fcb 0 000020BE 7303 JNC FindFCB ; everything seems ok 478 FCBOpenErr: 479 ; 480 ; AL has error code 481 ; 0 000020C0 E9[0000] transfer FCB_Ret_Err 483 FindFCB: 0 000020C3 E827FE invoke GetExtended ; DS:SI will point to FCB 0 000020C6 E8[0000] invoke LRUFCB ; get a sft entry (no error) 0 000020C9 722A JC HardMessage 487 ASSUME ES:NOTHING 488 489 ; Message 1,"Entering " 490 ; MessageNum ES 491 ; Message 1,":" 492 ; MessageNum DI 493 ; Message 1,<13,10> 494 495 sf_ISFCB equ sf_isfcb ; NASM port equate 0 000020CB 26C745020080 MOV word [ES:DI + sf_mode],sf_ISFCB 0 000020D1 1E5653 SaveReg ; save fcb pointer 0 000020D4 89CE MOV SI,CX 0 000020D6 161F Context DS ; let DOS_Open see variables 0 000020D8 FFD6 CALL SI ; go open the file 0 000020DA 5B5E1F RestoreReg ; get fcb 502 ASSUME DS:NOTHING 0 000020DD 36C43E[0000] LES DI,[ss:ThisSFT] ; get sf pointer 0 000020E2 7318 JNC FCBOK ; operation succeeded 505 Assert ISSFT,,"DeadFCB" 506 failopen: 0 000020E4 50 PUSH AX 0 000020E5 B052 MOV AL,"R" ; clear out field (free sft) 0 000020E7 E8[0000] invoke BlastSFT 0 000020EA 58 POP AX 0 000020EB 83F804 CMP AX,error_too_many_open_files 0 000020EE 7405 JZ HardMessage 0 000020F0 83F824 CMP AX,error_sharing_buffer_exceeded 0 000020F3 7505 jnz DeadFCB 515 HardMessage: 0 000020F5 50 PUSH AX 0 000020F6 E8[0000] invoke FCBHardErr 0 000020F9 58 POP AX 519 DeadFCB: 0 000020FA EBC4 transfer FCB_Ret_Err 521 FCBOK: 0 000020FC E8[0000] invoke IsSFTNet ;AN007;F.C. >32mb Non Fat file? 0 000020FF 7511 JNZ FCBOK2 ;AN007;F.C. >32mb yes 0 00002101 E8[0000] invoke CheckShare ;AN000;F.C. >32mb share around? 0 00002104 750C JNZ FCBOK2 ;AN000;F.C. >32mb yes 0 00002106 26837D1D00 CMP WORD PTR [ES:DI + sf_dirsec + 2],0 ;AN000;F.C. >32mb if dirsec >32mb 0 0000210B 7405 JZ FCBOK2 ;AN000;F.C. >32mb then error 0 0000210D B85A00 MOV AX,error_sys_comp_not_loaded ;AN000;F.C. >32mb 0 00002110 EBD2 JMP failopen ;AN000;F.C. >32mb 530 FCBOK2: 531 0 00002112 26FF05 INC word [ES:DI + sf_ref_count] ; increment reference count 0 00002115 E8[0000] invoke SaveFCBInfo 534 Assert ISSFT,,"FCBOK" 0 00002118 E8[0000] invoke SetOpenAge 536 Assert ISSFT,,"FCBOK/SetOpenAge" 0 0000211B 26F745058000 TEST word [ES:DI + sf_flags],devid_device 0 00002121 7509 JNZ FCBNoDrive ; do not munge drive on devices 0 00002123 8A04 MOV AL,[SI] ; get drive byte 0 00002125 E8[0000] invoke GetThisDrv ; convert 0 00002128 FEC0 INC AL 0 0000212A 8804 MOV [SI],AL ; stash in good drive letter 543 FCBNoDrive: 544 FCB_RecSiz equ fcb_RECSIZ ; NASM port label 0 0000212C C7440E8000 MOV word [SI + FCB_RecSiz],80h ; stuff in default record size 546 SF_Time equ sf_time ; NASM port label 0 00002131 268B450D MOV AX,[ES:DI + SF_Time] ; set time 0 00002135 894416 MOV [SI + FCB_FTime],AX 549 SF_Date equ sf_date ; NASM port label 0 00002138 268B450F MOV AX,[ES:DI + SF_Date] ; set date 0 0000213C 894414 MOV [SI + FCB_FDate],AX 552 SF_Size equ sf_size ; NASM port label 0 0000213F 268B4511 MOV AX,WORD PTR [ES:DI + SF_Size] ; set sizes 554 FCB_FILSIZ equ fcb_FILSIZ ; NASM port label 0 00002143 894410 MOV [SI + FCB_FILSIZ],AX 0 00002146 268B4513 MOV AX,WORD PTR [ES:DI + SF_Size + 2] 0 0000214A 894412 MOV [SI + FCB_FILSIZ + 2],AX 0 0000214D 31C0 XOR AX,AX ; convenient zero 559 FCB_Extent equ fcb_EXTENT ; NASM port label 0 0000214F 89440C MOV [SI + FCB_Extent],AX ; point to beginning of file 561 ; 562 ; We must scan the set of FCB SFTs for one that appears to match the current 563 ; one. We cheat and use CheckFCB to match the FCBs. 564 ; 565 SFTFCB equ sftFCB ; NASM port label 0 00002152 36C43E[0000] LES DI,[ss:SFTFCB] ; get the pointer to head of the list 567 sfCount equ SFCount ; NASM port label 0 00002157 268A6504 MOV AH,BYTE PTR [ES:DI + sfCount] ; get number of SFTs to scan 569 OpenScan: 0 0000215B 3A4418 CMP AL,[SI + fcb_sfn] ; don't compare ourselves 0 0000215E 7407 JZ SkipCheck 0 00002160 50 SaveReg ; preserve count 0 00002161 E8[0000] invoke CheckFCB ; do they match 0 00002164 58 RestoreReg ; get count back 0 00002165 7309 JNC OpenFound ; found a match! 576 SkipCheck: 0 00002167 FEC0 INC AL ; advance to next FCB 0 00002169 38E0 CMP AL,AH ; table full? 0 0000216B 75EE JNZ OpenScan ; no, go for more 580 OpenDone: 0 0000216D 30C0 xor al,al ; return success 0 0000216F C3 return 583 ; 584 ; The SFT at ES:DI is the one that is already in use for this FCB. We set the 585 ; FCB to use this one. We increment its ref count. We do NOT close it at all. 586 ; Consider: 587 ; 588 ; open (foo) delete (foo) open (bar) 589 ; 590 ; This causes us to recycle (potentially) bar through the same local SFT as 591 ; foo even though foo is no longer needed; this is due to the server closing 592 ; foo for us when we delete it. Unfortunately, we cannot see this closure. 593 ; If we were to CLOSE bar, the server would then close the only reference to 594 ; bar and subsequent I/O would be lost to the redirector. 595 ; 596 ; This gets solved by NOT closing the sft, but zeroing the ref count 597 ; (effectively freeing the SFT) and informing the sharer (if relevant) that 598 ; the SFT is no longer in use. Note that the SHARER MUST keep its ref counts 599 ; around. This will allow us to access the same file through multiple network 600 ; connections and NOT prematurely terminate when the ref count on one 601 ; connection goes to zero. 602 ; 603 OpenFound: 0 00002170 884418 MOV [SI + fcb_SFN],AL ; assign with this 0 00002173 26FF05 INC word [ES:DI + sf_ref_count] ; remember this new invocation 0 00002176 36A1[0000] MOV AX,[ss:FCBLRU] ; update LRU counts 0 0000217A 26894515 MOV [ES:DI + sf_LRU],AX 608 ; 609 ; We have an FCB sft that is now of no use. We release sharing info and then 610 ; blast it to prevent other reuse. 611 ; 0 0000217E 161F context DS 0 00002180 C43E[0000] LES DI,[ThisSFT] 0 00002184 26FF0D DEC word [ES:DI + sf_ref_count] ; free the newly allocated SFT 0 00002187 E8[0000] invoke ShareEnd 616 Assert ISSFT,,"Open blasting" 0 0000218A B043 MOV AL,'C' 0 0000218C E8[0000] invoke BlastSFT 0 0000218F EBDC JMP OpenDone 620 EndProc D_FCB_Open 621 622 BREAK <$FCB_Create - create a new directory entry> 623 624 ; 625 ; $FCB_Create - CPM compatability file create. The user has formatted an 626 ; FCB for us and asked to have the rest filled in. 627 ; 628 ; Inputs: DS:DX point to an unopenned FCB 629 ; Outputs: AL indicates status 0 is ok FF is error 630 ; FCB has the following fields filled in: 631 ; Time/Date Extent/NR Size 632 633 Procedure D_FCB_Create,NEAR 633 ****************** warning: proc D_FCB_Create... [-w+user] 634 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 00002191 B9[0000] MOV CX,OFFSET DOS_Create ; routine to call 0 00002194 31C0 XOR AX,AX ; attributes to create 0 00002196 E854FD invoke GetExtended ; get extended FCB 0 00002199 7403 JZ DoAccessJ ; not an extended FCB 0 0000219B 8A44FF MOV AL,[SI-1] ; get attributes 640 DoAccessJ: 0 0000219E E90FFF JMP DoAccess ; do dirty work 642 EndProc D_FCB_Create 643 644 BREAK <$FCB_Random_write_Block - write a block of records to a file > 645 646 ; 647 ; $FCB_Random_Write_Block - retrieve a location from the FCB, seek to it 648 ; and write a number of blocks from it. 649 ; 650 ; Inputs: DS:DX point to an FCB 651 ; Outputs: AL = 0 write was successful and the FCB position is updated 652 ; AL <> 0 Not enough room on disk for the output 653 ; 654 655 Procedure D_FCB_Random_Write_Block,NEAR 655 ****************** warning: proc D_FCB_Random_Write_Block... [-w+user] 656 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 000021A1 B00A MOV AL,Random+Block 0 000021A3 E962FD JMP FCBIO 659 EndProc D_FCB_Random_Write_Block 660 661 BREAK <$FCB_Random_Read_Block - read a block of records to a file > 662 663 ; 664 ; $FCB_Random_Read_Block - retrieve a location from the FCB, seek to it 665 ; and read a number of blocks from it. 666 ; 667 ; Inputs: DS:DX point to an FCB 668 ; Outputs: AL = error codes defined above 669 ; 670 671 Procedure D_FCB_Random_Read_Block,NEAR 671 ****************** warning: proc D_FCB_Random_Read_Block... [-w+user] 672 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 000021A6 B00E MOV AL,Random+FCBRead+Block 0 000021A8 E95DFD JMP FCBIO 675 EndProc D_FCB_Random_Read_Block 676 677 BREAK <$FCB_Seq_Read - read the next record from a file > 678 679 ; 680 ; $FCB_Seq_Read - retrieve the next record from an FCB and read it into 681 ; memory 682 ; 683 ; Inputs: DS:DX point to an FCB 684 ; Outputs: AL = error codes defined above 685 ; 686 687 Procedure D_FCB_Seq_Read,NEAR 687 ****************** warning: proc D_FCB_Seq_Read... [-w+user] 688 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 000021AB B004 MOV AL,FCBRead 0 000021AD E958FD JMP FCBIO 691 EndProc D_FCB_Seq_Read 692 693 BREAK <$FCB_Seq_Write - write the next record to a file > 694 695 ; 696 ; $FCB_Seq_Write - retrieve the next record from an FCB and write it to the 697 ; file 698 ; 699 ; Inputs: DS:DX point to an FCB 700 ; Outputs: AL = error codes defined above 701 ; 702 703 Procedure D_FCB_Seq_Write,NEAR 703 ****************** warning: proc D_FCB_Seq_Write... [-w+user] 704 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 000021B0 B000 MOV AL,0 0 000021B2 E953FD jmp FCBIO 707 EndProc D_FCB_SEQ_WRITE 708 709 BREAK <$FCB_Random_Read - Read a single record from a file > 710 711 ; 712 ; $FCB_Random_Read - retrieve a location from the FCB, seek to it and read a 713 ; record from it. 714 ; 715 ; Inputs: DS:DX point to an FCB 716 ; Outputs: AL = error codes defined above 717 ; 718 719 Procedure D_FCB_Random_Read,NEAR 719 ****************** warning: proc D_FCB_Random_Read... [-w+user] 720 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 000021B5 B006 MOV AL,Random+FCBRead 0 000021B7 E94EFD jmp FCBIO ; single block 723 EndProc D_FCB_RANDOM_READ 724 725 BREAK <$FCB_Random_Write - write a single record to a file > 726 727 ; 728 ; $FCB_Random_Write - retrieve a location from the FCB, seek to it and write 729 ; a record to it. 730 ; 731 ; Inputs: DS:DX point to an FCB 732 ; Outputs: AL = error codes defined above 733 ; 734 735 Procedure D_FCB_Random_Write,NEAR 735 ****************** warning: proc D_FCB_Random_Write... [-w+user] 736 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 000021BA B002 MOV AL,Random 0 000021BC E949FD jmp FCBIO 739 EndProc D_FCB_RANDOM_WRITE 740 741 END 742 743 744 745 === Trace listing source: ../DOS/search.lst 1 ; SCCSID = @(#)search.asm 1.1 85/04/10 2 ;TITLE SEARCH - Directory scan system calls 3 ;NAME SEARCH 4 5 ; 6 ; 7 ; Directory search system calls. These will be passed direct text of the 8 ; pathname from the user. They will need to be passed through the macro 9 ; expander prior to being sent through the low-level stuff. I/O specs are 10 ; defined in DISPATCH. The system calls are: 11 ; 12 ; 13 ; $Dir_Search_First written 14 ; $Dir_Search_Next written 15 ; $Find_First written 16 ; $Find_Next written 17 ; PackName written 18 ; 19 ; Modification history: 20 ; 21 ; Created: ARR 4 April 1983 22 ; 23 24 [list -] === Switch to base=008400h -> "DOSCODECODE" 31 section DOSCODECODE 32 [list -] 32 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 32 ****************** warning: out: BPB.INC... [-w+user] 32 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 32 ****************** warning: out: DEVSYM.INC... [-w+user] 41 42 i_need SEARCHBUF,53 43 i_need SATTRIB,BYTE 44 I_Need OpenBuf,128 45 I_need DMAAdd,DWORD 46 I_need THISFCB,DWORD 47 I_need CurDrv,BYTE 48 I_need EXTFCB,BYTE 49 I_need Fastopenflg,BYTE 50 I_need DOS34_FLAG,WORD 51 52 ; Inputs: 53 ; DS:DX Points to unopenned FCB 54 ; Function: 55 ; Directory is searched for first matching entry and the directory 56 ; entry is loaded at the disk transfer address 57 ; Returns: 58 ; AL = -1 if no entries matched, otherwise 0 59 60 procedure D_DIR_SEARCH_FIRST,NEAR 60 ****************** warning: proc D_DIR_SEARCH_FIRST... [-w+user] 61 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 62 0 000021BF 368916[0000] MOV WORD PTR [ss:THISFCB],DX 0 000021C4 368C1E[0200] MOV WORD PTR [ss:THISFCB+2],DS 0 000021C9 89D6 MOV SI,DX 0 000021CB 803CFF CMP BYTE PTR [SI],0FFH 0 000021CE 7503 JNZ NORMFCB4 0 000021D0 83C607 ADD SI,7 ; Point to drive select byte 69 NORMFCB4: 0 000021D3 FF34 SaveReg ; Save original drive byte for later 0 000021D5 1607 Context ES ; get es to address DOSGroup 72 DOSGroup equ DOSGROUP ; NASM port equate 0 000021D7 BF[0000] MOV DI,OFFSET OpenBuf wrt DOSGroup ; appropriate buffer 0 000021DA E8[0000] invoke TransFCB ; convert the FCB, set SATTRIB EXTFCB 0 000021DD 7304 JNC SearchIt ; no error, go and look 0 000021DF 5B RestoreReg ; Clean stack 77 ; 78 ; Error code is in AX 79 ; 0 000021E0 E9[0000] transfer FCB_Ret_Err ; error 81 82 SearchIt: 0 000021E3 161F Context DS ; get ready for search 0 000021E5 FF36[0000]FF36 SaveReg <, > 0 000021EB [0200] 0 000021ED C706[0000][0000] MOV WORD PTR [DMAAdd],OFFSET SEARCHBUF wrt DOSGroup 0 000021F3 8C1E[0200] MOV WORD PTR [DMAAdd+2],DS 0 000021F7 E88B01 invoke GET_FAST_SEARCH ; search 0 000021FA 8F06[0200]8F06 RestoreReg <, > 0 00002200 [0000] 0 00002202 7303 JNC SearchSet ; no error, transfer info 0 00002204 5B RestoreReg ; Clean stack 91 ; 92 ; Error code is in AX 93 ; 0 00002205 EBD9 transfer FCB_Ret_Err 95 96 ; 97 ; The search was successful (or the search-next). We store the information 98 ; into the user's FCB for continuation. 99 ; 100 SearchSet: 0 00002207 BE[0000] MOV SI,OFFSET SEARCHBUF wrt DOSGroup 0 0000220A C43E[0000] LES DI,[THISFCB] ; point to the FCB 0 0000220E F606[0000]FF TEST byte [EXTFCB],0FFH ; 0 00002213 7403 JZ NORMFCB1 0 00002215 83C707 ADD DI,7 ; Point past the extension 106 NORMFCB1: 0 00002218 5B RestoreReg ; Get original drive byte 0 00002219 08DB OR BL,BL 0 0000221B 7506 JNZ SearchDrv 0 0000221D 8A1E[0000] MOV BL,[CurDrv] 0 00002221 FEC3 INC BL 112 SearchDrv: 0 00002223 AC LODSB ; Get correct search contin drive byte 0 00002224 86C3 XCHG AL,BL ; Search byte to BL, user byte to AL 0 00002226 47 INC DI 116 ; STOSB ; Store the correct "user" drive byte 117 ; at the start of the search info 0 00002227 B90A00 MOV CX,20/2 0 0000222A F3A5 REP MOVSW ; Rest of search cont info, SI -> entry 0 0000222C 86C3 XCHG AL,BL ; User drive byte back to BL, search 121 ; byte to AL 0 0000222E AA STOSB ; Search contin drive byte at end of 123 ; contin info 0 0000222F C43E[0000] LES DI,[DMAAdd] 0 00002233 F606[0000]FF TEST byte [EXTFCB],0FFH 0 00002238 740E JZ NORMFCB2 0 0000223A B0FF MOV AL,0FFH 0 0000223C AA STOSB 0 0000223D FEC0 INC AL 0 0000223F B90500 MOV CX,5 0 00002242 F3AA REP STOSB 0 00002244 A0[0000] MOV AL,[SATTRIB] 0 00002247 AA STOSB 134 NORMFCB2: 0 00002248 88D8 MOV AL,BL ; User Drive byte 0 0000224A AA STOSB 137 %IF DBCS ;AN000; 138 MOVSW ; 2/13/KK ;AN000; 139 CMP BYTE PTR [ES:DI-2],5 ; 2/13/KK ;AN000; 140 JNZ NOTKTRAN ; 2/13/KK ;AN000; 141 MOV BYTE PTR [ES:DI-2],0E5H ; 2/13/KK ;AN000; 142 NOTKTRAN: ; 2/13/KK ;AN000; 143 MOV CX,15 ; 2/13/KK ;AN000; 144 %ELSE ;AN000; 0 0000224B B91000 MOV CX,16 ; 32 / 2 words of dir entry ;AN000; 146 %ENDIF ;AN000; 0 0000224E F3A5 REP MOVSW 0 00002250 E9[0000] transfer FCB_Ret_OK 149 150 EndProc D_DIR_SEARCH_FIRST 150 ****************** warning: ***** Possible stack size error in D_DIR_SEARCH_FIRST ***** [-w+user] 151 152 ; Inputs: 153 ; DS:DX points to unopenned FCB returned by $DIR_SEARCH_FIRST 154 ; Function: 155 ; Directory is searched for the next matching entry and the directory 156 ; entry is loaded at the disk transfer address 157 ; Returns: 158 ; AL = -1 if no entries matched, otherwise 0 159 160 procedure D_DIR_SEARCH_NEXT,NEAR 160 ****************** warning: proc D_DIR_SEARCH_NEXT... [-w+user] 161 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 162 0 00002253 368916[0000] MOV WORD PTR [ss:THISFCB],DX 0 00002258 368C1E[0200] MOV WORD PTR [ss:THISFCB+2],DS 0 0000225D 36C606[0000]00 MOV byte [ss:SATTRIB],0 0 00002263 36C606[0000]00 MOV byte [ss:EXTFCB],0 0 00002269 1607 Context ES 0 0000226B BF[0000] MOV DI,OFFSET SEARCHBUF wrt DOSGroup 0 0000226E 89D6 MOV SI,DX 0 00002270 803CFF CMP BYTE PTR [SI],0FFH 0 00002273 750D JNZ NORMFCB6 0 00002275 83C606 ADD SI,6 0 00002278 AC LODSB 0 00002279 36A2[0000] MOV [ss:SATTRIB],AL 0 0000227D 36FE0E[0000] DEC byte [ss:EXTFCB] 176 NORMFCB6: 0 00002282 AC LODSB ; Get original user drive byte 0 00002283 50 SaveReg ; Put it on stack 0 00002284 8A4414 MOV AL,[SI+20] ; Get correct search contin drive byte 0 00002287 AA STOSB ; Put in correct place 0 00002288 B90A00 MOV CX,20/2 0 0000228B F3A5 REP MOVSW ; Transfer in rest of search contin info 0 0000228D 161F Context DS 0 0000228F FF36[0000]FF36 SaveReg <, > 0 00002295 [0200] 0 00002297 C706[0000][0000] MOV WORD PTR [DMAAdd],OFFSET SEARCHBUF wrt DOSGroup 0 0000229D 8C1E[0200] MOV WORD PTR [DMAAdd+2],DS 0 000022A1 E8[0000] invoke DOS_SEARCH_NEXT ; Find it 0 000022A4 8F06[0200]8F06 RestoreReg <, > 0 000022AA [0000] 0 000022AC 7203 JC SearchNoMore 0 000022AE E956FF JMP SearchSet ; Ok set return 191 192 SearchNoMore: 0 000022B1 C43E[0000] LES DI,[THISFCB] 0 000022B5 F606[0000]FF TEST byte [EXTFCB],0FFH 0 000022BA 7403 JZ NORMFCB8 0 000022BC 83C707 ADD DI,7 ; Point past the extension 197 NORMFCB8: 0 000022BF 5B RestoreReg ; Get original drive byte 0 000022C0 26881D MOV [ES:DI],BL ; Store the correct "user" drive byte 200 ; at the right spot 201 ; 202 ; error code is in AX 203 ; 0 000022C3 E9[0000] transfer FCB_Ret_Err 205 206 EndProc D_DIR_SEARCH_NEXT 207 208 ; Assembler usage: 209 ; MOV AH, FindFirst 210 ; LDS DX, name 211 ; MOV CX, attr 212 ; INT 21h 213 ; ; DMA address has datablock 214 ; 215 ; Error Returns: 216 ; AX = error_path_not_found 217 ; = error_no_more_files 218 219 procedure D_FIND_FIRST,NEAR 219 ****************** warning: proc D_FIND_FIRST... [-w+user] 220 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 221 0 000022C6 89D6 MOV SI,DX ; get name in appropriate place 0 000022C8 36880E[0000] MOV [ss:SATTRIB],CL ; Search attribute to correct loc 0 000022CD BF[0000] MOV DI,OFFSET OpenBuf wrt DOSGroup ; appropriate buffer 0 000022D0 E8[0000] invoke TransPathSet ; convert the path 0 000022D3 7305 JNC Find_it ; no error, go and look 227 FindError: 0 000022D5 B003E9[0000] error error_path_not_found ; error and map into one. 229 Find_it: 0 000022DA 161F Context DS 0 000022DC FF36[0000]FF36 SaveReg <, > 0 000022E2 [0200] 0 000022E4 C706[0000][0000] MOV WORD PTR [DMAAdd],OFFSET SEARCHBUF wrt DOSGroup 0 000022EA 8C1E[0200] MOV WORD PTR [DMAAdd+2],DS 0 000022EE E89400 invoke GET_FAST_SEARCH ; search 0 000022F1 8F06[0200]8F06 RestoreReg <, > 0 000022F7 [0000] 0 000022F9 7302 JNC FindSet ; no error, transfer info 0 000022FB EBDA transfer Sys_Ret_Err 238 239 FindSet: 0 000022FD BE[0000] MOV SI,OFFSET SEARCHBUF wrt DOSGroup 0 00002300 C43E[0000] LES DI,[DMAAdd] 0 00002304 B91500 MOV CX,21 0 00002307 F3A4 REP MOVSB 0 00002309 56 PUSH SI ; Save pointer to start of entry 0 0000230A 8A440B MOV AL,[SI + dir_attr] 0 0000230D AA STOSB 0 0000230E 83C616 ADD SI,dir_time 0 00002311 A5 MOVSW ; dir_time 0 00002312 A5 MOVSW ; dir_date 0 00002313 46 INC SI 0 00002314 46 INC SI ; Skip dir_first 0 00002315 A5 MOVSW ; dir_size (2 words) 0 00002316 A5 MOVSW 0 00002317 5E POP SI ; Point back to dir_name 255 %IF DBCS ;AN000; 256 PUSH DI ; XXXX save dest name 2/13/KK ;AN000; 257 CALL PackName ;AN000; 258 POP DI ; XXXX Recover dest name 2/13/KK ;AN000; 259 CMP BYTE PTR [ES:DI],05H ; XXXX Need fix? 2/13/KK ;AN000; 260 JNZ FNXXX ; XXXX No 2/13/KK ;AN000; 261 MOV BYTE PTR [ES:DI],0E5H ; XXXX Yes, Fix 2/13/KK ;AN000; 262 FNXXX: ; 2/13/KK ;AN000; 263 %ELSE ;AN000; 0 00002318 E83500 CALL PackName 265 %ENDIF 0 0000231B E9[0000] transfer Sys_Ret_OK ; bye with no errors 267 EndProc D_FIND_FIRST 268 269 procedure D_FIND_NEXT,NEAR 269 ****************** warning: proc D_FIND_NEXT... [-w+user] 270 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 271 272 ; Assembler usage: 273 ; ; dma points at area returned by find_first 274 ; MOV AH, findnext 275 ; INT 21h 276 ; ; next entry is at dma 277 ; 278 ; Error Returns: 279 ; AX = error_no_more_files 280 0 0000231E 1607 Context ES 0 00002320 BF[0000] MOV DI,OFFSET SEARCHBUF wrt DOSGroup 0 00002323 36C536[0000] LDS SI,[ss:DMAAdd] 0 00002328 B91500 MOV CX,21 0 0000232B F3A4 REP MOVSB ; Put the search continuation info 286 ; in the right place 0 0000232D 161F Context DS ; get ready for search 0 0000232F FF36[0000]FF36 SaveReg <, > 0 00002335 [0200] 0 00002337 C706[0000][0000] MOV WORD PTR [DMAAdd],OFFSET SEARCHBUF wrt DOSGroup 0 0000233D 8C1E[0200] MOV WORD PTR [DMAAdd+2],DS 0 00002341 E8[0000] invoke DOS_SEARCH_NEXT ; Find it 0 00002344 8F06[0200]8F06 RestoreReg <, > 0 0000234A [0000] 0 0000234C 73AF JNC FindSet ; No error, set info 0 0000234E EBAB transfer Sys_Ret_Err 295 296 EndProc D_FIND_NEXT 297 298 Break 299 ; 300 ; PackName - transfer a file name from DS:SI to ES:DI and convert it to 301 ; the ASCIZ format. 302 ; 303 ; Input: DS:SI points to an 11 character FCB or dir entry name 304 ; ES:DI points to a destination area (13 bytes) 305 ; Output: Above pointers advanced 306 ; Registers modified: SI,DI,CX,AL 307 Procedure PackName,NEAR 307 ****************** warning: proc PackName... [-w+user] 308 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 00002350 B90800 MOV CX,8 ; Pack the name 0 00002353 F3A4 REP MOVSB ; Move all of it 311 main_kill_tail: 0 00002355 26807DFF20 CMP BYTE PTR [ES:DI-1]," " 0 0000235A 7507 JNZ find_check_dot 0 0000235C 4F DEC DI ; Back up over trailing space 0 0000235D 41 INC CX 0 0000235E 83F908 CMP CX,8 0 00002361 72F2 JB main_kill_tail 318 find_check_dot: 0 00002363 813C2020 CMP WORD PTR [SI],(" " << 8) | " " 0 00002367 7506 JNZ got_ext ; Some chars in extension 0 00002369 807C0220 CMP BYTE PTR [SI+2]," " 0 0000236D 7412 JZ find_done ; No extension 323 got_ext: 0 0000236F B02E MOV AL,"." 0 00002371 AA STOSB 0 00002372 B90300 MOV CX,3 0 00002375 F3A4 REP MOVSB 328 ext_kill_tail: 0 00002377 26807DFF20 CMP BYTE PTR [ES:DI-1]," " 0 0000237C 7503 JNZ find_done 0 0000237E 4F DEC DI ; Back up over trailing space 0 0000237F EBF6 JMP ext_kill_tail 333 find_done: 0 00002381 31C0 XOR AX,AX 0 00002383 AA STOSB ; NUL terminate 0 00002384 C3 return 337 EndProc PackName 338 339 procedure GET_FAST_SEARCH,NEAR 339 ****************** warning: proc GET_FAST_SEARCH... [-w+user] 340 ASSUME DS:NOTHING,ES:NOTHING 341 0 00002385 36810E[0000]0004 OR word [ss:DOS34_FLAG],SEARCH_FASTOPEN ;FO.trigger fastopen ;AN000; 0 0000238C E8[0000] invoke DOS_SEARCH_FIRST 0 0000238F C3 return 345 346 EndProc GET_FAST_SEARCH 347 END === Trace listing source: ../DOS/path.lst 1 ; SCCSID = @(#)path.asm 1.1 85/04/10 2 ;TITLE PATH - Directory related system calls 3 ;NAME PATH 4 5 ; 6 ; Directory related system calls. These will be passed direct text of the 7 ; pathname from the user. They will need to be passed through the macro 8 ; expander prior to being sent through the low-level stuff. I/O specs are 9 ; defined in DISPATCH. The system calls are: 10 ; 11 ; $CURRENT_DIR Written 12 ; $RMDIR Written 13 ; $CHDIR Written 14 ; $MKDIR Written 15 ; 16 ; 17 ; Modification history: 18 ; 19 ; Created: ARR 4 April 1983 20 ; MZ 10 May 1983 CurrentDir implemented 21 ; MZ 11 May 1983 RmDir, ChDir, MkDir implemented 22 ; EE 19 Oct 1983 RmDir no longer allows you to delete a 23 ; current directory. 24 ; MZ 19 Jan 1983 Brain damaged applications rely on success 25 ; values of AL. 26 [list -] === Switch to base=008400h -> "DOSCODECODE" 33 section DOSCODECODE 34 [list -] 34 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 34 ****************** warning: out: BPB.INC... [-w+user] 34 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 34 ****************** warning: out: DEVSYM.INC... [-w+user] 41 42 EXTRN DOS_MkDir:NEAR,DOS_RmDir:NEAR 43 44 I_Need ThisCDS,DWORD ; pointer to Current CDS 45 I_Need WFP_Start,WORD ; pointer to beginning of directory text 46 I_Need Curr_Dir_End,WORD ; offset to end of directory part 47 I_Need OpenBuf,128 ; temp spot for translated name 48 I_need fSplice,BYTE ; TRUE => do splice 49 I_Need NoSetDir,BYTE ; TRUE => no exact match on splice 50 I_Need cMeta,BYTE 51 I_Need DrvErr,BYTE ;AN000; 52 53 BREAK <$CURRENT_DIR - dump the current directory into user space> 54 ; 55 ; Assembler usage: 56 ; LDS SI,area 57 ; MOV DL,drive 58 ; INT 21h 59 ; ; DS:SI is a pointer to 64 byte area that contains drive 60 ; ; current directory. 61 ; Error returns: 62 ; AX = error_invalid_drive 63 ; 64 65 procedure D_CURRENT_DIR,NEAR 65 ****************** warning: proc D_CURRENT_DIR... [-w+user] 66 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING 0 00002390 E8[0000] EnterCrit critDisk 0 00002393 88D0 MOV AL,DL ; get drive number (0=def, 1=A) 0 00002395 E8[0000] Invoke GetVisDrv ; grab it 0 00002398 730A JNC CurrentValidate ; no error -> go and validate dir 71 CurdirErr: 0 0000239A E8[0000] LeaveCrit critDisk 0 0000239D 36A0[0000] MOV AL,[ss:DrvErr] ;IFS. ;AN000; 0 000023A1 E9[0000] transfer SYS_RET_ERR ;IFS. make noise ;AN000; 75 CurrentValidate: 0 000023A4 1E56 SaveReg ; save destination 0 000023A6 36C536[0000] LDS SI,[ss:ThisCDS] 0 000023AB F744430080 TEST word [SI + curdir_flags],curdir_isnet 0 000023B0 7500 JNZ DoCheck 80 ; Random optimization nuked due to some utilities using GetCurrentDir to do 81 ; media check. 82 ; CMP [SI].curdir_id,0 83 ; JZ GetDst 84 DoCheck: 0 000023B2 36C606[0000]00 MOV byte [ss:NoSetDir],0 ; interested only in contents 86 DOSGroup equ DOSGROUP ; NASM port equate 0 000023B8 BF[0000] MOV DI,OFFSET OpenBuf wrt DOSGroup 0 000023BB E8[0000] Invoke ValidateCDS ; output is ES:DI -> CDS 0 000023BE 0657 SaveReg ; swap source and destination 0 000023C0 5E1F RestoreReg 91 GetDst: 0 000023C2 5F07 RestoreReg ; get real destination 0 000023C4 72D4 JC CurdirErr 0 000023C6 83C600 ADD SI,curdir_text 95 curdir_END equ curdir_end ; NASM port equate 0 000023C9 03744F ADD SI,[SI + curdir_END] 0 000023CC 803C5C CMP BYTE PTR [SI],'\' ; root or subdirs present? 0 000023CF 7501 JNZ CurrentCopy 0 000023D1 46 INC SI 100 CurrentCopy: 101 ; Invoke FStrCpy 102 ;; 10/29/86 E5 char 0 000023D2 50 PUSH AX 0 000023D3 AC LODSB ; get char 0 000023D4 08C0 OR AL,AL 0 000023D6 7414 JZ FOK 0 000023D8 3C05 CMP AL,05 0 000023DA 740E JZ FCHANGE 0 000023DC EB02 JMP FFF 0 000023DE 90 nop ; identicalise 111 FCPYNEXT: 0 000023DF AC LODSB ; get char 113 FFF: 0 000023E0 3C5C CMP AL,'\' ; beginning of directory 0 000023E2 7508 JNZ FOK ; no 0 000023E4 AA STOSB ; put into user's buffer 0 000023E5 AC LODSB ; 1st char of dir is 05? 0 000023E6 3C05 CMP AL,05H 0 000023E8 7502 JNZ FOK ; no 120 FCHANGE: 0 000023EA B0E5 MOV AL,0E5H ; make it E5 122 FOK: 0 000023EC AA STOSB ; put into user's buffer 0 000023ED 08C0 OR AL,AL ; final char 0 000023EF 75EE JNZ FCPYNEXT ; no 0 000023F1 58 POP AX 127 128 ;; 10/29/86 E5 char 0 000023F2 30C0 xor AL,AL ; MZ 19 Jan 84 0 000023F4 E8[0000] LeaveCrit critDisk 0 000023F7 E9[0000] transfer Sys_Ret_OK ; no more, bye! 132 EndProc D_Current_Dir 133 134 BREAK <$RmDir -- Remove a directory> 135 136 ; Inputs: 137 ; DS:DX Points to asciz name 138 ; Function: 139 ; Delete directory if empty 140 ; Returns: 141 ; STD XENIX Return 142 ; AX = error_path_not_found If path bad 143 ; AX = error_access_denied If 144 ; Directory not empty 145 ; Path not directory 146 ; Root directory specified 147 ; Directory malformed (. and .. not first two entries) 148 ; User tries to delete a current directory 149 ; AX = error_current_directory 150 151 procedure D_RMDIR,NEAR 151 ****************** warning: proc D_RMDIR... [-w+user] 152 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 153 0 000023FA 52 push dx ; Save ptr to name 0 000023FB 1E push ds 0 000023FC 89D6 mov si,dx ; Load ptr into si 0 000023FE BF[0000] mov di,offset OpenBuf wrt DOSGroup ; di = ptr to buf for trans name 0 00002401 57 push di 0 00002402 E8[0000] Invoke TransPathNoSet ; Translate the name 0 00002405 5F pop di ; di = ptr to buf for trans name 0 00002406 7306 jnc rmlset ; If transpath succeeded, continue 0 00002408 1F pop ds 0 00002409 5A pop dx ; Restore the name 0 0000240A B003EB93 error error_path_not_found ; Otherwise, return an error 165 166 rmlset: 0 0000240E 36803E[0000]FF CMP byte [ss:cMeta],-1 ; if (cMeta >= 0) 0 00002414 7512 Jnz rmerr ; return (-1); 0 00002416 1607 Context ES 0 00002418 30C0 xor al,al ; al = 0 , ie drive a: 0 0000241A E8[0000] rmloop: Invoke GetCDSFromDrv ; Get curdir for drive in al 0 0000241D 720F jc rmcont ; If error, exit loop & cont normally 0 0000241F E8[0000] Invoke StrCmp ; Are the 2 paths the same? 0 00002422 7404 jz rmerr ; Yes, report error. 0 00002424 FEC0 inc al ; No, inc al to next drive number 0 00002426 EBF2 jmp rmloop ; Go check next drive. 177 178 rmerr: 0 00002428 1F pop ds 0 00002429 5A pop dx ; Restore the name 0 0000242A B010EBDE error error_current_directory ; error 182 183 rmcont: 0 0000242E 1F pop ds 0 0000242F 5A pop dx ; Restore the name 186 DOS_RmDIR equ DOS_RmDir ; NASM port label 0 00002430 BE[0000] MOV SI,OFFSET DOS_RmDIR 0 00002433 E97F00 JMP strict near DoDirCall 189 EndProc D_RMDIR 190 191 BREAK <$ChDir -- Change current directory on a drive> 192 193 ; 194 ; $ChDir - Top-level change directory system call. This call is responsible 195 ; for setting up the CDS for the specified drive appropriately. There are 196 ; several cases to consider: 197 ; 198 ; o Local, simple CDS. In this case, we take the input path and convert 199 ; it into a WFP. We verify the existance of this directory and then 200 ; copy the WFP into the CDS and set up the ID field to point to the 201 ; directory cluster. 202 ; o Net CDS. We form the path from the root (including network prefix) 203 ; and verify its existance (via DOS_Chdir). If successful, we copy the 204 ; WFP back into the CDS. 205 ; o SUBST'ed CDS. This is no different than the local, simple CDS. 206 ; o JOIN'ed CDS. This is trouble as there are two CDS's at work. If we 207 ; call TransPath, we will get the PHYSICAL CDS that the path refers to 208 ; and the PHYSICAL WFP that the input path refers to. This is perfectly 209 ; good for the validation but not for currency. We call TransPathNoSet 210 ; to process the path but to return the logical CDS and the logical 211 ; path. We then copy the logical path into the logical CDS. 212 ; 213 ; Inputs: 214 ; DS:DX Points to asciz name 215 ; Returns: 216 ; STD XENIX Return 217 ; AX = chdir_path_not_found if error 218 219 procedure D_CHDIR,NEAR 219 ****************** warning: proc D_CHDIR... [-w+user] 220 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 00002436 BF[0000] MOV DI,OFFSET OpenBuf wrt DOSGroup ; spot for translated name 0 00002439 89D6 MOV SI,DX ; get source 0 0000243B E8[0000] Invoke TransPath ; go munge the path and get real CDS 0 0000243E 7304 JNC ChDirCrack ; no errors, try path 225 ChDirErrP: 0 00002440 B003 MOV AL,error_path_not_found 227 ChdirErr: 0 00002442 EBE8 transfer SYS_Ret_Err ; oops! 229 230 ChDirCrack: 231 Assume DS:DOSGroup 0 00002444 803E[0000]FF CMP byte [cMeta],-1 ; No meta chars allowed. 0 00002449 75F5 JNZ ChDirErrP 234 ; 235 ; We cannot do a ChDir (yet) on a raw CDS. This is treated as a path not 236 ; found. 237 ; 0 0000244B C43E[0000] LES DI,[ThisCDS] 0 0000244F 83FFFF CMP DI,-1 ; if (ThisCDS == NULL) 0 00002452 74EC JZ ChDirErrP ; error (); 241 ; 242 ; Find out if the directory exists. 243 ; 0 00002454 E8[0000] Invoke DOS_ChDir 245 ChDirErr equ ChdirErr ; NASM port label 0 00002457 72E9 JC ChDirErr 247 ; 248 ; Get back CDS to see if a join as seen. Set the currency pointer (only if 249 ; not network). If one was seen, all we need to do is copy in the text 250 ; 0 00002459 C43E[0000] LES DI,[ThisCDS] 0 0000245D 26F745430020 TEST word [ES:DI + curdir_flags],curdir_splice 0 00002463 7425 JZ GotCDS 254 ; 255 ; The CDS was joined. Let's go back and grab the logical CDS. 256 ; 0 00002465 065751 SaveReg ; save CDS and cluster... 0 00002468 E8[0000] Invoke Get_User_Stack ; get original text 259 ASSUME DS:NOTHING 260 User_DX equ user_DX ; NASM port equate 0 0000246B 8B7C06 MOV DI,[SI + User_DX] 262 User_DS equ user_DS ; NASM port equate 0 0000246E 8E5C0E MOV DS,[SI + User_DS] 0 00002471 BE[0000] MOV SI,OFFSET OpenBuf wrt DOSGroup ; spot for translated name 0 00002474 87F7 XCHG SI,DI 0 00002476 30C0 XOR AL,AL ; do no splicing 0 00002478 57 SaveReg 0 00002479 E8[0000] Invoke TransPathNoSet ; Munge path 0 0000247C 5E RestoreReg 270 Assume DS:DOSGroup 271 ; 272 ; There should NEVER be an error here. 273 ; 274 %IF FALSE 275 SKipErr equ SkipErr ; NASM port label 276 JNC SKipErr 277 fmt <>,<>,<"$p: Internal CHDIR error\n"> 278 SkipErr: 279 %ENDIF 0 0000247D C43E[0000] LES DI,[ThisCDS] ; get new CDS 0 00002481 26C74549FFFF MOV word [ES:DI + curdir_ID],-1 ; no valid cluster here... 0 00002487 595F07 RestoreReg 283 ; 284 ; ES:DI point to the physical CDS, CX is the ID (local only) 285 ; 286 GotCDS: 287 ; 288 ; wfp_start points to the text. See if it is long enough 289 ; 0 0000248A E85200 CALL Check_PathLen ;PTM. ;AN000; 0 0000248D 77B1 JA ChDirErrP 0 0000248F 26F745430080 TEST word [ES:DI + curdir_flags],curdir_isnet 0 00002495 7513 JNZ SkipRecency 0 00002497 26F745430020 TEST word [ES:DI + curdir_flags],curdir_splice ;PTM. for Join and Subst ;AN000; 0 0000249D 7403 JZ setdirclus ;PTM. ;AN000; 0 0000249F B9FFFF MOV CX,-1 ;PTM. ;AN000; 297 setdirclus: 298 curdir_id equ curdir_ID ; NASM port equate 0 000024A2 26894D49 MOV [ES:DI + curdir_id],CX 0 000024A6 C43E[0000] LES DI,[ThisCDS] ; get logical CDS 301 SkipRecency: 0 000024AA E8[0000] invoke FStrCpy 0 000024AD 30C0 XOR AL,AL 0 000024AF E9[0000] transfer Sys_Ret_OK 305 EndProc D_CHDIR 306 307 BREAK <$MkDir - Make a directory entry> 308 ; Inputs: 309 ; DS:DX Points to asciz name 310 ; Function: 311 ; Make a new directory 312 ; Returns: 313 ; STD XENIX Return 314 ; AX = mkdir_path_not_found if path bad 315 ; AX = mkdir_access_denied If 316 ; Directory cannot be created 317 ; Node already exists 318 ; Device name given 319 ; Disk or directory(root) full 320 321 procedure D_MKDIR,NEAR 321 ****************** warning: proc D_MKDIR... [-w+user] 322 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 000024B2 BE[0000] MOV SI,OFFSET DOS_MkDir 324 DoDirCall: 0 000024B5 BF[0000] MOV DI,OFFSET OpenBuf wrt DOSGroup ; spot for translated name 0 000024B8 56 SaveReg 0 000024B9 89D6 MOV SI,DX ; get source 0 000024BB E8[0000] Invoke TransPath ; go munge the path 0 000024BE 5E RestoreReg 0 000024BF 7305 JNC MkDirCrack ; no errors, try path 331 MkErrP: 332 error_Path_Not_Found equ error_path_not_found ; NASM port equate 0 000024C1 B003 MOV AL,error_Path_Not_Found ; oops! 334 MkErr: 0 000024C3 E9[0000] transfer Sys_Ret_Err 336 MkDirCrack: 0 000024C6 36803E[0000]FF CMP byte [ss:cMeta],-1 0 000024CC 75F3 JNZ MkErrP 339 0 000024CE 56 PUSH SI ;PTM. ;AN000; 0 000024CF E80D00 CALL Check_PathLen ;PTM. check path len > 67 ? ;AN000; 0 000024D2 5E POP SI ;PTM. ;AN000; 0 000024D3 7604 JBE pathok ;PTM. ;AN000; 344 error_Access_Denied equ error_access_denied ; NASM port equate 0 000024D5 B005 MOV AL,error_Access_Denied ;PTM. ops! 0 000024D7 EBEA transfer Sys_Ret_Err ;PTM. 347 pathok: 0 000024D9 FFD6 CALL SI ; go get file 349 ASSUME ES:NOTHING 0 000024DB 72E6 JC MkErr ; no errors 0 000024DD EBD0 transfer Sys_Ret_OK 352 EndProc D_MKDIR 353 354 ; Inputs: 355 ; nothing 356 ; Function: 357 ; check if final path length greater than 67 358 ; Returns: 359 ; Above flag set if > 67 360 361 procedure Check_PathLen,NEAR 361 ****************** warning: proc Check_PathLen... [-w+user] 362 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 363 364 Wfp_Start equ WFP_Start ; NASM port label 0 000024DF 368B36[0000] MOV SI,[ss:Wfp_Start] 366 entry Check_PathLen2 0 000024E4 161F Context 0 000024E6 51 SaveReg 0 000024E7 E8[0000] invoke DStrLen 370 DirStrLen equ DIRSTRLEN ; NASM port equate 0 000024EA 83F943 CMP CX,DirStrLen 0 000024ED 59 RestoreReg 0 000024EE C3 ret 374 EndProc Check_PathLen 375 END 376 377 === Trace listing source: ../DOS/ioctl.lst 1 ; SCCSID = @(#)IOCTL.INC 1.15 85/09/05 2 ;TITLE IOCTL - IOCTL system call 3 ;NAME IOCTL 4 5 ; 6 ; 7 ; IOCTL system call. 8 ; 9 ; 10 ; $IOCTL 11 ; 12 ; Revision history: 13 ; 14 ; Created: ARR 4 April 1983 15 ; 16 ; GenericIOCTL added: KGS 22 April 1985 17 ; 18 ; A000 version 4.00 Jan. 1988 19 20 21 22 [list -] === Switch to base=008400h -> "DOSCODECODE" 29 section DOSCODECODE 30 [list -] 30 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 30 ****************** warning: out: BPB.INC... [-w+user] 30 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 30 ****************** warning: out: DEVSYM.INC... [-w+user] 30 ****************** warning: out: IOCTL.INC... [-w+user] 30 ****************** warning: out: BPB.INC... [-w+user] 39 40 i_need THISCDS,DWORD 41 i_need IOCALL,BYTE 42 i_need IOMED,BYTE 43 i_need IOSCNT,WORD 44 i_need IOXAD,DWORD 45 I_need RetryCount,WORD 46 I_need RetryLoop,WORD 47 I_need EXTERR_LOCUS,BYTE 48 I_need OPENBUF,BYTE 49 I_need ExtErr,WORD 50 I_need DrvErr,BYTE 51 I_need USER_IN_AX,WORD ;AN000; 52 I_need Temp_Var2,WORD ;AN000; 53 54 BREAK 55 56 ; 57 ; Assembler usage: 58 ; MOV BX, Handle 59 ; MOV DX, Data 60 ; 61 ; (or LDS DX,BUF 62 ; MOV CX,COUNT) 63 ; 64 ; MOV AH, Ioctl 65 ; MOV AL, Request 66 ; INT 21h 67 ; 68 ; AH = 0 Return a combination of low byte of sf_flags and device driver 69 ; attribute word in DX, handle in BX: 70 ; DH = high word of device driver attributes 71 ; DL = low byte of sf_flags 72 ; 1 Set the bits contained in DX to sf_flags. DH MUST be 0. Handle 73 ; in BX. 74 ; 2 Read CX bytes from the device control channel for handle in BX 75 ; into DS:DX. Return number read in AX. 76 ; 3 Write CX bytes to the device control channel for handle in BX from 77 ; DS:DX. Return bytes written in AX. 78 ; 4 Read CX bytes from the device control channel for drive in BX 79 ; into DS:DX. Return number read in AX. 80 ; 5 Write CX bytes to the device control channel for drive in BX from 81 ; DS:DX. Return bytes written in AX. 82 ; 6 Return input status of handle in BX. If a read will go to the 83 ; device, AL = 0FFh, otherwise 0. 84 ; 7 Return output status of handle in BX. If a write will go to the 85 ; device, AL = 0FFh, otherwise 0. 86 ; 8 Given a drive in BX, return 1 if the device contains non- 87 ; removable media, 0 otherwise. 88 ; 9 Return the contents of the device attribute word in DX for the 89 ; drive in BX. 0200h is the bit for shared. 1000h is the bit for 90 ; network. 8000h is the bit for local use. 91 ; A Return 8000h if the handle in BX is for the network or not. 92 ; B Change the retry delay and the retry count for the system. BX is 93 ; the count and CX is the delay. 94 ; 95 ; Error returns: 96 ; AX = error_invalid_handle 97 ; = error_invalid_function 98 ; = error_invalid_data 99 ; 100 ;------------------------------------------------------------------------------- 101 ; 102 ; This is the documentation copied from DOS 4.0 it is much better 103 ; than the above 104 ; 105 ; There are several basic forms of IOCTL calls: 106 ; 107 ; 108 ; ** Get/Set device information: ** 109 ; 110 ; ENTRY (AL) = function code 111 ; 0 - Get device information 112 ; 1 - Set device information 113 ; (BX) = file handle 114 ; (DX) = info for "Set Device Information" 115 ; EXIT 'C' set if error 116 ; (AX) = error code 117 ; 'C' clear if OK 118 ; (DX) = info for "Get Device Information" 119 ; USES ALL 120 ; 121 ; 122 ; ** Read/Write Control Data From/To Handle ** 123 ; 124 ; ENTRY (AL) = function code 125 ; 2 - Read device control info 126 ; 3 - Write device control info 127 ; (BX) = file handle 128 ; (CX) = transfer count 129 ; (DS:DX) = address for data 130 ; EXIT 'C' set if error 131 ; (AX) = error code 132 ; 'C' clear if OK 133 ; (AX) = count of bytes transfered 134 ; USES ALL 135 ; 136 ; 137 ; ** Read/Write Control Data From/To Block Device ** 138 ; 139 ; ENTRY (AL) = function code 140 ; 4 - Read device control info 141 ; 5 - Write device control info 142 ; (BL) = Drive number (0=default, 1='A', 2='B', etc) 143 ; (CX) = transfer count 144 ; (DS:DX) = address for data 145 ; EXIT 'C' set if error 146 ; (AX) = error code 147 ; 'C' clear if OK 148 ; (AX) = count of bytes transfered 149 ; USES ALL 150 ; 151 ; 152 ; ** Get Input/Output Status ** 153 ; 154 ; ENTRY (AL) = function code 155 ; 6 - Get Input status 156 ; 7 - Get Output Status 157 ; (BX) = file handle 158 ; EXIT 'C' set if error 159 ; (AX) = error code 160 ; 'C' clear if OK 161 ; (AL) = 00 if not ready 162 ; (AL) = FF if ready 163 ; USES ALL 164 ; 165 ; 166 ; ** Get Drive Information ** 167 ; 168 ; ENTRY (AL) = function code 169 ; 8 - Check for removable media 170 ; 9 - Get device attributes 171 ; (BL) = Drive number (0=default, 1='A', 2='B', etc) 172 ; EXIT 'C' set if error 173 ; (AX) = error code 174 ; 'C' clear if OK 175 ; (AX) = 0/1 media is removable/fixed (func. 8) 176 ; (DX) = device attribute word (func. 9) 177 ; USES ALL 178 ; 179 ; 180 ; ** Get Redirected bit ** 181 ; 182 ; ENTRY (AL) = function code 183 ; 0Ah - Network stuff 184 ; (BX) = file handle 185 ; EXIT 'C' set if error 186 ; (AX) = error code 187 ; 'C' clear if OK 188 ; (DX) = SFT flags word, 8000h set if network file 189 ; USES ALL 190 ; 191 ; 192 ; ** Change sharer retry parameters ** 193 ; 194 ; ENTRY (AL) = function code 195 ; 0Bh - Set retry parameters 196 ; (CX) = retry loop count 197 ; (DX) = number of retries 198 ; EXIT 'C' set if error 199 ; (AX) = error code 200 ; 'C' clear if OK 201 ; USES ALL 202 ; 203 ; 204 ; ================================================================= 205 ; 206 ; ** New Standard Control ** 207 ; 208 ; ALL NEW IOCTL FACILITIES SHOULD USE THIS FORM. THE OTHER 209 ; FORMS ARE OBSOLETE. 210 ; 211 ; ================================================================= 212 ; 213 ; ENTRY (AL) = function code 214 ; 0Ch - Control Function subcode 215 ; (BX) = File Handle 216 ; (CH) = Category Indicator 217 ; (CL) = Function within category 218 ; (DS:DX) = address for data, if any 219 ; (SI) = Passed to device as argument, use depends upon function 220 ; (DI) = Passed to device as argument, use depends upon function 221 ; EXIT 'C' set if error 222 ; (AX) = error code 223 ; 'C' clear if OK 224 ; (SI) = Return value, meaning is function dependent 225 ; (DI) = Return value, meaning is function dependent 226 ; (DS:DX) = Return address, use is function dependent 227 ; USES ALL 228 ; 229 ; ============== Generic IOCTL Definitions for DOS 3.2 ============ 230 ; (See dos/ioctl.mac for more info) 231 ; 232 ; ENTRY (AL) = function code 233 ; 0Dh - Control Function subcode 234 ; (BL) = Drive Number (0 = Default, 1= 'A') 235 ; (CH) = Category Indicator 236 ; (CL) = Function within category 237 ; (DS:DX) = address for data, if any 238 ; (SI) = Passed to device as argument, use depends upon function 239 ; (DI) = Passed to device as argument, use depends upon function 240 ; 241 ; EXIT 'C' set if error 242 ; (AX) = error code 243 ; 'C' clear if OK 244 ; (DS:DX) = Return address, use is function dependent 245 ; USES ALL 246 ; 247 248 procedure D_IOCTL,NEAR 248 ****************** warning: proc D_IOCTL... [-w+user] 249 ASSUME DS:NOTHING,ES:NOTHING 0 000024EF 8CDE MOV SI,DS ; Stash DS for calls 2,3,4 and 5 0 000024F1 161F context DS 0 000024F3 3C03 CMP AL,3 0 000024F5 7603 JBE ioctl_check_char ; char device 0 000024F7 E98400 JMP ioctl_check_block ; Block device 255 ioctl_check_char: 0 000024FA E8[0000] invoke SFFromHandle ; ES:DI -> SFT 0 000024FD 7305 JNC ioctl_check_permissions ; have valid handle 258 ioctl_bad_handle: 0 000024FF B006E9[0000] error error_invalid_handle 260 261 ioctl_check_permissions: 0 00002504 3C02 CMP AL,2 0 00002506 734F JAE ioctl_control_string 0 00002508 3C00 CMP AL,0 0 0000250A 268A4505 MOV AL,BYTE PTR [ES:DI + sf_flags]; Get low byte of flags 0 0000250E 7425 JZ ioctl_read ; read the byte 0 00002510 52 PUSH DX ;AN000;MS. 0 00002511 80E6FE AND DH,0FEH ;AN000;MS.allow DH=01H 0 00002514 5A POP DX ;AN000;MS. 0 00002515 7407 JZ ioctl_check_device ; can I set with this data? 0 00002517 B00DEBE6 error error_invalid_data ; no DH <> 0 272 273 ioctl_bad_funj2: 0 0000251B E96301 JMP ioctl_bad_fun 275 276 ioctl_check_device: 0 0000251E A880 TEST AL,devid_device ; can I set this handle? 0 00002520 740C JZ do_exception ; no, it is a file. 0 00002522 80CA80 OR DL,devid_device ; Make sure user doesn't turn off the 280 ; device bit!! He can muck with the 281 ; others at will. 0 00002525 C606[0000]04 MOV byte [EXTERR_LOCUS],errLOC_SerDev 0 0000252A 26885505 MOV BYTE PTR [ES:DI + sf_flags],DL ;AC000;MS.; Set flags 284 do_exception: 0 0000252E 26087506 OR BYTE PTR [ES:DI + sf_flags+1],DH;AN000;MS.;set 100H bit for disk full 286 0 00002532 E9[0000] transfer SYS_RET_OK 288 289 290 291 292 293 ioctl_read: 0 00002535 C606[0000]02 MOV byte [EXTERR_LOCUS],errLOC_Disk 0 0000253A 30E4 XOR AH,AH 0 0000253C A880 TEST AL,devid_device ; Should I set high byte 0 0000253E 740D JZ ioctl_no_high ; no 0 00002540 C606[0000]04 MOV byte [EXTERR_LOCUS],errLOC_SerDev 0 00002545 26C47D07 LES DI,[ES:DI + sf_devptr] ; Get device pointer 0 00002549 268A6505 MOV AH,BYTE PTR [ES:DI + SDEVATT+1] ; Get high byte 301 ioctl_no_high: 0 0000254D 89C2 MOV DX,AX 0 0000254F E8[0000] invoke get_user_stack 0 00002552 895406 MOV [SI + user_DX],DX 0 00002555 EBDB transfer SYS_RET_OK 306 307 ioctl_control_string: 0 00002557 26F745058000 TEST word [ES:DI + sf_flags],devid_device ; can I? 0 0000255D 7503 JNZ ioctl_ctl_str_1 0 0000255F E91F01 JMP ioctl_bad_fun ; No it is a file 311 ioctl_ctl_str_1: 0 00002562 26F745050080 TEST word [ES:DI + sf_flags],sf_isnet ;AN000;IFS.; IFS ? 0 00002568 7403 JZ localrw ;AN000;IFS.; no 0 0000256A E9B700 JMP callifs ;AN000;IFS.; call IFS 315 localrw: 0 0000256D C606[0000]04 MOV byte [EXTERR_LOCUS],errLOC_SerDev 0 00002572 26C47D07 LES DI,[ES:DI + sf_devptr] ; Get device pointer 0 00002576 30DB XOR BL,BL ; Unit number of char dev = 0 0 00002578 E9B701 JMP ioctl_do_string 320 321 ioctl_get_devj: 0 0000257B E9AF01 JMP ioctl_get_dev 323 324 ioctl_check_block: 0 0000257E FEC8 DEC AL 0 00002580 FEC8 DEC AL ; 4=2,5=3,6=4,7=5,8=6,9=7,10=8,11=9 0 00002582 3C03 CMP AL,3 0 00002584 76F5 JBE ioctl_get_devj 0 00002586 3C06 CMP AL,6 0 00002588 731F JAE ioctl_rem_media_check 331 0 0000258A B401 MOV AH,1 0 0000258C 2C04 SUB AL,4 ; 6=0,7=1 0 0000258E 7402 JZ ioctl_get_status 0 00002590 B403 MOV AH,3 336 ioctl_get_status: 0 00002592 50 PUSH AX 0 00002593 E8[0000] invoke GET_IO_SFT 0 00002596 58 POP AX 0 00002597 7303 JNC DO_IOFUNC 0 00002599 E963FF JMP ioctl_bad_handle ; invalid SFT 342 343 DO_IOFUNC: 0 0000259C E8[0000] invoke IOFUNC 0 0000259F 88C4 MOV AH,AL 0 000025A1 B0FF MOV AL,0FFH 0 000025A3 7502 JNZ ioctl_status_ret 0 000025A5 FEC0 INC AL 349 ioctl_status_ret: 0 000025A7 EBAC transfer SYS_RET_OK 351 352 ioctl_rem_media_check: ; 4=2,5=3,6=4,7=5,8=6,9=7,10=8,11=9 0 000025A9 7407 JE ioctl_rem_mediaj 354 0 000025AB 2C07 SUB AL,7 ; 9=0,10=1,11=2,12=3,13=4,14=5,15=6 0 000025AD 7509 JNZ Rem_med_chk_1 0 000025AF E91601 JMP Ioctl_Drive_attr 358 359 ioctl_rem_mediaj: 0 000025B2 E9D400 jmp ioctl_rem_media 361 362 ioctl_bad_funj4: 0 000025B5 E9C900 jmp ioctl_bad_fun 364 365 Rem_med_chk_1: 366 0 000025B8 FEC8 DEC AL ; 10=0,11=1,12=2,13=3,14=4,15=5 0 000025BA 7503 jnz Set_Retry_chk 369 Ioctl_Handle_redirj equ IOCtl_Handle_RedirJ ; NASM port label 0 000025BC E9BF00 Jmp Ioctl_Handle_redirj 371 372 Set_Retry_chk: 0 000025BF FEC8 DEC AL ; 11=0,12=1,13=2,14=3,15=4 0 000025C1 740F JZ Set_Retry_Parameters 375 0 000025C3 FEC8 DEC AL ; 12=0,13=1,14=2,15=3 0 000025C5 741C JZ GENERICIOCTLHANDLE 378 0 000025C7 FEC8 DEC AL ; 13=0,14=1,15=2 0 000025C9 743A JZ GENERICIOCTL 381 0 000025CB 3C02 CMP AL,2 0 000025CD 77E6 JA ioctl_bad_funj4 0 000025CF E92302 JMP ioctl_drive_owner 385 Set_Retry_Parameters: 0 000025D2 890E[0000] MOV [RetryLoop],CX ; 0 retry loop count allowed 0 000025D6 09D2 OR DX,DX ; zero retries not allowed 0 000025D8 7503 JNZ goodtr 389 IoCtl_Bad_Fun equ ioctl_bad_fun ; NASM port label 0 000025DA E9A400 JMP IoCtl_Bad_Fun 391 goodtr: 0 000025DD 8916[0000] MOV [RetryCount],DX ; Set new retry count 393 doneok: 0 000025E1 EBC4 transfer Sys_Ret_Ok ; Done 395 396 ; Generic IOCTL entry point. 397 ; here we invoke the Generic IOCTL using the IOCTL_Req structure. 398 ; SI:DX -> Users Device Parameter Table 399 ; IOCALL -> IOCTL_Req structure 400 GENERICIOCTLHANDLE: 0 000025E3 E8[0000] invoke SFFromHandle ; Get SFT for device. 0 000025E6 7303 jnc goodh 0 000025E8 E99B00 JMP ioctl_bad_handlej 404 goodh: 405 ; test word ptr [DI.sf_flags],sf_isnet 0 000025EB E85002 CALL TEST_IFS_REMOTE ;AN000;;IFS. test if remote 0 000025EE 7403 JZ okokok ;AN000;;IFS. 0 000025F0 E98E00 jmp ioctl_bad_fun ; Cannot do this over net. 409 okokok: 0 000025F3 F745050080 TEST word [DI + sf_flags],sf_isnet ;AN000;IFS.; local IFS 0 000025F8 752A JNZ callifs ;AN000;IFS.; yes 412 413 414 ErrLOC_Serdev equ errLOC_SerDev ; NASM port equate 0 000025FA C606[0000]04 mov byte [EXTERR_LOCUS],ErrLOC_Serdev 0 000025FF 26C47D07 les di,[es:di + sf_devptr] ; Get pointer to device. 0 00002603 EB3F jmp short Do_GenIOCTL 418 419 GENERICIOCTL: 420 ErrLOC_Disk equ errLOC_Disk ; NASM port equate 0 00002605 C606[0000]02 mov byte [EXTERR_LOCUS],ErrLOC_Disk 0 0000260A 80FD08 cmp ch,IOC_DC ; Only disk devices are allowed to use 0 0000260D 7572 jne ioctl_bad_fun ; no handles with Generic IOCTL. 0 0000260F E8BA01 CALL Check_If_Net ; ES:DI := Get_hdr_block of device in BL 0 00002612 756D JNZ ioctl_bad_fun ; There are no "net devices", and they 0 00002614 06 PUSH ES ; certainly don't know how to do this ;AN000; 0 00002615 57 PUSH DI ;AN000;IFS. 0 00002616 C43E[0000] LES DI,[THISCDS] ;AN000;IFS. ; 0 0000261A 26F745430080 TEST word [ES:DI + curdir_flags],curdir_isnet;AN000;IFS. ; local IFS ? 0 00002620 5F POP DI ;AN000;IFS. 0 00002621 07 POP ES ;AN000;IFS. 0 00002622 7420 JZ Do_GenIOCTL ;AN000;IFS. ; no 433 callifs: 434 User_In_AX equ USER_IN_AX ; NASM port label 0 00002624 803E[0100]69 CMP byte ptr [User_In_AX+1],69H ;AN000; ;IFS. 0 00002629 7506 JNZ is44xx ;AN000; ;IFS. 0 0000262B B80D44 MOV AX,440DH ;AN000; ;IFS. 0 0000262E 50 PUSH AX ;AN000; ;IFS. 0 0000262F EB04 JMP SHORT callrose ;AN000; ;IFS. 440 is44xx: 0 00002631 FF36[0000] PUSH word [User_In_AX] ;AN000; ;IFS. call IFSFUNC 442 callrose: 0 00002635 8EDE MOV DS,SI ;AN000; ;IFS. 444 multNET equ MultNET ; NASM port equate 0 00002637 B82B11 MOV AX,(multNET << 8) | 43 ;AN000; ;IFS. 0 0000263A CD2F INT 2FH ;AN000; ;IFS. 0 0000263C 5B POP BX ;AN000; ;IFS. 0 0000263D 73A2 JNC doneok ;AN000; ;IFS. 0 0000263F 89C7 MOV DI,AX ;AN000; ;IFS. 0 00002641 E94301 JMP device_err ;AN000; ;IFS. 451 Do_GenIOCTL: 0 00002644 26F745044000 test word [ES:DI + SDEVATT],DEV320 ; Can device handle Generic IOCTL funcs 0 0000264A 7435 jz ioctl_bad_fun 0 0000264C 06 PUSH ES ; DEVIOCALL2 expects Device header block 0 0000264D 57 PUSH DI ; in DS:SI 456 ;set up Generic IOCTL Request Block 457 IOCTL_Req_struc_size equ IOCTL_REQ_struc_size ; NASM port equate 458 ReqLen equ REQLEN ; NASM port equate 0 0000264E C606[0000]17 MOV byte [IOCALL + ReqLen],(IOCTL_Req_struc_size) 460 ReqFunc equ REQFUNC ; NASM port equate 0 00002653 C606[0200]13 MOV byte [IOCALL + ReqFunc],GENIOCTL 462 ReqUnit equ REQUNIT ; NASM port equate 0 00002658 881E[0100] MOV byte ptr [IOCALL + ReqUnit],BL 464 MajorFunction equ MAJORFUNCTION ; NASM port equate 0 0000265C 882E[0D00] MOV byte ptr [IOCALL + MajorFunction],CH 466 MinorFunction equ MINORFUNCTION ; NASM port equate 0 00002660 880E[0E00] MOV byte ptr [IOCALL + MinorFunction],CL 468 Reg_SI equ REG_SI ; NASM port equate 0 00002664 8936[0F00] MOV word ptr [IOCALL + Reg_SI],SI 470 Reg_DI equ REG_DI ; NASM port equate 0 00002668 893E[1100] MOV word ptr [IOCALL + Reg_DI],DI 472 GenericIOCTL_Packet equ GENERICIOCTL_PACKET ; NASM port equate 0 0000266C 8916[1300] MOV word ptr [IOCALL + GenericIOCTL_Packet],DX 0 00002670 8936[1500] MOV word ptr [IOCALL + GenericIOCTL_Packet + 2],SI 475 0 00002674 BB[0000] MOV BX,offset IOCALL wrt DOSGROUP 477 0 00002677 16 PUSH SS 0 00002678 07 POP ES 480 481 ASSUME DS:NOTHING ; DS:SI -> Device header. 0 00002679 5E POP SI 0 0000267A 1F POP DS 0 0000267B E9F200 jmp ioctl_do_IO ; Perform Call to device driver 485 486 IOCtl_Handle_RedirJ: 487 IOCTL_Handle_Redir equ Ioctl_Handle_redir ; NASM port label 0 0000267E E99A00 JMP IOCTL_Handle_Redir 489 ioctl_bad_fun: 0 00002681 B001E9[0000] error error_invalid_function 491 492 ioctl_bad_handlej: 0 00002686 E976FE jmp ioctl_bad_handle 494 495 ; Function 8 496 ioctl_rem_media: 0 00002689 E84001 CALL Check_If_Net 0 0000268C 75F3 JNZ ioctl_bad_fun ; There are no "net devices", and they 499 ; certainly don't know how to do this 500 ; call. 0 0000268E 26F745040008 TEST word [ES:DI + SDEVATT],DEVOPCL ; See if device can 0 00002694 74EB JZ ioctl_bad_fun ; NO 0 00002696 36C606[0200]0F MOV byte [ss:IOCALL + REQFUNC],DEVRMD 0 0000269C B00D MOV AL,REMHL 0 0000269E 88DC MOV AH,BL ; Unit number 0 000026A0 36A3[0000] MOV WORD PTR [ss:IOCALL + REQLEN],AX 0 000026A4 31C0 XOR AX,AX 0 000026A6 36A3[0300] MOV [ss:IOCALL + REQSTAT],AX 0 000026AA 06 PUSH ES 0 000026AB 1F POP DS 511 ASSUME DS:NOTHING 0 000026AC 89FE MOV SI,DI ; DS:SI -> driver 0 000026AE 16 PUSH SS 0 000026AF 07 POP ES 0 000026B0 BB[0000] MOV BX,OFFSET IOCALL wrt DOSGROUP ; ES:BX -> Call header 0 000026B3 1E56 SaveReg 0 000026B5 E8[0000] invoke DEVIOCALL2 0 000026B8 5E1F RestoreReg 0 000026BA 36A1[0300] MOV AX,[ss:IOCALL + REQSTAT] ; Get Status word 0 000026BE 250002 AND AX,STBUI ; Mask to busy bit 0 000026C1 B109 MOV CL,9 0 000026C3 D3E8 SHR AX,CL ; Busy bit to bit 0 0 000026C5 E9[0000] transfer SYS_RET_OK 524 525 ; Function 9 526 Ioctl_Drive_attr: 527 528 ;;;;; MOV AL,BL ;AC000;; Drive 529 ;;;;; invoke GETTHISDRV ;AC000; 530 ;;;;; ;AC000; 531 ;;;;; JC ioctl_drv_err ; drive not valid 0 000026C8 E8CB00 call Get_Driver_BL 0 000026CB 7247 JC ioctl_drv_err ; drive not valid 0 000026CD 36A1[0000] MOV AX,[ss:Temp_Var2] ;AN000;IFS. 0 000026D1 268B5504 mov dx,word ptr [es:di + SDEVATT] ; get device attribute word 0 000026D5 88C3 MOV BL,AL ; Phys letter to BL (A=0) 0 000026D7 36C43E[0000] LES DI,[ss:THISCDS] 538 ;;;;; TEST [ES:DI.curdir_flags],curdir_isnet 0 000026DC E8F200 CALL TEST_IFS_REMOTE2 ;AN000;IFS. test if remote 0 000026DF 7404 JZ IOCTLShare 0 000026E1 81CA0010 OR DX,1000h 542 IOCTLShare: 0 000026E5 161F Context DS 544 ASSUME DS:NOTHING 0 000026E7 BE[0000] MOV SI,OFFSET OPENBUF wrt DOSGROUP 0 000026EA 80C341 ADD BL,"A" 0 000026ED 881C MOV [SI],BL 0 000026EF C744013A00 MOV WORD PTR [SI+1],003AH ; ":",0 0 000026F4 B80003 MOV AX,0300H 0 000026F7 F8 CLC 0 000026F8 CD2A INT int_IBM 552 ioctlLocal equ IOCTLLocal ; NASM port label 0 000026FA 7304 JNC ioctlLocal ; Not shared 0 000026FC 81CA0002 OR DX,0200H ; Shared, bit 9 555 IOCTLLocal: 0 00002700 26F745430010 TEST word [ES:DI + curdir_flags],curdir_local 557 ioctl_set_dx equ ioctl_set_DX ; NASM port label 0 00002706 7404 JZ ioctl_set_dx 0 00002708 81CA0080 OR DX,8000h 560 561 ioctl_set_DX: 0 0000270C E8[0000] invoke get_user_stack 0 0000270F 895406 MOV [SI + user_DX],DX 0 00002712 EBB1 transfer SYS_RET_OK 565 566 ioctl_drv_err: 0 00002714 36A0[0000] MOV AL,[ss:DrvErr] ;AN000;IFS. DrvErr is saved in GetThisDrv 0 00002718 E9[0000] transfer SYS_RET_ERR ;AN000;IFS. 569 570 ; Function 10 571 Ioctl_Handle_redir: 0 0000271B E8[0000] invoke SFFromHandle ; ES:DI -> SFT 0 0000271E 7304 JNC ioctl_got_sft ; have valid handle 0 00002720 B006EBF4 error error_invalid_handle 575 576 ioctl_got_sft: 0 00002724 268B5505 MOV DX,[ES:DI + sf_flags] ; Get flags 0 00002728 EBE2 JMP ioctl_set_DX 579 580 ioctl_bad_funj: 0 0000272A E954FF JMP ioctl_bad_fun 582 583 ioctl_get_dev: 584 DOSAssume CS,,"IOCTL/IOCtl_Get_Dev" 0 0000272D E89C00 CALL Check_If_Net 0 00002730 75F8 JNZ ioctl_bad_funj ; There are no "net devices", and they 587 ; certainly don't know how to do this 588 ; call. 589 ioctl_do_string: 0 00002732 26F745040040 TEST word [ES:DI + SDEVATT],DEVIOCTL; See if device accepts control 0 00002738 74F0 JZ ioctl_bad_funj ; NO 0 0000273A FEC8 DEC AL 0 0000273C FEC8 DEC AL 0 0000273E 7407 JZ ioctl_control_read 0 00002740 C606[0200]0C MOV byte [IOCALL + REQFUNC],DEVWRIOCTL 0 00002745 EB05 JMP SHORT ioctl_control_call 597 ioctl_control_read: 0 00002747 C606[0200]03 MOV byte [IOCALL + REQFUNC],DEVRDIOCTL 599 ioctl_control_call: 0 0000274C B016 MOV AL,DRDWRHL 601 ioctl_setup_pkt: 0 0000274E 88DC MOV AH,BL ; Unit number 0 00002750 A3[0000] MOV WORD PTR [IOCALL + REQLEN],AX 0 00002753 31C0 XOR AX,AX 0 00002755 A3[0300] MOV [IOCALL + REQSTAT],AX 0 00002758 A2[0000] MOV [IOMED],AL 0 0000275B 890E[0000] MOV [IOSCNT],CX 0 0000275F 8916[0000] MOV WORD PTR [IOXAD],DX 0 00002763 8936[0200] MOV WORD PTR [IOXAD+2],SI 0 00002767 06 PUSH ES 0 00002768 1F POP DS 612 ASSUME DS:NOTHING 0 00002769 89FE MOV SI,DI ; DS:SI -> driver 0 0000276B 16 PUSH SS 0 0000276C 07 POP ES 0 0000276D BB[0000] MOV BX,OFFSET IOCALL wrt DOSGROUP ; ES:BX -> Call header 617 ioctl_do_IO: 0 00002770 E8[0000] invoke DEVIOCALL2 0 00002773 36F706[0300]0080 TEST word [ss:IOCALL + REQSTAT],STERR ;Error? 0 0000277A 7506 JNZ Ioctl_string_err 0 0000277C 36A1[0000] MOV AX,[ss:IOSCNT] ; Get actual bytes transferred 0 00002780 EB90 transfer SYS_RET_OK 623 624 Ioctl_string_err: 0 00002782 368B3E[0300] MOV DI,[ss:IOCALL + REQSTAT] ;Get Error 626 device_err: 0 00002787 81E7FF00 AND DI,STECODE ; mask out irrelevant bits 0 0000278B 89F8 MOV AX,DI 0 0000278D E8[0000] invoke SET_I24_EXTENDED_ERROR 630 extErr equ ExtErr ; NASM port label 0 00002790 36A1[0000] mov ax, [ss:extErr] 0 00002794 EB8C transfer SYS_RET_ERR 633 634 Get_Driver_BL: 635 DOSAssume CS,,"Get_Driver_BL" 636 ASSUME ES:NOTHING 637 ; BL is drive number (0=default) 638 ; Returns pointer to device in ES:DI, unit number in BL if carry clear 639 ; No regs modified 640 0 00002796 50 PUSH AX 0 00002797 88D8 MOV AL,BL ; Drive 0 00002799 E8[0000] invoke GETTHISDRV 0 0000279C 7307 JNC ioctl_goodrv ;AC000;IFS. 645 error_not_dos_disk equ error_not_DOS_disk ; NASM port equate 0 0000279E 3C1A CMP AL,error_not_dos_disk ;AN000;IFS. if unknow media then 0 000027A0 7403 JZ ioctl_goodrv ;AN000;IFS. let it go 0 000027A2 F9 STC ;AN000;IFS. else 0 000027A3 EB25 JMP SHORT ioctl_bad_drv ;AN000;IFS. error 650 ioctl_goodrv: 0 000027A5 30DB XOR BL,BL ; Unit zero on Net device 0 000027A7 C606[0000]03 MOV byte [EXTERR_LOCUS],errLOC_Net 0 000027AC C43E[0000] LES DI,[THISCDS] 654 ; TEST [ES:DI.curdir_flags],curdir_isnet 0 000027B0 E81E00 CALL TEST_IFS_REMOTE2 ;AN000;;IFS. test if remote 0 000027B3 26C47D45 LES DI,[ES:DI + curdir_devptr]; ES:DI -> Dpb or net dev 0 000027B7 750D JNZ got_dev_ptr ; Is net 0 000027B9 C606[0000]02 MOV byte [EXTERR_LOCUS],errLOC_Disk 0 000027BE 268A5D01 MOV BL,[ES:DI + dpb_UNIT] ; Unit number 0 000027C2 26C47D13 LES DI,[ES:DI + dpb_driver_addr] ; Driver addr 661 got_dev_ptr: 0 000027C6 F8 CLC 0 000027C7 A3[0000] MOV [Temp_Var2],AX ;AN000;IFS. 664 ioctl_bad_drv: 0 000027CA 58 POP AX 0 000027CB C3 return 667 668 ; 669 ; Checks if the device is over the net or not. Returns result in ZERO flag. 670 ; If no device is found, the return address is popped off the stack, and a 671 ; jump is made to ioctl_drv_err. 672 ; 673 ; On Entry: 674 ; Registers same as those for Get_Driver_BL 675 ; 676 ; On Exit: 677 ; ZERO flag - set if not a net device 678 ; - reset if net device 679 ; ES:DI -> the device 680 ; 681 Check_If_Net: 0 000027CC E8C7FF CALL Get_Driver_BL 0 000027CF 721B JC ioctl_drv_err_pop ; invalid drive letter 684 entry TEST_IFS_REMOTE2 0 000027D1 06 PUSH ES 0 000027D2 57 PUSH DI 0 000027D3 C43E[0000] LES DI,[THISCDS] 0 000027D7 26F745430080 TEST word [ES:DI + curdir_flags],curdir_isnet 0 000027DD 740A JZ belocal ;AN000; ;IFS. 0 000027DF 26C47D52 LES DI,[ES:DI + curdir_ifs_hdr] ;AN000; ;IFS. test if remote 691 TEST_REMOTE: ;AN000; 692 ifs_attribute equ IFS_ATTRIBUTE ; NASM port equate 0 000027E3 26F7450C0008 TEST word [ES:DI + ifs_attribute],IFSREMOTE;AN000; ;IFS. 694 belocal: 0 000027E9 5F POP DI 0 000027EA 07 POP ES 0 000027EB C3 ret 698 699 ioctl_drv_err_pop: 0 000027EC 58 pop ax ; pop off return address 0 000027ED E924FF jmp ioctl_drv_err 702 703 ioctl_bad_funj3: 0 000027F0 E98EFE jmp ioctl_bad_fun 705 706 ioctl_string_errj: 707 ioctl_string_err equ Ioctl_string_err ; NASM port label 0 000027F3 EB8D jmp ioctl_string_err 709 710 ; Functions 14 and 15 711 ioctl_drive_owner: 0 000027F5 E8D4FF Call Check_If_Net 0 000027F8 75F6 JNZ ioctl_bad_funj3 ; There are no "net devices", and they 714 ; certainly don't know how to do this 715 ; call. 0 000027FA 26F745044000 TEST word [ES:DI + SDEVATT],DEV320 ; See if device can handle this 0 00002800 74EE JZ ioctl_bad_funj3 ; NO 0 00002802 FEC8 dec al 0 00002804 7407 jz GetOwner 0 00002806 C606[0200]18 MOV byte [IOCALL + REQFUNC],DEVSETOWN 0 0000280B EB05 jmp short ioctl_do_own 722 GetOwner: 0 0000280D C606[0200]17 MOV byte [IOCALL + REQFUNC],DEVGETOWN 724 ioctl_do_own: 0 00002812 B00D MOV AL,OWNHL 0 00002814 88DC MOV AH,BL ; Unit number 0 00002816 A3[0000] MOV WORD PTR [IOCALL + REQLEN],AX 0 00002819 31C0 XOR AX,AX 0 0000281B A3[0300] MOV [IOCALL + REQSTAT],AX 0 0000281E 06 PUSH ES 0 0000281F 1F POP DS 732 ASSUME DS:NOTHING 0 00002820 89FE MOV SI,DI ; DS:SI -> driver 0 00002822 16 PUSH SS 0 00002823 07 POP ES 0 00002824 BB[0000] MOV BX,OFFSET IOCALL wrt DOSGROUP ; ES:BX -> Call header 0 00002827 1E56 SaveReg 0 00002829 E8[0000] invoke DEVIOCALL2 0 0000282C 5E1F RestoreReg 0 0000282E 36F706[0300]0080 test word [ss:IOCALL + REQSTAT],STERR 0 00002835 75BC jnz ioctl_string_errj 0 00002837 36A0[0100] MOV AL,BYTE PTR [ss:IOCALL + REQUNIT] ; Get owner returned by device 743 ; owner returned is 1-based. 0 0000283B E9[0000] transfer SYS_RET_OK 745 746 EndProc D_IOCTL 747 748 749 ;Input: ES:DI -> SFT 750 ;Functions: test if a remote file 751 ;Output: Z flag set, local file 752 ; 753 754 procedure TEST_IFS_REMOTE,NEAR ;AN000; 754 ****************** warning: proc TEST_IFS_REMOTE... [-w+user] 755 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 756 0 0000283E 26F745050080 TEST word [ES:DI + sf_flags],sf_isnet ;AN000;;IFS. ifs ? 0 00002844 7408 JZ nonifs ;AN000;;IFS. no 0 00002846 06 PUSH ES ;AN000;;IFS. save regs 0 00002847 57 PUSH DI ;AN000;;IFS. 761 sf_IFS_hdr equ sf_IFS_HDR ; NASM port equate 0 00002848 26C47D37 LES DI,[ES:DI + sf_IFS_hdr] ;AN000;;IFS. get ifs header 0 0000284C EB95 JMP TEST_REMOTE ;AN000;;IFS. 764 nonifs: ;AN000; 0 0000284E C3 return ;AN000;;IFS. 766 EndProc TEST_IFS_REMOTE ;AN000; 767 768 END === Trace listing source: ../DOS/delete.lst 1 ; SCCSID = @(#)delete.asm 1.3 85/10/18 2 ; SCCSID = @(#)delete.asm 1.3 85/10/18 3 ;TITLE DOS_DELETE - Internal DELETE call for MS-DOS 4 ;NAME DOS_DELETE 5 ; Low level routine for deleting files 6 ; 7 ; DOS_DELETE 8 ; REN_DEL_Check 9 ; FastOpen_Delete ; DOS 3.3 10 ; FastOpen_Update ; DOS 3.3 11 ; FastSeek_Open ; DOS 4.00 12 ; FSeek_dispatch ; DOS 4.00 13 ; FastSeek_Close ; DOS 4.00 14 ; FastSeek_Delete ; DOS 4.00 15 ; Delete_FSeek ; DOS 4.00 16 ; FastSeek_Lookup ; DOS 4.00 17 ; FastSeek_Insert ; DOS 4.00 18 ; FastSeek_Truncate ; DOS 4.00 19 ; FS_doit ; DOS 4.00 20 ; 21 ; Revision history: 22 ; 23 ; A000 version 4.00 Jan. 1988 24 ; 25 26 ; 27 ; get the appropriate segment definitions 28 ; 29 [list -] === Switch to base=008400h -> "DOSCODECODE" 33 section DOSCODECODE 34 [list -] 34 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 34 ****************** warning: out: BPB.INC... [-w+user] 34 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 34 ****************** warning: out: DEVSYM.INC... [-w+user] 44 45 %iassign Installed TRUE 46 47 i_need NoSetDir,BYTE 48 i_need Creating,BYTE 49 i_need DELALL,BYTE 50 i_need THISDPB,DWORD 51 i_need THISSFT,DWORD 52 i_need THISCDS,DWORD 53 i_need CURBUF,DWORD 54 i_need ATTRIB,BYTE 55 i_need SATTRIB,BYTE 56 i_need WFP_START,WORD 57 i_need FoundDel,BYTE 58 i_need AUXSTACK,BYTE 59 i_need VOLCHNG_FLAG,BYTE 60 i_need JShare,DWORD 61 i_need FastOpenTable,BYTE ; DOS 3.3 62 i_need FastTable,BYTE ; DOS 4.00 63 i_need FSeek_drive,BYTE ; DOS 4.00 64 i_need FSeek_firclus,WORD ; DOS 4.00 65 i_need FSeek_logclus,WORD ; DOS 4.00 66 i_need FSeek_logsave,WORD ; DOS 4.00 67 i_need FastSeekflg,BYTE ; DOS 4.00 68 i_need Del_ExtCluster,WORD ; DOS 4.00 69 i_need SAVE_BX,WORD ; DOS 4.00 70 i_need DMAADD,DWORD 71 i_need RENAMEDMA,BYTE 72 73 ; Inputs: 74 ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL 75 ; terminated) 76 ; [CURR_DIR_END] Points to end of Current dir part of string 77 ; ( = -1 if current dir not involved, else 78 ; Points to first char after last "/" of current dir part) 79 ; [THISCDS] Points to CDS being used 80 ; (Low word = -1 if NUL CDS (Net direct request)) 81 ; [SATTRIB] Is attribute of search, determines what files can be found 82 ; Function: 83 ; Delete the specified file(s) 84 ; Outputs: 85 ; CARRY CLEAR 86 ; OK 87 ; CARRY SET 88 ; AX is error code 89 ; error_file_not_found 90 ; Last element of path not found 91 ; error_path_not_found 92 ; Bad path (not in curr dir part if present) 93 ; error_bad_curr_dir 94 ; Bad path in current directory part of path 95 ; error_access_denied 96 ; Attempt to delete device or directory 97 ; ***error_sharing_violation*** 98 ; Deny both access required, generates an INT 24. 99 ; This error is NOT returned. The INT 24H is generated, 100 ; and the file is ignored (not deleted). Delete will 101 ; simply continue on looking for more files. 102 ; Carry will NOT be set in this case. 103 ; DS preserved, others destroyed 104 105 fileFound equ 01h 106 fileDeleted equ 10h 107 108 procedure DOS_DELETE,NEAR 108 ****************** warning: proc DOS_DELETE... [-w+user] 109 DOSAssume CS,,"DOS_Delete" 110 ASSUME ES:NOTHING 111 0 0000284F E8[0000] Invoke TestNet 0 00002852 7306 JNC LOCAL_DELETE 114 ; invoke OWN_SHARE2 ;IFS. IFS owns share ? ;AN000; 115 ; JZ ifsshare ;IFS. yes ;AN000; 116 ; PUSH WORD PTR [DMAADD+2] ;IFS. save DMAADD ;AN000; 117 ; PUSH WORD PTR [DMAADD] ;IFS. ;AN000; 118 ; CALL IFS_SEARCH_FIRST ;IFS. do search first ;AN000; 119 ; JC nofiles ;IFS. file not existing ;AN000; 120 delete_next_file: ;IFS. ;AN000; 121 ; CALL IFS_REN_DEL_CHECK ;IFS. do REN_DEL_CHECK ;AN000; 122 ; JNC share_okok ;IFS. share ok ;AN000; 123 ; MOV AX,error_sharing_violation ;IFS. share violation ;AN000; 124 ; JMP SHORT nofiles ;IFS. ;AN000; 125 share_okok: 126 ; MOV AX,(multNET SHL 8) OR 19 ;IFS. delete it now ;AN000; 127 ;; INT 2FH ;IFS. ;AN000; 128 ; JC nofiles ;IFS. error ;AN000; 129 ; invoke DOS_SEARCH_NEXT ;IFS. get next entry ;AN000; 130 ; JNC delete_next_file ;IFS. ;AN000; 131 ; CLC ;IFS. no more files ;AN000; 132 nofiles: 133 ; POP WORD PTR [DMAADD] ;IFS. retor DMAADD ;AN000; 134 ; POP WORD PTR [DMAADD+2] ;IFS. ;AN000; 135 ; ret ;IFS. return 136 ifsshare: 137 138 139 %IFN Installed 140 transfer NET_DELETE 141 %ELSE 142 multNET equ MultNET ; NASM port equate 0 00002854 B81311 MOV AX,(multNET << 8) | 19 0 00002857 CD2F INT 2FH 0 00002859 C3 return 146 %ENDIF 147 148 LOCAL_DELETE: 0 0000285A C606[0000]00 MOV byte [FoundDel],00 ; No files found and no files deleted 0 0000285F E8[0000] EnterCrit critDisk 151 CREATING equ Creating ; NASM port label 0 00002862 C706[0000]00E5 MOV WORD PTR [CREATING],0E500H ; Assume not del *.* 0 00002868 8B36[0000] MOV SI,[WFP_START] 154 SKPNUL: 0 0000286C AC LODSB 0 0000286D 08C0 OR AL,AL 0 0000286F 75FB JNZ SKPNUL ; go to end 0 00002871 83EE04 SUB SI,4 ; Back over possible "*.*" 0 00002874 813C2A2E CMP WORD PTR [SI],("." << 8 | "*") 0 00002878 7506 JNZ TEST_QUEST 0 0000287A 807C022A CMP BYTE PTR [SI+2],"*" 0 0000287E 741F JZ CHECK_ATTS 163 TEST_QUEST: 0 00002880 83EE09 SUB SI,9 ; Back over possible "????????.???" 0 00002883 87FE XCHG DI,SI 0 00002885 1607 context ES 0 00002887 B83F3F MOV AX,"??" 0 0000288A B90400 MOV CX,4 ; four sets of "??" 0 0000288D F3AF REPE SCASW 0 0000288F 751C JNZ NOT_ALL 0 00002891 87FE XCHG DI,SI 0 00002893 AD LODSW 0 00002894 3D2E3F CMP AX,("?" << 8) | "." 0 00002897 7514 JNZ NOT_ALL 0 00002899 AD LODSW 0 0000289A 3D3F3F CMP AX,"??" 0 0000289D 750E JNZ NOT_ALL 178 CHECK_ATTS: 0 0000289F A0[0000] MOV AL,BYTE PTR [SATTRIB] 0 000028A2 241F AND AL,attr_hidden+attr_system+attr_directory+attr_volume_id+attr_read_only 181 ; Look only at hidden bits 0 000028A4 3C1F CMP AL,attr_hidden+attr_system+attr_directory+attr_volume_id+attr_read_only 183 ; All must be set 0 000028A6 7505 JNZ NOT_ALL 185 186 ; NOTE WARNING DANGER----- 187 ; This DELALL stuff is not safe. It allows directories to be deleted. 188 ; It should ONLY be used by FORMAT in the ROOT directory. 189 ; 190 0 000028A8 C606[0000]00 MOV byte [DELALL],0 ; DEL *.* - flag deleting all 192 NOT_ALL: 0 000028AD C606[0000]01 MOV byte [NoSetDir],1 0 000028B2 E8[0000] invoke GetPathNoSet 195 ASSUME ES:NOTHING 0 000028B5 7313 JNC Del_found 0 000028B7 750C JNZ bad_path 0 000028B9 08C9 OR CL,CL 0 000028BB 7408 JZ bad_path 200 No_file: 0 000028BD B80200 MOV AX,error_file_not_found 202 ErrorReturn: 0 000028C0 F9 STC 0 000028C1 E8[0000] LeaveCrit critDisk 0 000028C4 C3 return 206 207 bad_path: 0 000028C5 B80300 MOV AX,error_path_not_found 0 000028C8 EBF6 JMP ErrorReturn 210 211 Del_found: 0 000028CA 750C JNZ NOT_DIR ; Check for dir specified 213 DelAll equ DELALL ; NASM port label 0 000028CC 803E[0000]00 CMP byte [DelAll],0 ; DelAll = 0 allows delete of dir. 215 Not_Dir equ NOT_DIR ; NASM port label 0 000028D1 7405 JZ Not_Dir 217 Del_access_err: 0 000028D3 B80500 MOV AX,error_access_denied 0 000028D6 EBE8 JMP ErrorReturn 220 221 NOT_DIR: 0 000028D8 08E4 OR AH,AH ; Check if device name 0 000028DA 78F7 JS Del_access_err ; Can't delete I/O devices 224 ; 225 ; Main delete loop. CURBUF+2:BX points to a matching directory entry. 226 ; 227 DELFILE: 0 000028DC 800E[0000]01 OR byte [FoundDel],fileFound ; file found, not deleted yet 229 ; 230 ; If we are deleting the Volume ID, then we set VOLUME_CHNG flag to make 231 ; DOS issue a build BPB call the next time this drive is accessed. 232 ; 0 000028E1 1E PUSH DS 0 000028E2 8A26[0000] MOV AH,[DELALL] 0 000028E6 C53E[0000] LDS DI,[CURBUF] 236 ASSUME DS:NOTHING 237 ;; Extended Attributes 238 ; PUSH AX ;FT. save cluster of XA ;AN000; 239 ; MOV AX,[DS:BX.dir_ExtCluster];FT. ;AN000; 240 ; MOV [Del_ExtCluster],AX ;FT. ;AN000; 241 ; POP AX ;FT, ;AN000; 242 243 ;; Extended Attributes 244 Attrib equ ATTRIB ; NASM port label 0 000028EA 36F606[0000]01 TEST byte [ss:Attrib],attr_read_only ; are we deleting RO files too? 0 000028F0 7509 JNZ DoDelete ; yes 0 000028F2 F6470B01 TEST byte [BX + dir_attr],attr_read_only 0 000028F6 7403 JZ DoDelete ; not read only 0 000028F8 1F POP DS 250 DelNxt equ DELNXT ; NASM port label 0 000028F9 EB35 JMP SHORT DelNxt ; Skip it (Note ES:BP not set) 252 253 DoDelete: 0 000028FB E88800 call REN_DEL_Check ; Sets ES:BP = [THISDPB] 0 000028FE 7303 JNC DEL_SHARE_OK 0 00002900 1F POP DS 0 00002901 EB2D JMP SHORT DelNxt ; Skip it 258 259 DEL_SHARE_OK: 260 Assert ISBUF,,"Del_Share_OK" 0 00002903 F6450540 TEST byte [DI + buf_flags],buf_dirty ;LB. if already dirty ;AN000; 0 00002907 7507 JNZ yesdirty ;LB. don't increment dirty count ;AN000; 0 00002909 E8[0000] invoke INC_DIRTY_COUNT ;LB. ;AN000; 0 0000290C 804D0540 OR byte [DI + buf_flags],buf_dirty 265 yesdirty: 0 00002910 8827 MOV [BX],AH ; Put in E5H or 0 0 00002912 8B1C MOV BX,[SI] ; Get firclus pointer 0 00002914 1F POP DS 269 DOSAssume CS,,"Del_Share_OK" 0 00002915 800E[0000]10 OR byte [FoundDel],fileDeleted ; Deleted file 0 0000291A 83FB02 CMP BX,2 0 0000291D 7211 JB DELEXT ; File has invalid FIRCLUS (too small) 0 0000291F 263B5E0D CMP BX,[ES:BP + dpb_max_cluster] 0 00002923 770B JA DELEXT ; File has invalid FIRCLUS (too big) 275 ;; FastSeek 10/27/86 0 00002925 E82D01 CALL Delete_FSeek ; delete the fastseek entry 277 ;; FastSeek 10/27/86 278 0 00002928 E8[0000] invoke RELEASE ; Free file data 0 0000292B 7253 JC No_fileJ 281 ; DOS 3.3 FastOpen 282 0 0000292D E8C300 CALL FastOpen_Delete ; delete the dir info in fastopen 284 285 286 ; DOS 3.3 FastOpen 287 ;; Extended Attributes 288 DELEXT: 289 290 ; MOV BX,[Del_ExtCluster] ;FT. delete XA cluster chain ;AN000; 291 ; CMP BX,2 ;FT. ;AN000; 292 ; JB DELNXT ;FT. XA has invalid cluster (too small) ;AN000; 293 ; CMP BX,[ES:BP.dpb_max_cluster];FT. ;AN000; 294 ; JA DELNXT ;FT. XA has invalid cluster (too big) ;AN000; 295 ; invoke RELEASE ;FT. Free extended attrs cluster ;AN000; 296 ; JC No_fileJ ;FT. ;AN000; 297 298 ;; Extended Attributes 299 DELNXT: 0 00002930 C42E[0000] LES BP,[THISDPB] ; Possible to get here without this set 0 00002934 E8[0000] invoke GETENTRY ; Registers need to be reset 0 00002937 7247 JC No_fileJ 0 00002939 E8[0000] invoke NEXTENT 304 %if DEBUG 305 Flsh equ flsh ; NASM port label 306 JC Flsh 307 DelFile equ DELFILE ; NASM port label 308 JMP DelFile 309 flsh: 310 %ELSE 0 0000293C 739E JNC DELFILE 312 %ENDIF 0 0000293E C42E[0000] LES BP,[THISDPB] ; NEXTENT sets ES=DOSGROUP 0 00002942 268A4600 MOV AL,[ES:BP + dpb_drive] 0 00002946 E8[0000] invoke FLUSHBUF 0 00002949 7235 JC No_fileJ 317 ; 318 ; Now we need to test FoundDel for our flags. The cases to consider are: 319 ; 320 ; not found not deleted file not found 321 ; not found deleted *** impossible *** 322 ; found not deleted access denied (read-only) 323 ; found deleted no error 324 ; 0 0000294B F606[0000]10 TEST byte [FoundDel],fileDeleted ; did we delete a file? 0 00002950 7427 JZ DelError ; no, figure out what's wrong. 327 ; We set VOLCHNG_FLAG to indicate that we have changed the volume label 328 ; and to force the DOS to issue a media check. 0 00002952 F606[0000]08 TEST byte [Attrib],attr_volume_id 0 00002957 741C jz No_Set_Flag 0 00002959 50 PUSH AX 0 0000295A 06 PUSH ES 0 0000295B 57 PUSH DI 0 0000295C C43E[0000] LES DI,[THISCDS] 335 ASSUME ES:NOTHING 0 00002960 268A25 MOV AH,BYTE PTR [ES:DI] ; Get drive 0 00002963 80EC41 SUB AH,'A' ; Convert to 0-based 0 00002966 8826[0000] mov byte ptr [VOLCHNG_FLAG],AH 0 0000296A 30FF XOR BH,BH ;>32mb delte volume id from boot record ;AN000; 0 0000296C E8[0000] invoke $Set_Media_ID ;>32mb set voulme id to boot record ;AN000; 0 0000296F E8[0000] invoke FATRead_CDS ; force media check 0 00002972 5F POP DI 0 00002973 07 POP ES 0 00002974 58 POP AX 345 No_Set_Flag: 0 00002975 E8[0000] LeaveCrit critDisk ; carry is clear 0 00002978 C3 return 348 DelError: 0 00002979 F606[0000]01 TEST byte [FoundDel],fileFound ; not deleted. Did we find file? 350 Del_access_errJ equ Del_Access_errJ ; NASM port label 0 0000297E 7503 JNZ Del_access_errJ ; yes. Access denied 352 No_fileJ: 0 00002980 E93AFF JMP No_file ; Nope 354 Del_Access_errJ: 0 00002983 E94DFF JMP Del_access_err 356 357 EndProc DOS_DELETE 358 359 Break 360 361 ; Inputs: 362 ; [THISDPB] set 363 ; [CURBUF+2]:BX points to entry 364 ; [CURBUF+2]:SI points to firclus field of entry 365 ; [WFP_Start] points to name 366 ; Function: 367 ; Check for Exclusive access on given file. 368 ; Used by RENAME, SET_FILE_INFO, and DELETE. 369 ; Outputs: 370 ; ES:BP = [THISDPB] 371 ; NOTE: The WFP string pointed to by [WFP_Start] Will be Modified. The 372 ; last element will be loaded from the directory entry. This is 373 ; so the name given to the sharer doesn't have any meta chars in 374 ; it. 375 ; Carry set if sharing violation, INT 24H generated 376 ; NOTE THAT AX IS NOT error_sharing_violation. 377 ; This is because input AX is preserved. 378 ; Caller must set the error if needed. 379 ; Carry clear 380 ; OK 381 ; AX,DS,BX,SI,DI preserved 382 383 procedure REN_DEL_Check,NEAR 383 ****************** warning: proc REN_DEL_Check... [-w+user] 384 ASSUME DS:NOTHING,ES:NOTHING 385 0 00002986 1E PUSH DS 0 00002987 57 PUSH DI 0 00002988 50 PUSH AX 0 00002989 53 PUSH BX 0 0000298A 56 PUSH SI ; Save CURBUF pointers 0 0000298B 1607 context ES 392 ASSUME ES:DOSGROUP 0 0000298D 368B3E[0000] MOV DI,[ss:WFP_START] ; ES:DI -> WFP 0 00002992 89DE MOV SI,BX 0 00002994 368E1E[0200] MOV DS,WORD PTR [ss:CURBUF+2] ; DS:SI -> entry (FCB style name) 0 00002999 89FB MOV BX,DI ; Set backup limit for skipback 0 0000299B 83C302 ADD BX,2 ; Skip over d: to point to leading '\' 0 0000299E E8[0000] invoke StrLen ; CX is length of ES:DI including NUL 0 000029A1 49 DEC CX ; Don't include nul in count 0 000029A2 01CF ADD DI,CX ; Point to NUL at end of string 0 000029A4 E8[0000] invoke SkipBack ; Back up one element 0 000029A7 47 INC DI ; Point to start of last element 0 000029A8 36893E[0000] MOV [ss:SAVE_BX],DI ;IFS. save for DOS_RENAME ;AN000; 0 000029AD E8[0000] invoke PackName ; Transfer name from entry to ASCIZ tail. 0 000029B0 5E POP SI ; Get back entry pointers 0 000029B1 5B POP BX 0 000029B2 53 PUSH BX 0 000029B3 56 PUSH SI ; Back on stack 0 000029B4 161F context DS 410 ASSUME DS:DOSGROUP 411 ; 412 ; Close the file if possible by us. 413 ; 414 %if installed 0 000029B6 FF1E[3400] Call far [JShare + 13 * 4] 416 %else 417 Call ShCloseFile 418 %endif 0 000029BA 8C1E[0200] MOV WORD PTR [THISSFT+2],DS 0 000029BE C706[0000][C5FF] MOV WORD PTR [THISSFT],OFFSET AUXSTACK - (sf_entry_struc_size) wrt DOSGROUP 421 ; Scratch space 0 000029C4 30E4 XOR AH,AH ; Indicate file to DOOPEN (high bit off) 0 000029C6 E8[0000] invoke DOOPEN ; Fill in SFT for share check 0 000029C9 C43E[0000] LES DI,[THISSFT] 0 000029CD 26C745021000 MOV word [ES:DI + sf_mode],sharing_deny_both ; requires exclusive access 0 000029D3 26C7050100 MOV word [ES:DI + sf_ref_count],1 ; Pretend open 0 000029D8 E8[0000] invoke ShareEnter 0 000029DB 720C jc CheckDone 0 000029DD C43E[0000] LES DI,[THISSFT] 0 000029E1 26832500 and word [ES:DI + sf_ref_count],0 ; Pretend closed and free 0 000029E5 E8[0000] invoke SHAREEND ; Tell sharer we're done with THISSFT 0 000029E8 F8 CLC 433 CheckDone: 0 000029E9 C42E[0000] LES BP,[THISDPB] 0 000029ED 5E POP SI 0 000029EE 5B POP BX 0 000029EF 58 POP AX 0 000029F0 5F POP DI 0 000029F1 1F POP DS 0 000029F2 C3 return 441 442 EndProc REN_DEL_Check 443 444 Break 445 446 ; Inputs: 447 ; None 448 ; Function: 449 ; Call FastOpen to delete the dir info. 450 ; Outputs: 451 ; None 452 ; 453 ; 454 455 procedure FastOpen_Delete,NEAR 455 ****************** warning: proc FastOpen_Delete... [-w+user] 456 ASSUME DS:NOTHING,ES:NOTHING 0 000029F3 9C PUSHF ; save flag 0 000029F4 56 PUSH SI ; save registers 0 000029F5 53 PUSH BX 0 000029F6 50 PUSH AX 461 462 WFP_Start equ WFP_START ; NASM port label 0 000029F7 368B36[0000] MOV SI,[ss:WFP_Start] ; ds:si points to path name 0 000029FC B003 MOV AL,FONC_delete ; al = 3 465 fastinvoke: 0 000029FE BB[0200] MOV BX,OFFSET FastTable + 2 wrt DOSGROUP 0 00002A01 36FF1F CALL far [ss:BX] ; call fastopen 468 0 00002A04 58 POP AX ; restore registers 0 00002A05 5B POP BX 0 00002A06 5E POP SI 0 00002A07 9D POPF ; restore flag 0 00002A08 C3 return 474 EndProc FastOpen_Delete 475 476 477 Break 478 479 ; Inputs: 480 ; DL drive number (A=0,B=1,,,) 481 ; CX first cluster # 482 ; AH 0 updates dir entry 483 ; 1 updates CLUSNUM , BP = new CLUSNUM 484 ; ES:DI directory entry 485 ; Function: 486 ; Call FastOpen to update the dir info. 487 ; Outputs: 488 ; None 489 ; 490 ; 491 492 procedure FastOpen_Update,NEAR 492 ****************** warning: proc FastOpen_Update... [-w+user] 493 ASSUME DS:NOTHING,ES:NOTHING 0 00002A09 9C PUSHF ; save flag 0 00002A0A 56 PUSH SI 0 00002A0B 53 PUSH BX ; save regs 0 00002A0C 50 PUSH AX 498 0 00002A0D B004 MOV AL,FONC_update ; al = 4 0 00002A0F EBED JMP fastinvoke 501 502 EndProc FastOpen_Update 503 504 Break 505 506 ; Inputs: 507 ; DL drive number (0=A,1=B,,,) 508 ; CX first cluster # 509 ; Function: 510 ; Create a file extent cache entry 511 ; Outputs: 512 ; None 513 ; 514 ; 515 516 procedure FastSeek_Open,NEAR ;AN000; 516 ****************** warning: proc FastSeek_Open... [-w+user] 517 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 518 ;AN000; 0 00002A11 36F606[0000]80 TEST byte [ss:FastSeekflg],Fast_yes ; Fastseek installed ? ;AN000; 0 00002A17 7409 JZ fs_no11 ; no ;AN000; 0 00002A19 56 PUSH SI ; save regs ;AN000; 0 00002A1A 50 PUSH AX ;AN000; 0 00002A1B B00B MOV AL,FSEC_open ; al = 11 ;AN000; 524 fseek_disp: ;AN000; 0 00002A1D E80300 CALL FSeek_dispatch ; call fastseek ;AN000; 0 00002A20 58 POP AX ; restore regs ;AN000; 0 00002A21 5E POP SI ;AN000; 528 fs_no11: ;AN000; 0 00002A22 C3 return ; return ;AN000; 530 EndProc FastSeek_Open ;AN000; 531 532 ; Inputs: 533 ; none 534 ; Function: 535 ; Call Fastseek 536 ; Outputs: 537 ; Output of Fastseek 538 ; 539 540 procedure FSeek_dispatch,NEAR 540 ****************** warning: proc FSeek_dispatch... [-w+user] 541 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 542 ;AN000; 0 00002A23 B402 MOV AH,FastSeek_ID ; fastseek ID = 1 ;AN000; 544 entry Fast_Dispatch ; future fastxxxx entry ;AN000; 0 00002A25 50 PUSH AX ; save ax ;AN000; 0 00002A26 88E0 MOV AL,AH ; al=fastseek ID ;AN000; 0 00002A28 30E4 XOR AH,AH ; ;AN000; 0 00002A2A 48 DEC AX ; ;AN000; 0 00002A2B D1E0 SHL AX,1 ; times 4 to get entry offset ;AN000; 0 00002A2D D1E0 SHL AX,1 ;AN000; 551 ;AN000; 0 00002A2F BE[0200] MOV SI,OFFSET FastTable + 2 wrt DOSGROUP ; index to the ;AN000; 0 00002A32 01C6 ADD SI,AX ; fastxxxx entry ;AN000; 0 00002A34 58 POP AX ; restore ax ;AN000; 0 00002A35 36FF1C CALL far [ss:SI] ; call fastseek ;AN000; 0 00002A38 C3 return 557 EndProc FSeek_dispatch 558 559 Break 560 561 ; Inputs: 562 ; DL drive number (0=A,1=B,,,) 563 ; CX first cluster # 564 ; Function: 565 ; Close a file extent entry 566 ; Outputs: 567 ; None 568 ; 569 ; 570 571 procedure FastSeek_Close,NEAR 571 ****************** warning: proc FastSeek_Close... [-w+user] 572 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 573 0 00002A39 36F606[0000]80 TEST byte [ss:FastSeekflg],Fast_yes ; Fastseek installed ? ;AN000; 0 00002A3F 7429 JZ fs_no2 ; no ;AN000; 0 00002A41 56 PUSH SI ; save regs ;AN000; 0 00002A42 50 PUSH AX ; ;AN000; 0 00002A43 B00C MOV AL,FSEC_close ; al = 12 ;AN000; 0 00002A45 EBD6 JMP fseek_disp ; call fastseek ;AN000; 580 EndProc FastSeek_Close ;AN000; 581 582 Break 583 584 ; Inputs: 585 ; DL drive number (0=A,1=B,,,) 586 ; CX first cluster # 587 ; Function: 588 ; Delete a file extent entry 589 ; Outputs: 590 ; None 591 ; 592 ; 593 594 procedure FastSeek_Delete,NEAR 594 ****************** warning: proc FastSeek_Delete... [-w+user] 595 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 596 ;AN000; 0 00002A47 36F606[0000]80 TEST byte [ss:FastSeekflg],Fast_yes ; Fastseek installed ? ;AN000; 0 00002A4D 741B JZ fs_no2 ; no ;AN000; 0 00002A4F 56 PUSH SI ; save regs ;AN000; 0 00002A50 50 PUSH AX ;AN000; 0 00002A51 B00D MOV AL,FSEC_delete ; al=13 ;AN000; 0 00002A53 EBC8 JMP fseek_disp ; call fastseek ;AN000; 603 EndProc FastSeek_Delete ;AN000; 604 ;AN000; 605 ; Inputs: 606 ; FastSeekflg= 0 , not installed 607 ; 1 , installed 608 ; BX= first cluster number 609 ; ES:BP = addr of DPB 610 ; Function: 611 ; Delete a file extent entry 612 ; Outputs: 613 ; None 614 ; 615 616 procedure Delete_FSeek,NEAR ;AN000; 616 ****************** warning: proc Delete_FSeek... [-w+user] 617 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 0 00002A55 36F606[0000]80 TEST byte [ss:FastSeekflg],Fast_yes ; Fastseek installed ? ;AN000; 0 00002A5B 740D JZ fs_no2 ; no ;AN000; 0 00002A5D 51 PUSH CX ; save regs ;AN000; 0 00002A5E 52 PUSH DX ;AN000; 0 00002A5F 89D9 MOV CX,BX ; first cluster # ;AN000; 0 00002A61 268A5600 MOV DL,[ES:BP + dpb_drive] ; drive # ;AN000; 0 00002A65 E8DFFF CALL FastSeek_Delete ; call fastseek to delete an entry ;AN000; 0 00002A68 5A POP DX ; restore regs ;AN000; 0 00002A69 59 POP CX ;AN000; 627 fs_no2: ;AN000; 0 00002A6A C3 return ; exit ;AN000; 629 EndProc Delete_FSeek ;AN000; 630 631 Break 632 633 ; Inputs: 634 ; FSeek_drive : drive number (0=A,1=B,,,) 635 ; FSeek_firclus: first cluster # 636 ; FSeek_logclus: logical cluster # 637 ; Function: 638 ; Look up a physical cluster # 639 ; Outputs: 640 ; carry clear, DI = physical cluster #, FSeek_logsave=DI-1 641 ; carry set, 642 ; partially found, DI=last physical cluster # 643 ; FSeek_logsave=last logical cluster # 644 645 procedure FastSeek_Lookup,NEAR ;AN000; 645 ****************** warning: proc FastSeek_Lookup... [-w+user] 646 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 647 0 00002A6B 50 PUSH AX ; save ax ;AN000; 0 00002A6C B00E MOV AL,FSEC_lookup ; al = 14 ;AN000; 0 00002A6E 53 PUSH BX ; save bx ;AN000; 0 00002A6F E82900 CALL FS_doit ; call fastseek ;AN000; 0 00002A72 36891E[0000] MOV [ss:FSeek_logsave],BX ; save returned BX ;AN000; 0 00002A77 5B POP BX ; restore bx ;AN000; 0 00002A78 58 POP AX ; restore ax ;AN000; 0 00002A79 C3 return ;AN000; 656 EndProc FastSeek_Lookup ;AN000; 657 ;AN000; 658 659 Break 660 661 ; Inputs: 662 ; FSeek_drive : drive number (0=A,1=B,,,) 663 ; FSeek_firclus: first cluster # 664 ; FSeek_logclus: logical cluster # 665 ; DI: physical cluster # to be inserted 666 ; Function: 667 ; insert a physical cluster # 668 ; Outputs: 669 ; none 670 ; 671 672 procedure FastSeek_Insert,NEAR 672 ****************** warning: proc FastSeek_Insert... [-w+user] 673 ASSUME DS:NOTHING,ES:NOTHING 674 0 00002A7A 36F606[0000]02 TEST byte [ss:FastSeekflg],FS_insert ; insert mode set ? ;AN000; 0 00002A80 7409 JZ no_insert ; no ;AN000; 677 ;AN000; 0 00002A82 50 PUSH AX ; save regs ;AN000; 0 00002A83 53 PUSH BX ;AN000; 0 00002A84 B00F MOV AL,FSEC_insert ; al = 15 ;AN000; 681 FSentry: ;AN000; 0 00002A86 E81200 CALL FS_doit ; call fastseek ;AN000; 0 00002A89 5B POP BX ; restore regs ;AN000; 0 00002A8A 58 POP AX ;AN000; 685 no_insert: 0 00002A8B C3 return 687 EndProc FastSeek_insert 688 689 Break 690 691 ; Inputs: 692 ; FSeek_drive : drive number (0=A,1=B,,,) 693 ; FSeek_firclus: first cluster # 694 ; FSeek_logclus: logical cluster # 695 ; Function: 696 ; truncate physical cluster #s starting from FSeek_logclus 697 ; Outputs: 698 ; none 699 ; 700 701 procedure FastSeek_Truncate,NEAR 701 ****************** warning: proc FastSeek_Truncate... [-w+user] 702 ASSUME DS:NOTHING,ES:NOTHING 703 ;AN000; 0 00002A8C 36F606[0000]80 TEST byte [ss:FastSeekflg],Fast_yes ; Fastseek installed ? ;AN000; 0 00002A92 7406 JZ fs_no ; no ;AN000; 0 00002A94 50 PUSH AX ; save regs ;AN000; 0 00002A95 53 PUSH BX ;AN000; 0 00002A96 B010 MOV AL,FSEC_truncate ; al = 16 ;AN000; 0 00002A98 EBEC JMP FSentry ; call fastseek ;AN000; 710 fs_no: ;AN000; 0 00002A9A C3 return ;AN000; 712 EndProc FastSeek_Truncate ;AN000; 713 714 ; Inputs: 715 ; FSeek_drive : drive number (0=A,1=B,,,) 716 ; FSeek_firclus: first cluster # 717 ; FSeek_logclus: logical cluster # 718 ; Function: 719 ; set up parameters and call fastseek 720 ; Outputs: 721 ; outputs of fastseek 722 ; 723 procedure FS_doit,NEAR 723 ****************** warning: proc FS_doit... [-w+user] 724 ASSUME DS:NOTHING,ES:NOTHING 725 ;AN000; 0 00002A9B 51 PUSH CX ; save regs ;AN000; 0 00002A9C 52 PUSH DX ;AN000; 0 00002A9D 56 PUSH SI ;AN000; 0 00002A9E 368A16[0000] MOV DL,[ss:FSeek_drive] ; set drive # ;AN000; 0 00002AA3 368B0E[0000] MOV CX,[ss:FSeek_firclus] ; set 1st cluster # ;AN000; 0 00002AA8 368B1E[0000] MOV BX,[ss:FSeek_logclus] ; set logical cluster # ;AN000; 732 ;AN000; 0 00002AAD E873FF CALL FSeek_dispatch ; call fastseek ;AN000; 734 ;AN000; 735 ; carry clear if found in DI ;AN000; 0 00002AB0 5E POP SI ; otherwise, carry set ;AN000; 737 ;AN000; 0 00002AB1 5A POP DX ; restore regs ;AN000; 0 00002AB2 59 POP CX ;AN000; 0 00002AB3 C3 return ;AN000; 741 EndProc FS_doit ;AN000; 742 743 744 ; Inputs: 745 ; same as DOS_SEARCH_FIRST 746 ; Function: 747 ; do a IFS search first 748 ; Outputs: 749 ; same as DOS_SEARCH_FIRST 750 ; 751 procedure IFS_SEARCH_FIRST,NEAR ;AN000; 751 ****************** warning: proc IFS_SEARCH_FIRST... [-w+user] 752 DOSAssume CS,,"IFS_SEARCH_FIRST" ;AN000; 753 ASSUME ES:NOTHING ;AN000; 754 755 ; MOV WORD PTR [DMAADD+2],DS ;IFS. replace with scratch area ;AN000;;AN000; 756 ; MOV WORD PTR [DMAADD],OFFSET RENAMEDMA wrt DOSGROUP ;IFS. ;AN000; 757 ; invoke SET_THISDPB ;IFS. THISDPB set ;AN000; 758 ; invoke DOS_SEARCH_FIRST ;IFS. search first ;AN000; 759 ; return ;AN000; 760 EndProc IFS_SEARCH_FIRST ;AN000; 761 762 763 ; Inputs: 764 ; THISDPB set 765 ; WFP_Start points to name 766 ; Function: 767 ; do a IFS REN_DEL_CHECK 768 ; Outputs: 769 ; same as REN_DEL_CHECK 770 ; 771 procedure IFS_REN_DEL_CHECK,NEAR ;AN000; 771 ****************** warning: proc IFS_REN_DEL_CHECK... [-w+user] 772 DOSAssume CS,,"IFS_REN_DEL_CHECK" ;AN000; 773 ASSUME ES:NOTHING ;AN000; 774 775 ; MOV AX,WORD PTR [DMAADD+2] ;IFS. set up ;AN000;;AN000; 776 ; MOV WORD PTR [CURBUF+2],AX ;IFS. curbuf+2 : bx -> dir entry ;AN000; 777 ; MOV BX,WORD PTR [DMAADD] ;IFS. ;AN000; 778 ; ADD BX,21 ;IFS. ;AN000; 779 ; MOV SI,BX ;IFS. curbuf+2:si -> dir_first ;AN000; 780 ; ADD SI,dir_first ;IFS. ;AN000; 781 ; EnterCrit critDisk ;IFS. enter critical section ;AN000; 782 ; CALL REN_DEL_Check ;IFS. share check ;AN000; 783 ; LeaveCrit critDisk ;IFS. leave critical section ;AN000; 784 ; return ;AN000; 785 EndProc IFS_REN_DEL_CHECK ;AN000; 786 787 END === Trace listing source: ../DOS/rename.lst 1 ; SCCSID = @(#)rename.asm 1.1 85/04/10 2 ;TITLE DOS_RENAME - Internal RENAME call for MS-DOS 3 ;NAME DOS_RENAME 4 ; Low level routine for renaming files 5 ; 6 ; DOS_RENAME 7 ; 8 ; Modification history: 9 ; 10 ; Created: ARR 30 March 1983 11 ; 12 13 ; 14 ; get the appropriate segment definitions 15 ; 16 [list -] === Switch to base=008400h -> "DOSCODECODE" 20 section DOSCODECODE 21 [list -] 21 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 21 ****************** warning: out: BPB.INC... [-w+user] 21 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 21 ****************** warning: out: DEVSYM.INC... [-w+user] 28 29 %iassign Installed TRUE 30 31 i_need RENAMEDMA,BYTE 32 i_need AUXSTACK,BYTE 33 i_need DESTSTART,WORD 34 i_need DIRSTART,WORD 35 i_need CURBUF,DWORD 36 I_need NAME1,BYTE 37 i_need NAME2,BYTE 38 i_need WFP_START,WORD 39 i_need REN_WFP,WORD 40 i_need CURR_DIR_END,WORD 41 i_need DMAADD,DWORD 42 i_need THISCDS,DWORD 43 i_need THISDPB,DWORD 44 i_need THISSFT,DWORD 45 i_need CREATING,BYTE 46 i_need THISDRV,BYTE 47 i_need ATTRIB,BYTE 48 i_need FOUND_DEV,BYTE 49 i_need FAILERR,BYTE 50 i_need EXTERR_LOCUS,BYTE 51 i_need SAVE_BX,WORD 52 53 ; Inputs: 54 ; [WFP_START] Points to SOURCE WFP string ("d:/" must be first 3 55 ; chars, NUL terminated) 56 ; [CURR_DIR_END] Points to end of Current dir part of string [SOURCE] 57 ; ( = -1 if current dir not involved, else 58 ; Points to first char after last "/" of current dir part) 59 ; [REN_WFP] Points to DEST WFP string ("d:/" must be first 3 60 ; chars, NUL terminated) 61 ; [THISCDS] Points to CDS being used 62 ; (Low word = -1 if NUL CDS (Net direct request)) 63 ; [SATTRIB] Is attribute of search, determines what files can be found 64 ; Function: 65 ; Rename the specified file(s) 66 ; NOTE: This routine uses most of AUXSTACK as a temp buffer. 67 ; Outputs: 68 ; CARRY CLEAR 69 ; OK 70 ; CARRY SET 71 ; AX is error code 72 ; error_file_not_found 73 ; No match for source, or dest path invalid 74 ; error_not_same_device 75 ; Source and dest are on different devices 76 ; error_access_denied 77 ; Directory specified (not simple rename), 78 ; Device name given, Destination exists. 79 ; NOTE: In third case some renames may have 80 ; been done if metas. 81 ; error_path_not_found 82 ; Bad path (not in curr dir part if present) 83 ; SOURCE ONLY 84 ; error_bad_curr_dir 85 ; Bad path in current directory part of path 86 ; SOURCE ONLY 87 ; error_sharing_violation 88 ; Deny both access required, generates an INT 24. 89 ; DS preserved, others destroyed 90 91 procedure DOS_RENAME,NEAR 91 ****************** warning: proc DOS_RENAME... [-w+user] 92 DOSAssume CS,,"DOS_Rename" 93 ASSUME ES:NOTHING 94 0 00002AB4 E8[0000] Invoke TestNet 0 00002AB7 7306 JNC LOCAL_RENAME 97 ; invoke OWN_SHARE2 ;IFS. IFS owns share ? ;AN000; 98 ; JZ ifsshare ;IFS. yes ;AN000; 99 ; PUSH WORD PTR [DMAADD+2] ;IFS. save DMAADD ;AN000; 100 ; PUSH WORD PTR [DMAADD] ;IFS. ;AN000; 101 ; 102 ; invoke IFS_SEARCH_FIRST ;IFS. search source name ;AN000; 103 ; JC nofiles ;IFS. not found ;AN000; 104 rename_next_file: 105 ; invoke IFS_REN_DEL_CHECK ;IFS. do share check ;AN000; 106 ; JNC share_okok ;IFS. share ok ;AN000; 107 ; MOV AX,error_sharing_violation ;IFS. share error ;AN000; 108 ; JMP SHORT nofiles ;IFS. ;AN000; 109 share_okok: 110 ; PUSH CS ;IFS. ;AN000; 111 ; POP ES ;IFS. ;AN000; 112 ; MOV SI,[REN_WFP] ;IFS. ds:si -> destination name ;AN000; 113 ; MOV BX,SI ;IFS. ;AN000; 114 fndnxt: ;IFS. ;AN000; 115 ; LODSB ;IFS. ;AN000; 116 ; CMP AL,0 ;IFS. ;AN000; 117 ; JNZ fndnxt ;IFS. ;AN000; 118 ; MOV DI,SI ;IFS. es:di -> end of destinatio ;AN000; 119 ; ADD BX,2 ;IFS. ;AN000; 120 ; invoke SkipBack ;IFS. ;AN000; 121 ; INC DI ;IFS. es:di -> last component of ;AN000; 122 ; MOV SI,DI ;IFS. dstination ;AN000; 123 ; MOV BX,[SAVE_BX] ;IFS. ds:bx -> last component of ;AN000; 124 ; CALL NEW_RENAME ;IFS. source ;AN000; 125 ; MOV AX,(multNET SHL 8) OR 17 ;IFS. replace ? chars with ;AN000; 126 ; INT 2FH ;IFS. source and issue RENAME ;AN000; 127 ; JC nofiles ;IFS. error ;AN000; 128 ; invoke DOS_SEARCH_NEXT ;IFS. serch next source ;AN000; 129 ; JNC rename_next_file ;IFS. rename next ;AN000; 130 ; CLC ;IFS. no more files ;AN000; 131 nofiles: 132 ; POP WORD PTR [DMAADD] ;IFS. restore DMAADD ;AN000; 133 ; POP WORD PTR [DMAADD+2] ;IFS. ;AN000; 134 ; ret ;IFS. return ;AN000; 135 ifsshare: 136 137 %IFN Installed 138 transfer NET_RENAME 139 %ELSE 140 multNET equ MultNET ; NASM port equate 0 00002AB9 B81111 MOV AX,(multNET << 8) | 17 0 00002ABC CD2F INT 2FH 0 00002ABE C3 return 144 %ENDIF 145 146 LOCAL_RENAME: 0 00002ABF C606[0000]02 MOV byte [EXTERR_LOCUS],errLOC_Disk 0 00002AC4 8B36[0000] MOV SI,[WFP_START] 0 00002AC8 8B3E[0000] MOV DI,[REN_WFP] 0 00002ACC 8A04 MOV AL,BYTE PTR [SI] 0 00002ACE 8A25 MOV AH,BYTE PTR [DI] 0 00002AD0 0D2020 OR AX,2020H ; Lower case 0 00002AD3 38E0 CMP AL,AH 0 00002AD5 7405 JZ SAMEDRV 0 00002AD7 B81100 MOV AX,error_not_same_device 0 00002ADA F9 STC 0 00002ADB C3 return 158 159 SAMEDRV: 0 00002ADC FF36[0200] PUSH WORD PTR [DMAADD+2] 0 00002AE0 FF36[0000] PUSH WORD PTR [DMAADD] 0 00002AE4 8C1E[0200] MOV WORD PTR [DMAADD+2],DS 0 00002AE8 C706[0000][0000] MOV WORD PTR [DMAADD],OFFSET RENAMEDMA wrt DOSGROUP 164 Found_dev equ FOUND_DEV ; NASM port label 0 00002AEE C606[0000]00 MOV byte [Found_dev],0 ; Rename fails on DEVS, assume not a dev 0 00002AF3 E8[0000] EnterCrit critDisk 0 00002AF6 E8[0000] invoke DOS_SEARCH_FIRST ; Sets [NoSetDir] to 1, [CURBUF+2]:BX 168 ; points to entry 169 Check_Dev equ Check_dev ; NASM port label 0 00002AF9 7315 JNC Check_Dev 0 00002AFB 83F812 CMP AX,error_no_more_files 0 00002AFE 7503 JNZ GOTERR 0 00002B00 B80200 MOV AX,error_file_not_found 174 GOTERR: 0 00002B03 F9 STC 176 RENAME_POP: 0 00002B04 8F06[0000] POP WORD PTR [DMAADD] 0 00002B08 8F06[0200] POP WORD PTR [DMAADD+2] 0 00002B0C E8[0000] LeaveCrit critDisk 0 00002B0F C3 return 181 182 Check_dev: 0 00002B10 B80500 MOV AX,error_access_denied ; Assume error 184 0 00002B13 1E PUSH DS ;PTM. ;AN000; 0 00002B14 C536[0000] LDS SI,[DMAADD] ;PTM. chek if source a dir ;AN000; 0 00002B18 83C615 ADD SI,find_buf_attr ;PTM. ;AN000; 0 00002B1B F6440B10 TEST byte [SI + dir_attr],attr_directory ;PTM. ;AN000; 0 00002B1F 7407 JZ notdir ;PTM. ;AN000; 0 00002B21 8B36[0000] MOV SI,[REN_WFP] ;PTM. if yes, make sure path ;AN000; 0 00002B25 E8[0000] invoke Check_Pathlen2 ;PTM. length < 67 ;AN000; 192 notdir: 0 00002B28 1F POP DS ;PTM. ;AN000; 0 00002B29 77D8 JA GOTERR ;PTM. ;AN000; 195 0 00002B2B 803E[0000]00 CMP byte [Found_dev],0 0 00002B30 75D1 JNZ GOTERR 198 ; At this point a source has been found. There is search continuation info (a 199 ; la DOS_SEARCH_NEXT) for the source at RENAMEDMA, together with the first 200 ; directory entry found. 201 ; [THISCDS], [THISDPB], and [THISDRV] are set and will remain correct 202 ; throughout the RENAME since it is known at this point that the source and 203 ; destination are both on the same device. 204 ; [SATTRIB] is also set. 0 00002B32 89DE MOV SI,BX 0 00002B34 83C61A ADD SI,dir_first 0 00002B37 E8[0000] invoke REN_DEL_Check 0 00002B3A 7305 JNC REN_OK1 0 00002B3C B82000 MOV AX,error_sharing_violation 0 00002B3F EBC3 JMP RENAME_POP 211 212 REN_OK1: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 0 00002B41 E8[0000] invoke FastOpen_Delete ; delete dir info in fastopen DOS 3.3 0 00002B44 8B36[0000] MOV SI,[REN_WFP] ; Swap source and destination 0 00002B48 8936[0000] MOV [WFP_START],SI 0 00002B4C C706[0000]FFFF MOV word [CURR_DIR_END],-1 ; No current dir on dest 0 00002B52 C706[0000]FFE5 MOV WORD PTR [CREATING],0E5FFH ; Creating, not DEL *.* 218 ; A rename is like a CREATE_NEW as far 219 ; as the destination is concerned. 0 00002B58 E8[0000] invoke GetPathNoSet 221 ; If this Getpath fails due to file not found, we know all renames will work 222 ; since no files match the destination name. If it fails for any other 223 ; reason, the rename fails on a path not found, or whatever (also fails if 224 ; we find a device or directory). If the Getpath succeeds, we aren't sure 225 ; if the rename should fail because we haven't built an explicit name by 226 ; substituting for the meta chars in it. In this case the destination file 227 ; spec with metas is in [NAME1] and the explicit source name is at RENAMEDMA 228 ; in the directory entry part. 0 00002B5B 7221 JC NODEST 230 ;; JZ BAD_ACC ; Dest string is a directory ;AC000; 0 00002B5D 08E4 OR AH,AH ; Device? 0 00002B5F 7931 JNS SAVEDEST ; No, continue 233 BAD_ACC: 0 00002B61 B80500 MOV AX,error_access_denied 0 00002B64 F9 STC 236 RENAME_CLEAN: 0 00002B65 9C PUSHF ; Save carry state 0 00002B66 50 PUSH AX ; and error code (if carry set) 0 00002B67 A0[0000] MOV AL,[THISDRV] 0 00002B6A E8[0000] invoke FLUSHBUF 0 00002B6D 58 POP AX 0 00002B6E 803E[0000]00 CMP byte [FAILERR],0 0 00002B73 7503 JNZ BAD_ERR ; User FAILed to I 24 0 00002B75 9D POPF 0 00002B76 EB8C JMP RENAME_POP 246 247 BAD_ERR: 0 00002B78 58 POP AX ; Saved flags 0 00002B79 B80300 MOV AX,error_path_not_found 0 00002B7C EB85 JMP GOTERR 251 252 NODEST: 0 00002B7E 750B JNZ BAD_PATH 0 00002B80 803E[0000]00 CMP byte [FAILERR],0 0 00002B85 7504 JNZ BAD_PATH ; Search for dest failed because user FAILed on 256 ; I 24 0 00002B87 08C9 OR CL,CL 0 00002B89 7507 JNZ SAVEDEST 259 BAD_PATH: 0 00002B8B B80300 MOV AX,error_path_not_found 0 00002B8E F9 STC 0 00002B8F E972FF JMP RENAME_POP 263 264 SAVEDEST: 0 00002B92 1607 Context ES 0 00002B94 BF[0000] MOV DI,OFFSET NAME2 wrt DOSGROUP 0 00002B97 BE[0000] MOV SI,OFFSET NAME1 wrt DOSGROUP 0 00002B9A B90B00 MOV CX,11 0 00002B9D F3A4 REP MOVSB ; Save dest with metas at NAME2 0 00002B9F A1[0000] MOV AX,[DIRSTART] 0 00002BA2 A3[0000] MOV [DESTSTART],AX 272 BUILDDEST: 0 00002BA5 1607 Context ES ; needed due to JMP BUILDDEST below 0 00002BA7 BB[1500] MOV BX,OFFSET RENAMEDMA + 21 wrt DOSGROUP ; Source of replace chars 0 00002BAA BF[0000] MOV DI,OFFSET NAME1 wrt DOSGROUP ; Real dest name goes here 0 00002BAD BE[0000] MOV SI,OFFSET NAME2 wrt DOSGROUP ; Raw dest 0 00002BB0 B90B00 MOV CX,11 0 00002BB3 E8F400 CALL NEW_RENAME ;IFS. replace ? chars ;AN000; 279 0 00002BB6 C606[0000]16 MOV byte [ATTRIB],attr_all ; Stop duplicates with any attributes 0 00002BBB C606[0000]FF MOV byte [CREATING],0FFH 0 00002BC0 E8[0000] invoke DEVNAME ; Check if we built a device name 283 ASSUME ES:NOTHING 0 00002BC3 739C JNC BAD_ACC 0 00002BC5 8B1E[0000] MOV BX,[DESTSTART] 0 00002BC9 C42E[0000] LES BP,[THISDPB] 0 00002BCD E8[0000] invoke SetDirSrch ; Reset search to start of dir 0 00002BD0 728F JC BAD_ACC ; Screw up 0 00002BD2 E8[0000] invoke FINDENTRY ; See if new name already exists 0 00002BD5 738A JNC BAD_ACC ; Error if found 0 00002BD7 803E[0000]00 CMP byte [FAILERR],0 0 00002BDC 752A JNZ BAD_ACCJ ; Find failed because user FAILed to I 24 0 00002BDE A1[0000] MOV AX,[DESTSTART] ; DIRSTART of dest 0 00002BE1 3B06[0F00] CMP AX,WORD PTR [RENAMEDMA + 15] ; DIRSTART of source 0 00002BE5 745D JZ SIMPLE_RENAME ; If =, just give new name 296 0 00002BE7 A0[2000] MOV AL,[RENAMEDMA + 21 + dir_attr] 0 00002BEA A810 TEST AL,attr_directory 0 00002BEC 751A JNZ BAD_ACCJ ; Can only do a simple rename on dirs, 300 ; otherwise the . and .. entries get 301 ; wiped. 0 00002BEE A2[0000] MOV [ATTRIB],AL 0 00002BF1 8C1E[0200] MOV WORD PTR [THISSFT+2],DS 304 SF_ENTRY_struc_size equ sf_entry_struc_size ; NASM port equate 0 00002BF5 BE[C5FF] MOV SI,OFFSET AUXSTACK - SF_ENTRY_struc_size wrt DOSGROUP 0 00002BF8 8936[0000] MOV WORD PTR [THISSFT],SI 0 00002BFC C744020200 MOV word [SI + sf_mode],sharing_compat+open_for_both 0 00002C01 31C9 XOR CX,CX ; Set "device ID" for call into makenode 0 00002C03 E8[0000] invoke RENAME_MAKE ; This is in mknode 0 00002C06 7303 JNC GOT_DEST 311 BAD_ACCJ: 0 00002C08 E956FF JMP BAD_ACC 313 314 GOT_DEST: 0 00002C0B 53 SaveReg 316 ThisSFT equ THISSFT ; NASM port label 0 00002C0C C43E[0000] LES DI,[ThisSFT] ; Rename_make entered this into sharing 0 00002C10 E8[0000] Invoke ShareEnd ; we need to remove it. 0 00002C13 5B RestoreReg 320 ; A zero length entry with the correct new name has now been made at 321 ; [CURBUF+2]:BX. 0 00002C14 C43E[0000] LES DI,[CURBUF] 323 Assert ISBUF,,"Got_Dest" 324 0 00002C18 26F6450540 TEST byte [ES:DI + buf_flags],buf_dirty ;LB. if already dirty ;AN000; 0 00002C1D 7508 JNZ yesdirty ;LB. don't increment dirty count ;AN000; 0 00002C1F E8[0000] invoke INC_DIRTY_COUNT ;LB. ;AN000; 0 00002C22 26804D0540 OR byte [ES:DI + buf_flags],buf_dirty 329 yesdirty: 0 00002C27 89DF MOV DI,BX 0 00002C29 83C70B ADD DI,dir_attr ; Skip name 0 00002C2C BE[2000] MOV SI,OFFSET RENAMEDMA + 21 + dir_attr wrt DOSGROUP 0 00002C2F B91500 MOV CX,(dir_entry_struc_size) - dir_attr 0 00002C32 F3A4 REP MOVSB 0 00002C34 E85B00 CALL GET_SOURCE 0 00002C37 7255 JC RENAME_OVER 0 00002C39 89DF MOV DI,BX 0 00002C3B 8E06[0200] MOV ES,WORD PTR [CURBUF+2] 0 00002C3F B0E5 MOV AL,0E5H 0 00002C41 AA STOSB ; "free" the source 0 00002C42 EB13 JMP SHORT DIRTY_IT 342 343 SIMPLE_RENAME: 0 00002C44 E84B00 CALL GET_SOURCE ; Get the source back 0 00002C47 7245 JC RENAME_OVER 0 00002C49 89DF MOV DI,BX 0 00002C4B 8E06[0200] MOV ES,WORD PTR [CURBUF+2] 0 00002C4F BE[0000] MOV SI,OFFSET NAME1 wrt DOSGROUP ; New Name 0 00002C52 B90B00 MOV CX,11 0 00002C55 F3A4 REP MOVSB 351 DIRTY_IT: 0 00002C57 8B3E[0000] MOV DI,WORD PTR [CURBUF] 353 0 00002C5B 26F6450540 TEST byte [ES:DI + buf_flags],buf_dirty ;LB. if already dirty ;AN000; 0 00002C60 7508 JNZ yesdirty2 ;LB. don't increment dirty count ;AN000; 0 00002C62 E8[0000] invoke INC_DIRTY_COUNT ;LB. ;AN000; 0 00002C65 26804D0540 OR byte [ES:DI + buf_flags],buf_dirty 358 yesdirty2: 359 Assert ISBUF,,"Dirty_it" 360 NEXT_SOURCE: 0 00002C6A BE[0100] MOV SI,OFFSET RENAMEDMA + 1 wrt DOSGROUP ;Name 362 ; 363 ; WARNING! Rename_Next leaves the disk critical section *ALWAYS*. We need 364 ; to enter it before going to RENAME_Next. 365 ; 0 00002C6D E8[0000] EnterCrit critDisk 0 00002C70 C606[0000]00 MOV byte [CREATING],0 ; Correct setting for search (we changed it 368 ; to FF when we made the prev new file). 0 00002C75 E8[0000] invoke RENAME_NEXT 370 ; 371 ; Note, now, that we have exited the previous ENTER and so are back to where 372 ; we were before. 373 ; 0 00002C78 7214 JC RENAME_OVER 375 dir_First equ dir_first ; NASM port equate 0 00002C7A 8D771A LEA SI,[BX + dir_First] 0 00002C7D E8[0000] invoke REN_DEL_Check 0 00002C80 7306 JNC REN_OK2 0 00002C82 B82000 MOV AX,error_sharing_violation 0 00002C85 E9DDFE JMP RENAME_CLEAN 381 382 REN_OK2: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 0 00002C88 E8[0000] invoke FastOpen_Delete ; delete dir info in fastopen DOS 3.3 0 00002C8B E917FF JMP BUILDDEST 385 386 RENAME_OVER: 0 00002C8E F8 CLC 0 00002C8F E9D3FE JMP RENAME_CLEAN 389 390 ; Inputs: 391 ; RENAMEDMA has source info 392 ; Function: 393 ; Re-find the source 394 ; Output: 395 ; [CURBUF] set 396 ; [CURBUF+2]:BX points to entry 397 ; Carry set if error (currently user FAILed to I 24) 398 ; DS preserved, others destroyed 399 400 GET_SOURCE: 401 DOSAssume CS,,"Get_Source" 402 ASSUME ES:NOTHING 403 0 00002C92 8B1E[0F00] MOV BX,WORD PTR [RENAMEDMA + 15] ; DirStart 405 ThisDPB equ THISDPB ; NASM port label 0 00002C96 C42E[0000] LES BP,[ThisDPB] 0 00002C9A E8[0000] invoke SetDirSrch 0 00002C9D 7301C3 retc 0 00002CA0 E8[0000] invoke StartSrch 0 00002CA3 A1[0D00] MOV AX,WORD PTR [RENAMEDMA + 13] ; Lastent 0 00002CA6 E8[0000] invoke GetEnt 0 00002CA9 C3 return 413 414 EndProc DOS_RENAME 415 416 ;Input: DS:SI -> raw string with ? 417 ; ES:DI -> destination string 418 ; DS:BX -> source string 419 ;Function: replace ? chars of raw string with chars in source string and 420 ; put in destination string 421 ;Output: ES:DI-> new string 422 423 424 425 procedure NEW_RENAME,NEAR 425 ****************** warning: proc NEW_RENAME... [-w+user] 426 DOSAssume CS,,"DOS_Rename" 427 ASSUME ES:NOTHING 428 NEWNAM: 0 00002CAA AC LODSB 0 00002CAB 3C3F CMP AL,"?" 0 00002CAD 7502 JNZ NOCHG 0 00002CAF 8A07 MOV AL,[BX] ; Get replace char 433 NOCHG: 0 00002CB1 AA STOSB 0 00002CB2 43 INC BX ; Next replace char 0 00002CB3 E2F5 LOOP NEWNAM 0 00002CB5 C3 return 438 439 EndProc NEW_RENAME 440 441 END === Trace listing source: ../DOS/finfo.lst 1 ; SCCSID = @(#)finfo.asm 1.1 85/04/11 2 ;TITLE FILE_INFO - Internal Get/Set File Info routines 3 ;NAME FILE_INFO 4 ; Low level routines for returning file information and setting file 5 ; attributes 6 ; 7 ; GET_FILE_INFO 8 ; SET_FILE_ATTRIBUTE 9 ; 10 ; Modification history: 11 ; 12 ; Created: ARR 30 March 1983 13 ; 14 15 ; 16 ; get the appropriate segment definitions 17 ; 18 [list -] === Switch to base=008400h -> "DOSCODECODE" 22 section DOSCODECODE 23 [list -] 23 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 23 ****************** warning: out: BPB.INC... [-w+user] 23 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 23 ****************** warning: out: DEVSYM.INC... [-w+user] 32 33 %iassign Installed TRUE 34 35 i_need THISCDS,DWORD 36 i_need CURBUF,DWORD 37 i_need NoSetDir,BYTE 38 i_need THISDRV,BYTE 39 I_need EXTERR_CLASS,BYTE 40 I_need EXTERR_ACTION,BYTE 41 I_need EXTERR_LOCUS,BYTE 42 i_need DMAADD,DWORD 43 i_need FastOpenFlg,BYTE 44 45 ;SUBTTL GET_FILE_INFO -- Get File Information 46 ;PAGE 47 48 ; Inputs: 49 ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL 50 ; terminated) 51 ; [CURR_DIR_END] Points to end of Current dir part of string 52 ; ( = -1 if current dir not involved, else 53 ; Points to first char after last "/" of current dir part) 54 ; [THISCDS] Points to CDS being used 55 ; (Low word = -1 if NUL CDS (Net direct request)) 56 ; [SATTRIB] Is attribute of search, determines what files can be found 57 ; Function: 58 ; Get Information about a file 59 ; Returns: 60 ; CARRY CLEAR 61 ; AX = Attribute of file 62 ; CX = Time stamp of file 63 ; DX = Date stamp of file 64 ; BX:DI = Size of file (32 bit) 65 ; CARRY SET 66 ; AX is error code 67 ; error_file_not_found 68 ; Last element of path not found 69 ; error_path_not_found 70 ; Bad path (not in curr dir part if present) 71 ; error_bad_curr_dir 72 ; Bad path in current directory part of path 73 ; DS preserved, others destroyed 74 75 procedure GET_FILE_INFO,NEAR 75 ****************** warning: proc GET_FILE_INFO... [-w+user] 76 DOSAssume CS,,"Get_File_Info" 77 ASSUME ES:NOTHING 78 0 00002CB6 E8[0000] Invoke TestNet 80 Local_Info equ LOCAL_INFO ; NASM port label 0 00002CB9 7306 JNC Local_Info 82 ; invoke OWN_SHARE2 ;IFS. IFS owns share ? ;AN000; 83 ; JZ ifsshare ;IFS. yes ;AN000; 84 ; PUSH WORD PTR [DMAADD+2] ;IFS. save DMAADD ;AN000; 85 ; PUSH WORD PTR [DMAADD] ;IFS. ;AN000; 86 ; invoke IFS_SEARCH_FIRST ;IFS. do search first ;AN000; 87 ; JC nofiles ;IFS. file not existing ;AN000; 88 delete_next_file: ;IFS. ;AN000; 89 ; invoke IFS_REN_DEL_CHECK ;IFS. do REN_DEL_CHECK ;AN000; 90 ; JNC share_okok ;IFS. share ok ;AN000; 91 ; MOV AX,error_sharing_violation ;IFS. share violation ;AN000; 92 ; JMP SHORT nofiles ;IFS. ;AN000; 93 share_okok: 94 ; POP WORD PTR [DMAADD] ;IFS. retor DMAADD ;AN000; 95 ; POP WORD PTR [DMAADD+2] ;IFS. ;AN000; 96 ifsshare: 97 %IFN Installed 98 transfer NET_GET_FILE_INFO 99 %ELSE 100 multNET equ MultNET ; NASM port equate 0 00002CBB B80F11 MOV AX,(multNET << 8) | 15 0 00002CBE CD2F INT 2FH 0 00002CC0 C3 return 104 %ENDIF 105 nofiles: 106 ; POP WORD PTR [DMAADD] ;IFS. retor DMAADD ;AN000; 107 ; POP WORD PTR [DMAADD+2] ;IFS. ;AN000; 108 ; ret ;IFS. return 109 110 LOCAL_INFO: 0 00002CC1 E8[0000] EnterCrit critDisk 0 00002CC4 C606[0000]01 MOV byte [NoSetDir],1 ; if we find a dir, don't change to it 0 00002CC9 E8[0000] invoke Get_FAST_PATH 114 info_check: 0 00002CCC 7313 JNC info_check_dev 116 117 NO_PATH: 118 DOSAssume CS,,"FINFO/No_Path" 119 ASSUME ES:NOTHING 120 0 00002CCE 750C JNZ bad_path 0 00002CD0 08C9 OR CL,CL 0 00002CD2 7408 JZ bad_path 124 info_no_file: 0 00002CD4 B80200 MOV AX,error_file_not_found 126 BadRet: 0 00002CD7 F9 STC 128 justRet: 0 00002CD8 E8[0000] LeaveCrit critDisk 0 00002CDB C3 return 131 132 bad_path: 0 00002CDC B80300 MOV AX,error_path_not_found 0 00002CDF EBF6 jmp BadRet 135 136 info_check_dev: 0 00002CE1 08E4 OR AH,AH 0 00002CE3 78EF JS info_no_file ; device 0 00002CE5 1E PUSH DS 0 00002CE6 8E1E[0200] MOV DS,WORD PTR [CURBUF+2] 141 ASSUME DS:NOTHING 0 00002CEA 89DE MOV SI,BX 0 00002CEC 31DB XOR BX,BX ; Assume size=0 (dir) 0 00002CEE 89DF MOV DI,BX 0 00002CF0 8B4C16 MOV CX,[SI + dir_time] 0 00002CF3 8B5418 MOV DX,[SI + dir_date] 0 00002CF6 30E4 XOR AH,AH 0 00002CF8 8A440B MOV AL,[SI + dir_attr] 0 00002CFB A810 TEST AL,attr_directory 0 00002CFD 7506 JNZ NO_SIZE 0 00002CFF 8B7C1C MOV DI,[SI + dir_size_l] 0 00002D02 8B5C1E MOV BX,[SI + dir_size_h] 153 NO_SIZE: 0 00002D05 1F POP DS 0 00002D06 F8 CLC 156 JustRet equ justRet ; NASM port label 0 00002D07 EBCF jmp JustRet 158 EndProc GET_FILE_INFO 159 160 Break 161 162 ; Inputs: 163 ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL 164 ; terminated) 165 ; [CURR_DIR_END] Points to end of Current dir part of string 166 ; ( = -1 if current dir not involved, else 167 ; Points to first char after last "/" of current dir part) 168 ; [THISCDS] Points to CDS being used 169 ; (Low word = -1 if NUL CDS (Net direct request)) 170 ; [SATTRIB] is attribute of search (determines what files may be found) 171 ; AX is new attributes to give to file 172 ; Function: 173 ; Set File Attributes 174 ; Returns: 175 ; CARRY CLEAR 176 ; No error 177 ; CARRY SET 178 ; AX is error code 179 ; error_file_not_found 180 ; Last element of path not found 181 ; error_path_not_found 182 ; Bad path (not in curr dir part if present) 183 ; error_bad_curr_dir 184 ; Bad path in current directory part of path 185 ; error_access_denied 186 ; Attempt to set an attribute which cannot be set 187 ; (attr_directory, attr_volume_ID) 188 ; error_sharing_violation 189 ; Sharing mode of file did not allow the change 190 ; (this request requires exclusive write/read access) 191 ; (INT 24H generated) 192 ; DS preserved, others destroyed 193 194 procedure SET_FILE_ATTRIBUTE,NEAR 194 ****************** warning: proc SET_FILE_ATTRIBUTE... [-w+user] 195 DOSAssume CS,,"Set_File_Attribute" 196 ASSUME ES:NOTHING 197 0 00002D09 A9D8FF TEST AX,~ attr_changeable 0 00002D0C 7414 JZ set_look 200 BAD_ACC: 201 ExtErr_Locus equ EXTERR_LOCUS ; NASM port label 202 errLoc_UNK equ errLOC_Unk ; NASM port equate 0 00002D0E C606[0000]01 MOV byte [ExtErr_Locus],errLoc_UNK 204 ExtErr_Class equ EXTERR_CLASS ; NASM port label 205 errClass_Apperr equ errCLASS_Apperr ; NASM port equate 0 00002D13 C606[0000]07 MOV byte [ExtErr_Class],errClass_Apperr 207 ExtErr_Action equ EXTERR_ACTION ; NASM port label 208 errAct_Abort equ errACT_Abort ; NASM port equate 0 00002D18 C606[0000]04 MOV byte [ExtErr_Action],errAct_Abort 0 00002D1D B80500 MOV AX,error_access_denied 0 00002D20 F9 STC 0 00002D21 C3 return 213 214 set_look: 0 00002D22 E8[0000] Invoke TestNet 216 Local_Set equ LOCAL_SET ; NASM port label 0 00002D25 7308 JNC Local_Set 218 219 %IFN Installed 220 transfer NET_SEQ_SET_FILE_ATTRIBUTE 221 %ELSE 0 00002D27 50 PUSH AX 0 00002D28 B80E11 MOV AX,(multNET << 8) | 14 0 00002D2B CD2F INT 2FH 0 00002D2D 5B POP BX ; clean stack 0 00002D2E C3 return 227 %ENDIF 228 229 LOCAL_SET: 0 00002D2F E8[0000] EnterCrit critDisk 0 00002D32 50 PUSH AX ; Save new attributes 0 00002D33 C606[0000]01 MOV byte [NoSetDir],1 ; if we find a dir, don't change to it 0 00002D38 E8[0000] invoke GetPath ; get path through fastopen if there ;AC000; 0 00002D3B 7303 JNC set_check_device 0 00002D3D 5B POP BX ; Clean stack (don't zap AX) 0 00002D3E EB8E JMP NO_PATH 237 238 set_check_device: 0 00002D40 08E4 OR AH,AH 0 00002D42 7906 JNS set_check_share 0 00002D44 58 POP AX 0 00002D45 E8[0000] LeaveCrit critDisk 0 00002D48 EBC4 JMP BAD_ACC ; device 244 245 set_check_share: 0 00002D4A 58 POP AX ; Get new attributes 0 00002D4B E8[0000] invoke REN_DEL_Check 0 00002D4E 7305 JNC set_do 0 00002D50 B82000 MOV AX,error_sharing_violation 250 ok_bye equ OK_BYE ; NASM port label 0 00002D53 EB34 jmp short ok_bye 252 253 set_do: 0 00002D55 C43E[0000] LES DI,[CURBUF] 0 00002D59 2680670BD8 AND BYTE PTR [ES:BX + dir_attr],~ attr_changeable 0 00002D5E 2608470B OR BYTE PTR [ES:BX + dir_attr],AL 257 0 00002D62 26F6450540 TEST byte [ES:DI + buf_flags],buf_dirty ;LB. if already dirty ;AN000; 0 00002D67 7508 JNZ yesdirty ;LB. don't increment dirty count ;AN000; 0 00002D69 E8[0000] invoke INC_DIRTY_COUNT ;LB. ;AN000; 0 00002D6C 26804D0540 OR byte [ES:DI + buf_flags],buf_dirty 262 yesdirty: 0 00002D71 A0[0000] MOV AL,[THISDRV] 264 ;;;; 10/1/86 F.C update fastopen cache 0 00002D74 52 PUSH DX 0 00002D75 57 PUSH DI 0 00002D76 B400 MOV AH,0 ; dir entry update 0 00002D78 88C2 MOV DL,AL ; drive number A=0,B=1,, 0 00002D7A 89DF MOV DI,BX ; ES:DI -> dir entry 0 00002D7C E8[0000] invoke FastOpen_Update 0 00002D7F 5F POP DI 0 00002D80 5A POP DX 273 ;;;; 9/11/86 F.C update fastopen cache 0 00002D81 E8[0000] invoke FlushBuf 0 00002D84 7303 JNC OK_BYE 0 00002D86 B80200 MOV AX,error_file_not_found 277 OK_BYE: 0 00002D89 E8[0000] LeaveCrit critDisk 0 00002D8C C3 return 280 281 EndProc SET_FILE_ATTRIBUTE 282 283 284 285 procedure GET_FAST_PATH,NEAR 285 ****************** warning: proc GET_FAST_PATH... [-w+user] 286 ASSUME DS:NOTHING,ES:NOTHING 287 0 00002D8D 36800E[0000]01 OR byte [ss:FastOpenFlg],FastOpen_Set ;FO. trigger fastopen ;AN000; 0 00002D93 E8[0000] invoke GetPath 0 00002D96 9C PUSHF ;FO. ;AN000; 0 00002D97 368026[0000]80 AND byte [ss:FastOpenFlg],Fast_yes ;FO. clear all fastopen flags ;AN000; 0 00002D9D 9D POPF ;FO. ;AN000; 0 00002D9E C3 return 294 295 EndProc GET_FAST_PATH 296 297 END === Trace listing source: ../DOS/dup.lst 1 ; SCCSID = @(#)dup.asm 1.1 85/04/10 2 ; SCCSID = @(#)dup.asm 1.1 85/04/10 3 ;TITLE DOS_DUP - Internal SFT DUP (for network SFTs) 4 ;NAME DOS_DUP 5 ; Low level DUP routine for use by EXEC when creating a new process. Exports 6 ; the DUP to the server machine and increments the SFT ref count 7 ; 8 ; DOS_DUP 9 ; 10 ; Modification history: 11 ; 12 ; Created: ARR 30 March 1983 13 ; 14 15 ; 16 ; get the appropriate segment definitions 17 ; 18 [list -] === Switch to base=008400h -> "DOSCODECODE" 22 section DOSCODECODE 23 [list -] 23 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 23 ****************** warning: out: BPB.INC... [-w+user] 23 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 23 ****************** warning: out: DEVSYM.INC... [-w+user] 30 31 i_need THISSFT,DWORD 32 33 BREAK 34 35 ; Inputs: 36 ; [THISSFT] set to the SFT for the file being DUPed 37 ; (a non net SFT is OK, in this case the ref 38 ; count is simply incremented) 39 ; Function: 40 ; Signal to the devices that alogical open is occurring 41 ; Returns: 42 ; ES:DI point to SFT 43 ; Carry clear 44 ; SFT ref_count is incremented 45 ; Registers modified: None. 46 47 procedure DOS_DUP,NEAR 47 ****************** warning: proc DOS_DUP... [-w+user] 48 ASSUME ES:NOTHING,SS:NOTHING 49 50 extern doscode_getdosdata 51 52 ThisSFT equ THISSFT ; NASM port label 0 00002D9F 97 xchg ax, di 0 00002DA0 E8[0000] call doscode_getdosdata 0 00002DA3 8EC0 mov es, ax 0 00002DA5 97 xchg ax, di 0 00002DA6 26C43E[0000] LES DI,[es:ThisSFT] 58 Entry Dos_Dup_Direct 59 Assert ISSFT,,"DOSDup" 0 00002DAB E8[0000] invoke IsSFTNet 0 00002DAE 7503 JNZ DO_INC 0 00002DB0 E8[0000] invoke DEV_OPEN_SFT 63 DO_INC: 64 Assert ISSFT,,"DOSDup/DoInc" 0 00002DB3 26FF05 INC word [ES:DI + sf_ref_count] ; Clears carry (if this ever wraps 66 ; we're in big trouble anyway) 0 00002DB6 C3 return 68 69 EndProc DOS_DUP 70 71 END === Trace listing source: ../DOS/create.lst 1 ; SCCSID = @(#)create.asm 1.6 85/08/19 2 ;TITLE DOS_CREATE/DOS_CREATE_NEW - Internal CREATE calls for MS-DOS 3 ;NAME DOS_CREATE 4 ; Internal Create and Create new to create a local or NET file and SFT. 5 ; 6 ; DOS_CREATE 7 ; DOS_CREATE_NEW 8 ; SET_MKND_ERR 9 ; SET_Media_ID 10 ; SET_EXT_Mode 11 ; 12 ; Revision history: 13 ; 14 ; A000 version 4.00 Jan. 1988 15 ; A001 D490 -- Change IOCTL subfunctios from 63h,43h to 66h, 46h 16 17 ; 18 ; get the appropriate segment definitions 19 ; 20 [list -] === Switch to base=008400h -> "DOSCODECODE" 24 section DOSCODECODE 25 [list -] 25 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 25 ****************** warning: out: BPB.INC... [-w+user] 25 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 25 ****************** warning: out: DEVSYM.INC... [-w+user] 25 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 33 34 %iassign Installed TRUE 35 36 extrn IFS_extopen_shared:near 37 38 i_need NoSetDir,BYTE 39 i_need THISSFT,DWORD 40 i_need THISCDS,DWORD 41 I_need EXTERR,WORD 42 I_Need ExtErr_locus,BYTE 43 I_need JShare,DWORD 44 I_need VOLCHNG_FLAG,BYTE 45 I_need SATTRIB,BYTE 46 I_need CALLVIDM,DWORD 47 I_need OpenBuf,128 48 I_need EXTOPEN_ON,BYTE ;AN000; extended open 49 I_need NAME1,BYTE ;AN000; 50 I_need NO_NAME_ID,BYTE ;AN000; 51 I_need Packet_Temp,WORD ;AN000; 52 I_need DOS34_FLAG,WORD ;AN000; 53 I_need SAVE_BX,WORD ;AN000; 54 I_need SAVE_CX,WORD 55 56 ; Inputs: 57 ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL 58 ; terminated) 59 ; [CURR_DIR_END] Points to end of Current dir part of string 60 ; ( = -1 if current dir not involved, else 61 ; Points to first char after last "/" of current dir part) 62 ; [THISCDS] Points to CDS being used 63 ; (Low word = -1 if NUL CDS (Net direct request)) 64 ; [THISSFT] Points to SFT to fill in if file created 65 ; (sf_mode field set so that FCB may be detected) 66 ; [SATTRIB] Is attribute of search, determines what files can be found 67 ; AX is Attribute to create 68 ; Function: 69 ; Try to create the specified file truncating an old one that exists 70 ; Outputs: 71 ; sf_ref_count is NOT altered 72 ; CARRY CLEAR 73 ; THISSFT filled in. 74 ; sf_mode = unchanged for FCB, sharing_compat + open_for_both 75 ; CARRY SET 76 ; AX is error code 77 ; error_path_not_found 78 ; Bad path (not in curr dir part if present) 79 ; error_bad_curr_dir 80 ; Bad path in current directory part of path 81 ; error_access_denied 82 ; Attempt to re-create read only file , or 83 ; create a second volume id or create a dir 84 ; error_sharing_violation 85 ; The sharing mode was correct but not allowed 86 ; generates an INT 24 87 ; DS preserved, others destroyed 88 89 procedure DOS_Create,NEAR 89 ****************** warning: proc DOS_Create... [-w+user] 90 DOSAssume CS,,"DOS_Create" 91 ASSUME ES:NOTHING 92 0 00002DB7 30E4 XOR AH,AH ; Truncate is OK 94 Create_inter: 0 00002DB9 A880 TEST AL,~ (attr_all + attr_ignore + attr_volume_id) 96 ; Mask out any meaningless bits 0 00002DBB 7512 JNZ AttErr 0 00002DBD A808 TEST AL,attr_volume_id 0 00002DBF 7408 JZ NoReset 0 00002DC1 810E[0000]8000 OR word [DOS34_FLAG],DBCS_VOLID ;AN000;FOR dbcs volid 0 00002DC7 B008 MOV AL,attr_volume_id 102 NoReset: 0 00002DC9 0C20 OR AL,attr_archive ; File changed 0 00002DCB A850 TEST AL,attr_directory + attr_device 0 00002DCD 740A JZ ATT_OK 106 AttErr: 0 00002DCF B80500 MOV AX,5 ; Attribute problem 108 Exterr_Locus equ ExtErr_locus ; NASM port label 0 00002DD2 C606[0000]01 MOV byte [Exterr_Locus],errLOC_Unk 0 00002DD7 EB5D JMP SHORT SET_MKND_ERR ; Gotta use MKDIR to make dirs, NEVER allow 111 ; attr_device to be set. 112 ATT_OK: 0 00002DD9 C43E[0000] LES DI,[THISSFT] 0 00002DDD 06 PUSH ES 0 00002DDE C436[0000] LES SI,[THISCDS] 0 00002DE2 83FEFF CMP SI,-1 0 00002DE5 7513 JNZ TEST_RE_NET 0 00002DE7 07 POP ES 119 120 ;Extended open hooks 0 00002DE8 F606[0000]01 TEST byte [EXTOPEN_ON],ext_open_on ;AN000;EO. from extnded open 0 00002DED 7403 JZ NOEXTOP ;AN000;EO. no, do normal 123 IFS_extopen: 0 00002DEF E9[0000] jmp IFS_extopen_shared 125 NOEXTOP: ;AN000; 126 ;Extended open hooks 127 128 %IFN Installed 129 transfer NET_SEQ_CREATE 130 %ELSE 0 00002DF2 50 PUSH AX 132 multNET equ MultNET ; NASM port equate 0 00002DF3 B81811 MOV AX,(multNET << 8) | 24 0 00002DF6 CD2F INT 2FH 0 00002DF8 5B POP BX ; BX is trashed anyway 0 00002DF9 C3 return 137 %ENDIF 138 139 TEST_RE_NET: 0 00002DFA 26F744430080 TEST word [ES:SI + curdir_flags],curdir_isnet 0 00002E00 07 POP ES 0 00002E01 7419 JZ LOCAL_CREATE 143 0 00002E03 E8B700 CALL Set_EXT_mode ;AN000;EO. 0 00002E06 7205 JC SHORT dochk ;AN000;EO. 0 00002E08 26834D0202 OR word [ES:DI + sf_mode],sharing_compat + open_for_both ;IFS. 147 dochk: 148 ; invoke IFS_SHARE_CHECK ;AN000;IFS. check share 149 ; JC nomore ;AN000;IFS. share violation 150 151 ;Extended open hooks 0 00002E0D F606[0000]01 TEST byte [EXTOPEN_ON],ext_open_on ;AN000;EO. from extnded open 0 00002E12 75DB JNZ IFS_extopen ;AN000;EO. yes, issue extended open 154 ;Extended open hooks 155 156 %IFN Installed 157 transfer NET_CREATE 158 %ELSE 0 00002E14 50 PUSH AX 0 00002E15 B81711 MOV AX,(multNET << 8) | 23 0 00002E18 CD2F INT 2FH 0 00002E1A 5B POP BX ; BX is trashed anyway 163 nomore: 0 00002E1B C3 return 165 %ENDIF 166 167 LOCAL_CREATE: 0 00002E1C E89E00 CALL Set_EXT_mode ;AN000;EO. set mode if from extended open 0 00002E1F 7205 JC setdone ;AN000;EO. 0 00002E21 26834D0202 OR word [ES:DI + sf_mode],sharing_compat+open_for_both 171 setdone: 0 00002E26 E8[0000] EnterCrit critDisk 0 00002E29 E8[0000] invoke MakeNode 0 00002E2C 730F JNC Create_ok 0 00002E2E C606[0000]FF mov byte [VOLCHNG_FLAG],-1 ; indicate no change in volume label 0 00002E33 E8[0000] LeaveCrit critDisk 177 178 entry SET_MKND_ERR 179 DOSAssume CS,,"Set_MkNd_Err" 180 ASSUME ES:NOTHING 181 ; Looks up MakeNode errors and converts them. AL is MakeNode 182 ; error, SI is GetPath bad spot return if path_not_found error. 183 0 00002E36 BB[0000] MOV BX,OFFSET CRTERRTAB 0 00002E39 2ED7 cs xlatb 186 CreatBadRet: 0 00002E3B F9 STC 0 00002E3C C3 return 189 === Switch to base=008400h -> "DOSCODETABLE" 190 section DOSCODETABLE 191 Public CREAT001S,CREAT001E 192 CREAT001S label byte 193 CRTERRTAB LABEL BYTE ; Lookup table for MakeNode returns 0 00000466 ?? DB ? ; none 0 00000467 05 DB error_access_denied ; MakeNode error 1 0 00000468 52 DB error_cannot_make ; MakeNode error 2 0 00000469 50 DB error_file_exists ; MakeNode error 3 0 0000046A 03 DB error_path_not_found ; MakeNode error 4 0 0000046B 05 DB error_access_denied ; MakeNode error 5 0 0000046C 20 DB error_sharing_violation ; MakeNode error 6 0 0000046D 02 DB error_file_not_found ; MakeNode error 7 202 CREAT001E label byte === Switch to base=008400h -> "DOSCODECODE" 203 section DOSCODECODE 204 205 ; 206 ; We have just created a new file. This results in the truncation of old 207 ; files. We must inform the sharer to slash all the open SFT's for this 208 ; file to the current size. 209 ; 210 Create_ok: 211 ; If we created a volume id on the diskette, set the VOLCHNG_FLAG to logical 212 ; drive number to force a Build BPB after Media Check. 213 214 ;;; FASTOPEN 8/29/86 0 00002E3D E8[0000] invoke FastOpen_Delete 216 ;;; FASTOPEN 8/29/86 0 00002E40 A0[0000] mov al,[SATTRIB] 0 00002E43 A808 test al,attr_volume_id 0 00002E45 741C jz NoVolLabel 0 00002E47 C43E[0000] LES DI,[THISCDS] 0 00002E4B 268A25 mov ah,byte ptr [ES:DI] ; get drive letter 0 00002E4E 80EC41 sub ah,'A' ; convert to drive letter 0 00002E51 8826[0000] mov [VOLCHNG_FLAG],ah ;Set flag to indicate volid change 0 00002E55 B701 MOV BH,1 ;AN000;>32mb set volume id to boot record 0 00002E57 E81F00 CALL $Set_Media_ID ;AN000;>32mb 226 0 00002E5A E8[0000] EnterCrit CritDisk 0 00002E5D E8[0000] invoke FatRead_CDS ; force a media check 0 00002E60 E8[0000] LeaveCrit CritDisk 230 NoVolLabel: 0 00002E63 B80200 MOV ax,2 232 ThisSFT equ THISSFT ; NASM port label 0 00002E66 C43E[0000] LES DI,[ThisSFT] 234 %if installed 0 00002E6A FF1E[3800] call far [JShare + 14 * 4] 236 %else 237 Call ShSU 238 %endif 0 00002E6E E8[0000] LeaveCrit critDisk 0 00002E71 E9[0000] transfer SET_SFT_MODE 241 242 EndProc DOS_Create 243 244 ; Inputs: 245 ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL 246 ; terminated) 247 ; [CURR_DIR_END] Points to end of Current dir part of string 248 ; ( = -1 if current dir not involved, else 249 ; Points to first char after last "/" of current dir part) 250 ; [THISCDS] Points to CDS being used 251 ; (Low word = -1 if NUL CDS (Net direct request)) 252 ; [THISSFT] Points to SFT to fill in if file created 253 ; (sf_mode field set so that FCB may be detected) 254 ; [SATTRIB] Is attribute of search, determines what files can be found 255 ; AX is Attribute to create 256 ; Function: 257 ; Try to create the specified file truncating an old one that exists 258 ; Outputs: 259 ; sf_ref_count is NOT altered 260 ; CARRY CLEAR 261 ; THISSFT filled in. 262 ; sf_mode = sharing_compat + open_for_both for Non-FCB SFT 263 ; CARRY SET 264 ; AX is error code 265 ; error_path_not_found 266 ; Bad path (not in curr dir part if present) 267 ; error_bad_curr_dir 268 ; Bad path in current directory part of path 269 ; error_access_denied 270 ; Create a second volume id or create a dir 271 ; error_file_exists 272 ; Already a file by this name 273 ; DS preserved, others destroyed 274 275 procedure DOS_Create_New,NEAR 275 ****************** warning: proc DOS_Create_New... [-w+user] 276 DOSAssume CS,,"DOS_Create_New" 277 ASSUME ES:NOTHING 278 0 00002E74 B401 MOV AH,1 ; Truncate is NOT OK 0 00002E76 E940FF JMP Create_inter 281 282 EndProc DOS_Create_New 283 284 285 ; Inputs: 286 ; NAME1= Volume ID 287 ; BH= 0, delete volume id 288 ; 1, set new volume id 289 ; DS= DOSGROUP 290 ; Function: 291 ; Set Volume ID to DOS 4.00 Boot record. 292 ; Outputs: 293 ; CARRY CLEAR 294 ; volume id set 295 ; CARRY SET 296 ; AX is error code 297 298 procedure $Set_Media_ID,NEAR ;AN000; 298 ****************** warning: proc $Set_Media_ID... [-w+user] 299 DOSAssume CS,,"DOS_Create_New" ;AN000; 300 ASSUME ES:NOTHING ;AN000; 301 0 00002E79 50 PUSH AX ;AN000;;>32mb 0 00002E7A 06 PUSH ES ;AN000;;>32mb 0 00002E7B 57 PUSH DI ;AN000;;>32mb 305 0 00002E7C FEC4 INC AH ;AN000;;>32mb bl=drive # 0 00002E7E 88E3 MOV BL,AH ;AN000;;>32mb bl=drive # (A=1,B=2,,,) 0 00002E80 B00D MOV AL,0DH ;AN000;;>32mb generic IOCTL 0 00002E82 B96608 MOV CX,0866H ;AN001;;>32mb get media id 310 PACKET_TEMP equ Packet_Temp ; NASM port label 0 00002E85 BA[0000] MOV DX,OFFSET PACKET_TEMP wrt DOSGROUP ;AN000;>32mb 312 0 00002E88 53 PUSH BX ;AN000;;>32mb 0 00002E89 52 PUSH DX ;AN000;;>32mb 0 00002E8A 30FF XOR BH,BH ;AN000;;>32mb 316 0 00002E8C E8[0000] invoke D_IOCTL ;AN000;;>32mb 0 00002E8F 5A POP DX ;AN000;;>32mb 0 00002E90 5B POP BX ;AN000;;>32mb 0 00002E91 7224 JC geterr ;AN000;;>32mb 321 0 00002E93 08FF OR BH,BH ;AN000;;>32mb delete volume id 323 NoName equ Noname ; NASM port label 0 00002E95 7405 JZ NoName ;AN000;>32mb yes 0 00002E97 BE[0000] MOV SI,OFFSET NAME1 wrt DOSGROUP ;AN000;>32mb 0 00002E9A EB03 JMP SHORT doset ;AN000;>32mb yes 327 Noname: ;AN000; 0 00002E9C BE[0000] MOV SI,OFFSET NO_NAME_ID wrt DOSGROUP ;AN000;>32mb 329 doset: ;AN000; 0 00002E9F 89D7 MOV DI,DX ;AN000;;>32mb 331 MEDIA_LABEL equ MEDIA_Label ; NASM port equate 0 00002EA1 83C706 ADD DI,MEDIA_LABEL ;AN000;;>32mb 0 00002EA4 16 PUSH ss ;AN000;;>32mb move new volume id to packet 0 00002EA5 1F POP DS ;AN000;;>32mb 0 00002EA6 16 PUSH ss ;AN000;;>32mb 0 00002EA7 07 POP ES ;AN000;;>32mb 0 00002EA8 B90B00 MOV CX,11 ;AN000;;>32mb 0 00002EAB F3A4 REP MOVSB ;AN000;;>32mb 0 00002EAD B94608 MOV CX,0846H ;AN001;;>32mb 0 00002EB0 B00D MOV AL,0DH ;AN000;;>32mb 0 00002EB2 30FF XOR BH,BH ;AN000;;>32mb 0 00002EB4 E8[0000] invoke D_IOCTL ;AN000;;>32mb set volume id 343 geterr: ;AN000; 0 00002EB7 16 PUSH ss ;AN000;>32mb 0 00002EB8 1F POP DS ;AN000;>32mb ds= dosgroup 346 0 00002EB9 5F POP DI ;AN000;;>32mb 0 00002EBA 07 POP ES ;AN000;;>32mb 0 00002EBB 58 POP AX ;AN000;;>32mb 0 00002EBC C3 return ;AN000;>32mb 351 352 EndProc $Set_Media_ID ;AN000; 353 354 355 ; Inputs: 356 ; [EXTOPEN_ON]= flag for extende open 357 ; SAVE_BX= mode specified in Extended Open 358 ; Function: 359 ; Set mode in ThisSFT 360 ; Outputs: 361 ; carry set,mode is set if from Extended Open 362 ; carry clear, mode not set yet 363 364 %IFN IBMCOPYRIGHT 365 public Set_EXT_mode 366 %ENDIF 367 368 procedure Set_EXT_mode,NEAR ;AN000; 368 ****************** warning: proc Set_EXT_mode... [-w+user] 369 ASSUME ES:NOTHING,DS:NOTHING ;AN000; 370 0 00002EBD 36F606[0000]01 TEST byte [ss:EXTOPEN_ON],ext_open_on ;AN000;EO. from extnded open 0 00002EC3 740B JZ NOTEX ;AN000;EO. no, do normal 0 00002EC5 50 PUSH AX ;AN000;EO. 0 00002EC6 36A1[0000] MOV AX,[ss:SAVE_BX] ;AN000;EO. 0 00002ECA 26094502 OR [ES:DI + sf_mode],AX ;AN000;EO. 0 00002ECE 58 POP AX ;AN000;EO. 0 00002ECF F9 STC ;AN000;EO. 378 NOTEX: ;AN000; 0 00002ED0 C3 return ;AN000;EO. 380 381 EndProc Set_EXT_mode ;AN000; 382 383 END 384 385 === Trace listing source: ../DOS/open.lst 1 ; SCCSID = @(#)open.asm 1.1 85/04/10 2 ;TITLE DOS_OPEN - Internal OPEN call for MS-DOS 3 ;NAME DOS_OPEN 4 ; Low level routines for openning a file from a file spec. 5 ; Also misc routines for sharing errors 6 ; 7 ; DOS_Open 8 ; Check_Access_AX 9 ; SHARE_ERROR 10 ; SET_SFT_MODE 11 ; Code_Page_Mismatched_Error ; DOS 4.00 12 ; 13 ; Revision history: 14 ; 15 ; Created: ARR 30 March 1983 16 ; A000 version 4.00 Jan. 1988 17 ; 18 19 ; 20 ; get the appropriate segment definitions 21 ; 22 [list -] === Switch to base=008400h -> "DOSCODECODE" 27 section DOSCODECODE 28 [list -] 28 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 28 ****************** warning: out: BPB.INC... [-w+user] 28 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 28 ****************** warning: out: DEVSYM.INC... [-w+user] 38 39 %iassign Installed TRUE 40 41 i_need NoSetDir,BYTE 42 i_need THISSFT,DWORD 43 i_need THISCDS,DWORD 44 i_need CURBUF,DWORD 45 i_need CurrentPDB,WORD 46 i_need CURR_DIR_END,WORD 47 I_need RetryCount,WORD 48 I_need Open_Access,BYTE 49 I_need fSharing,BYTE 50 i_need JShare,DWORD 51 I_need FastOpenFlg,byte 52 I_need EXTOPEN_ON,BYTE ;AN000;; DOS 4.00 53 I_need ALLOWED,BYTE ;AN000;; DOS 4.00 54 I_need EXTERR,WORD ;AN000;; DOS 4.00 55 I_need EXTERR_LOCUS,BYTE ;AN000;; DOS 4.00 56 I_need EXTERR_ACTION,BYTE ;AN000;; DOS 4.00 57 I_need EXTERR_CLASS,BYTE ;AN000;; DOS 4.00 58 I_need CPSWFLAG,BYTE ;AN000;; DOS 4.00 59 I_need EXITHOLD,DWORD ;AN000;; DOS 4.00 60 I_need THISDPB,DWORD ;AN000;; DOS 4.00 61 I_need SAVE_CX,WORD ;AN000;; DOS 4.00 62 63 Break 64 65 ; Inputs: 66 ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL 67 ; terminated) 68 ; [CURR_DIR_END] Points to end of Current dir part of string 69 ; ( = -1 if current dir not involved, else 70 ; Points to first char after last "/" of current dir part) 71 ; [THISCDS] Points to CDS being used 72 ; (Low word = -1 if NUL CDS (Net direct request)) 73 ; [THISSFT] Points to SFT to fill in if file found 74 ; (sf_mode field set so that FCB may be detected) 75 ; [SATTRIB] Is attribute of search, determines what files can be found 76 ; AX is Access and Sharing mode 77 ; High NIBBLE of AL (Sharing Mode) 78 ; sharing_compat file is opened in compatibility mode 79 ; sharing_deny_none file is opened Multi reader, Multi writer 80 ; sharing_deny_read file is opened Only reader, Multi writer 81 ; sharing_deny_write file is opened Multi reader, Only writer 82 ; sharing_deny_both file is opened Only reader, Only writer 83 ; Low NIBBLE of AL (Access Mode) 84 ; open_for_read file is opened for reading 85 ; open_for_write file is opened for writing 86 ; open_for_both file is opened for both reading and writing. 87 ; 88 ; For FCB SFTs AL should = sharing_compat + open_for_both 89 ; (not checked) 90 ; Function: 91 ; Try to open the specified file 92 ; Outputs: 93 ; sf_ref_count is NOT altered 94 ; CARRY CLEAR 95 ; THISSFT filled in. 96 ; CARRY SET 97 ; AX is error code 98 ; error_file_not_found 99 ; Last element of path not found 100 ; error_path_not_found 101 ; Bad path (not in curr dir part if present) 102 ; error_bad_curr_dir 103 ; Bad path in current directory part of path 104 ; error_invalid_access 105 ; Bad sharing mode or bad access mode or bad combination 106 ; error_access_denied 107 ; Attempt to open read only file for writting, or 108 ; open a directory 109 ; error_sharing_violation 110 ; The sharing mode was correct but not allowed 111 ; generates an INT 24 on compatibility mode SFTs 112 ; DS preserved, others destroyed 113 114 procedure DOS_Open,NEAR 114 ****************** warning: proc DOS_Open... [-w+user] 115 DOSAssume CS,,"DOS_Open" 116 ASSUME ES:NOTHING 117 0 00002ED1 C606[0000]00 MOV byte [NoSetDir],0 0 00002ED6 E86201 CALL Check_Access_AX 0 00002ED9 7301C3 retc 0 00002EDC C43E[0000] LES DI,[THISSFT] 0 00002EE0 30E4 XOR AH,AH 123 ; sleaze! move only access/sharing mode in. Leave sf_isFCB unchanged 0 00002EE2 26884502 MOV BYTE PTR [ES:DI + sf_mode],AL ; For moment do this on FCBs too 0 00002EE6 06 PUSH ES 0 00002EE7 C436[0000] LES SI,[THISCDS] 0 00002EEB 83FEFF CMP SI,-1 0 00002EEE 752C JNZ TEST_RE_NET 0 00002EF0 07 POP ES 130 ;Extended open hooks 131 0 00002EF1 F606[0000]01 TEST byte [EXTOPEN_ON],ext_open_on ;FT. from extnded open ;AN000; 0 00002EF6 741C JZ NOEXTOP ;FT. no, do normal ;AN000; 134 IFS_extopen: ;AN000; 135 136 public IFS_extopen_shared 137 IFS_extopen_shared: 0 00002EF8 A0[0000] MOV AL,byte ptr [SAVE_CX] ;FT. al= create attribute ;AN000; 0 00002EFB 50 PUSH AX ;FT. pass create attr to IFS ;AN000; 140 multNET equ MultNET ; NASM port equate 0 00002EFC B82E11 MOV AX,(multNET << 8) | 46 ;FT. issue extended open verb ;AN000; 0 00002EFF CD2F INT 2FH ;FT. ;AN000; 0 00002F01 5B POP BX ;FT. trash bx ;AN000; 0 00002F02 C606[0000]00 MOV byte [EXTOPEN_ON],0 ;FT. ;AN000; 0 00002F07 720A jc @F 0 00002F09 1E push ds 0 00002F0A 56 push si 0 00002F0B E8[0000] invoke get_user_stack 0 00002F0E 894C04 mov [SI + user_CX], cx 0 00002F11 5E pop si 0 00002F12 1F pop ds 152 ; ecm: this is a no-op 153 ; jmp update_size ;IFS. file may be opened ;AN000; 154 @@: 0 00002F13 C3 return ;FT. ;AN000; 156 NOEXTOP: 157 ;Extended open hooks 158 159 160 %IFN Installed 161 transfer NET_SEQ_OPEN 162 %ELSE 0 00002F14 50 PUSH AX 0 00002F15 B81611 MOV AX,(multNET << 8) | 22 0 00002F18 CD2F INT 2FH 0 00002F1A 5B POP BX ; clean stack 0 00002F1B C3 return 168 %ENDIF 169 170 TEST_RE_NET: 0 00002F1C 26F744430080 TEST word [ES:SI + curdir_flags],curdir_isnet 0 00002F22 07 POP ES 0 00002F23 740F JZ LOCAL_OPEN 174 ; CALL IFS_SHARE_CHECK ;IFS. check IFS share,may create share ;AN000; 175 ; JC nomore ;IFS. share violation ;AN000; 176 ;Extended open hooks 177 0 00002F25 F606[0000]01 TEST byte [EXTOPEN_ON],ext_open_on ;FT. from extnded open ;AN000; 0 00002F2A 75CC JNZ IFS_extopen ;FT. isuue extended open ;AN000; 180 ;Extended open hooks 181 182 %IFN Installed 183 transfer NET_OPEN 184 %ELSE 0 00002F2C 50 PUSH AX 0 00002F2D B81611 MOV AX,(multNET << 8) | 22 0 00002F30 CD2F INT 2FH 0 00002F32 5B POP BX ; clean stack 189 ; JC nomore ;IFS. error ;AN000; 190 update_size: ;AN000; 191 ; CALL OWN_SHARE ;IFS. IFS owns share ? ;AN000; 192 ; JZ nomore2 ;IFS. yes ;AN000; 193 ; MOV AX,3 ;IFS. update file size for all SFT ;AN000; 194 ; LES DI,ThisSFT ;IFS. ;AN000; 195 ; call JShare + 14 * 4 ;IFS. call ShSu ;AN000; 196 nomore2: 197 ; CLC 198 nomore: 0 00002F33 C3 return 200 %ENDIF 201 202 LOCAL_OPEN: 0 00002F34 E8[0000] EnterCrit critDisk 204 205 ; DOS 3.3 FastOPen 6/16/86 206 0 00002F37 800E[0000]05 OR byte [FastOpenFlg],FastOpen_Set+Special_Fill_Set ; only open can 0 00002F3C E8[0000] invoke GetPath 209 210 211 ; DOS 3.3 FastOPen 6/16/86 212 0 00002F3F 7320 JNC Open_found 0 00002F41 7514 JNZ bad_path 0 00002F43 08C9 OR CL,CL 0 00002F45 7410 JZ bad_path 217 OpenFNF: 0 00002F47 B80200 MOV AX,error_file_not_found 219 OpenBadRet: 0 00002F4A 368026[0000]80 AND BYTE PTR [ss:FastOpenFlg],Fast_yes ;; DOS 3.3 0 00002F50 F9 STC 0 00002F51 E8[0000] LeaveCrit critDisk 0 00002F54 E9A100 JMP Clear_FastOpen 224 225 bad_path: 0 00002F57 B80300 MOV AX,error_path_not_found 0 00002F5A EBEE JMP OpenBadRet 228 229 open_bad_access: 0 00002F5C B80500 MOV AX,error_access_denied 0 00002F5F EBE9 JMP OpenBadRet 232 233 Open_found: 234 Open_Bad_Access equ open_bad_access ; NASM port label 0 00002F61 74F9 JZ Open_Bad_Access ; test for directories 0 00002F63 08E4 OR AH,AH 0 00002F65 783F JS open_ok ; Devices don't have attributes 0 00002F67 8E06[0200] MOV ES,WORD PTR [CURBUF+2] ; get buffer location 0 00002F6B 268A470B MOV AL,[ES:BX + dir_attr] 0 00002F6F A808 TEST AL,attr_volume_id ; can't open volume ids 0 00002F71 75E9 JNZ open_bad_access 0 00002F73 A801 TEST AL,attr_read_only ; check write on read only 0 00002F75 742F JZ open_ok 244 ; 245 ; The file is marked READ-ONLY. We verify that the open mode allows access to 246 ; the read-only file. Unfortunately, with FCB's and net-FCB's we cannot 247 ; determine at the OPEN time if such access is allowed. Thus, we defer such 248 ; processing until the actual write operation: 249 ; 250 ; If FCB, then we change the mode to be read_only. 251 ; If net_FCB, then we change the mode to be read_only. 252 ; If not open for read then error. 253 ; 0 00002F77 1E56 SaveReg 0 00002F79 C536[0000] LDS SI,[THISSFT] 0 00002F7D 8B4C02 MOV CX,[SI + sf_mode] 257 sf_isFCB equ sf_isfcb ; NASM port equate 0 00002F80 F7C10080 TEST CX,sf_isFCB ; is it FCB? 0 00002F84 750A JNZ ResetAccess ; yes, reset the access 0 00002F86 88CA MOV DL,CL 0 00002F88 80E2F0 AND DL,sharing_mask 0 00002F8B 80FA70 CMP DL,sharing_net_FCB ; is it net FCB? 0 00002F8E 7508 JNZ NormalOpen ; no 264 ResetAccess: 0 00002F90 83E1F0 AND CX,~ access_mask ; clear access 266 errnz open_for_read 267 ; OR CX,open_for_read ; stick in open_for_read 0 00002F93 894C02 MOV [SI + sf_mode],CX 0 00002F96 EB0C JMP SHORT FillSFT 270 ; 271 ; The SFT is normal. See if the requested access is open_for_read 272 ; 273 NormalOpen: 0 00002F98 80E10F AND CL,access_mask ; remove extras 0 00002F9B 80F900 CMP CL,open_for_read ; is it open for read? 0 00002F9E 7404 JZ FillSFT 0 00002FA0 5E1F RestoreReg 0 00002FA2 EBB8 JMP short open_bad_access 279 ; 280 ; All done, restore registers and fill the SFT. 281 ; 282 FillSFT: 0 00002FA4 5E1F RestoreReg 284 open_ok: 285 ;;; File Tagging DOS 4.00 286 ; OR AH,AH ;FT. device ? ;AN000; 287 ; JS NORM0 ;FT. yes, don't do code page matching ;AN000; 288 ; CMP [CPSWFLAG],0 ;FT. code page matching on ;AN000; 289 ; JZ NORM0 ;FT. no ;AN000; 290 ; CMP [ES:BX].dir_CODEPG,0 ;FT. code page 0 ;AN000; 291 ; JZ NORM0 ;FT. yes do nothing ;AN000; 292 ; PUSH AX ;FT. ;AN000; 293 ; invoke Get_Global_CdPg ;FT. get global code page ;AN000; 294 ; CMP [ES:BX].dir_CODEPG,AX ;FT. equal to global code page ;AN000; 295 ; JZ NORM1 ;FT. yes ;AN000; 296 ; call Code_Page_Mismatched_Error ;FT. ;AN000; 297 ; CMP AL,0 ;FT. ignore ? ;AN000; 298 ; JZ NORM1 ;FT. ;AN000; 299 ; POP AX ;FT. ;AN000; 300 ; JMP open_bad_access ;FT. set carry and return ;AN000; 301 NORM1: ;AN000; 302 ; POP AX ;FT. ;AN000; 303 NORM0: 304 305 ;;; File Tagging DOS 4.00 0 00002FA6 E8[0000] invoke DOOPEN ; Fill in SFT 0 00002FA9 368026[0000]80 AND BYTE PTR [ss:FastOpenFlg],Fast_yes ;; DOS 3.3 0 00002FAF E86500 CALL DO_SHARE_CHECK ; 309 Share_Ok equ SHARE_OK ; NASM port label 0 00002FB2 7306 JNC Share_Ok 0 00002FB4 E8[0000] LeaveCrit critDisk 312 Clear_FastOPen equ Clear_FastOpen ; NASM port label 0 00002FB7 EB3F JMP Clear_FastOPen 0 00002FB9 90 nop ; identicalise 315 316 SHARE_OK: 0 00002FBA B80300 MOV AX,3 318 ThisSFT equ THISSFT ; NASM port label 0 00002FBD C43E[0000] LES DI,[ThisSFT] 320 %if installed 0 00002FC1 FF1E[3800] call far [JShare + 14 * 4] 322 %else 323 Call ShSU 324 %endif 325 ;; DOS 4.00 10/27/86 0 00002FC5 C43E[0000] LES DI,[ThisSFT] ; if this is a newly ;AN000; 0 00002FC9 26837D0B00 CMP word [ES:DI + sf_firclus],0 ; created file then ;AN000; 0 00002FCE 740E JZ no_fastseek ; do nothing ;AN000; 0 00002FD0 268B4D0B MOV CX,[ES:DI + sf_firclus] ; first cluster # ;AN000; 0 00002FD4 26C47D07 LES DI,[ES:DI + sf_devptr] ; pointer to DPB ;AN000; 0 00002FD8 268A15 MOV DL,[ES:DI + dpb_drive] ; drive # ;AN000; 0 00002FDB E8[0000] invoke FastSeek_Open ; call fastseek ;AN000; 333 no_fastseek: 334 335 ;; DOS 4.00 10/27/86 336 0 00002FDE E8[0000] LeaveCrit critDisk 338 339 ; 340 ; Finish SFT initialization for new reference. Set the correct mode. 341 ; 342 ; Inputs: 343 ; ThisSFT points to SFT 344 ; 345 ; Outputs: 346 ; Carry clear 347 ; Registers modified: AX. 348 349 entry SET_SFT_MODE 350 DOSAssume CS,,"Set_SFT_Mode" 351 ASSUME ES:NOTHING 352 0 00002FE1 C43E[0000] LES DI,[ThisSFT] 0 00002FE5 E8[0000] invoke DEV_OPEN_SFT 0 00002FE8 26F745020080 TEST word [ES:DI + sf_mode],sf_isfcb; Clears carry 0 00002FEE 7501C3 retz ; sf_mode correct 0 00002FF1 A1[0000] MOV AX,[CurrentPDB] 0 00002FF4 26894531 MOV [ES:DI + sf_PID],AX ; For FCB sf_PID=PID 359 360 Clear_FastOpen: 0 00002FF8 C3 return ;;;;; DOS 3.3 362 363 EndProc DOS_Open 363 ****************** warning: ***** Possible stack size error in DOS_Open ***** [-w+user] 364 365 ; Called on sharing violations. ES:DI points to SFT. AX has error code 366 ; If SFT is FCB or compatibility mode gens INT 24 error. 367 ; Returns carry set AX=error_sharing_violation if user says ignore (can't 368 ; really ignore). Carry clear 369 ; if user wants a retry. ES, DI, DS preserved 370 371 procedure SHARE_ERROR,NEAR 371 ****************** warning: proc SHARE_ERROR... [-w+user] 372 DOSAssume CS,,"Share_Error" 373 ASSUME ES:NOTHING 0 00002FF9 26F745020080 TEST word [ES:DI + sf_mode],sf_isfcb 0 00002FFF 750C JNZ HARD_ERR 0 00003001 268A4D02 MOV CL,BYTE PTR [ES:DI + sf_mode] 0 00003005 80E1F0 AND CL,sharing_mask 0 00003008 80F900 CMP CL,sharing_compat 0 0000300B 7505 JNE NO_HARD_ERR 380 HARD_ERR: 0 0000300D E8[0000] invoke SHARE_VIOLATION 0 00003010 73E6 retnc ; User wants retry 383 NO_HARD_ERR: 0 00003012 B82000 MOV AX,error_sharing_violation 0 00003015 F9 STC 0 00003016 C3 return 387 388 EndProc SHARE_ERROR 389 390 391 ; Input: THISDPB, WFP_Start, THISSFT set 392 ; Functions: check file sharing mode is valid 393 ; Output: carry set, error 394 ; carry clear, share ok 395 396 procedure DO_SHARE_CHECK,NEAR 396 ****************** warning: proc DO_SHARE_CHECK... [-w+user] 397 DOSAssume CS,,"DO_SHARE__CHECK" 398 ASSUME ES:NOTHING 0 00003017 E8[0000] EnterCrit critDisk ; enter critical section 400 401 OPN_RETRY: 0 0000301A 8B0E[0000] MOV CX,[RetryCount] ; Get # tries to do 403 OpenShareRetry: 0 0000301E 51 SaveReg ; Save number left to do 0 0000301F E8[0000] invoke SHARE_CHECK ; Final Check 0 00003022 59 RestoreReg ; CX = # left 0 00003023 730E JNC Share_Ok2 ; No problem with access 0 00003025 E8[0000] Invoke Idle 0 00003028 E2F4 LOOP OpenShareRetry ; One more retry used up 410 OpenShareFail: 411 ThisSft equ THISSFT ; NASM port label 0 0000302A C43E[0000] LES DI,[ThisSft] 0 0000302E E8C8FF invoke SHARE_ERROR 0 00003031 73E7 JNC OPN_RETRY ; User wants more retry 415 Share_Ok2: 0 00003033 E8[0000] LeaveCrit critDisk ; leave critical section 0 00003036 C3 return 418 419 EndProc DO_SHARE_CHECK 420 421 422 ; Input: ES:DI -> SFT 423 ; Functions: check if IFS owns SHARE 424 ; Output: Zero set, use IFS SHARE 425 ; otherwise, use DOS SHARE 426 427 procedure OWN_SHARE,NEAR ;AN000; 427 ****************** warning: proc OWN_SHARE... [-w+user] 428 DOSAssume CS,,"OWN_SHARE" ;AN000; 429 ASSUME ES:NOTHING ;AN000; 430 431 ; PUSH DS ;IFS. save reg ;AN000; 432 ; PUSH SI ;IFS. save reg ;AN000; 433 ; LDS SI,[ES:DI.sf_IFS_HDR] ;IFS. ds:si-> IFS header ;AN000; 434 ; TEST [SI.IFS_ATTRIBUTE],IFSUSESHARE ;IFS. save reg ;AN000; 435 ; POP SI ;IFS. retore reg ;AN000; 436 ; POP DS ;IFS. restore reg ;AN000; 0 00003037 C3 return ;IFS. return ;AN000; 438 439 EndProc OWN_SHARE ;AN000; 440 441 442 ; Input: THISCDS -> CDS 443 ; Functions: check if IFS owns SHARE 444 ; Output: Zero set, use IFS SHARE 445 ; otherwise, use DOS SHARE 446 447 procedure OWN_SHARE2,NEAR ;AN000; 447 ****************** warning: proc OWN_SHARE2... [-w+user] 448 DOSAssume CS,,"OWN_SHARE2" ;AN000; 449 ASSUME ES:NOTHING ;AN000; 450 451 ; CMP WORD PTR [THISCDS],-1 ;IFS. UNC ? ;AN000; 452 ; JZ ifs_hasit ;IFS. yes ;AN000; 453 ; PUSH DS ;IFS. save reg ;AN000; 454 ; PUSH SI ;IFS. save reg ;AN000; 455 ; LDS SI,[THISCDS] ;IFS. DS:SI -> ThisCDS ;AN000; 456 ; LDS SI,[SI.curdir_IFS_HDR] ;IFS. ds:si-> IFS header ;AN000; 457 ; TEST [SI.IFS_ATTRIBUTE],IFSUSESHARE ;IFS. ;AN000; 458 ; POP SI ;IFS. retore reg ;AN000; 459 ; POP DS ;IFS. restore reg ;AN000; 460 ifs_hasit: ;AN000; 0 00003038 C3 return ;IFS. return ;AN000; 462 463 EndProc OWN_SHARE2 ;AN000; 464 465 466 ; Input: ES:DI -> SFT 467 ; Functions: set THISDPB 468 ; Output: none 469 470 procedure SET_THISDPB,NEAR ;AN000; 470 ****************** warning: proc SET_THISDPB... [-w+user] 471 DOSAssume CS,,"SET_THISDPB" ;AN000; 472 ASSUME ES:NOTHING ;AN000; 473 474 ; PUSH DS ;IFS. save reg ;AN000; 475 ; PUSH SI ;IFS. save reg ;AN000; 476 ; LDS SI,[THISCDS] ;IFS. ds:si-> CDS ;AN000; 477 ; LDS SI,[SI.CURDIR_DEVPTR] ;IFS. ds:si-> DPB ;AN000; 478 ; MOV WORD PTR [THISDPB],SI ;IFS. set THISDPB ;AN000; 479 ; MOV WORD PTR [THISDPB+2],DS ;IFS. ;AN000; 480 ; POP SI ;IFS. retore reg ;AN000; 481 ; POP DS ;IFS. restore reg ;AN000; 0 00003039 C3 return ;IFS. return ;AN000; 483 484 EndProc SET_THISDPB ;AN000; 485 486 487 ; Input: ES:DI -> SFT 488 ; Functions: check IFS share 489 ; Output: none 490 491 procedure IFS_SHARE_CHECK,NEAR ;AN000; 491 ****************** warning: proc IFS_SHARE_CHECK... [-w+user] 492 DOSAssume CS,,"IFS_SHARE_CHECK" ;AN000; 493 ASSUME ES:NOTHING ;AN000; 494 495 496 ; CALL OWN_SHARE ;IFS. IFS owns share ;AN000; 497 ; JZ IFSSHARE ;IFS. yes ;AN000; 498 ; PUSH AX ;IFS. save mode ;AN000; 499 ; CALL SET_THISDPB ;IFS. set THISDPB for SHARE_VIOLATION ;AN000; 500 ; CALL DO_SHARE_CHECK ;IFS. check share ;AN000; 501 ; POP AX ;IFS. restore mode and share ok ;AN000; 502 IFSSHARE: ;AN000; 0 0000303A C3 return ;IFS. return ;AN000; 504 505 EndProc IFS_SHARE_CHECK ;AN000; 506 507 ; Inputs: 508 ; AX is mode 509 ; High NIBBLE of AL (Sharing Mode) 510 ; sharing_compat file is opened in compatibility mode 511 ; sharing_deny_none file is opened Multi reader, Multi writer 512 ; sharing_deny_read file is opened Only reader, Multi writer 513 ; sharing_deny_write file is opened Multi reader, Only writer 514 ; sharing_deny_both file is opened Only reader, Only writer 515 ; Low NIBBLE of AL (Access Mode) 516 ; open_for_read file is opened for reading 517 ; open_for_write file is opened for writing 518 ; open_for_both file is opened for both reading and writing. 519 ; Function: 520 ; Check this access mode for correctness 521 ; Outputs: 522 ; [open_access] = AL input 523 ; Carry Clear 524 ; Mode is correct 525 ; AX unchanged 526 ; Carry Set 527 ; Mode is bad 528 ; AX = error_invalid_access 529 ; No other registers effected 530 531 procedure Check_Access_AX 531 ****************** warning: proc Check_Access_AX... [-w+user] 532 DOSAssume CS,,"Check_Access" 533 ASSUME ES:NOTHING 534 0 0000303B A2[0000] MOV [Open_Access],AL 0 0000303E 53 PUSH BX 537 ; 538 ; If sharing, then test for special sharing mode for FCBs 539 ; 0 0000303F 88C3 MOV BL,AL 0 00003041 80E3F0 AND BL,sharing_mask 0 00003044 803E[0000]FF CMP byte [fSharing],-1 0 00003049 7505 JNZ CheckShareMode ; not through server call, must be ok 544 sharing_NET_FCB equ sharing_net_FCB ; NASM port equate 0 0000304B 80FB70 CMP BL,sharing_NET_FCB 0 0000304E 7405 JZ CheckAccessMode ; yes, we have an FCB 547 CheckShareMode: 0 00003050 80FB40 CMP BL,40h ; is this a good sharing mode? 549 Make_Bad_Access equ make_bad_access ; NASM port label 0 00003053 770D JA Make_Bad_Access 551 CheckAccessMode: 0 00003055 88C3 MOV BL,AL 0 00003057 80E30F AND BL,access_mask 0 0000305A 80FB02 CMP BL,2 0 0000305D 7703 JA Make_Bad_Access 0 0000305F 5B POP BX 0 00003060 F8 CLC 0 00003061 C3 return 559 560 make_bad_access: 0 00003062 B80C00 MOV AX,error_invalid_access 0 00003065 5B POP BX 0 00003066 F9 STC 0 00003067 C3 return 565 566 EndProc Check_Access_AX 567 568 ; Input: none 569 ; Function: Issue Code Page Mismatched INT 24 Critical Error 570 ; OutPut: AL =0 ignore 571 ; =3 fail 572 573 procedure Code_Page_Mismatched_Error,NEAR ;AN000; 573 ****************** warning: proc Code_Page_Mismatched_Error... [-w+user] 574 DOSAssume CS,,"Code_Page_Mismatched_Error" ;AN000; 575 ASSUME ES:NOTHING ;AN000; 576 577 ; PUSH DS ;FT. ;AN000; 578 ; Context DS ;FT. ds=cs ;AN000; 579 ; MOV AH,0A9H ;FT. fail,ignore,device,write ;AN000; 580 ; MOV DI,error_I24_gen_failure ;FT. set error ;AN000; 581 ; MOV [EXTERR],error_Code_Page_Mismatched ;FT. ;AN000; 582 ; MOV [EXTERR_CLASS],errCLASS_NotFnd ;FT. ;AN000; 583 ; MOV [EXTERR_ACTION],errACT_Abort ;FT. ;AN000; 584 ; MOV [EXTERR_LOCUS],errLOC_Unk ;FT. ;AN000; 585 ; MOV word ptr [EXITHOLD + 2],ES ;FT. save es:bp ;AN000; 586 ; MOV word ptr [EXITHOLD],BP ;FT. ;AN000; 587 ; invoke NET_I24_ENTRY ;FT. issue int 24H ;AN000; 588 ; POP DS ;FT. ;AN000; 589 ; return ;FT. ;AN000; 590 591 EndProc Code_Page_Mismatched_Error ;AN000; 592 END === Trace listing source: ../DOS/dinfo.lst 1 ; SCCSID = @(#)dinfo.asm 1.1 85/04/10 2 ; SCCSID = @(#)dinfo.asm 1.1 85/04/10 3 ;TITLE DISK_INFO - Internal Get Disk Info 4 ;NAME DISK_INFO 5 ; Low level routine for returning disk drive information from a local 6 ; or NET device 7 ; 8 ; DISK_INFO 9 ; 10 ; Modification history: 11 ; 12 ; Created: ARR 30 March 1983 13 ; 14 15 ; 16 ; get the appropriate segment definitions 17 ; 18 [list -] === Switch to base=008400h -> "DOSCODECODE" 22 section DOSCODECODE 23 [list -] 23 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 23 ****************** warning: out: BPB.INC... [-w+user] 23 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 23 ****************** warning: out: DEVSYM.INC... [-w+user] 30 31 %iassign Installed TRUE 32 33 i_need THISCDS,DWORD 34 i_need CURBUF,DWORD 35 i_need EXTERR_LOCUS,BYTE 36 %if debug 37 I_need BugLev,WORD 38 I_need BugTyp,WORD 39 %include "bugtyp.nas" 40 %endif 41 42 Break 43 44 ; Inputs: 45 ; [THISCDS] Points to the Macro List Structure of interest 46 ; (It MAY NOT be NUL, error not detected) 47 ; Function: 48 ; Get Interesting Drive Information 49 ; Returns: 50 ; DX = Number of free allocation units 51 ; BX = Total Number of allocation units on disk 52 ; CX = Sector size 53 ; AL = Sectors per allocation unit 54 ; AH = FAT ID BYTE 55 ; Carry set if error (currently user FAILed to I 24) 56 ; Segs except ES preserved, others destroyed 57 58 procedure DISK_INFO,NEAR 58 ****************** warning: proc DISK_INFO... [-w+user] 59 DOSAssume CS,,"Disk_Info" 60 ASSUME ES:NOTHING 61 0 00003068 E8[0000] Invoke TestNet 0 0000306B 7306 JNC LOCAL_INFO 64 %IFN Installed 65 transfer NET_DISK_INFO 66 %ELSE 67 multNET equ MultNET ; NASM port equate 0 0000306D B80C11 MOV AX,(multNET << 8) | 12 0 00003070 CD2F INT 2FH 0 00003072 C3 return 71 %ENDIF 72 73 LOCAL_INFO: 0 00003073 C606[0000]02 MOV byte [EXTERR_LOCUS],errLOC_Disk 0 00003078 E8[0000] EnterCrit critDisk 0 0000307B E8[0000] invoke FATREAD_CDS ; perform media check. 0 0000307E 7241 JC CRIT_LEAVE 0 00003080 BB0200 MOV BX,2 0 00003083 E8[0000] invoke UNPACK ; Get first FAT sector into CURBUF 0 00003086 7239 JC CRIT_LEAVE 0 00003088 C536[0000] LDS SI,[CURBUF] 82 ASSUME DS:NOTHING 83 bufinsiz equ BUFINSIZ ; NASM port equate 0 0000308C 8A6410 MOV AH,[SI + bufinsiz] ; get FAT ID BYTE 0 0000308F 161F context DS 0 00003091 268B4E0D MOV CX,[ES:BP + dpb_max_cluster] 87 ; 88 ; Examine the current free count. If it indicates that we have an invalid 89 ; count, do the expensive calculation. 90 ; 0 00003095 268B561F MOV DX,[ES:BP + dpb_free_cnt] ; get free count 0 00003099 83FAFF CMP DX,-1 ; is it valid? 0 0000309C 7404 JZ DoScan 94 ; 95 ; Check to see if it is in a reasonalbe range. If so, trust it and return. 96 ; Otherwise, we need to blast out an internal error message and then recompute 97 ; the count. 98 ; 0 0000309E 39CA CMP DX,CX ; is it in a reasonable range? 0 000030A0 7223 JB GotVal ; yes, trust it. 101 fmt TypInt,LevLog,<"Internal error: MaxClus <= FreeClus\n"> 102 DoScan: 0 000030A2 31D2 XOR DX,DX 0 000030A4 49 DEC CX 105 SCANFREE: 0 000030A5 E8[0000] invoke UNPACK 107 Crit_Leave equ CRIT_LEAVE ; NASM port label 0 000030A8 7217 JC Crit_Leave 0 000030AA 7501 JNZ NOTFREECLUS 0 000030AC 42 INC DX ; A free one 111 NOTFREECLUS: 0 000030AD 43 INC BX ; Next cluster 0 000030AE E2F5 LOOP SCANFREE 0 000030B0 4B DEC BX ; BX was next cluster. Convert to 115 ReturnVals: 0 000030B1 4B DEC BX ; count 0 000030B2 268A4604 MOV AL,[ES:BP + dpb_cluster_mask] 0 000030B6 FEC0 INC AL ; Sectors/cluster 119 ; overflow to 0 if it is 256 0 000030B8 268B4E02 MOV CX,[ES:BP + dpb_sector_size] ; Bytes/sector 0 000030BC 2689561F MOV [ES:BP + dpb_free_cnt],DX 0 000030C0 F8 CLC 123 CRIT_LEAVE: 0 000030C1 E8[0000] LeaveCrit critDisk 0 000030C4 C3 return 126 ; 127 ; We have correctly computed everything previously. Load up registers for 128 ; return. 129 ; 0 000030C5 89CB GotVal: MOV BX,CX ; get cluster count 0 000030C7 EBE8 JMP ReturnVals 132 133 EndProc DISK_INFO 134 135 END === Trace listing source: ../DOS/isearch.lst 1 ; SCCSID = @(#)isearch.asm 1.1 85/04/10 2 ;TITLE DOS_SEARCH - Internal SEARCH calls for MS-DOS 3 ;NAME DOS_SEARCH 4 ; Low level routines for doing local and NET directory searches 5 ; 6 ; DOS_SEARCH_FIRST 7 ; DOS_SEARCH_NEXT 8 ; RENAME_NEXT 9 ; 10 ; Revision history: 11 ; 12 ; Created: ARR 30 March 1983 13 ; A000 version 4.00 Jan. 1988 14 ; A001 PTM 3564 -- serach for fastopen 15 16 ; 17 ; get the appropriate segment definitions 18 ; 19 [list -] === Switch to base=008400h -> "DOSCODECODE" 23 section DOSCODECODE 24 [list -] 24 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 24 ****************** warning: out: BPB.INC... [-w+user] 24 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 24 ****************** warning: out: DEVSYM.INC... [-w+user] 33 34 %iassign Installed TRUE 35 36 i_need NoSetDir,BYTE 37 i_need Creating,BYTE 38 i_need THISCDS,DWORD 39 i_need CURBUF,DWORD 40 i_need DMAADD,DWORD 41 i_need DummyCDS,128 42 i_need THISDPB,DWORD 43 i_need THISDRV,BYTE 44 i_need NAME1,BYTE 45 i_need ATTRIB,BYTE 46 i_need DIRSTART,WORD 47 i_need LASTENT,WORD 48 i_need FOUND_DEV,BYTE 49 I_need WFP_Start,WORD 50 i_need EXTERR_LOCUS,BYTE 51 i_need FastopenFlg,BYTE 52 I_need DOS34_FLAG,WORD 53 54 ; Inputs: 55 ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL 56 ; terminated) 57 ; [CURR_DIR_END] Points to end of Current dir part of string 58 ; ( = -1 if current dir not involved, else 59 ; Points to first char after last "/" of current dir part) 60 ; [THISCDS] Points to CDS being used 61 ; (Low word = -1 if NUL CDS (Net direct request)) 62 ; [SATTRIB] Is attribute of search, determines what files can be found 63 ; [DMAADD] Points to 53 byte buffer 64 ; Function: 65 ; Initiate a search for the given file spec 66 ; Outputs: 67 ; CARRY CLEAR 68 ; The 53 bytes ot DMAADD are filled in as follows: 69 ; 70 ; LOCAL 71 ; Drive Byte (A=1, B=2, ...) High bit clear 72 ; NEVER STORE DRIVE BYTE AFTER found_it 73 ; 11 byte search name with Meta chars in it 74 ; Search Attribute Byte, attribute of search 75 ; WORD LastEnt value 76 ; WORD DirStart 77 ; 4 byte pad 78 ; 32 bytes of the directory entry found 79 ; NET 80 ; 21 bytes First byte has high bit set 81 ; 32 bytes of the directory entry found 82 ; 83 ; CARRY SET 84 ; AX = error code 85 ; error_no_more_files 86 ; No match for this file 87 ; error_path_not_found 88 ; Bad path (not in curr dir part if present) 89 ; error_bad_curr_dir 90 ; Bad path in current directory part of path 91 ; DS preserved, others destroyed 92 93 procedure DOS_SEARCH_FIRST,NEAR 93 ****************** warning: proc DOS_SEARCH_FIRST... [-w+user] 94 DOSAssume CS,,"DOS_Search_First" 95 ASSUME ES:NOTHING 96 0 000030C9 C43E[0000] LES DI,[THISCDS] 0 000030CD 83FFFF CMP DI,-1 0 000030D0 7506 JNZ TEST_RE_NET 100 %IFN Installed 101 transfer NET_SEQ_SEARCH_FIRST 102 %ELSE 103 multNET equ MultNET ; NASM port equate 0 000030D2 B81911 MOV AX,(multNET << 8) | 25 0 000030D5 CD2F INT 2FH 0 000030D7 C3 return 107 %ENDIF 108 109 TEST_RE_NET: 0 000030D8 26F745430080 TEST word [ES:DI + curdir_flags],curdir_isnet 0 000030DE 7406 JZ LOCAL_SEARCH_FIRST 112 %IFN Installed 113 transfer NET_SEARCH_FIRST 114 %ELSE 0 000030E0 B81B11 MOV AX,(multNET << 8) | 27 0 000030E3 CD2F INT 2FH 0 000030E5 C3 return 118 %ENDIF 119 120 LOCAL_SEARCH_FIRST: 0 000030E6 E8[0000] EnterCrit critDisk 0 000030E9 F706[0000]0004 TEST word [DOS34_FLAG],SEARCH_FASTOPEN ;AN000; 0 000030EF 7405 JZ NOFN ;AN000; 124 FastOpenflg equ FastopenFlg ; NASM port label 125 Fastopen_Set equ FastOpen_Set ; NASM port equate 0 000030F1 800E[0000]01 OR byte [FastOpenflg],Fastopen_Set ;AN000; 127 NOFN: ;AN000; 0 000030F6 C606[0000]01 MOV byte [NoSetDir],1 ; if we find a dir, don't change to it 0 000030FB E84301 CALL CHECK_QUESTION ;AN000;;FO. is '?' in path 0 000030FE 7305 JNC norm_getpath ;AN000;;FO. no 0 00003100 8026[0000]80 AND byte [FastOpenflg],Fast_yes ;AN000;;FO. reset fastopen 132 norm_getpath: 0 00003105 E8[0000] invoke GetPath 134 getdone: 0 00003108 7319 JNC find_check_dev 0 0000310A 7512 JNZ bad_path 0 0000310C 08C9 OR CL,CL 0 0000310E 740E JZ bad_path 139 find_no_more: 0 00003110 B81200 MOV AX,error_no_more_files 141 BadBye: 0 00003113 368026[0000]80 AND byte [ss:FastOpenflg],Fast_yes ;AN000;;FO. reset fastopen 143 0 00003119 F9 STC 0 0000311A E8[0000] LeaveCrit critDisk 0 0000311D C3 return 147 148 bad_path: 0 0000311E B80300 MOV AX,error_path_not_found 0 00003121 EBF0 JMP BadBye 151 152 find_check_dev: 0 00003123 08E4 OR AH,AH 0 00003125 790A JNS found_entry 155 LastEnt equ LASTENT ; NASM port label 0 00003127 C706[0000]FFFF MOV word [LastEnt],-1 ; Cause DOS_SEARCH_NEXT to fail 157 Found_Dev equ FOUND_DEV ; NASM port label 0 0000312D FE06[0000] INC byte [Found_Dev] ; Tell DOS_RENAME we found a device 159 found_entry: 160 ; 161 ; We set the physical drive byte here Instead of after found_it; Doing 162 ; a search-next may not have wfp_start set correctly 163 ; 0 00003131 C43E[0000] LES DI,[DMAADD] 0 00003135 8B36[0000] MOV SI,[WFP_Start] ; get pointer to beginning 0 00003139 AC LODSB 0 0000313A 2C40 SUB AL,'A'-1 ; logical drive 0 0000313C AA STOSB ; High bit not set (local) 169 found_it: 0 0000313D C43E[0000] LES DI,[DMAADD] 0 00003141 47 INC DI 0 00003142 1E PUSH DS ;FO.;AN001; save ds 173 Fastopenflg equ FastopenFlg ; NASM port label 0 00003143 F606[0000]10 TEST byte [Fastopenflg],Set_For_Search ;FO.;AN001; from fastopen 0 00003148 7408 JZ notfast ;FO.;AN001; 0 0000314A 89DE MOV SI,BX ;FO.;AN001; 0 0000314C 8E1E[0200] MOV DS,WORD PTR [CURBUF+2] ;FO.;AN001; 0 00003150 EB03 JMP SHORT movmov ;FO.;AN001; 179 180 181 notfast: 0 00003152 BE[0000] MOV SI,OFFSET NAME1 wrt DOSGROUP; find_buf 2 = formatted name 183 movmov: 184 ; Special E5 code 0 00003155 A4 MOVSB 0 00003156 26807DFF05 CMP BYTE PTR [ES:DI-1],5 0 0000315B 7505 JNZ NOTKANJB 0 0000315D 26C645FFE5 MOV BYTE PTR [ES:DI-1],0E5H 189 NOTKANJB: 190 0 00003162 B90A00 MOV CX,10 0 00003165 F3A4 REP MOVSB 0 00003167 1F POP DS ;FO.;AN001; restore ds 194 195 196 Attrib equ ATTRIB ; NASM port label 0 00003168 A0[0000] MOV AL,[Attrib] 0 0000316B AA STOSB 0 0000316C 50 PUSH AX ; Save AH device info 0 0000316D A1[0000] MOV AX,[LastEnt] 0 00003170 AB STOSW 202 DirStart equ DIRSTART ; NASM port label 0 00003171 A1[0000] MOV AX,[DirStart] 0 00003174 AB STOSW 205 ; 4 bytes of 21 byte cont structure left for NET stuff 0 00003175 83C704 ADD DI,4 0 00003178 58 POP AX ; Recover AH device info 0 00003179 08E4 OR AH,AH 0 0000317B 781B JS DOSREL ; Device entry is DOSGROUP relative 0 0000317D 833E[0000]FF CMP WORD PTR [CURBUF],-1 0 00003182 7510 JNZ OKSTORE 212 FastOPenFlg equ FastopenFlg ; NASM port label 0 00003184 F606[0000]10 TEST byte [FastOPenFlg],Set_For_Search ;AN000;;FO. from fastopen and is good 0 00003189 7509 JNZ OKSTORE ;AN000;;FO. 215 216 217 218 ; The user has specified the root directory itself, rather than some 219 ; contents of it. We can't "find" that. 0 0000318B 26C745F8FFFF MOV WORD PTR [ES:DI-8],-1 ; Cause DOS_SEARCH_NEXT to fail by 221 ; stuffing a -1 at Lastent 0 00003191 E97CFF JMP find_no_more 223 224 OKSTORE: 0 00003194 8E1E[0200] MOV DS,WORD PTR [CURBUF+2] 226 ASSUME DS:NOTHING 227 DOSREL: 0 00003198 89DE MOV SI,BX ; SI-> start of entry 229 230 ; NOTE: DOS_RENAME depends on BX not being altered after this point 231 0 0000319A B92000 MOV CX,dir_entry_struc_size 233 ;;;;; 7/29/86 0 0000319D 89F8 MOV AX,DI ; save the 1st byte addr 0 0000319F F3A4 REP MOVSB 0 000031A1 89C7 MOV DI,AX ; restore 1st byte addr 0 000031A3 26803D05 CMP BYTE PTR [ES:DI],05H ; special char check 0 000031A7 7504 JNZ NO05 0 000031A9 26C605E5 MOV BYTE PTR [ES:DI],0E5H ; convert it back to E5 240 NO05: 241 242 ;;;;; 7/29/86 0 000031AD 161F context DS 0 000031AF 8026[0000]80 AND byte [FastOpenflg],Fast_yes ;AN000;;FO. reset fastopen 0 000031B4 F8 CLC 0 000031B5 E8[0000] LeaveCrit critDisk 0 000031B8 C3 return 248 249 EndProc DOS_SEARCH_FIRST 250 251 BREAK 252 253 ; Inputs: 254 ; [DMAADD] Points to 53 byte buffer returned by DOS_SEARCH_FIRST 255 ; (only first 21 bytes must have valid information) 256 ; Function: 257 ; Look for subsequent matches 258 ; Outputs: 259 ; CARRY CLEAR 260 ; The 53 bytes at DMAADD are updated for next call 261 ; (see DOS_SEARCH_FIRST) 262 ; CARRY SET 263 ; AX = error code 264 ; error_no_more_files 265 ; No more files to find 266 ; DS preserved, others destroyed 267 268 procedure DOS_SEARCH_NEXT,NEAR 268 ****************** warning: proc DOS_SEARCH_NEXT... [-w+user] 269 DOSAssume CS,,"DOS_Search_Next" 270 ASSUME ES:NOTHING 271 0 000031B9 C43E[0000] LES DI,[DMAADD] 0 000031BD 268A05 MOV AL,[ES:DI] 0 000031C0 A880 TEST AL,80H ; Test for NET 0 000031C2 7406 JZ LOCAL_SEARCH_NEXT 276 %IFN Installed 277 transfer NET_SEARCH_NEXT 278 %ELSE 0 000031C4 B81C11 MOV AX,(multNET << 8) | 28 0 000031C7 CD2F INT 2FH 0 000031C9 C3 return 282 %ENDIF 283 284 LOCAL_SEARCH_NEXT: 285 ;AL is drive A=1 0 000031CA C606[0000]02 MOV byte [EXTERR_LOCUS],errLOC_Disk 0 000031CF E8[0000] EnterCrit critDisk 288 ThisCDS equ THISCDS ; NASM port label 0 000031D2 C706[0000][0000] MOV WORD [ThisCDS],OFFSET DummyCDS wrt DOSGROUP 0 000031D8 8C1E[0200] MOV WORD PTR [ThisCDS+2], ds 0 000031DC 0440 ADD AL,'A'-1 0 000031DE E8[0000] invoke InitCDS 293 294 ; invoke GetThisDrv ; Set CDS pointer 295 0 000031E1 7236 JC No_files ; Bogus drive letter 0 000031E3 C43E[0000] LES DI,[THISCDS] ; Get CDS pointer 0 000031E7 26C46D45 LES BP,[ES:DI + curdir_devptr]; Get DPB pointer 0 000031EB E8[0000] invoke GOTDPB ; [THISDPB] = ES:BP 300 0 000031EE 268A4600 mov AL,[ES:BP + dpb_drive] 302 ThisDrv equ THISDRV ; NASM port label 0 000031F2 A2[0000] mov [ThisDrv],AL 304 305 CREATING equ Creating ; NASM port label 0 000031F5 C706[0000]00E5 MOV WORD PTR [CREATING],0E500H 0 000031FB C606[0000]01 MOV byte [NoSetDir],1 ; if we find a dir, don't change to it 0 00003200 C536[0000] LDS SI,[DMAADD] 309 ASSUME DS:NOTHING 0 00003204 AC LODSB ; Drive Byte 311 312 ; DEC AL 313 ; MOV [THISDRV],AL 314 315 entry RENAME_NEXT ; Entry used by DOS_RENAME 316 0 00003205 1607 context ES ; THIS BLOWS ES:BP POINTER TO DPB 0 00003207 BF[0000] MOV DI,OFFSET NAME1 wrt DOSGROUP 0 0000320A B90B00 MOV CX,11 0 0000320D F3A4 REP MOVSB ; Search name 0 0000320F AC LODSB ; Attribute 0 00003210 36A2[0000] MOV [ss:ATTRIB],AL 0 00003214 AD LODSW ; LastEnt 0 00003215 09C0 OR AX,AX 0 00003217 7903 JNS cont_load 326 No_files: 0 00003219 E9F4FE JMP find_no_more 328 329 cont_load: 0 0000321C 50 PUSH AX ; Save LastEnt 0 0000321D AD LODSW ; DirStart 0 0000321E 89C3 MOV BX,AX 0 00003220 161F context DS 0 00003222 C42E[0000] LES BP,[THISDPB] ; Recover ES:BP 0 00003226 E8[0000] invoke SetDirSrch 0 00003229 7303 JNC SEARCH_GOON 0 0000322B 58 POP AX ; Clean stack 0 0000322C EBEB JMP No_files 339 340 SEARCH_GOON: 0 0000322E E8[0000] invoke StartSrch 0 00003231 58 POP AX 0 00003232 E8[0000] invoke GetEnt 0 00003235 72E2 JC No_files 0 00003237 E8[0000] invoke NextEnt 0 0000323A 72DD JC No_files 0 0000323C 30E4 XOR AH,AH ; If Search_Next, can't be a DEV 0 0000323E E9FCFE JMP found_it 349 350 EndProc DOS_SEARCH_NEXT 351 352 353 ;Input: [WFP_START]= pointer to final path 354 ;Function: check '?' char 355 ;Output: carry clear, if no '?' 356 ; carry set, if '?' exists 357 358 procedure CHECK_QUESTION,NEAR ;AN000; 358 ****************** warning: proc CHECK_QUESTION... [-w+user] 359 ASSUME ES:NOTHING,DS:NOTHING ;AN000; 360 0 00003241 16 PUSH ss ;AN000;;FO. 0 00003242 1F POP DS ;AN000;;FO. ds:si -> final path 363 WFP_START equ WFP_Start ; NASM port label 0 00003243 8B36[0000] MOV SI,[WFP_START] ;AN000;;FO. 365 getnext: ;AN000; 0 00003247 AC LODSB ;AN000;;FO. get char 0 00003248 84C0 test AL,AL ;AN000;;FO. is it null 0 0000324A 7405 JZ NO_Question ;AN000;;FO. yes --> (NC) 0 0000324C 3C3F CMP AL,'?' ;AN000;;FO. is '?' 0 0000324E 75F7 JNZ getnext ;AN000;;FO. no 0 00003250 F9 STC ;AN000;;FO. 372 NO_Question: ;AN000; 0 00003251 C3 return ;AN000;;FO. 374 375 EndProc CHECK_QUESTION ;AN000; 376 377 END === Trace listing source: ../DOS/abort.lst 1 ; SCCSID = @(#)abort.asm 1.4 85/10/02 2 ;TITLE DOS_ABORT - Internal SFT close all files for proc call for MSDOS 3 ;NAME DOS_ABORT 4 5 ; Internal Abort call closes all handles and FCBs associated with a process. 6 ; If process has NET resources a close all is sent out over the net. 7 ; 8 ; DOS_ABORT 9 ; 10 ; Modification history: 11 ; 12 ; Created: ARR 30 March 1983 13 ; 14 15 ; 16 ; get the appropriate segment definitions 17 ; 18 19 %include "dosseg.nas" 1 <1> ; SCCSID = @(#)dosseg.asm 1.1 85/04/10 2 <1> ; SCCSID = @(#)dosseg.asm 1.1 85/04/10 3 <1> ; 4 <1> ; segment ordering for MSDOS 5 <1> ; 6 <1> 7 <1> %include "ddataseg.nas" 1 <2> === Switch to base=001140h -> "DOSSTART" 2 <2> section DOSSTART align=16 PUBLIC class=DOSSTART 3 <2> ; (no prior section) ; DOSSTART ENDS 4 <2> === Switch to base=001140h -> "START" 5 <2> section START align=1 PUBLIC class=START 6 <2> ; (no prior section) ; START ENDS 7 <2> === Switch to base=001140h -> "CONSTANTS" 8 <2> section CONSTANTS align=2 PUBLIC class=CONST 9 <2> ; (no prior section) ; CONSTANTS ENDS 10 <2> === Switch to base=001140h -> "DATA" 11 <2> section DATA align=2 PUBLIC class=DATA 12 <2> ; (no prior section) ; DATA ENDS 13 <2> === Switch to base=001140h -> "TABLE" 14 <2> section TABLE align=2 PUBLIC class=TABLE 15 <2> ; (no prior section) ; TABLE ENDS 16 <2> === Switch to base=001140h -> "CODE" 17 <2> section CODE align=1 PUBLIC class=CODE 18 <2> ; (no prior section) ; CODE ENDS 19 <2> === Switch to base=001140h -> "DOSDATATABLE" 20 <2> section DOSDATATABLE align=2 PUBLIC class=DOSDATACODE 21 <2> ; (no prior section) ; DOSDATATABLE ENDS 22 <2> === Switch to base=001140h -> "DOSDATACODE" 23 <2> section DOSDATACODE align=1 PUBLIC class=DOSDATACODE 24 <2> ; (no prior section) ; DOSDATACODE ENDS 25 <2> === Switch to base=001140h -> "LAST" 26 <2> section LAST align=16 PUBLIC class=LAST 27 <2> ; (no prior section) ; LAST ENDS 28 <2> 29 <2> group DOSGROUP DOSSTART START CONSTANTS DATA TABLE CODE DOSDATATABLE DOSDATACODE LAST 8 <1> 9 <1> %include "dcodeseg.nas" 1 <2> 2 <2> %ifndef DCODESEGNAS 3 <2> %assign DCODESEGNAS 1 4 <2> === Switch to base=008400h -> "DOSCODETABLE" 5 <2> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <2> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=008400h -> "DOSCODECODE" 7 <2> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <2> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=008400h -> "DOSBIOCODE" 9 <2> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=008400h -> "BIOCODE" 10 <2> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <2> 12 <2> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <2> 14 <2> %endif 10 <1> === Switch to base=001140h -> "LAST" 11 <1> section LAST 12 <1> ; (no prior section) ; LAST ENDS 20 === Switch to base=008400h -> "DOSCODECODE" 21 section DOSCODECODE 22 23 [list -] 23 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 23 ****************** warning: out: BPB.INC... [-w+user] 23 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 23 ****************** warning: out: DEVSYM.INC... [-w+user] 29 30 %iassign Installed TRUE 31 32 I_Need PROC_ID,WORD ; current process ID 33 I_Need USER_ID,WORD ; current user ID 34 i_need CurrentPDB,WORD 35 i_need sft_addr,DWORD 36 i_need THISSFT,DWORD 37 i_need JSHARE,DWORD 38 I_need sftFCB,DWORD ; pointer to SFTs for FCB cache 39 40 Break 41 42 ; Inputs: 43 ; [CurrentPDB] set to PID of process aborting 44 ; Function: 45 ; Close all files and free all SFTs for this PID 46 ; Returns: 47 ; None 48 ; All destroyed except stack 49 50 Procedure DOS_ABORT,NEAR 50 ****************** warning: proc DOS_ABORT... [-w+user] 51 ASSUME DS:NOTHING,ES:NOTHING 52 0 00003252 368E06[0000] MOV ES,[ss:CurrentPDB] 0 00003257 268B0E3200 MOV CX,[ES:PDB_JFN_Length] ; Number of JFNs 55 reset_free_jfn: 0 0000325C 89CB MOV BX,CX 0 0000325E 51 PUSH CX 0 0000325F 4B DEC BX ; get jfn (start with last one) 59 0 00003260 E8[0000] invoke D_close 0 00003263 59 POP CX 0 00003264 E2F6 LOOP reset_free_jfn ; and do 'em all 63 ; 64 ; Note: We do need to explicitly close FCBs. Reasons are as follows: If we 65 ; are running in the no-sharing no-network environment, we are simulating the 66 ; 2.0 world and thus if the user doesn't close the file, that is his problem 67 ; BUT... the cache remains in a state with garbage that may be reused by the 68 ; next process. We scan the set and blast the ref counts of the FCBs we own. 69 ; 70 ; If sharing is loaded, then the following call to close process will 71 ; correctly close all FCBs. We will then need to walk the list AFTER here. 72 ; 73 ; Finally, the following call to NET_Abort will cause an EOP to be sent to all 74 ; known network resources. These resources are then responsible for cleaning 75 ; up after this process. 76 ; 77 ; Sleazy, eh? 78 ; 0 00003266 161F context DS 80 multNet equ MultNET ; NASM port equate 0 00003268 B81D11CD2F CallInstall Net_Abort, multNet, 29 82 %if installed 83 JShare equ JSHARE ; NASM port label 0 0000326D FF1E[1000] call far [JShare + 4 * 4] 85 %else 86 call mftCloseP 87 %endif 88 assume ds:nothing 89 ; 90 ; Scan the FCB cache for guys that belong to this process and zap their ref 91 ; counts. 92 ; 0 00003271 36C43E[0000] les di,[ss:sftFCB] ; grab the pointer to the table 94 sfCount equ SFCount ; NASM port equate 0 00003276 268B4D04 mov cx,[es:di + sfCount] 0 0000327A E317 jcxz FCBScanDone 97 sfTable equ SFTable ; NASM port equate 0 0000327C 8D7D06 LEA DI,[DI + sfTable] ; point at table 99 proc_id equ PROC_ID ; NASM port label 0 0000327F 36A1[0000] mov ax,[ss:proc_id] 101 FCBTest: 0 00003283 26394531 cmp [es:di + sf_PID],ax ; is this one of ours 0 00003287 7505 jnz FCBNext ; no, skip it 0 00003289 26C7050000 mov word [es:di + sf_ref_count],0 ; yes, blast ref count 105 FCBNext: 106 sf_Entry_struc_size equ sf_entry_struc_size ; NASM port equate 0 0000328E 83C73B add di,sf_Entry_struc_size 0 00003291 E2F0 loop FCBTest 109 FCBScanDone: 110 111 ; 112 ; Walk the SFT to eliminate all busy SFT's for this process. 113 ; 0 00003293 31DB XOR BX,BX 115 Scan: 0 00003295 53 push bx 0 00003296 E8[0000] invoke SFFromSFN 0 00003299 5B pop bx 0 0000329A 7301C3 retc 0 0000329D 26833D00 cmp word [es:di + sf_ref_count],0 0 000032A1 7419 jz next 122 ; 123 ; we have a SFT that is not free. See if it is for the current process 124 ; 0 000032A3 36A1[0000] mov ax,[ss:proc_id] 126 sf_pid equ sf_PID ; NASM port equate 0 000032A7 26394531 cmp [es:di + sf_pid],ax 0 000032AB 750F jnz next 129 user_id equ USER_ID ; NASM port label 0 000032AD 36A1[0000] mov ax,[ss:user_id] 131 sf_uid equ sf_UID ; NASM port equate 0 000032B1 2639452F cmp [es:di + sf_uid],ax 0 000032B5 7505 jnz next 134 ; 135 ; This SFT is labelled as ours. 136 ; 0 000032B7 26C7050000 mov word [es:di + sf_ref_count],0 138 next: 0 000032BC 43 inc bx 140 scan equ Scan ; NASM port label 0 000032BD EBD6 jmp scan 142 143 EndProc DOS_Abort 144 145 END === Trace listing source: ../DOS/close.lst 1 ; SCCSID = @(#)close.asm 1.1 85/04/09 2 ;TITLE DOS_CLOSE/COMMIT - Internal SFT close and commit call for MSDOS 3 ;NAME DOS_CLOSE 4 ; Internal Close and Commit calls to close a local or NET SFT. 5 ; 6 ; DOS_CLOSE 7 ; DOS_COMMIT 8 ; FREE_SFT 9 ; SetSFTTimes 10 ; 11 ; Revision history: 12 ; 13 ; AN000 version 4.00 Jan. 1988 14 ; A005 PTM 3718 --- lost clusters when fastopen installed 15 ; A011 PTM 4766 --- C2 fastopen problem 16 17 ; 18 ; get the appropriate segment definitions 19 ; 20 [list -] === Switch to base=008400h -> "DOSCODECODE" 24 section DOSCODECODE 25 [list -] 25 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 25 ****************** warning: out: BPB.INC... [-w+user] 25 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 25 ****************** warning: out: DEVSYM.INC... [-w+user] 32 33 %iassign Installed TRUE 34 35 I_need Attrib,BYTE 36 i_need THISSFT,DWORD 37 i_need CURBUF,DWORD 38 i_need THISDRV,BYTE 39 i_need ALLOWED,BYTE 40 i_need EXTERR_LOCUS,BYTE 41 I_need FailErr,BYTE 42 I_Need PROC_ID,WORD 43 I_Need USER_ID,WORD 44 i_need JShare,DWORD 45 i_need HIGH_SECTOR,WORD ;F.C. >32mb 46 i_need OLD_FIRSTCLUS,WORD ;F.O. >32mb 47 %if debug 48 I_need BugLev,WORD 49 I_need BugTyp,WORD 50 %include "bugtyp.nas" 51 %endif 52 53 Break 54 55 ; Inputs: 56 ; [THISSFT] set to the SFT for the file being used 57 ; Function: 58 ; Close the indicated file via the SFT 59 ; Returns: 60 ; sf_ref_count decremented otherwise 61 ; ES:DI point to SFT 62 ; Carry set if error 63 ; AX has error code 64 ; DS preserved, others destroyed 65 66 procedure DOS_CLOSE,NEAR 66 ****************** warning: proc DOS_CLOSE... [-w+user] 67 DOSAssume CS,,"DOS_Close" 68 ASSUME ES:NOTHING 69 0 000032BF C43E[0000] LES DI,[THISSFT] 71 Assert ISSFT,,<"DOS_CLOSE"> 72 fmt TypAccess,LevBUSY,<"$p: CLOSE SFT: $x:$x\n">, 0 000032C3 268B5D05 MOV BX,[ES:DI + sf_flags] 74 ; 75 ; Network closes are handled entirely by the net code. 76 ; 0 000032C7 F7C30080 TEST BX,sf_isnet 0 000032CB 7406 JZ LocalClose 79 ; invoke OWN_SHARE ;IFS. IFS owns share ? ;AN000; 80 ; JZ noshare ;IFS. yes ;AN000; 81 ; EnterCrit critDisk ;IFS. ;AN000; 82 ; CALL SetSFTTimes ;IFS. set time for all SFT ;AN000; 83 ; LeaveCrit critDisk ;IFS. ;AN000; 84 noshare: 85 multnet equ MultNET ; NASM port equate 0 000032CD B80611CD2F CallInstall Net_Close,multnet,6 87 ; JC nomore ;IFS. error ;AN000; 88 ; invoke OWN_SHARE ;IFS. IFS owns share ? ;AN000; 89 ; JZ nomore ;IFS. yes ;AN000; 90 ; invoke ShareEnd ;IFS. remove SFT entry from share ;AN000; 91 nomore: 0 000032D2 C3 return 93 94 ; 95 ; All closes release the sharing information. 96 ; No commit releases sharing information 97 ; 98 ; All closes decrement the ref count. 99 ; No commit decrements the ref count. 100 ; 101 LocalClose: 0 000032D3 E8[0000] EnterCrit critDisk 0 000032D6 E88C01 CALL SetSFTTimes 104 Free_SFT equ FREE_SFT ; NASM port label 0 000032D9 E80001 CALL Free_SFT ; dec ref count or mark as busy 106 0 000032DC F7C38000 TEST BX,devid_device ;FS. device ? ;AN000; 0 000032E0 7511 JNZ nofastsk ;FS. yes ;AN000; 0 000032E2 268B4D0B MOV CX,[ES:DI + sf_firclus] ;FS. cx= first cluster ;AN000; 0 000032E6 09C9 OR CX,CX ;FS. cx=0 ? ;AN000; 0 000032E8 7409 JZ nofastsk ;FS. yes, dont do it ;AN000; 0 000032EA 26C57507 LDS SI,[ES:DI + sf_devptr] ;FS. ;AN000; 0 000032EE 8A14 MOV DL,[SI + dpb_drive] ;FS. dl= drive ;AN000; 0 000032F0 E8[0000] invoke FastSeek_Close ;FS. invoke fastseek ;AN000; 115 nofastsk: 0 000032F3 161F Context DS 0 000032F5 5053 SaveReg 0 000032F7 E8[0000] invoke ShareEnd 0 000032FA 5B58 RestoreReg 120 ; 121 ; Commit enters here. AX from commit MUST be <> 1, BX is flags word 122 ; 123 CloseEntry: 0 000032FC 50 PUSH AX 125 ; 126 ; File clean or device does not get stamped nor disk looked at. 127 ; 0 000032FD F7C3C000 TEST BX,devid_file_clean + devid_device 0 00003301 7403 JZ rdir 130 Free_SFT_OK equ FREE_SFT_OK ; NASM port label 0 00003303 E9C300 JMP Free_SFT_OK ; either clean or device 132 ; 133 ; Retrieve the directory entry for the file 134 ; 135 rdir: 0 00003306 E8E000 CALL DirFromSFT 137 ASSUME DS:NOTHING 0 00003309 B005 MOV AL,error_access_denied 0 0000330B 7303 JNC clook 0 0000330D E9BA00 JMP CloseFinish ; pretend the close worked. 141 clook: 142 ; 143 ; ES:DI points to entry 144 ; DS:SI points to SFT 145 ; ES:BX points to buffer header 146 ; 0 00003310 5756 SaveReg 0 00003312 8D7420 LEA SI,[SI + sf_name] 149 ; 150 ; ES:DI point to directory entry 151 ; DS:SI point to unpacked name 152 ; 0 00003315 E8[0000] invoke XCHGP 154 ; 155 ; ES:DI point to unpacked name 156 ; DS:SI point to directory entry 157 ; 0 00003318 E8[0000] invoke MetaCompare 0 0000331B E8[0000] invoke XCHGP 0 0000331E 5E5F RestoreReg 0 00003320 740C JZ CLOSE_GO ; Name OK 0 00003322 89F7 Bye: MOV DI,SI 0 00003324 1E PUSH DS 0 00003325 07 POP ES ; ES:DI points to SFT 0 00003326 16 PUSH SS 0 00003327 1F POP DS 0 00003328 F9 STC 0 00003329 B002 MOV AL,error_file_not_found 0 0000332B E99C00 JMP CloseFinish 170 171 CLOSE_GO: 0 0000332E F744020080 TEST word [SI + sf_mode],sf_isfcb ; FCB ? 0 00003333 7412 JZ nofcb ; no, set dir attr, sf_attr 0 00003335 268A6D0B MOV CH,[ES:DI + dir_attr] 0 00003339 8A4404 MOV AL,[SI + sf_attr] 0 0000333C 36A2[0000] MOV [ss:Attrib],AL 0 00003340 E8[0000] invoke MatchAttributes 0 00003343 75DD JNZ Bye ; attributes do not match 0 00003345 EB07 JMP SHORT setattr ;FT. 180 nofcb: 0 00003347 8A4404 MOV AL,[SI + sf_attr] ;FT. ;AN000; 0 0000334A 2688450B MOV [ES:DI + dir_attr],AL ;FT. ;AN000; 183 setattr: 0 0000334E 26804D0B20 OR BYTE PTR [ES:DI + dir_attr],attr_archive ;Set archive 0 00003353 268B451A MOV AX,[ES:DI + dir_first] ;AN011;F.O. save old first clusetr 0 00003357 36A3[0000] MOV [ss:OLD_FIRSTCLUS],AX ;AN011;F.O. save old first clusetr 187 0 0000335B 8B440B MOV AX,[SI + sf_firclus] 0 0000335E 2689451A MOV [ES:DI + dir_first],AX ;Set firclus pointer 0 00003362 8B4411 MOV AX,WORD PTR [SI + sf_size] 0 00003365 2689451C MOV [ES:DI + dir_size_l],AX ;Set size 0 00003369 8B4413 MOV AX,WORD PTR [SI + sf_size+2] 0 0000336C 2689451E MOV [ES:DI + dir_size_h],AX 0 00003370 8B440F MOV AX,[SI + sf_date] 0 00003373 26894518 MOV [ES:DI + dir_date],AX ;Set date 0 00003377 8B440D MOV AX,[SI + sf_time] 0 0000337A 26894516 MOV [ES:DI + dir_time],AX ;Set time 198 ;; File Tagging 199 200 ; MOV AX,[SI.sf_codepage] ;AN000; 201 ; MOV [ES:DI.dir_codepg],AX ;AN000;Set code page 202 ; MOV AX,[SI.sf_extcluster] ;AN000; 203 ; MOV [ES:DI.dir_extcluster],AX ;AN000; ;Set XA cluster 204 ; MOV AL,[SI.sf_attr_hi] ;AN000; 205 ; MOV [ES:DI.dir_attr2],AL ;AN000; ;Set high attr 206 207 ;; File Tagging 0 0000337E 26F6470540 TEST byte [ES:BX + buf_flags],buf_dirty ;LB. if already dirty ;AN000; 0 00003383 7508 JNZ yesdirty ;LB. don't increment dirty count ;AN000; 0 00003385 E8[0000] invoke INC_DIRTY_COUNT ;LB. ;AN000; 0 00003388 26804F0540 OR byte [ES:BX + buf_flags],buf_dirty ;Buffer dirty 212 yesdirty: 0 0000338D 1E56 SaveReg 0 0000338F 8B4C0B MOV CX,[SI + sf_firclus] ; do this for Fastopen 0 00003392 36A0[0000] MOV AL,[ss:THISDRV] 216 ;;; 10/1/86 update fastopen cache 0 00003396 52 PUSH DX 0 00003397 B400 MOV AH,0 ; dir entry update 0 00003399 88C2 MOV DL,AL ; drive number A=0, B=1,,, 0 0000339B 09C9 OR CX,CX ;AN005; first cluster 0; may be truncated 0 0000339D 750D JNZ do_update2 ;AN005; no, do update 0 0000339F B403 MOV AH,3 ;AN005; do a delete cache entry 0 000033A1 8B7C1B MOV DI,WORD PTR [SI + sf_dirsec] ;AN005; cx:di = dir sector 0 000033A4 8B4C1D MOV CX,WORD PTR [SI + sf_dirsec+2] ;AN005; 0 000033A7 8A741F MOV DH,[SI + sf_dirpos] ;AN005; dh= dir pos 0 000033AA EB0E JMP SHORT do_update ;AN011;F.O. 227 do_update2: ;AN011;F.O. 0 000033AC 363B0E[0000] CMP CX,[ss:OLD_FIRSTCLUS] ;AN011;F.O. same as old first clusetr? 0 000033B1 7407 JZ do_update ;AN011;F.O. yes 0 000033B3 B402 MOV AH,2 ;AN011;F.O. delete the old entry 0 000033B5 368B0E[0000] MOV CX,[ss:OLD_FIRSTCLUS] ;AN011;F.O. 232 do_update: ;AN005; 0 000033BA 161F Context DS 0 000033BC E8[0000] invoke FastOpen_Update ; invoke fastopen 0 000033BF 5A POP DX 236 237 ;;; 10/1/86 update fastopen cache 0 000033C0 E8[0000] invoke FLUSHBUF ; flush all relevant buffers 0 000033C3 5F07 RestoreReg 0 000033C5 B005 MOV AL,error_access_denied 0 000033C7 7201 JC CloseFinish 242 FREE_SFT_OK: 0 000033C9 F8 CLC ; signal no error. 244 CloseFinish: 245 ; 246 ; Indicate to the device that the SFT is being closed. 247 ; 248 ;;;; 7/21/86 0 000033CA 9C PUSHF ; save flag from DirFromSFT 0 000033CB E8[0000] invoke Dev_Close_SFT 0 000033CE 9D POPF 252 ;;;; 7/21/86 253 ; 254 ; See if the ref count indicates that we have busied the SFT. If so, mark the 255 ; SFT as being free. Note that we do NOT need to be in critSFT as we are ONLY 256 ; going to be moving from busy to free. 257 ; 0 000033CF 59 POP CX ; get old ref count 0 000033D0 9C PUSHF 260 fmt TypAccess,LevBUSY,<"$p: DOSFreeSFT: $x:$x from $x\n">, 0 000033D1 49 DEC CX ; if cx != 1 0 000033D2 7503 JNZ NoFree ; then do NOT free SFT 263 Assert ISSFT,,"DOS_FREE_SFT" 264 sf_ref_Count equ sf_ref_count ; NASM port equate 0 000033D4 26890D MOV [ES:DI + sf_ref_Count],CX 266 NoFree: 0 000033D7 E8[0000] LeaveCrit critDisk 0 000033DA 9D POPF 0 000033DB C3 return 270 EndProc DOS_Close 271 272 ; 273 ; ES:DI -> SFT. Decs sft_ref_count. If the count goes to 0, mark it as busy. 274 ; Flags preserved. Return old ref count in AX 275 ; 276 ; Note that busy is indicated by the SFT ref count being -1. 277 ; 278 Procedure FREE_SFT,NEAR 278 ****************** warning: proc FREE_SFT... [-w+user] 279 DOSAssume CS,,"Free_SFT" 280 ASSUME ES:NOTHING 281 0 000033DC 9C PUSHF ; Save carry state 0 000033DD 268B05 MOV AX,[ES:DI + sf_ref_count] 0 000033E0 48 DEC AX 0 000033E1 7501 JNZ SetCount 0 000033E3 48 DEC AX 287 SetCount: 0 000033E4 268705 XCHG AX,[ES:DI + sf_ref_count] 0 000033E7 9D POPF 0 000033E8 C3 return 291 292 EndProc Free_SFT 293 294 ; 295 ; DirFromSFT - locate a directory entry given an SFT. 296 ; 297 ; Inputs: ES:DI point to SFT 298 ; DS = DOSGroup 299 ; Outputs: 300 ; EXTERR_LOCUS = errLOC_Disk 301 ; CurBuf points to buffer 302 ; Carry Clear -> operation OK 303 ; ES:DI point to entry 304 ; ES:BX point to buffer 305 ; DS:SI point to SFT 306 ; Carry SET -> operation failed 307 ; registers trashified 308 ; Registers modified: ALL 309 310 Procedure DirFromSFT,NEAR 310 ****************** warning: proc DirFromSFT... [-w+user] 311 ASSUME DS:DOSGroup,ES:NOTHING 312 0 000033E9 C606[0000]02 MOV byte [EXTERR_LOCUS],errLOC_Disk 0 000033EE 0657 SaveReg 0 000033F0 268B551D MOV DX,WORD PTR [ES:DI + sf_dirsec+2] ;F.C. >32mb 0 000033F4 8916[0000] MOV [HIGH_SECTOR],DX ;F.C. >32mb 0 000033F8 268B551B MOV DX,WORD PTR [ES:DI + sf_dirsec] 318 0 000033FC FF36[0000] PUSH word [HIGH_SECTOR] ;F.C. >32mb 0 00003400 52 PUSH DX 0 00003401 E8[0000] invoke FATREAD_SFT ; ES:BP points to DPB, [THISDRV] set 322 ; [THISDPB] set 0 00003404 5A POP DX 0 00003405 8F06[0000] POP word [HIGH_SECTOR] ;F.C. >32mb 0 00003409 7225 JC PopDone 0 0000340B 30C0 XOR AL,AL ; Pre read 327 allowed_FAIL equ Allowed_FAIL ; NASM port equate 328 allowed_RETRY equ Allowed_RETRY ; NASM port equate 0 0000340D C606[0000]18 MOV byte [ALLOWED],allowed_FAIL + allowed_RETRY 0 00003412 E8[0000] invoke GETBUFFR 0 00003415 7219 JC PopDone 0 00003417 5E1F RestoreReg ; Get back SFT pointer 333 ASSUME DS:NOTHING 334 Curbuf equ CURBUF ; NASM port label 0 00003419 36C43E[0000] LES DI,[ss:Curbuf] 0 0000341E 26804D0504 OR byte [ES:DI + buf_flags],buf_isDIR 0 00003423 89FB MOV BX,DI ; ES:BX point to buffer header 0 00003425 8D7D10 LEA DI,[DI + BUFINSIZ] ; Point to buffer 0 00003428 B020 MOV AL,dir_entry_struc_size 340 sf_DirPos equ sf_dirpos ; NASM port equate 0 0000342A F6641F MUL byte [SI + sf_DirPos] 0 0000342D 01C7 ADD DI,AX ; Point at the entry 343 0 0000342F C3 return ; carry is clear 345 PopDone: 0 00003430 5F07 RestoreReg 0 00003432 C3 return 348 EndProc DirFromSFT 348 ****************** warning: ***** Possible stack size error in DirFromSFT ***** [-w+user] 349 350 Break 351 352 ; Inputs: 353 ; Same as DOS_CLOSE 354 ; Function: 355 ; Commit the file 356 ; Returns: 357 ; Same as DOS_CLOSE except ref_count field is not altered 358 ; DS preserved, others destroyed 359 360 procedure DOS_COMMIT,NEAR 360 ****************** warning: proc DOS_COMMIT... [-w+user] 361 DOSAssume CS,,"DOS_Commit" 362 ASSUME ES:NOTHING 363 0 00003433 C43E[0000] LES DI,[THISSFT] 0 00003437 268B5D05 MOV BX,[ES:DI + sf_flags] 0 0000343B F7C3C000 TEST BX,devid_file_clean + devid_device ;Clears carry 0 0000343F 75F1 retnz 0 00003441 F7C30080 TEST BX,sf_isnet 0 00003445 7406 JZ LOCAL_COMMIT 370 %IFN Installed 371 transfer NET_COMMIT 372 %ELSE 373 multNET equ MultNET ; NASM port equate 0 00003447 B80711 MOV AX,(multNET << 8) | 7 0 0000344A CD2F INT 2FH 0 0000344C C3 return 377 %ENDIF 378 379 ; 380 ; Perform local commit operation by doing a close but not releaseing the SFT. 381 ; There are three ways we can do this. One is to enter a critical section to 382 ; protect a potential free. The second is to increment the ref count to mask 383 ; the close decrementing. 384 ; 385 ; The proper way is to let the caller's of close decide if a decrement should 386 ; be done. We do this by providing another entry into close after the 387 ; decrement and after the share information release. 388 ; 389 LOCAL_COMMIT: 0 0000344D E8[0000] EnterCrit critDisk 0 00003450 E8[0000] EnterCrit critDisk ;PTM. ;AN000; 0 00003453 E80F00 call SetSFTTimes 0 00003456 B8FFFF MOV AX,-1 0 00003459 E8A0FE call CloseEntry 0 0000345C 9C PUSHF ;PTM. ;AN000; 0 0000345D E8[0000] invoke DEV_OPEN_SFT ;PTM. increment device count ;AN000; 0 00003460 9D POPF ;PTM. ;AN000; 0 00003461 E8[0000] LeaveCrit CritDisk ;PTM. ;AN000; 0 00003464 C3 return 400 401 EndProc DOS_COMMIT 402 403 Break 404 405 ; 406 ; SetSFTTimes - Examine the flags for a SFT and set the time appropriately. 407 ; Reflect these times in other SFT's for the same file. 408 ; 409 ; Inputs: ES:DI point to SFT 410 ; BX = sf_flags set apprpriately 411 ; Outputs: Set sft times to current time iff File & dirty & !nodate 412 ; Registers modified: All except ES:DI, BX, AX 413 ; 414 415 Procedure SetSFTTimes,NEAR 415 ****************** warning: proc SetSFTTimes... [-w+user] 416 Assert ISSFT,,"SetSFTTimes" 417 ; 418 ; File clean or device does not get stamped nor disk looked at. 419 ; 0 00003465 F7C3C000 TEST BX,devid_file_clean + devid_device 0 00003469 75F9 retnz ; clean or device => no timestamp 422 ; 423 ; file and dirty. See if date is good 424 ; 0 0000346B F7C30040 TEST BX,sf_close_nodate 0 0000346F 75F3 retnz ; nodate => no timestamp 0 00003471 5053 SaveReg 0 00003473 E8[0000] invoke DATE16 ; Date/Time to AX/DX 0 00003476 2689450F MOV [ES:DI + sf_date],AX 0 0000347A 2689550D MOV [ES:DI + sf_time],DX 0 0000347E 31C0 XOR AX,AX 432 %if installed 0 00003480 FF1E[3800] call far [JShare + 14 * 4] 434 %else 435 call ShSU 436 %endif 0 00003484 5B58 RestoreReg 0 00003486 C3 return 439 EndProc SetSFTTimes 440 441 END === Trace listing source: ../DOS/dircall.lst 1 ; SCCSID = @(#)dircall.asm 1.1 85/04/10 2 ; SCCSID = @(#)dircall.asm 1.1 85/04/10 3 ;TITLE DIRCALL - Directory manipulation internal calls 4 ;NAME DIRCALL 5 ; Low level directory manipulation routines for making removing and 6 ; verifying local or NET directories 7 ; 8 ; DOS_MKDIR 9 ; DOS_CHDIR 10 ; DOS_RMDIR 11 ; 12 ; Modification history: 13 ; 14 ; Created: ARR 30 March 1983 15 ; 16 17 ; 18 ; get the appropriate segment definitions 19 ; 20 [list -] === Switch to base=008400h -> "DOSCODECODE" 24 section DOSCODECODE 25 [list -] 25 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 25 ****************** warning: out: BPB.INC... [-w+user] 25 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 25 ****************** warning: out: DEVSYM.INC... [-w+user] 34 35 %iassign Installed TRUE 36 37 i_need THISSFT,DWORD 38 i_need THISCDS,DWORD 39 i_need NoSetDir,BYTE 40 i_need CURBUF, DWORD 41 i_need DIRSTART,WORD 42 i_need THISDPB,DWORD 43 i_need NAME1,BYTE 44 i_need LASTENT,WORD 45 i_need SATTRIB,BYTE 46 i_need ATTRIB,BYTE 47 i_need ALLOWED,BYTE 48 i_need FAILERR,BYTE 49 i_need RenBuf,BYTE 50 i_need FastOpenFlg,BYTE ; DOS 3.3 51 i_need FastOpenTable,BYTE ; DOS 3.3 52 i_need WFP_START,WORD ; DOS 3.3 53 i_need HIGH_SECTOR,WORD ; F.C. >32mb 54 55 BREAK 56 57 ; Inputs: 58 ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL 59 ; terminated) 60 ; [CURR_DIR_END] Points to end of Current dir part of string 61 ; ( = -1 if current dir not involved, else 62 ; Points to first char after last "/" of current dir part) 63 ; [THISCDS] Points to CDS being used 64 ; (Low word = -1 if NUL CDS (Net direct request)) 65 ; Function: 66 ; Make a new directory 67 ; Returns: 68 ; Carry Clear 69 ; No error 70 ; Carry Set 71 ; AX is error code 72 ; error_path_not_found 73 ; Bad path (not in curr dir part if present) 74 ; error_bad_curr_dir 75 ; Bad path in current directory part of path 76 ; error_access_denied 77 ; Already exists, device name 78 ; DS preserved, Others destroyed 79 80 procedure DOS_MKDIR,NEAR 80 ****************** warning: proc DOS_MKDIR... [-w+user] 81 DOSAssume CS,,"DOS_MkDir" 82 ASSUME ES:NOTHING 83 0 00003487 E8[0000] Invoke TestNet 85 local_mkdir equ LOCAL_MKDIR ; NASM port label 0 0000348A 7314 JNC local_mkdir 87 %IFN Installed 88 transfer NET_MKDIR 89 %ELSE 90 multNET equ MultNET ; NASM port equate 0 0000348C B80311 MOV AX,(multNET << 8) | 3 0 0000348F CD2F INT 2FH 0 00003491 C3 return 94 %ENDIF 95 96 NODEACCERRJ: 0 00003492 B80500 MOV AX,error_access_denied 98 BadRet: 0 00003495 F9 STC 0 00003496 E8[0000] LeaveCrit critDisk 0 00003499 C3 return 102 103 PATHNFJ: 0 0000349A E8[0000] LeaveCrit critDisk 0 0000349D E9[0000] transfer SET_MKND_ERR ; Map the MakeNode error and return 106 107 LOCAL_MKDIR: 0 000034A0 E8[0000] EnterCrit critDisk 109 ; 110 ; MakeNode requires an SFT to fiddle with. We Use a temp spot (RENBUF) 111 ; 0 000034A3 8C16[0200] MOV WORD PTR [THISSFT+2],SS 113 DOSGroup equ DOSGROUP ; NASM port equate 0 000034A7 C706[0000][0000] MOV WORD PTR [THISSFT],OFFSET RenBuf wrt DOSGroup 115 ; 116 ; NOTE: Need WORD PTR because MASM takes type of 117 ; TempSFT (byte) instead of type of sf_mft (word). 118 ; 119 sf_mft equ sf_MFT ; NASM port equate 0 000034AD C706[3300]0000 MOV WORD [RenBuf + sf_mft],0 ; make sure SHARER won't complain. 0 000034B3 B010 MOV AL,attr_directory 0 000034B5 E8[0000] invoke MAKENODE 123 0 000034B8 72E0 JC PATHNFJ 0 000034BA 83F803 CMP AX,3 0 000034BD 74D3 JZ NODEACCERRJ ; Can't make a device into a directory 0 000034BF C42E[0000] LES BP,[THISDPB] ; Makenode zaps this 0 000034C3 C53E[0000] LDS DI,[CURBUF] 129 ASSUME DS:NOTHING 0 000034C7 29FE SUB SI,DI 0 000034C9 56 PUSH SI ; Pointer to dir_first 0 000034CA FF750A PUSH WORD PTR [DI + buf_sector+2] ;F.C. >32mb 133 0 000034CD FF7508 PUSH WORD PTR [DI + buf_sector] ; Sector of new node 0 000034D0 161F context DS 0 000034D2 FF36[0000] PUSH word [DIRSTART] ; Parent for .. entry 0 000034D6 31C0 XOR AX,AX 0 000034D8 A3[0000] MOV [DIRSTART],AX ; Null directory 0 000034DB E8[0000] invoke NEWDIR 0 000034DE 7277 JC NODEEXISTSPOPDEL ; No room 0 000034E0 E8[0000] invoke GETENT ; First entry 0 000034E3 7272 JC NODEEXISTSPOPDEL ; Screw up 0 000034E5 C43E[0000] LES DI,[CURBUF] 144 0 000034E9 26F6450540 TEST byte [ES:DI + buf_flags],buf_dirty ;LB. if already dirty ;AN000; 0 000034EE 7508 JNZ yesdirty ;LB. don't increment dirty count ;AN000; 0 000034F0 E8[0000] invoke INC_DIRTY_COUNT ;LB. ;AN000; 0 000034F3 26804D0540 OR byte [ES:DI + buf_flags],buf_dirty 149 yesdirty: 0 000034F8 83C710 ADD DI,BUFINSIZ ; Point at buffer 0 000034FB B82E20 MOV AX,202EH ; ". " 0 000034FE 8B16[0000] MOV DX,[DIRSTART] ; Point at itself 0 00003502 E8[0000] invoke SETDOTENT 0 00003505 B82E2E MOV AX,2E2EH ; ".." 0 00003508 5A POP DX ; Parent 0 00003509 E8[0000] invoke SETDOTENT 0 0000350C C42E[0000] LES BP,[THISDPB] 158 allowed_FAIL equ Allowed_FAIL ; NASM port equate 159 allowed_RETRY equ Allowed_RETRY ; NASM port equate 0 00003510 C606[0000]18 MOV byte [ALLOWED],allowed_FAIL + allowed_RETRY 0 00003515 5A POP DX ; Entry sector 0 00003516 8F06[0000] POP word [HIGH_SECTOR] ;F.C. >32mb 163 0 0000351A 30C0 XOR AL,AL ; Pre read 0 0000351C E8[0000] invoke GETBUFFR 0 0000351F 7263 JC NODEEXISTSP 0 00003521 8B16[0000] MOV DX,[DIRSTART] 0 00003525 C53E[0000] LDS DI,[CURBUF] 169 ASSUME DS:NOTHING 0 00003529 804D0504 OR byte [DI + buf_flags],buf_isDIR 0 0000352D 5E POP SI ; dir_first pointer 0 0000352E 01FE ADD SI,DI 0 00003530 8914 MOV [SI],DX 0 00003532 31D2 XOR DX,DX 0 00003534 895402 MOV [SI+2],DX ; Zero size 0 00003537 895404 MOV [SI+4],DX 177 DIRUP: 0 0000353A F6450540 TEST byte [DI + buf_flags],buf_dirty ;LB. if already dirty ;AN000; 0 0000353E 7507 JNZ yesdirty2 ;LB. don't increment dirty count ;AN000; 0 00003540 E8[0000] invoke INC_DIRTY_COUNT ;LB. ;AN000; 0 00003543 804D0540 OR byte [DI + buf_flags],buf_dirty ; Dirty buffer 182 yesdirty2: 0 00003547 161F context DS 0 00003549 268A4600 MOV AL,[ES:BP + dpb_drive] 0 0000354D E8[0000] invoke FLUSHBUF 0 00003550 B80500 MOV AX,error_access_denied 0 00003553 E8[0000] LeaveCrit critDisk 0 00003556 C3 return 189 190 NODEEXISTSPOPDEL: 0 00003557 5A POP DX ; Parent 0 00003558 5A POP DX ; Entry sector 0 00003559 8F06[0000] POP word [HIGH_SECTOR] ; F.C. >32mb 194 0 0000355D C42E[0000] LES BP,[THISDPB] 0 00003561 C606[0000]18 MOV byte [ALLOWED],allowed_FAIL + allowed_RETRY 0 00003566 30C0 XOR AL,AL ; Pre read 0 00003568 E8[0000] invoke GETBUFFR 0 0000356B 7217 JC NODEEXISTSP 0 0000356D C53E[0000] LDS DI,[CURBUF] 201 ASSUME DS:NOTHING 0 00003571 804D0504 OR byte [DI + buf_flags],buf_isDIR 0 00003575 5E POP SI ; dir_first pointer 0 00003576 01FE ADD SI,DI 0 00003578 83EE1A SUB SI,dir_first ;Point back to start of dir entry 0 0000357B C604E5 MOV BYTE PTR [SI],0E5H ; Free the entry 0 0000357E E8B9FF CALL DIRUP ; Error doesn't matter since erroring anyway 208 NODEEXISTS: 0 00003581 E90EFF JMP NODEACCERRJ 210 211 NODEEXISTSP: 0 00003584 5E POP SI ; Clean stack 0 00003585 EBFA JMP NODEEXISTS 214 215 EndProc DOS_MKDIR 216 217 BREAK 218 219 ; Inputs: 220 ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL 221 ; terminated) 222 ; [CURR_DIR_END] Points to end of Current dir part of string 223 ; ( = -1 if current dir not involved, else 224 ; Points to first char after last "/" of current dir part) 225 ; [THISCDS] Points to CDS being used May not be NUL 226 ; Function: 227 ; Validate the path for potential new current directory 228 ; Returns: 229 ; NOTE: 230 ; [SATTRIB] is modified by this call 231 ; Carry Clear 232 ; CX is cluster number of the DIR, LOCAL CDS ONLY 233 ; Caller must NOT set ID fields on a NET CDS. 234 ; Carry Set 235 ; AX is error code 236 ; error_path_not_found 237 ; Bad path 238 ; error_access_denied 239 ; device or file name 240 ; DS preserved, Others destroyed 241 242 procedure DOS_CHDIR,NEAR 242 ****************** warning: proc DOS_CHDIR... [-w+user] 243 DOSAssume CS,,"DOS_Chdir" 244 ASSUME ES:NOTHING 245 0 00003587 E8[0000] Invoke TestNet 0 0000358A 7306 JNC LOCAL_CHDIR 248 %IFN Installed 249 transfer NET_CHDIR 250 %ELSE 0 0000358C B80511 MOV AX,(multNET << 8) | 5 0 0000358F CD2F INT 2FH 0 00003591 C3 return 254 %ENDIF 255 256 LOCAL_CHDIR: 0 00003592 E8[0000] EnterCrit critDisk 0 00003595 26F745430020 TEST word [ES:DI + curdir_flags],curdir_splice ;PTM. 0 0000359B 7406 JZ nojoin ;PTM. 0 0000359D 26C74549FFFF MOV word [ES:DI + curdir_ID],0FFFFH ;PTM. 261 nojoin: 0 000035A3 C606[0000]00 MOV byte [NoSetDir],FALSE 0 000035A8 C606[0000]16 MOV byte [SATTRIB],attr_directory+attr_system+attr_hidden 264 ; Dir calls can find these 265 ; DOS 3.3 6/24/86 FastOpen 266 0 000035AD 800E[0000]01 OR byte [FastOpenFlg],FastOpen_Set ; set fastopen flag 0 000035B2 E8[0000] invoke GetPath 0 000035B5 9C PUSHF ;AN000; 0 000035B6 8026[0000]80 AND byte [FastOpenFlg],Fast_yes ; clear it all ;AC000; 0 000035BB 9D POPF ;AN000; 272 ; DOS 3.3 6/24/86 FastOpen 0 000035BC B80300 MOV AX,error_path_not_found 0 000035BF 7207 JC ChDirDone 0 000035C1 753B JNZ NOTDIRPATH ; Path not a DIR 0 000035C3 8B0E[0000] MOV CX,[DIRSTART] ; Get cluster number 0 000035C7 F8 CLC 278 ChDirDone: 0 000035C8 E8[0000] LeaveCrit critDisk 0 000035CB C3 return 281 282 EndProc DOS_CHDIR 283 284 BREAK 285 286 ; Inputs: 287 ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL 288 ; terminated) 289 ; [CURR_DIR_END] Points to end of Current dir part of string 290 ; ( = -1 if current dir not involved, else 291 ; Points to first char after last "/" of current dir part) 292 ; [THISCDS] Points to CDS being used 293 ; (Low word = -1 if NUL CDS (Net direct request)) 294 ; Function: 295 ; Remove a directory 296 ; NOTE: Attempt to remove current directory must be detected by caller 297 ; Returns: 298 ; NOTE: 299 ; [SATTRIB] is modified by this call 300 ; Carry Clear 301 ; No error 302 ; Carry Set 303 ; AX is error code 304 ; error_path_not_found 305 ; Bad path (not in curr dir part if present) 306 ; error_bad_curr_dir 307 ; Bad path in current directory part of path 308 ; error_access_denied 309 ; device or file name, root directory 310 ; Bad directory ('.' '..' messed up) 311 ; DS preserved, Others destroyed 312 313 procedure DOS_RMDIR,NEAR 313 ****************** warning: proc DOS_RMDIR... [-w+user] 314 DOSAssume CS,,"DOS_RmDir" 315 ASSUME ES:NOTHING 316 0 000035CC E8[0000] Invoke TestNet 318 Local_RmDIR equ LOCAL_RMDIR ; NASM port label 0 000035CF 7306 JNC Local_RmDIR 320 %IFN Installed 321 transfer NET_RMDIR 322 %ELSE 0 000035D1 B80111 MOV AX,(multNET << 8) | 1 0 000035D4 CD2F INT 2FH 0 000035D6 C3 return 326 %ENDIF 327 328 LOCAL_RMDIR: 0 000035D7 E8[0000] EnterCrit critDisk 0 000035DA C606[0000]00 MOV byte [NoSetDir],0 0 000035DF C606[0000]16 MOV byte [SATTRIB],attr_directory+attr_system+attr_hidden 332 ; Dir calls can find these 0 000035E4 E8[0000] invoke GetPath 0 000035E7 720C JC NOPATH ; Path not found 0 000035E9 7513 JNZ NOTDIRPATH ; Path not a DIR 0 000035EB 8B3E[0000] MOV DI,[DIRSTART] 0 000035EF 09FF OR DI,DI ; Root ? 0 000035F1 750E JNZ rmdir_get_buf ; No 0 000035F3 EB09 JMP SHORT NOTDIRPATH 340 341 NOPATH: 0 000035F5 B80300 MOV AX,error_path_not_found 0 000035F8 E99AFE JMP BadRet 344 345 NOTDIRPATHPOP: 0 000035FB 58 POP AX ;F.C. >32mb 0 000035FC 58 POP AX 348 NOTDIRPATHPOP2: 0 000035FD 58 POP AX 350 NOTDIRPATH: 351 NodeAccErrJ equ NODEACCERRJ ; NASM port label 0 000035FE E991FE JMP NodeAccErrJ 353 354 rmdir_get_buf: 0 00003601 C53E[0000] LDS DI,[CURBUF] 356 ASSUME DS:NOTHING 0 00003605 29FB SUB BX,DI ; Compute true offset 0 00003607 53 PUSH BX ; Save entry pointer 0 00003608 FF750A PUSH WORD PTR [DI + buf_sector+2] ;F.C. >32mb 0 0000360B FF7508 PUSH WORD PTR [DI + buf_sector] ; Save sector number 0 0000360E 161F context DS 0 00003610 1607 context ES 0 00003612 BF[0000] MOV DI,OFFSET NAME1 wrt DOSGROUP 0 00003615 B03F MOV AL,'?' 0 00003617 B90B00 MOV CX,11 0 0000361A F3AA REP STOSB 0 0000361C 30C0 XOR AL,AL 0 0000361E AA STOSB ; Nul terminate it 0 0000361F E8[0000] invoke STARTSRCH ; Set search 0 00003622 E8[0000] invoke GETENTRY ; Get start of directory 0 00003625 72D4 JC NOTDIRPATHPOP ; Screw up 0 00003627 8E1E[0200] MOV DS,WORD PTR [CURBUF+2] 373 ASSUME DS:NOTHING 0 0000362B 89DE MOV SI,BX 0 0000362D AD LODSW 0 0000362E 3D2E20 CMP AX,(' ' << 8) | '.' ; First entry '.'? 0 00003631 75C8 JNZ NOTDIRPATHPOP ; Nope 0 00003633 83C61E ADD SI,(dir_entry_struc_size) - 2 ; Next entry 0 00003636 AD LODSW 0 00003637 3D2E2E CMP AX,('.' << 8) | '.' ; Second entry '..'? 0 0000363A 75BF JNZ NOTDIRPATHPOP ; Nope 0 0000363C 161F context DS 0 0000363E C706[0000]0200 MOV word [LASTENT],2 ; Skip . and .. 0 00003644 E8[0000] invoke GETENTRY ; Get next entry 0 00003647 72B2 JC NOTDIRPATHPOP ; Screw up 0 00003649 C606[0000]16 MOV byte [ATTRIB],attr_directory+attr_hidden+attr_system 0 0000364E E8[0000] invoke SRCH ; Do a search 0 00003651 73A8 JNC NOTDIRPATHPOP ; Found another entry! 0 00003653 803E[0000]00 CMP byte [FAILERR],0 0 00003658 75A1 JNZ NOTDIRPATHPOP ; Failure of search due to I 24 FAIL 0 0000365A C42E[0000] LES BP,[THISDPB] 0 0000365E 8B1E[0000] MOV BX,[DIRSTART] 393 ;; FastSeek 10/27/86 0 00003662 E8[0000] invoke Delete_FSeek ; delete the fastseek entry 395 ;; FastSeek 10/27/86 0 00003665 E8[0000] invoke RELEASE ; Release data in sub dir 0 00003668 7291 JC NOTDIRPATHPOP ; Screw up 0 0000366A 5A POP DX ; Sector # of entry 0 0000366B 8F06[0000] POP word [HIGH_SECTOR] ; F.C. >32mb 400 0 0000366F C606[0000]18 MOV byte [ALLOWED],allowed_FAIL + allowed_RETRY 0 00003674 30C0 XOR AL,AL ; Pre read 0 00003676 E8[0000] invoke GETBUFFR ; Get sector back 0 00003679 7282 JC NOTDIRPATHPOP2 ; Screw up 0 0000367B C53E[0000] LDS DI,[CURBUF] 406 ASSUME DS:NOTHING 0 0000367F 804D0504 OR byte [DI + buf_flags],buf_isDIR 0 00003683 5B POP BX ; Pointer to start of entry 0 00003684 01FB ADD BX,DI ; Corrected 0 00003686 C607E5 MOV BYTE PTR [BX],0E5H ; Free the entry 411 412 ;DOS 3.3 FastOpen 6/16/86 F.C. 0 00003689 1E PUSH DS 0 0000368A 161F context DS 0 0000368C E8[0000] invoke FastOpen_Delete ; call fastopen to delete an entry 0 0000368F 1F POP DS 417 ;DOS 3.3 FastOpen 6/16/86 F.C. 418 0 00003690 E9A7FE JMP DIRUP ; In MKDIR, dirty buffer and flush 420 421 EndProc DOS_RMDIR 422 423 END === Trace listing source: ../DOS/disk.lst 1 ; SCCSID = @(#)disk.asm 1.1 85/04/10 2 ; SCCSID = @(#)disk.asm 1.1 85/04/10 3 ;TITLE DISK - Disk utility routines 4 ;NAME Disk 5 ; Low level Read and write routines for local SFT I/O on files and devs 6 ; 7 ; SWAPCON 8 ; SWAPBACK 9 ; DOS_READ 10 ; DOS_WRITE 11 ; get_io_sft 12 ; DirRead 13 ; FIRSTCLUSTER 14 ; SET_BUF_AS_DIR 15 ; FATSecRd 16 ; DREAD 17 ; CHECK_WRITE_LOCK 18 ; CHECK_READ_LOCK 19 ; 20 ; Revision history: 21 ; 22 ; A000 version 4.00 Jan. 1988 23 ; 24 25 ; 26 ; get the appropriate segment definitions 27 ; 28 [list -] === Switch to base=008400h -> "DOSCODECODE" 34 section DOSCODECODE 35 [list -] 35 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 35 ****************** warning: out: BPB.INC... [-w+user] 35 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 35 ****************** warning: out: DEVSYM.INC... [-w+user] 35 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 43 44 %iassign Installed TRUE 45 46 I_need DirStart,WORD 47 I_Need CONSft,DWORD ; SFT for swapped console In/Out 48 i_need CONSWAP,BYTE 49 i_need IDLEINT,BYTE 50 i_need THISSFT,DWORD 51 i_need DMAADD,DWORD 52 i_need DEVCALL,BYTE 53 i_need CALLSCNT,WORD 54 i_need CALLXAD,DWORD 55 i_need CONTPOS,WORD 56 i_need NEXTADD,WORD 57 i_need CONBUF,BYTE 58 i_need ClusFac,BYTE 59 i_need Cluster_Factor_EDR,WORD 60 i_need SecClusPos,BYTE 61 i_need DirSec,DWORD ;AN000; 62 i_need ClusNum,WORD 63 i_need NxtClusNum,WORD 64 i_need ReadOp,BYTE 65 i_need CURBUF,DWORD 66 i_need ALLOWED,BYTE 67 i_need EXTERR_LOCUS,BYTE 68 i_need FastSeekflg,BYTE ;AN000; 69 i_need HIGH_SECTOR,WORD ;AN000; 70 I_need JShare,DWORD ;AN000; 71 i_need DOS34_FLAG,WORD ;AN000; 72 73 %ifndef BUF2 74 %IF BUFFERFLAG 75 i_need BUF_EMS_MODE,BYTE 76 i_need BUF_EMS_LAST_PAGE,BYTE 77 I_need BUF_EMS_FIRST_PAGE,DWORD 78 I_need BUF_EMS_SAFE_FLAG,BYTE 79 I_need BUF_EMS_NPA640,WORD 80 I_need BUF_EMS_PAGE_FRAME,WORD 81 I_need BUF_EMS_PFRAME,WORD 82 I_need LASTBUFFER,DWORD 83 84 extrn save_user_map:near 85 extrn restore_user_map:near 86 extrn Setup_EMS_Buffers:near 87 %ENDIF 88 %endif 89 90 Break 91 ; * * * * Drivers for file input from devices * * * * 92 93 ; Indicate that ther is no more I/O occurring through another SFT outside of 94 ; handles 0 and 1 95 ; 96 ; Inputs: DS is DOSGroup 97 ; Outputs: CONSWAP is set to false. 98 ; Registers modified: none 99 100 procedure SWAPBACK,NEAR 100 ****************** warning: proc SWAPBACK... [-w+user] 101 DOSAssume CS,,"SwapBack" 102 ASSUME ES:NOTHING 0 00003693 C606[0000]00 MOV BYTE PTR [CONSWAP],0 ; signal no conswaps 0 00003698 C3 return 105 EndProc SWAPBACK 106 107 ; Copy ThisSFT to CONSFT for use by the 1-12 primitives. 108 ; 109 ; Inputs: ThisSFT as the sft of the desired file 110 ; DS is DOSGroup 111 ; Outputs: CONSWAP is set. CONSFT = ThisSFT. 112 ; Registers modified: none 113 procedure SWAPCON,NEAR 113 ****************** warning: proc SWAPCON... [-w+user] 114 DOSAssume CS,,"SwapCon" 115 ASSUME ES:NOTHING 0 00003699 0657 SaveReg 0 0000369B C606[0000]01 MOV BYTE PTR [CONSWAP],1 ; CONSwap = TRUE; 118 ThisSFT equ THISSFT ; NASM port label 0 000036A0 C43E[0000] LES DI,[ThisSFT] 120 Assert ISSFT,,"SwapCon" 121 CONSFT equ CONSft ; NASM port label 0 000036A4 893E[0000] MOV WORD PTR [CONSFT],DI 0 000036A8 8C06[0200] MOV WORD PTR [CONSFT+2],ES 0 000036AC 5F07 RestoreReg 0 000036AE C3 return 126 EndProc SWAPCON 127 128 Break 129 130 ; 131 ; Inputs: 132 ; [THISSFT] set to the SFT for the file being used 133 ; [DMAADD] contains transfer address 134 ; CX = No. of bytes to read 135 ; Function: 136 ; Perform read operation 137 ; Outputs: 138 ; Carry clear 139 ; SFT Position and cluster pointers updated 140 ; CX = No. of bytes read 141 ; ES:DI point to SFT 142 ; Carry set 143 ; AX is error code 144 ; CX = 0 145 ; ES:DI point to SFT 146 ; DS preserved, all other registers destroyed 147 148 procedure DOS_READ,NEAR 148 ****************** warning: proc DOS_READ... [-w+user] 149 DOSAssume CS,,"DOS_Read" 150 ASSUME ES:NOTHING 151 152 %ifndef BUF2 153 %IF BUFFERFLAG 154 cmp byte [BUF_EMS_MODE], -1 155 jz dos_rd_call 156 call choose_buf_page 157 jnc sav_map_rd_hndl 158 return 159 sav_map_rd_hndl: 160 ; call save_user_map 161 dos_rd_call: 162 %ENDIF 163 %endif 164 0 000036AF C43E[0000] LES DI,[THISSFT] 166 Assert ISSFT,,"DOS_Read" 167 ; 168 ; Verify that the sft has been opened in a mode that allows reading. 169 ; 0 000036B3 268A4502 MOV AL,BYTE PTR [ES:DI + sf_mode] 0 000036B7 240F AND AL,access_mask 0 000036B9 3C01 CMP AL,open_for_write 0 000036BB 7503 JNE READ_NO_MODE ;Is read or both 0 000036BD E9[0000] transfer SET_ACC_ERR 175 176 READ_NO_MODE: 0 000036C0 E8[0000] invoke SETUP 0 000036C3 E30B JCXZ NoIORet ; no bytes to read - fast return 0 000036C5 E8[0000] invoke IsSFTNet 0 000036C8 7408 JZ LOCAL_READ 181 182 ; invoke OWN_SHARE ;AN000;;IFS. IFS owns share ? 183 ; JZ IFS_HAS_SHARE ;AN000;;IFS. yes 184 ; EnterCrit critDisk ;AN000;;IFS. enter critical section 185 ; CALL CHECK_READ_LOCK ;AN000;;IFS. check read lock 186 ; JNC READ_OK2 ;AN000;;IFS. lock check ok 187 ; JMP SHORT critexit ;AN000;;IFS. fail 188 READ_OK2: ;AN000; 189 ; LeaveCrit critDisk ;AN000;;IFS. leave critical section 190 IFS_HAS_SHARE: ;AN000; 191 192 %IFN Installed 193 transfer NET_READ 194 %ELSE 195 multNET equ MultNET ; NASM port equate 0 000036CA B80811 MOV AX,(multNET << 8) | 8 0 000036CD CD2F INT 2FH 0 000036CF C3 return 199 %ENDIF 200 201 ; 202 ; The user ended up requesting 0 bytes of input. We do nothing for this case 203 ; except return immediately. 204 ; 205 NoIORet: 0 000036D0 F8 CLC 0 000036D1 C3 return 208 209 LOCAL_READ: 0 000036D2 26F745058000 TEST word [ES:DI + sf_flags],devid_device ; Check for named device I/O 0 000036D8 7523 JNZ READDEV 0 000036DA C606[0000]02 MOV byte [EXTERR_LOCUS],errLOC_Disk 0 000036DF E8[0000] EnterCrit critDisk 0 000036E2 F606[0000]80 TEST byte [FastSeekflg],Fast_yes ; FastSeek installed ? 0 000036E7 7405 JZ FS_no ; no 0 000036E9 800E[0000]01 OR byte [FastSeekflg],FS_begin ; set fastseek mode 217 FS_no: 0 000036EE E8[0000] invoke DISKREAD 0 000036F1 9C PUSHF ; save flag 0 000036F2 368026[0000]FE AND byte [ss:FastSeekflg],FS_end ; reset fastseek mode 0 000036F8 9D POPF ; retore flag 222 critexit: 0 000036F9 E8[0000] LeaveCrit critDisk 0 000036FC C3 return 225 226 ; 227 ; We are reading from a device. Examine the status of the device to see if we 228 ; can short-circuit the I/O. If the device in the EOF state or if it is the 229 ; null device, we can safely indicate no transfer. 230 ; 231 READDEV: 232 DOSAssume CS,,"DISK/ReadDev" 233 ASSUME ES:NOTHING 0 000036FD C606[0000]04 MOV byte [EXTERR_LOCUS],errLOC_SerDev 0 00003702 268A5D05 MOV BL,BYTE PTR [ES:DI + sf_flags] 0 00003706 C43E[0000] LES DI,[DMAADD] 0 0000370A F6C340 TEST BL,devid_device_EOF ; End of file? 0 0000370D 7407 JZ ENDRDDEVJ3 0 0000370F F6C304 TEST BL,devid_device_null ; NUL device? 0 00003712 7405 JZ TESTRAW ; NO 0 00003714 30C0 XOR AL,AL ; Indicate EOF by setting zero 242 ENDRDDEVJ3: 0 00003716 E9C000 JMP ENDRDDEVJ2 244 245 ; 246 ; We need to hit the device. Figure out if we do a raw read or we do the 247 ; bizarre std_con_string_input. 248 ; 249 TESTRAW: 0 00003719 F6C320 TEST BL,devid_device_raw ; Raw mode? 0 0000371C 7508 JNZ DVRDRAW ; Yes, let the device do all local editing 0 0000371E F6C301 TEST BL,devid_device_con_in ; Is it console device? 0 00003721 7449 JZ NOTRDCON 0 00003723 E9E900 JMP READCON 255 256 DVRDRAW: 257 DOSAssume CS,,"DISK/DvRdRaw" 0 00003726 06 PUSH ES 0 00003727 1F POP DS ; Xaddr to DS:DI 260 ASSUME DS:NOTHING 261 ReadRawRetry: 0 00003728 89FB MOV BX,DI ; DS:BX transfer addr 0 0000372A 31C0 XOR AX,AX ; Media Byte, unit = 0 0 0000372C 89C2 MOV DX,AX ; Start at 0 0 0000372E E8[0000] invoke SETREAD 0 00003731 1E PUSH DS ; Save Seg part of Xaddr 0 00003732 36C536[0000] LDS SI,[ss:THISSFT] 268 Assert ISSFT,,"DOS_Read/DvRdRawR" 0 00003737 E8[0000] invoke DEVIOCALL 0 0000373A 89FA MOV DX,DI ; DS:DX is preserved by INT 24 0 0000373C B486 MOV AH,86H ; Read error 0 0000373E 368B3E[0300] MOV DI,[ss:DEVCALL + REQSTAT] 0 00003743 F7C70080 TEST DI,STERR 0 00003747 7419 JZ CRDROK ; No errors 0 00003749 E8[0000] invoke CHARHARD 0 0000374C 89D7 MOV DI,DX ; DS:DI is Xaddr 0 0000374E 08C0 OR AL,AL 0 00003750 7410 JZ CRDROK ; Ignore 0 00003752 3C03 CMP AL,3 0 00003754 7403 JZ CRDFERR ; fail. 0 00003756 1F POP DS ; Recover saved seg part of Xaddr 0 00003757 EBCF JMP ReadRawRetry ; Retry 283 284 ; 285 ; We have encountered a device-driver error. We have informed the user of it 286 ; and he has said for us to fail the system call. 287 ; 288 CRDFERR: 0 00003759 5F POP DI ; Clean stack 290 DEVIOFERR: 0 0000375A 36C43E[0000] LES DI,[ss:THISSFT] 292 Assert ISSFT,,"DOS_Read/DEVIOFERR" 0 0000375F E9[0000] transfer SET_ACC_ERR_DS 294 295 CRDROK: 0 00003762 5F POP DI ; Chuck saved seg of Xaddr 0 00003763 89D7 MOV DI,DX 0 00003765 36033E[0000] ADD DI,[ss:CALLSCNT] ; Amount transferred 0 0000376A EBAA JMP SHORT ENDRDDEVJ3 300 301 ; We are going to do a cooked read on some character device. There is a 302 ; problem here, what does the data look like? Is it a terminal device, line 303 ; CR line CR line CR, or is it file data, line CR LF line CR LF? Does it have 304 ; a ^Z at the end which is data, or is the ^Z not data? In any event we're 305 ; going to do this: Read in pieces up to CR (CRs included in data) or ^z (^z 306 ; included in data). this "simulates" the way con works in cooked mode 307 ; reading one line at a time. With file data, however, the lines will look 308 ; like, LF line CR. This is a little weird. 309 310 NOTRDCON: 0 0000376C 8CC0 MOV AX,ES 0 0000376E 8ED8 MOV DS,AX 313 ASSUME DS:NOTHING 0 00003770 89FB MOV BX,DI 0 00003772 31D2 XOR DX,DX 0 00003774 89D0 MOV AX,DX 0 00003776 51 PUSH CX 0 00003777 B90100 MOV CX,1 0 0000377A E8[0000] invoke SETREAD 0 0000377D 59 POP CX 0 0000377E 36C536[0000] LDS SI,[ss:THISSFT] 322 Assert ISSFT,,"DOS_Read/NotRdCon" 0 00003783 C57407 LDS SI,[SI + sf_devptr] 324 DVRDLP: 0 00003786 E8[0000] invoke DSKSTATCHK 0 00003789 E8[0000] invoke DEVIOCALL2 0 0000378C 57 PUSH DI ; Save "count" done 0 0000378D B486 MOV AH,86H 0 0000378F 368B3E[0300] MOV DI,[ss:DEVCALL + REQSTAT] 0 00003794 F7C70080 TEST DI,STERR 0 00003798 7417 JZ CRDOK 0 0000379A E8[0000] invoke CHARHARD 0 0000379D 5F POP DI 0 0000379E 36C706[0000]0100 MOV word [ss:CALLSCNT],1 0 000037A5 3C01 CMP AL,1 0 000037A7 74DD JZ DVRDLP ;Retry 0 000037A9 3C03 CMP AL,3 0 000037AB 74AD JZ DEVIOFERR ; FAIL 0 000037AD 30C0 XOR AL,AL ; Ignore, Pick some random character 0 000037AF EB12 JMP SHORT DVRDIGN 341 342 CRDOK: 0 000037B1 5F POP DI 0 000037B2 36833E[0000]01 CMP word [ss:CALLSCNT],1 0 000037B8 751F JNZ ENDRDDEVJ2 0 000037BA 1E PUSH DS 0 000037BB 368E1E[0200] MOV DS,WORD PTR [ss:CALLXAD+2] 0 000037C0 8A05 MOV AL,BYTE PTR [DI] ; Get the character we just read 0 000037C2 1F POP DS 350 DVRDIGN: 0 000037C3 36FF06[0000] INC WORD PTR [ss:CALLXAD] ; Next character 0 000037C8 36C706[0300]0000 MOV word [ss:DEVCALL + REQSTAT],0 0 000037CF 47 INC DI ; Next character 0 000037D0 3C1A CMP AL,1AH ; ^Z? 0 000037D2 7405 JZ ENDRDDEVJ2 ; Yes, done zero set (EOF) 0 000037D4 3C0D CMP AL,c_CR ; CR? 0 000037D6 E0AE LOOPNZ DVRDLP ; Loop if no, else done 0 000037D8 40 INC AX ; Resets zero flag so NOT EOF, unless 359 ; AX=FFFF which is not likely 360 ENDRDDEVJ2: 0 000037D9 EB1F JMP SHORT ENDRDDEV 362 363 ASSUME DS:NOTHING,ES:NOTHING 364 365 TRANBUF: 0 000037DB AC LODSB 0 000037DC AA STOSB 0 000037DD 3C0D CMP AL,c_CR ; Check for carriage return 0 000037DF 7503 JNZ NORMCH 0 000037E1 C6040A MOV BYTE PTR [SI],c_LF 371 NORMCH: 0 000037E4 3C0A CMP AL,c_LF 0 000037E6 E0F3 LOOPNZ TRANBUF 0 000037E8 7507 JNZ ENDRDCON 0 000037EA 31F6 XOR SI,SI ; Cause a new buffer to be read 0 000037EC E8[0000] invoke OUTT ; Transmit linefeed 0 000037EF 0C01 OR AL,1 ; Clear zero flag--not end of file 378 ENDRDCON: 0 000037F1 161F Context DS 0 000037F3 E89DFE CALL SWAPBACK 0 000037F6 8936[0000] MOV [CONTPOS],SI 382 ENDRDDEV: 0 000037FA 161F Context DS 0 000037FC 893E[0000] MOV [NEXTADD],DI 0 00003800 7509 JNZ SETSFTC ; Zero set if Ctrl-Z found in input 0 00003802 C43E[0000] LES DI,[THISSFT] 387 Assert ISSFT,,"DOS_Read/EndRdDev" 0 00003806 26806505BF AND BYTE PTR [ES:DI + sf_flags],~ devid_device_EOF ; Mark as no more data available 389 SETSFTC: 0 0000380B E8[0000] invoke SETSFT 0 0000380E C3 return 392 393 ASSUME DS:NOTHING,ES:NOTHING 394 395 READCON: 396 DOSAssume CS,,"ReadCon" 0 0000380F E887FE CALL SWAPCON 0 00003812 8B36[0000] MOV SI,[CONTPOS] 0 00003816 09F6 OR SI,SI 0 00003818 75C1 JNZ TRANBUF 0 0000381A 803E[0000]80 CMP BYTE PTR [CONBUF],128 0 0000381F 7406 JZ GETBUF 0 00003821 C706[0000]80FF MOV WORD PTR [CONBUF],0FF80H ; Set up 128-byte buffer with no template 404 GETBUF: 0 00003827 51 PUSH CX 0 00003828 06 PUSH ES 0 00003829 57 PUSH DI 0 0000382A BA[0000] MOV DX,OFFSET CONBUF wrt DOSGROUP 0 0000382D E8[0000] invoke D_STD_CON_STRING_INPUT ; Get input buffer 0 00003830 5F POP DI 0 00003831 07 POP ES 0 00003832 59 POP CX 0 00003833 BE[0200] MOV SI,2 + OFFSET CONBUF wrt DOSGROUP 0 00003836 803C1A CMP BYTE PTR [SI],1AH ; Check for Ctrl-Z in first character 0 00003839 75A0 JNZ TRANBUF 0 0000383B B01A MOV AL,1AH 0 0000383D AA STOSB 0 0000383E 4F DEC DI 0 0000383F B00A MOV AL,c_LF 0 00003841 E8[0000] invoke OUTT ; Send linefeed 0 00003844 31F6 XOR SI,SI 0 00003846 EBA9 JMP ENDRDCON 423 424 EndProc DOS_READ 425 426 Break 427 428 ; 429 ; Inputs: 430 ; [THISSFT] set to the SFT for the file being used 431 ; [DMAADD] contains transfer address 432 ; CX = No. of bytes to write 433 ; Function: 434 ; Perform write operation 435 ; NOTE: If CX = 0 on input, file is truncated or grown 436 ; to current sf_position 437 ; Outputs: 438 ; Carry clear 439 ; SFT Position and cluster pointers updated 440 ; CX = No. of bytes written 441 ; ES:DI point to SFT 442 ; Carry set 443 ; AX is error code 444 ; CX = 0 445 ; ES:DI point to SFT 446 ; DS preserved, all other registers destroyed 447 448 procedure DOS_WRITE,NEAR 448 ****************** warning: proc DOS_WRITE... [-w+user] 449 DOSAssume CS,,"DOS_Write" 450 ASSUME ES:NOTHING 451 452 %ifndef BUF2 453 %IF BUFFERFLAG 454 cmp byte [BUF_EMS_MODE], -1 455 jz dos_wrt_call 456 call choose_buf_page 457 jnc sav_map_wrt_hndl 458 return 459 sav_map_wrt_hndl: 460 ; call save_user_map 461 dos_wrt_call: 462 %ENDIF 463 %endif 464 0 00003848 C43E[0000] LES DI,[THISSFT] 466 Assert ISSFT,,"DosWrite" 0 0000384C 268A4502 MOV AL,BYTE PTR [ES:DI + sf_mode] 0 00003850 240F AND AL,access_mask 0 00003852 3C00 CMP AL,open_for_read 0 00003854 7503 JNE Check_FCB_RO ;Is write or both 471 BadMode: 0 00003856 E9[0000] transfer SET_ACC_ERR 473 474 ; 475 ; NOTE: The following check for writting to a Read Only File is performed 476 ; ONLY on FCBs!!!! 477 ; We ALLOW writes to Read Only files via handles to allow a CREATE 478 ; of a read only file which can then be written to. 479 ; This is OK because we are NOT ALLOWED to OPEN a RO file via handles 480 ; for writting, or RE-CREATE an EXISTING RO file via handles. Thus, 481 ; CREATing a NEW RO file, or RE-CREATing an existing file which 482 ; is NOT RO to be RO, via handles are the only times we can write 483 ; to a read-only file. 484 ; 485 Check_FCB_RO: 0 00003859 26F745020080 TEST word [ES:DI + sf_mode],sf_isfcb 0 0000385F 7407 JZ WRITE_NO_MODE ; Not an FCB 0 00003861 26F6450401 TEST byte [ES:DI + sf_attr],attr_read_only 0 00003866 75EE JNZ BadMode ; Can't write to Read_Only files via FCB 490 WRITE_NO_MODE: 0 00003868 E8[0000] invoke SETUP 0 0000386B E8[0000] invoke IsSFTNet 0 0000386E 7406 JZ LOCAL_WRITE 494 495 ; invoke OWN_SHARE ;AN000;;IFS. IFS owns share ? 496 ; JZ IFS_HAS_SHARE2 ;AN000;;IFS. yes 497 ; EnterCrit critDisk ;AN000;;IFS. enter critical section 498 ; CALL CHECK_WRITE_LOCK ;AN000;;IFS. check write lock 499 ; JC nocommit ;AN000;;IFS. lock error 500 ; 501 ; LeaveCrit critDisk ;AN000;;IFS. leave critical section 502 IFS_HAS_SHARE2: ;AN000; 503 504 505 %IFN Installed 506 transfer NET_WRITE 507 %ELSE 0 00003870 B80911 MOV AX,(multNET << 8) | 9 0 00003873 CD2F INT 2FH 510 ; JC nomore ;AN000;;IFS. error 511 ; invoke OWN_SHARE ;AN000;;IFS. IFS owns share ? 512 ; JZ nomore ;AN000;;IFS. yes 513 ; 514 ; MOV AX,1 ;AN000;;IFS. update all SFT for new size 515 ; call JShare + 14 * 4 ;AN000;;IFS. call ShSu 516 517 nomore: ;AN000; 0 00003875 C3 return 519 %ENDIF 520 521 522 LOCAL_WRITE: 0 00003876 26F745058000 TEST word [ES:DI + sf_flags],devid_device ; Check for named device I/O 0 0000387C 757B JNZ WRTDEV 0 0000387E C606[0000]02 MOV byte [EXTERR_LOCUS],errLOC_Disk 0 00003883 E8[0000] EnterCrit critDisk 0 00003886 F606[0000]80 TEST byte [FastSeekflg],Fast_yes ;AN000;FO. FastSeek installed ? 0 0000388B 7405 JZ FS_no2 ;AN000;FO. no 0 0000388D 800E[0000]01 OR byte [FastSeekflg],FS_begin ;AN000;FO. set fastseek mode 530 FS_no2: ;AN000; 0 00003892 E8[0000] invoke DISKWRITE 0 00003895 9C PUSHF ;AN000;FO. save flag 0 00003896 368026[0000]FE AND byte [ss:FastSeekflg],FS_end ;AN000;FO. reset fastseek mode 0 0000389C 9D POPF ;AN000;FO. restore flag 535 ;; Extended Open 0 0000389D 7211 JC nocommit ;AN000;EO. 0 0000389F C43E[0000] LES DI,[THISSFT] ;AN000;EO. 0 000038A3 26F745020040 TEST word [ES:DI + sf_mode],auto_commit_write ;AN000;EO. 0 000038A9 7405 JZ nocommit ;AN000;EO. 0 000038AB 51 PUSH CX ;AN000;EO. 0 000038AC E8[0000] invoke DOS_COMMIT ;AN000;EO. 0 000038AF 59 POP CX ;AN000;EO. 543 nocommit: ;AN000; 544 ;; Extended Open 0 000038B0 E8[0000] LeaveCrit critDisk 0 000038B3 C3 return 547 548 DVWRTRAW: 549 ASSUME DS:NOTHING 0 000038B4 31C0 XOR AX,AX ; Media Byte, unit = 0 0 000038B6 E8[0000] invoke SETWRITE 0 000038B9 1E PUSH DS ; Save seg of transfer 0 000038BA 36C536[0000] LDS SI,[ss:THISSFT] 554 Assert ISSFT,,"DosWrite/DvWrtRaw" 0 000038BF E8[0000] invoke DEVIOCALL ; DS:SI -> DEVICE 0 000038C2 89FA MOV DX,DI ; Offset part of Xaddr saved in DX 0 000038C4 B487 MOV AH,87H 0 000038C6 368B3E[0300] MOV DI,[ss:DEVCALL + REQSTAT] 0 000038CB F7C70080 TEST DI,STERR 0 000038CF 7414 JZ CWRTROK 0 000038D1 E8[0000] invoke CHARHARD 0 000038D4 89D3 MOV BX,DX ; Recall transfer addr 0 000038D6 08C0 OR AL,AL 0 000038D8 740B JZ CWRTROK ; Ignore 0 000038DA 3C03 CMP AL,3 0 000038DC 7403 JZ CWRFERR 0 000038DE 1F POP DS ; Recover saved seg of transfer 0 000038DF EBD3 JMP DVWRTRAW ; Try again 569 570 CWRFERR: 0 000038E1 58 POP AX ; Chuck saved seg of transfer 0 000038E2 E974FE JMP CRDFERR ; Will pop one more stack element 573 574 CWRTROK: 0 000038E5 58 POP AX ; Chuck saved seg of transfer 0 000038E6 1F POP DS 577 DOSAssume CS,,"DISK/CWrtOK" 0 000038E7 A1[0000] MOV AX,[CALLSCNT] ; Get actual number of bytes transferred 579 ENDWRDEV: 0 000038EA C43E[0000] LES DI,[THISSFT] 581 Assert ISSFT,,"DosWrite/EndWrDev" 0 000038EE 89C1 MOV CX,AX 0 000038F0 E8[0000] invoke ADDREC 0 000038F3 C3 return 585 586 WRTNUL: 0 000038F4 89CA MOV DX,CX ;Entire transfer done 588 WrtCookJ: 0 000038F6 E99D00 JMP WRTCOOKDONE 590 591 WRTDEV: 592 DOSAssume CS,,"DISK/WrtDev" 0 000038F9 C606[0000]04 MOV byte [EXTERR_LOCUS],errLOC_SerDev 0 000038FE 26804D0540 OR BYTE PTR [ES:DI + sf_flags],devid_device_EOF ; Reset EOF for input 0 00003903 268A5D05 MOV BL,BYTE PTR [ES:DI + sf_flags] 0 00003907 31C0 XOR AX,AX 0 00003909 E3DF JCXZ ENDWRDEV ; problem of creating on a device. 0 0000390B 1E PUSH DS 0 0000390C 88D8 MOV AL,BL 0 0000390E C51E[0000] LDS BX,[DMAADD] ; Xaddr to DS:BX 601 ASSUME DS:NOTHING 0 00003912 89DF MOV DI,BX ; Xaddr to DS:DI 0 00003914 31D2 XOR DX,DX ; Set starting point 0 00003916 A820 TEST AL,devid_device_raw ; Raw? 0 00003918 7402 JZ TEST_DEV_CON 0 0000391A EB98 JMP DVWRTRAW 607 608 TEST_DEV_CON: 0 0000391C A802 TEST AL,devid_device_con_out ; Console output device? 0 0000391E 757C JNZ WRITECON 0 00003920 A804 TEST AL,devid_device_null 0 00003922 75D0 JNZ WRTNUL 0 00003924 89D0 MOV AX,DX 0 00003926 803F1A CMP BYTE PTR [BX],1AH ; ^Z? 615 WRTCOOKJ equ WrtCookJ ; NASM port label 0 00003929 74CB JZ WRTCOOKJ ; Yes, transfer nothing 0 0000392B 51 PUSH CX 0 0000392C B90100 MOV CX,1 0 0000392F E8[0000] invoke SETWRITE 0 00003932 59 POP CX 0 00003933 36C536[0000] LDS SI,[ss:THISSFT] 622 X25_Special equ X25_special ; NASM port equate 0 00003938 36810E[0000]0008 OR word [ss:DOS34_FLAG],X25_Special;AN000;;PTM. bad x25 driver 0 0000393F B403 MOV AH,3 ;AN000;;PTM. prompt critical error ASAP 0 00003941 E8[0000] invoke IOFUNC ;AN000;;PTM. 626 Assert ISSFT,,"DosWrite/TestDevCon" 0 00003944 C57407 LDS SI,[SI + sf_devptr] 628 DVWRTLP: 0 00003947 E8[0000] invoke DSKSTATCHK 0 0000394A E8[0000] invoke DEVIOCALL2 0 0000394D 57 PUSH DI 0 0000394E B487 MOV AH,87H 0 00003950 368B3E[0300] MOV DI,[ss:DEVCALL + REQSTAT] 0 00003955 F7C70080 TEST DI,STERR 0 00003959 7416 JZ CWROK 0 0000395B E8[0000] invoke CHARHARD 0 0000395E 5F POP DI 0 0000395F 36C706[0000]0100 MOV word [ss:CALLSCNT],1 0 00003966 3C01 CMP AL,1 0 00003968 74DD JZ DVWRTLP ; Retry 0 0000396A 08C0 OR AL,AL 0 0000396C 740C JZ DVWRTIGN ; Ignore 0 0000396E E9E8FD JMP CRDFERR ; Fail, pops one stack element 644 645 CWROK: 0 00003971 5F POP DI 0 00003972 36833E[0000]00 CMP word [ss:CALLSCNT],0 0 00003978 741C JZ WRTCOOKDONE 649 DVWRTIGN: 0 0000397A 42 INC DX 0 0000397B 36FF06[0000] INC WORD PTR [ss:CALLXAD] 0 00003980 47 INC DI 0 00003981 1E PUSH DS 0 00003982 368E1E[0200] MOV DS,WORD PTR [ss:CALLXAD+2] 0 00003987 803D1A CMP BYTE PTR [DI],1AH ; ^Z? 0 0000398A 1F POP DS 0 0000398B 7409 JZ WRTCOOKDONE 0 0000398D 36C706[0300]0000 MOV word [ss:DEVCALL + REQSTAT],0 0 00003994 E2B1 LOOP DVWRTLP 660 WRTCOOKDONE: 0 00003996 89D0 MOV AX,DX 0 00003998 1F POP DS 0 00003999 E94EFF JMP ENDWRDEV 664 665 WRITECON: 0 0000399C 1E PUSH DS 0 0000399D 161F Context DS 0 0000399F E8F7FC CALL SWAPCON 0 000039A2 1F POP DS 670 ASSUME DS:NOTHING 0 000039A3 89DE MOV SI,BX 0 000039A5 51 PUSH CX 673 WRCONLP: 0 000039A6 AC LODSB 0 000039A7 3C1A CMP AL,1AH ; ^Z? 0 000039A9 7405 JZ CONEOF 0 000039AB E8[0000] invoke OUTT 0 000039AE E2F6 LOOP WRCONLP 679 CONEOF: 0 000039B0 58 POP AX ; Count 0 000039B1 29C8 SUB AX,CX ; Amount actually written 0 000039B3 1F POP DS 683 DOSAssume CS,,"DISK/ConEOF" 0 000039B4 E8DCFC CALL SWAPBACK 0 000039B7 E930FF JMP ENDWRDEV 686 EndProc DOS_WRITE 687 688 ; Convert JFN number in BX to sf_entry in DS:SI We get the normal SFT if 689 ; CONSWAP is FALSE or if the handle desired is 2 or more. Otherwise, we 690 ; retrieve the sft from ConSFT which is set by SwapCon. 691 692 procedure get_io_sft,near 692 ****************** warning: proc get_io_sft... [-w+user] 693 ASSUME DS:NOTHING,ES:NOTHING 694 ConSwap equ CONSWAP ; NASM port label 0 000039BA 36F606[0000]FF TEST byte [ss:ConSwap],-1 0 000039C0 7512 JNZ GetRedir 697 GetNormal: 0 000039C2 161F Context DS 0 000039C4 06 PUSH ES 0 000039C5 57 PUSH DI 0 000039C6 E8[0000] invoke SFFromHandle 0 000039C9 7206 JC RET44P 0 000039CB 8CC6 MOV SI,ES 0 000039CD 8EDE MOV DS,SI 705 ASSUME DS:NOTHING 0 000039CF 89FE MOV SI,DI 707 RET44P: 0 000039D1 5F POP DI 0 000039D2 07 POP ES 0 000039D3 C3 return 711 GetRedir: 0 000039D4 83FB01 CMP BX,1 0 000039D7 77E9 JA GetNormal 714 ConSFT equ CONSft ; NASM port label 0 000039D9 36C536[0000] LDS SI,[ss:ConSFT] 716 Assert ISSFT,,"GetIOSft" 0 000039DE F8 CLC 0 000039DF C3 return 719 EndProc get_io_sft 720 721 Break 722 723 ; Inputs: 724 ; AX = Directory block number (relative to first block of directory) 725 ; ES:BP = Base of drive parameters 726 ; [DIRSEC] = First sector of first cluster of directory 727 ; [CLUSNUM] = Next cluster 728 ; [CLUSFAC] = Sectors/Cluster 729 ; Function: 730 ; Read the directory block into [CURBUF]. 731 ; Outputs: 732 ; [NXTCLUSNUM] = Next cluster (after the one skipped to) 733 ; [SECCLUSPOS] Set 734 ; ES:BP unchanged 735 ; [CURBUF] Points to Buffer with dir sector 736 ; Carry set if error (user said FAIL to I 24) 737 ; DS preserved, all other registers destroyed. 738 739 procedure DirRead,NEAR 739 ****************** warning: proc DirRead... [-w+user] 740 DOSAssume CS,,"DirRead" 741 ASSUME ES:NOTHING 742 Assert ISDPB,,"DirRead" 743 744 ; 745 ; Note that ClusFac is is the sectors per cluster. This is NOT necessarily 746 ; the same as what is in the DPB! In the case of the root directory, we have 747 ; ClusFac = # sectors in the root directory. The root directory is detected 748 ; by DIRStart = 0. 749 ; 0 000039E0 31D2 XOR DX,DX 0 000039E2 833E[0000]00 CMP word [DirStart],0 0 000039E7 7504 jnz SubDir 0 000039E9 92 XCHG AX,DX 0 000039EA EB0D JMP DoRead 0 000039EC 90 nop ; identicalise 756 ; 757 ; Convert the sector number in AX into cluster and sector-within-cluster pair 758 ; 759 SubDir: 0 000039ED 88C2 MOV DL,AL 0 000039EF 26225604 AND DL,[ES:BP + dpb_cluster_mask] 762 ; 763 ; DX is the sector-in-cluster 764 ; 0 000039F3 268A4E05 MOV CL,[ES:BP + dpb_cluster_shift] 0 000039F7 D3E8 SHR AX,CL 767 ; 768 ; DX is position in cluster 769 ; AX is number of clusters to skip 770 ; 771 DoRead: 772 SECCLUSPOS equ SecClusPos ; NASM port label 0 000039F9 8816[0000] MOV [SECCLUSPOS],DL 0 000039FD 89C1 MOV CX,AX 0 000039FF 88D4 MOV AH,DL 776 ; 777 ; CX is number of clusters to skip. 778 ; AH is remainder 779 ; 780 DIRSEC equ DirSec ; NASM port label 0 00003A01 8B16[0200] MOV DX,WORD PTR [DIRSEC+2] ;AN000;>32mb 0 00003A05 8916[0000] MOV [HIGH_SECTOR],DX ;AN000;>32mb 0 00003A09 8B16[0000] MOV DX,WORD PTR [DIRSEC] 0 00003A0D 00E2 ADD DL,AH 0 00003A0F 80D600 ADC DH,0 0 00003A12 8316[0000]00 ADC word [HIGH_SECTOR],0 ;AN000;>32mb 787 788 CLUSNUM equ ClusNum ; NASM port label 0 00003A17 8B1E[0000] MOV BX,[CLUSNUM] 790 NXTCLUSNUM equ NxtClusNum ; NASM port label 0 00003A1B 891E[0000] MOV [NXTCLUSNUM],BX 0 00003A1F E319 JCXZ FIRSTCLUSTER 793 SKPCLLP: 0 00003A21 E8[0000] invoke UNPACK 0 00003A24 72B9 retc 0 00003A26 87DF XCHG BX,DI 0 00003A28 E8[0000] invoke IsEOF ; test for eof based on fat size 0 00003A2B 7302 JAE HAVESKIPPED 0 00003A2D E2F2 LOOP SKPCLLP 800 HAVESKIPPED: 0 00003A2F 891E[0000] MOV [NXTCLUSNUM],BX 0 00003A33 89FA MOV DX,DI 0 00003A35 88E3 MOV BL,AH 0 00003A37 E8[0000] invoke FIGREC 805 806 entry FIRSTCLUSTER 807 808 allowed_RETRY equ Allowed_RETRY ; NASM port equate 809 allowed_FAIL equ Allowed_FAIL ; NASM port equate 0 00003A3A C606[0000]18 MOV byte [ALLOWED],allowed_RETRY + allowed_FAIL 0 00003A3F 30C0 XOR AL,AL ; Indicate pre-read 0 00003A41 E8[0000] invoke GETBUFFR 0 00003A44 7299 retc 814 815 entry SET_BUF_AS_DIR 816 DOSAssume CS,,"SET_BUF_AS_DIR" 817 ASSUME ES:NOTHING 818 ; Set the type of CURBUF to be a directory sector. 819 ; Only flags are modified. 820 0 00003A46 1E PUSH DS 0 00003A47 56 PUSH SI 0 00003A48 C536[0000] LDS SI,[CURBUF] 824 Assert ISBUF,,"SetBufAsDir" 0 00003A4C 804C0504 OR byte [SI + buf_flags],buf_isDIR ; Clears carry 0 00003A50 5E POP SI 0 00003A51 1F POP DS 0 00003A52 C3 return 829 EndProc DirRead 830 831 Break 832 833 ; Inputs: 834 ; Same as DREAD 835 ; DS:BX = Transfer address 836 ; CX = Number of sectors 837 ; DX = Absolute record number 838 ; ES:BP = Base of drive parameters 839 ; Function: 840 ; Calls BIOS to perform FAT read. 841 ; Outputs: 842 ; Same as DREAD 843 844 procedure FATSecRd,NEAR 844 ****************** warning: proc FATSecRd... [-w+user] 845 ASSUME DS:NOTHING,ES:NOTHING 846 847 Assert ISDPB,,"FATSecRd" 0 00003A53 36C606[0000]18 MOV byte [ss:ALLOWED],allowed_RETRY + allowed_FAIL 0 00003A59 89CF MOV DI,CX 0 00003A5B 268A4E08 MOV CL,[ES:BP + dpb_FAT_count] 0 00003A5F 268B460F MOV AX,[ES:BP + dpb_FAT_size] ;AN000;>32mb 852 ; XOR AH,AH 0 00003A63 30ED XOR CH,CH ;AN000;>32mb 0 00003A65 52 PUSH DX 855 NXTFAT: 0 00003A66 36C706[0000]0000 MOV word [ss:HIGH_SECTOR],0 ;AN000;>32mb FAT sectors cannot exceed 0 00003A6D 51 PUSH CX ;AN000;>32mb 0 00003A6E 50 PUSH AX 0 00003A6F 89F9 MOV CX,DI 0 00003A71 E8[0000] invoke DSKREAD 0 00003A74 58 POP AX 0 00003A75 59 POP CX 0 00003A76 7420 JZ RET41P ; Carry clear 0 00003A78 01C2 ADD DX,AX 0 00003A7A E2EA LOOP NXTFAT 0 00003A7C 5A POP DX 0 00003A7D 89F9 MOV CX,DI 868 869 ; NOTE FALL THROUGH 870 871 Break 872 873 ; Inputs: 874 ; DS:BX = Transfer address 875 ; CX = Number of sectors 876 ; DX = Absolute record number (LOW) 877 ; [HIGH_SECTOR]= Absolute record number (HIGH) 878 ; ES:BP = Base of drive parameters 879 ; [ALLOWED] must be set in case call to HARDERR_DOS needed 880 ; Function: 881 ; Calls BIOS to perform disk read. If BIOS reports 882 ; errors, will call HARDERRRW for further action. 883 ; Outputs: 884 ; Carry set if error (currently user FAILED to INT 24) 885 ; DS,ES:BP preserved. All other registers destroyed. 886 887 entry DREAD 888 ASSUME DS:NOTHING,ES:NOTHING 889 890 Assert ISDPB,,"DREAD" 0 00003A7F E8[0000] invoke DSKREAD 0 00003A82 74CE retz ; Carry clear 893 READOP equ ReadOp ; NASM port label 0 00003A84 36C606[0000]00 MOV BYTE PTR [ss:READOP],0 0 00003A8A E8[0000] invoke HARDERRRW 0 00003A8D 3C01 CMP AL,1 ; Check for retry 0 00003A8F 74EE JZ DREAD 0 00003A91 3C03 CMP AL,3 ; Check for FAIL 0 00003A93 F8 CLC 0 00003A94 7501 JNZ NO_CAR ; Ignore 0 00003A96 F9 STC 902 NO_CAR: 0 00003A97 C3 return 904 0 00003A98 5A RET41P: POP DX 0 00003A99 C3 return 907 EndProc FATSecRd 908 909 910 Break 911 912 ; Inputs: 913 ; output of SETUP 914 ; ES:DI -> SFT 915 ; Function: 916 ; check write lock 917 ; Outputs: 918 ; Carry set if error 919 ; Carry clear if ok 920 921 procedure CHECK_WRITE_LOCK,NEAR ;AN000; 921 ****************** warning: proc CHECK_WRITE_LOCK... [-w+user] 922 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 923 0 00003A9A 26F6450408 TEST byte [ES:DI + sf_attr],attr_volume_id ;AN000;;MS. volume id 0 00003A9F 7404 JZ write_cont ;AN000;;MS. no 0 00003AA1 E8[0000] invoke SET_ACC_ERR_DS ;AN000;;MS. 0 00003AA4 C3 return ;AN000;;MS. 928 write_cont: ;AN000; 0 00003AA5 51 PUSH CX ;AN000;;MS. save reg 0 00003AA6 09C9 OR CX,CX ;AN000;;MS. 0 00003AA8 7503 JNZ Not_Truncate ;AN000;;MS. 0 00003AAA B9FFFF MOV CX,0FFFFH ;AN000;;MS. check for lock on whole file 933 Not_Truncate: ;AN000; 0 00003AAD B080 MOV AL,80H ;AN000;;MS. check write access 0 00003AAF E8[0000] invoke LOCK_CHECK ;AN000;;MS. check lock 0 00003AB2 59 POP CX ;AN000;;MS. restore reg 0 00003AB3 7305 JNC WRITE_OK ;AN000;;MS. lock ok 0 00003AB5 E8[0000] invoke WRITE_LOCK_VIOLATION ;AN000;;MS. issue I24 0 00003AB8 73E0 JNC CHECK_WRITE_LOCK ;AN000;;MS. retry 940 WRITE_OK: ;AN000; 0 00003ABA C3 return ;AN000;;MS. 942 EndProc CHECK_WRITE_LOCK ;AN000; 943 944 945 Break 946 947 ; Inputs: 948 ; ES:DI -> SFT 949 ; output of SETUP 950 ; Function: 951 ; check read lock 952 ; Outputs: 953 ; Carry set if error 954 ; Carry clear if ok 955 956 procedure CHECK_READ_LOCK,NEAR ;AN000; 956 ****************** warning: proc CHECK_READ_LOCK... [-w+user] 957 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 958 0 00003ABB 26F6450408 TEST byte [ES:DI + sf_attr],attr_volume_id ;AN000;;MS. volume id 0 00003AC0 7404 JZ do_retry ;AN000;;MS. no 0 00003AC2 E8[0000] invoke SET_ACC_ERR ;AN000;;MS. 0 00003AC5 C3 return ;AN000;;MS. 963 do_retry: ;AN000; 0 00003AC6 B000 MOV AL,0 ;AN000;;MS. check read access 0 00003AC8 E8[0000] invoke LOCK_CHECK ;AN000;;MS. check lock 0 00003ACB 7305 JNC READ_OK ;AN000;;MS. lock ok 0 00003ACD E8[0000] invoke READ_LOCK_VIOLATION ;AN000;;MS. issue I24 0 00003AD0 73E9 JNC CHECK_READ_LOCK ;AN000;;MS. retry 969 READ_OK: ;AN000; MS. 0 00003AD2 C3 return ;AN000;;MS. 971 EndProc CHECK_READ_LOCK ;AN000; 972 973 %ifndef BUF2 974 %IF BUFFERFLAG 975 976 ;------------------------------------------------------------------------- 977 ; Function name : choose_buf_page 978 ; Inputs : DMAADD = Xaddr 979 ; cx = # of bytes to transfer 980 ; Outputs : if NC 981 ; 982 ; SAFE_FLAG - 0 ==> page is safe. no need to 983 ; detect collision between 984 ; user & system buffer. 985 ; SAFE_FLAG - 1 ==> page is unsafe. Must check 986 ; for collision 987 ; 988 ; CY - error 989 ; 990 ; 991 ; High Level Alogrithm: 992 ; 993 ; 1. If Xaddr. is above the first physical page above 640K 994 ; 2. choose that page 995 ; 3. set safe flag 996 ; 4. else 997 ; 5. choose highest page above 640K 998 ; 6. If 6 or more pages above 640k 999 ; 7. Set safe flag 1000 ; 8. else 1001 ; 9. if Xaddr. + # of bytes to transfer does not spill into the 1002 ; chosen page 1003 ; 10. set safe flag 1004 ; 11.else 1005 ; 12. clear safe flag 1006 ; 13.endif 1007 ; 14.endif 1008 ; 15.endif 1009 ; 1010 ;---------------------------------------------------------------------------- 1011 Procedure choose_buf_page,near 1012 1013 assume cs:dosgroup, ds:nothing, es:nothing, ss:dosgroup 1014 1015 push cx 1016 push bx 1017 push dx 1018 push si 1019 push ds 1020 push ax 1021 1022 mov ax, word ptr [ss:DMAADD+2] 1023 and ax, 0fc00h ; page segment of transfer segment 1024 1025 cmp ax, word ptr [ss:BUF_EMS_FIRST_PAGE] 1026 ja pick_first 1027 1028 cmp word [ss:BUF_EMS_NPA640], 6 1029 jae safe_pick_last 1030 1031 add cx, word ptr [ss:DMAADD] ; get final offset 1032 mov bx, cx 1033 1034 mov cl, 4 1035 shr bx, cl ; get # of paragraphs 1036 mov ax, word ptr [ss:DMAADD+2] ; get initial segment 1037 add ax, bx ; get final segment 1038 1039 and ax, 0fc00h 1040 cmp ax, word ptr [ss:BUF_EMS_LAST_PAGE] 1041 jne safe_pick_last 1042 1043 mov byte [ss:BUF_EMS_SAFE_FLAG], 0 1044 jmp fin_choose_page 1045 nop ; identicalise 1046 1047 safe_pick_last: 1048 mov byte [ss:BUF_EMS_SAFE_FLAG], 1 1049 jmp fin_choose_page 1050 nop ; identicalise 1051 1052 ;pick_last: 1053 ; mov ax, word ptr [BUF_EMS_LAST_PAGE] 1054 ; mov [BUF_EMS_PFRAME], ax 1055 ; mov ax, word ptr [BUF_EMS_LAST_PAGE+2] 1056 ; mov [BUF_EMS_PAGE_FRAME], ax 1057 ; xor ax, ax 1058 ; jmp fin_choose_page 1059 1060 pick_first: 1061 mov ax, word ptr [ss:BUF_EMS_FIRST_PAGE] 1062 cmp [ss:BUF_EMS_PFRAME], ax 1063 je fin_choose_page 1064 call restore_user_map 1065 mov word ptr [ss:LASTBUFFER], -1 1066 mov [ss:BUF_EMS_PFRAME], ax 1067 mov ax, word ptr [ss:BUF_EMS_FIRST_PAGE+2] 1068 mov [ss:BUF_EMS_PAGE_FRAME], ax 1069 mov byte [ss:BUF_EMS_SAFE_FLAG], 1 1070 call Setup_EMS_Buffers 1071 call save_user_map 1072 jmp fin_choose_page 1073 nop ; identicalise 1074 1075 err_choose_page: 1076 stc 1077 1078 fin_choose_page: 1079 clc 1080 1081 pop ax 1082 pop ds 1083 pop si 1084 pop dx 1085 pop bx 1086 pop cx 1087 return 1088 1089 EndProc choose_buf_page 1090 1091 %ENDIF 1092 %endif 1093 1094 END 1095 1096 1097 === Trace listing source: ../DOS/disk2.lst 1 ; SCCSID = @(#)disk2.asm 1.3 85/06/19 2 ; SCCSID = @(#)disk2.asm 1.3 85/06/19 3 ;TITLE DISK2 - Disk utility routines 4 ;NAME Disk2 5 ; Low level Read and write routines for local SFT I/O on files and devs 6 ; 7 ; DskRead 8 ; DWRITE 9 ; DSKWRITE 10 ; HarderrRW 11 ; SETUP 12 ; BREAKDOWN 13 ; READ_LOCK_VIOLATION 14 ; WRITE_LOCK_VIOLATION 15 ; DISKREAD 16 ; SET_ACC_ERR_DS 17 ; SET_ACC_ERR 18 ; SETSFT 19 ; SETCLUS 20 ; AddRec 21 ; 22 ; Revision history: 23 ; 24 ; AN000 version 4.00 Jan. 1988 25 ; 26 27 ; 28 ; get the appropriate segment definitions 29 ; 30 [list -] === Switch to base=008400h -> "DOSCODECODE" 34 section DOSCODECODE 35 [list -] 35 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 35 ****************** warning: out: BPB.INC... [-w+user] 35 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 35 ****************** warning: out: DEVSYM.INC... [-w+user] 35 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 43 44 %iassign Installed TRUE 45 46 i_need THISSFT,DWORD 47 i_need DMAADD,DWORD 48 i_need NEXTADD,WORD 49 i_need ThisDrv,BYTE 50 i_need SecClusPos,BYTE 51 i_need ClusNum,WORD 52 i_need ReadOp,BYTE 53 i_need Trans,BYTE 54 i_need BytPos,4 55 i_need SecPos,DWORD ; DOS 4.00 >32mb ;AN000; 56 i_need BytSecPos,WORD 57 i_need BytCnt1,WORD 58 i_need BytCnt2,WORD 59 i_need SecCnt_DOS,WORD 60 i_need ThisDPB,DWORD 61 i_need LastPos,WORD 62 i_need EXTERRPT,DWORD 63 i_need CALLVIDRW,DWORD 64 i_need ALLOWED,BYTE 65 i_need DEVCALL,BYTE 66 i_need CALLSCNT,WORD 67 i_need DISK_FULL,BYTE ; disk full flag for ran blk wrt 68 i_need FSeek_drive,BYTE ; DOS 4.00 ;AN000; 69 i_need FSeek_firclus,WORD ; DOS 4.00 ;AN000; 70 i_need HIGH_SECTOR,WORD ; F.C. >32mb ;AN000; 71 i_need TEMP_VAR2,WORD ; LB. ;AN000; 72 i_need TEMP_VAR,WORD ; LB. ;AN000; 73 i_need IFS_DRIVER_ERR,WORD ; LB. ;AN000; 74 %ifdef BUF2 75 i_need BUF2_Dirty_Count,WORD 76 i_need BUFFHEAD,DWORD 77 %else 78 i_need CurHashEntry,DWORD ; DOS 4.00 current Hash entry ;AN000; 79 i_need BUF_HASH_PTR,DWORD ; DOS 4.00 Hash table pointer ;AN000; 80 i_need BUF_HASH_COUNT,WORD ; DOS 4.00 Hash table entries ;AN000; 81 %endif 82 i_need LastBuffer,DWORD 83 i_need FIRST_BUFF_ADDR,WORD ; first buffer address ;AN000; 84 85 %ifndef BUF2 86 %IF BUFFERFLAG 87 EXTRN SAVE_MAP:NEAR 88 EXTRN RESTORE_MAP:NEAR 89 EXTRN SAVE_USER_MAP:NEAR 90 EXTRN RESTORE_USER_MAP:NEAR 91 i_need BUF_EMS_SAFE_FLAG,BYTE 92 i_need BUF_EMS_MODE,BYTE 93 i_need CURADD,WORD 94 %ENDIF 95 %endif 96 97 98 Break 99 100 ; Inputs: 101 ; DS:BX = Transfer addr 102 ; CX = Number of sectors 103 ; [HIGH_SECTOR] = Absolute record number (HIGH) 104 ; DX = Absolute record number (LOW) 105 ; ES:BP = Base of drive parameters 106 ; Function: 107 ; Call BIOS to perform disk read 108 ; Outputs: 109 ; DI = CX on entry 110 ; CX = Number of sectors unsuccessfully transfered 111 ; AX = Status word as returned by BIOS (error code in AL if error) 112 ; Zero set if OK (from BIOS) (carry clear) 113 ; Zero clear if error (carry clear) 114 ; SI Destroyed, others preserved 115 116 procedure DskRead,NEAR 116 ****************** warning: proc DskRead... [-w+user] 117 ASSUME DS:NOTHING,ES:NOTHING 118 119 Assert ISDPB,,"DskRead" 0 00003AD3 51 PUSH CX 0 00003AD4 268A6617 MOV AH,[ES:BP + dpb_media] 0 00003AD8 268A4601 MOV AL,[ES:BP + dpb_UNIT] 0 00003ADC 53 PUSH BX 0 00003ADD 06 PUSH ES 0 00003ADE E8[0000] invoke SETREAD 0 00003AE1 EB29 JMP DODSKOP 0 00003AE3 90 nop ; identicalise 128 129 Break 130 131 ; Inputs: 132 ; DS:BX = Transfer address 133 ; CX = Number of sectors 134 ; [HIGH_SECTOR] = Absolute record number (HIGH) 135 ; DX = Absolute record number (LOW) 136 ; ES:BP = Base of drive parameters 137 ; [ALLOWED] must be set in case HARDERR_DOS called 138 ; Function: 139 ; Calls BIOS to perform disk write. If BIOS reports 140 ; errors, will call HARDERRRW for further action. 141 ; Output: 142 ; Carry set if error (currently, user FAILed to I 24) 143 ; BP preserved. All other registers destroyed. 144 145 entry DWRITE 146 ASSUME DS:NOTHING,ES:NOTHING 147 148 Assert ISDPB,,"DWrite" 0 00003AE4 E81700 CALL DSKWRITE 0 00003AE7 7501C3 retz ; Carry clear 151 READOP equ ReadOp ; NASM port label 0 00003AEA 36C606[0000]01 MOV BYTE PTR [ss:READOP],1 0 00003AF0 E83E00 invoke HARDERRRW 0 00003AF3 3C01 CMP AL,1 ; Check for retry 0 00003AF5 74ED JZ DWRITE 0 00003AF7 3C03 CMP AL,3 ; Check for FAIL 0 00003AF9 F8 CLC 0 00003AFA 7501 JNZ NO_CAR2 ; Ignore 0 00003AFC F9 STC 160 NO_CAR2: 0 00003AFD C3 return 162 163 Break 164 165 ; Inputs: 166 ; DS:BX = Transfer addr 167 ; CX = Number of sectors 168 ; DX = Absolute record number (LOW) 169 ; [HIGH_SECTOR] = Absolute record number (HIGH) 170 ; ES:BP = Base of drive parameters 171 ; Function: 172 ; Call BIOS to perform disk read 173 ; Outputs: 174 ; DI = CX on entry 175 ; CX = Number of sectors unsuccessfully transfered 176 ; AX = Status word as returned by BIOS (error code in AL if error) 177 ; Zero set if OK (from BIOS) (carry clear) 178 ; Zero clear if error (carry clear) 179 ; SI Destroyed, others preserved 180 181 entry DSKWRITE 182 ASSUME DS:NOTHING,ES:NOTHING 183 184 Assert ISDPB,,"DskWrite" 0 00003AFE 51 PUSH CX 0 00003AFF 268A6617 MOV AH,[ES:BP + dpb_media] 0 00003B03 268A4601 MOV AL,[ES:BP + dpb_UNIT] 0 00003B07 53 PUSH BX 0 00003B08 06 PUSH ES 0 00003B09 E8[0000] invoke SETWRITE 191 DODSKOP: 0 00003B0C 8CD9 MOV CX,DS ; Save DS 0 00003B0E 1F POP DS ; DS:BP points to DPB 0 00003B0F 1E PUSH DS 0 00003B10 3EC57613 LDS SI,[DS:BP + dpb_driver_addr] 0 00003B14 E8[0000] invoke DEVIOCALL2 0 00003B17 8ED9 MOV DS,CX ; Restore DS 0 00003B19 07 POP ES ; Restore ES 0 00003B1A 5B POP BX 0 00003B1B 368B0E[0000] MOV CX,[ss:CALLSCNT] ; Number of sectors transferred 0 00003B20 5F POP DI 0 00003B21 29F9 SUB CX,DI 0 00003B23 F7D9 NEG CX ; Number of sectors not transferred 0 00003B25 36A1[0300] MOV AX,[ss:DEVCALL + REQSTAT] 0 00003B29 36A3[0000] MOV [ss:IFS_DRIVER_ERR],AX ;IFS. save it for IFS ;AN000; 0 00003B2D A90080 TEST AX,STERR 0 00003B30 C3 return 208 EndProc DskRead 209 210 211 212 Break 213 214 ; Inputs: 215 ; AX is error code from read or write 216 ; Other registers set as per HARDERR_DOS 217 ; Function: 218 ; Checks the error code for special extended 219 ; errors and maps them if needed. Then invokes 220 ; Harderr_DOS 221 ; Outputs: 222 ; Of HARDERR_DOS 223 ; AX may be modified prior to call to HARDERR_DOS. 224 ; No other registers altered. 225 226 procedure HARDERRRW,near 226 ****************** warning: proc HARDERRRW... [-w+user] 227 ASSUME DS:NOTHING,ES:NOTHING 228 0 00003B31 3C0F CMP AL,error_I24_wrong_disk 0 00003B33 7513 JNZ DO_ERR ; Nothing to do 0 00003B35 1E PUSH DS 0 00003B36 56 PUSH SI 0 00003B37 36C536[0000] LDS SI,[ss:CALLVIDRW] ; Get pointer from dev 0 00003B3C 368C1E[0200] MOV WORD PTR [ss:EXTERRPT+2],DS ; Set ext err pointer 0 00003B41 368936[0000] MOV WORD PTR [ss:EXTERRPT],SI 0 00003B46 5E POP SI 0 00003B47 1F POP DS 238 DO_ERR: 0 00003B48 E8[0000] invoke HARDERR_DOS 0 00003B4B C3 return 241 242 EndProc HARDERRRW 243 244 Break 245 246 ; Inputs: 247 ; ES:DI point to SFT (value also in THISSFT) 248 ; [DMAADD] contains transfer address 249 ; CX = Byte count 250 ; WARNING Stack must be clean, two ret addrs on stack, 1st of caller, 251 ; 2nd of caller of caller. 252 ; Outputs: 253 ; CX = byte count 254 ; [THISDPB] = Base of drive parameters if file 255 ; = Pointer to device header if device or NET 256 ; ES:DI Points to SFT 257 ; [NEXTADD] = Displacement of disk transfer within segment 258 ; [TRANS] = 0 (No transfers yet) 259 ; [BYTPOS] = Byte position in file 260 ; 261 ; The following fields are relevant to local files (not devices) only: 262 ; 263 ; [SECPOS] = Position of first sector (local files only) 264 ; [BYTSECPOS] = Byte position in first sector (local files only) 265 ; [CLUSNUM] = First cluster (local files only) 266 ; [SECCLUSPOS] = Sector within first cluster (local files only) 267 ; [THISDRV] = Physical unit number (local files only) 268 ; 269 ; RETURNS ONE LEVEL UP WITH: 270 ; CX = 0 271 ; CARRY = Clear 272 ; IF AN ERROR IS DETECTED 273 ; All other registers destroyed 274 275 procedure SETUP,NEAR 275 ****************** warning: proc SETUP... [-w+user] 276 DOSAssume CS,,"SetUp" 277 ASSUME ES:NOTHING 278 279 Assert ISSFT,,"SetUp" 0 00003B4C 26C57507 LDS SI,[ES:DI + sf_devptr] 281 ASSUME DS:NOTHING 282 THISDPB equ ThisDPB ; NASM port label 0 00003B50 368C1E[0200] MOV WORD PTR [ss:THISDPB+2],DS 0 00003B55 161F context DS 0 00003B57 8936[0000] MOV WORD PTR [THISDPB],SI 0 00003B5B 8B1E[0000] MOV BX,WORD PTR [DMAADD] 0 00003B5F 891E[0000] MOV [NEXTADD],BX ;Set NEXTADD to start of Xaddr 288 TRANS equ Trans ; NASM port label 0 00003B63 C606[0000]00 MOV BYTE PTR [TRANS],0 ;No transferes 290 sf_Position equ sf_position ; NASM port equate 0 00003B68 268B4515 MOV AX,WORD PTR [ES:DI + sf_Position] 0 00003B6C 268B5517 MOV DX,WORD PTR [ES:DI + sf_Position+2] 293 BYTPOS equ BytPos ; NASM port label 0 00003B70 8916[0200] MOV WORD PTR [BYTPOS+2],DX ;Set it 0 00003B74 A3[0000] MOV WORD PTR [BYTPOS],AX 0 00003B77 26F745058080 TEST word [ES:DI + sf_flags],sf_isnet + devid_device 0 00003B7D 754C JNZ NOSETSTUFF ;Following not done on devs or NET 0 00003B7F 06 PUSH ES 0 00003B80 C42E[0000] LES BP,[THISDPB] ;Point at the DPB 300 Assert ISDPB,,"Setup" 0 00003B84 268A5E00 MOV BL,[ES:BP + dpb_drive] 302 THISDRV equ ThisDrv ; NASM port label 0 00003B88 881E[0000] MOV [THISDRV],BL ;Set THISDRV 0 00003B8C 268B5E02 MOV BX,[ES:BP + dpb_sector_size] 305 ; CMP DX,BX ; See if divide will overflow 306 ; JNC EOFERR ; for 16 bit sector 307 ;; 32 bit divide 0 00003B90 E8[0000] invoke DIV32 ; F.C. >32mb ;AN000; 309 SECPOS equ SecPos ; NASM port label 0 00003B93 A3[0000] MOV WORD PTR [SECPOS],AX ; F.C. >32mb ;AN000; 0 00003B96 8B1E[0000] MOV BX,[HIGH_SECTOR] ; F.C. >32mb ;AN000; 0 00003B9A 891E[0200] MOV WORD PTR [SECPOS+2],BX ; F.C. >32mb ;AN000; 313 314 BYTSECPOS equ BytSecPos ; NASM port label 0 00003B9E 8916[0000] MOV [BYTSECPOS],DX 0 00003BA2 89C2 MOV DX,AX 0 00003BA4 26224604 AND AL,[ES:BP + dpb_cluster_mask] 318 SECCLUSPOS equ SecClusPos ; NASM port label 0 00003BA8 A2[0000] MOV [SECCLUSPOS],AL 0 00003BAB 89C8 MOV AX,CX ; Save byte count 321 ; MOV CL,[ES:BP.dpb_cluster_shift] 0 00003BAD FF36[0200] PUSH WORD PTR [SECPOS+2] ; F.C. >32mb ;AN000; 0 00003BB1 8F06[0000] POP word [HIGH_SECTOR] ; F.C. >32mb ;AN000; 0 00003BB5 50 PUSH AX ; F.C. >32mb save ax ;AN000; 0 00003BB6 89D0 MOV AX,DX ; F.C. >32mb ax=dx ;AN000; 0 00003BB8 E8[0000] invoke SHR32 ; F.C. >32mb shift ax ;AN000; 0 00003BBB 89C2 MOV DX,AX ; F.C. >32mb dx=ax ;AN000; 0 00003BBD 58 POP AX ; F.C. >32mb restore dx ;AN000; 329 330 ; SHR DX,CL 0 00003BBE 263B560D CMP DX,[ES:BP + dpb_max_cluster] ;>32mb if > disk size ;AN000; ;AN000; 0 00003BC2 771C JA EOFERR ;>32mb then EOF ;AN000; ;AN000; 333 334 CLUSNUM equ ClusNum ; NASM port label 0 00003BC4 8916[0000] MOV [CLUSNUM],DX 0 00003BC8 07 POP ES ; ES:DI point to SFT 0 00003BC9 89C1 MOV CX,AX ; Put byte count back in CX 338 NOSETSTUFF: 0 00003BCB 89C8 MOV AX,CX ; Need it in AX too 0 00003BCD 0306[0000] ADD AX,WORD PTR [DMAADD] ; See if it will fit in one segment 0 00003BD1 730C JNC OK ; Must be less than 64K 0 00003BD3 A1[0000] MOV AX,WORD PTR [DMAADD] 0 00003BD6 F7D8 NEG AX ; Amount of room left in segment (know 344 ; less than 64K since max value of CX 345 ; is FFFF). 0 00003BD8 7501 JNZ NoDec 0 00003BDA 48 DEC AX 348 NoDec: 0 00003BDB 89C1 MOV CX,AX ; Can do this much 0 00003BDD E304 JCXZ NOROOM ; Silly user gave Xaddr of FFFF in segment 351 OK: 0 00003BDF C3 return 353 354 EOFERR: 0 00003BE0 07 POP ES ; ES:DI point to SFT 0 00003BE1 31C9 XOR CX,CX ; No bytes read 357 ;;;;;;;;;;; 7/18/86 358 ; MOV BYTE PTR [DISK_FULL],1 ; set disk full flag 359 ;;;;;;;;;;; 360 NOROOM: 0 00003BE3 5B POP BX ; Kill return address 0 00003BE4 F8 CLC 0 00003BE5 C3 return ; RETURN TO CALLER OF CALLER 364 EndProc SETUP 365 366 Break 367 368 ; Inputs: 369 ; CX = Length of disk transfer in bytes 370 ; ES:BP = Base of drive parameters 371 ; [BYTSECPOS] = Byte position witin first sector 372 ; Outputs: 373 ; [BYTCNT1] = Bytes to transfer in first sector 374 ; [SECCNT_DOS] = No. of whole sectors to transfer 375 ; [BYTCNT2] = Bytes to transfer in last sector 376 ; AX, BX, DX destroyed. No other registers affected. 377 378 procedure BREAKDOWN,near 378 ****************** warning: proc BREAKDOWN... [-w+user] 379 DOSAssume CS,,"BreakDown" 380 ASSUME ES:NOTHING 381 382 Assert ISDPB,,"BreakDown" 0 00003BE6 A1[0000] MOV AX,[BYTSECPOS] 0 00003BE9 89CB MOV BX,CX 0 00003BEB 09C0 OR AX,AX 0 00003BED 740E JZ SAVFIR ; Partial first sector? 0 00003BEF 262B4602 SUB AX,[ES:BP + dpb_sector_size] 0 00003BF3 F7D8 NEG AX ; Max number of bytes left in first sector 0 00003BF5 29C3 SUB BX,AX ; Subtract from total length 0 00003BF7 7304 JAE SAVFIR 0 00003BF9 01D8 ADD AX,BX ; Don't use all of the rest of the sector 0 00003BFB 31DB XOR BX,BX ; And no bytes are left 393 SAVFIR: 394 BYTCNT1 equ BytCnt1 ; NASM port label 0 00003BFD A3[0000] MOV [BYTCNT1],AX 0 00003C00 89D8 MOV AX,BX 0 00003C02 31D2 XOR DX,DX 0 00003C04 26F77602 DIV word [ES:BP + dpb_sector_size] ; How many whole sectors? 399 SECCNT_DOS equ SecCnt_DOS ; NASM port label 0 00003C08 A3[0000] MOV [SECCNT_DOS],AX 401 BYTCNT2 equ BytCnt2 ; NASM port label 0 00003C0B 8916[0000] MOV [BYTCNT2],DX ; Bytes remaining for last sector 0 00003C0F 0B16[0000] OR DX,[BYTCNT1] 0 00003C13 75D0 retnz ; NOT (BYTCNT1 = BYTCNT2 = 0) 0 00003C15 83F801 CMP AX,1 0 00003C18 75CB retnz 0 00003C1A 268B4602 MOV AX,[ES:BP + dpb_sector_size] ; Buffer EXACT one sector I/O 0 00003C1E A3[0000] MOV [BYTCNT2],AX 0 00003C21 8916[0000] MOV [SECCNT_DOS],DX ; DX = 0 410 RET45: 0 00003C25 C3 return 412 EndProc BreakDown 413 414 ; ES:DI points to SFT. This entry used by NET_READ 415 ; Carry set if to return error (CX=0,AX=error_sharing_violation). 416 ; Else do retrys. 417 ; ES:DI,DS,CX preserved 418 419 procedure READ_LOCK_VIOLATION,NEAR 419 ****************** warning: proc READ_LOCK_VIOLATION... [-w+user] 420 DOSAssume CS,,"Read_Lock_Violation" 421 ASSUME ES:NOTHING 422 423 Assert ISSFT,,"ReadLockViolation" 424 0 00003C26 C606[0000]00 MOV byte [READOP],0 426 ERR_ON_CHECK: 0 00003C2B 26F745020080 TEST word [ES:DI + sf_mode],sf_isfcb 0 00003C31 750E JNZ HARD_ERR 0 00003C33 51 PUSH CX 0 00003C34 268A4D02 MOV CL,BYTE PTR [ES:DI + sf_mode] 0 00003C38 80E1F0 AND CL,sharing_mask 0 00003C3B 80F900 CMP CL,sharing_compat 0 00003C3E 59 POP CX 0 00003C3F 7505 JNE NO_HARD_ERR 435 HARD_ERR: 0 00003C41 E8[0000] invoke LOCK_VIOLATION 0 00003C44 73DF retnc ; User wants Retrys 438 NO_HARD_ERR: 0 00003C46 31C9 XOR CX,CX ;No bytes transferred 0 00003C48 B82100 MOV AX,error_lock_violation 0 00003C4B F9 STC 0 00003C4C C3 return 443 444 EndProc READ_LOCK_VIOLATION 445 446 ; Same as READ_LOCK_VIOLATION except for READOP. 447 ; This entry used by NET_WRITE 448 procedure WRITE_LOCK_VIOLATION,NEAR 448 ****************** warning: proc WRITE_LOCK_VIOLATION... [-w+user] 449 DOSAssume CS,,"Write_Lock_Violation" 450 ASSUME ES:NOTHING 451 Assert ISSFT,,"WriteLockViolation" 452 0 00003C4D C606[0000]01 MOV byte [READOP],1 0 00003C52 EBD7 JMP ERR_ON_CHECK 455 456 EndProc WRITE_LOCK_VIOLATION 457 458 459 Break 460 461 ; Inputs: 462 ; Outputs of SETUP 463 ; Function: 464 ; Perform disk read 465 ; Outputs: 466 ; Carry clear 467 ; CX = No. of bytes read 468 ; ES:DI point to SFT 469 ; SFT offset and cluster pointers updated 470 ; Carry set 471 ; CX = 0 472 ; ES:DI point to SFT 473 ; AX has error code 474 475 procedure DISKREAD,NEAR 475 ****************** warning: proc DISKREAD... [-w+user] 476 DOSAssume CS,,"DiskRead" 477 ASSUME ES:NOTHING 478 479 Assert ISSFT,,"DISKREAD" 0 00003C54 26FF750B PUSH word [ES:DI + sf_firclus] ; set up 1st cluster # for FastSeek 0 00003C58 8F06[0000] POP word [FSeek_firclus] ; 11/5/86 482 0 00003C5C 268B4511 MOV AX,WORD PTR [ES:DI + sf_size] 0 00003C60 268B5D13 MOV BX,WORD PTR [ES:DI + sf_size+2] 0 00003C64 2B06[0000] SUB AX,WORD PTR [BYTPOS] 0 00003C68 1B1E[0200] SBB BX,WORD PTR [BYTPOS+2] 0 00003C6C 722D JB RDERR ;Read starts past EOF 0 00003C6E 750A JNZ ENUF ;More than 64k to EOF 0 00003C70 09C0 OR AX,AX 0 00003C72 7427 JZ RDERR ;Read starts at EOF 0 00003C74 39C8 CMP AX,CX 0 00003C76 7302 JAE ENUF ;I/O fits 0 00003C78 89C1 MOV CX,AX ;Limit read to up til EOF 494 ENUF: 0 00003C7A E8[0000] invoke CHECK_READ_LOCK ;IFS. check read lock ;AN000; 496 Read_Ok equ READ_OK ; NASM port label 0 00003C7D 7301 JNC Read_Ok ; There are no locks 0 00003C7F C3 return 499 500 READ_OK: 0 00003C80 C42E[0000] LES BP,[THISDPB] 502 Assert ISDPB,,"DISKREAD/ReadOK" 0 00003C84 268A4600 MOV AL,[ES:BP + dpb_drive] ; set up drive # for FastSeek 0 00003C88 A2[0000] MOV [FSeek_drive],AL ; 11/5/86 ;AN000; 505 0 00003C8B E858FF CALL BREAKDOWN 0 00003C8E 8B0E[0000] MOV CX,[CLUSNUM] 0 00003C92 E8[0000] invoke FNDCLUS 509 ;------------------------------------------------------------------------ 510 %IFN IBMCOPYRIGHT 0 00003C95 7217 JC SET_ACC_ERR_DS ; fix to take care of I24 fail 512 ; migrated from 330a - HKN 513 %ENDIF 514 ;------------------------------------------------------------------------ 0 00003C97 09C9 OR CX,CX 0 00003C99 741C JZ SKIPERR 517 RDERR: 0 00003C9B C606[0000]01 MOV byte [DISK_FULL],1 ;MS. EOF detection ;AN000; 0 00003CA0 B40E MOV AH,0EH ;MS. read/data/fail ;AN000; 0 00003CA2 E9[0000] transfer WRTERR22 0 00003CA5 E90001 RDLASTJ:JMP RDLAST 0 00003CA8 E91A01 SETSFTJ2: JMP SETSFT 523 524 CANOT_READ: 0 00003CAB 59 POP CX ; Clean stack 0 00003CAC 59 POP CX 0 00003CAD 5B POP BX 528 529 entry SET_ACC_ERR_DS 530 ASSUME DS:NOTHING,ES:NOTHING 0 00003CAE 161F Context DS 532 533 entry SET_ACC_ERR 534 DOSAssume CS,,"SET_ACC_ERR" 535 0 00003CB0 31C9 XOR CX,CX 0 00003CB2 B80500 MOV AX,error_access_denied 0 00003CB5 F9 STC 0 00003CB6 C3 return 540 541 SKIPERR: 542 LASTPOS equ LastPos ; NASM port label 0 00003CB7 8916[0000] MOV [LASTPOS],DX 0 00003CBB 891E[0000] MOV [CLUSNUM],BX 0 00003CBF 833E[0000]00 CMP word [BYTCNT1],0 0 00003CC4 7405 JZ RDMID 0 00003CC6 E8[0000] invoke BUFRD 0 00003CC9 72E3 JC SET_ACC_ERR_DS 549 RDMID: 0 00003CCB 833E[0000]00 CMP word [SECCNT_DOS],0 0 00003CD0 74D3 JZ RDLASTJ 0 00003CD2 E8[0000] invoke NEXTSEC 0 00003CD5 72D1 JC SETSFTJ2 0 00003CD7 C606[0000]01 MOV BYTE PTR [TRANS],1 ; A transfer is taking place 555 ONSEC: 0 00003CDC 8A16[0000] MOV DL,[SECCLUSPOS] 0 00003CE0 8B0E[0000] MOV CX,[SECCNT_DOS] 0 00003CE4 8B1E[0000] MOV BX,[CLUSNUM] 559 RDLP: 0 00003CE8 E8[0000] invoke OPTIMIZE 0 00003CEB 72C1 JC SET_ACC_ERR_DS 0 00003CED 57 PUSH DI 0 00003CEE 50 PUSH AX 0 00003CEF 53 PUSH BX 565 allowed_RETRY equ Allowed_RETRY ; NASM port equate 566 allowed_FAIL equ Allowed_FAIL ; NASM port equate 567 allowed_IGNORE equ Allowed_IGNORE ; NASM port equate 0 00003CF0 C606[0000]38 MOV byte [ALLOWED],allowed_RETRY + allowed_FAIL + allowed_IGNORE 0 00003CF5 8E1E[0200] MOV DS,WORD PTR [DMAADD+2] 570 ASSUME DS:NOTHING 0 00003CF9 52 PUSH DX 0 00003CFA 51 PUSH CX 573 %ifndef BUF2 574 invoke SET_RQ_SC_PARMS ;LB. do this for SC ;AN000; 575 576 %IF BUFFERFLAG 577 pushf 578 cmp byte [ss:BUF_EMS_SAFE_FLAG], 1 579 je safe_read 580 save_map equ SAVE_MAP ; NASM port label 581 call save_map 582 restore_user_map equ RESTORE_USER_MAP ; NASM port label 583 call restore_user_map 584 safe_read: 585 popf 586 %ENDIF 587 %endif 588 0 00003CFB E8[0000] invoke DREAD 590 591 %ifndef BUF2 592 %IF BUFFERFLAG 593 pushf 594 cmp byte [ss:BUF_EMS_SAFE_FLAG], 1 595 je safe_mapping 596 save_user_map equ SAVE_USER_MAP ; NASM port label 597 call save_user_map 598 restore_map equ RESTORE_MAP ; NASM port label 599 call restore_map 600 safe_mapping: 601 popf 602 %ENDIF 603 %endif 604 0 00003CFE 5B POP BX 0 00003CFF 5A POP DX 0 00003D00 7302 JNC SKP_CANOT_READ 0 00003D02 EBA7 JMP CANOT_READ 609 SKP_CANOT_READ: 0 00003D04 36891E[0000] MOV [ss:TEMP_VAR],BX ;LB. save sector count ;AN000; 0 00003D09 368916[0000] MOV [ss:TEMP_VAR2],DX ;LB. 1st sector ;AN000; 612 SCAN_NEXT: 613 ;;;;;;; invoke GETCURHEAD ;LB. get buffer header ;AN000; 0 00003D0E 52 PUSH DX ;LB. save regs ;AN000; 0 00003D0F 50 PUSH AX ;LB. ;AN000; 0 00003D10 53 PUSH BX ;LB. ;AN000; 617 %ifdef BUF2 0 00003D11 36833E[0000]00 cmp word [ss:BUF2_Dirty_Count], 0 0 00003D17 7505 jne yesdirty 620 %else 621 MOV AX,DX ;LB. 622 ; MOV DX,[HIGH_SECTOR] ;LB. HASH(sector#) and get entry # ;AN000; 623 XOR DX,DX ;LB. to avoid divide overflow ;AN000; 624 DIV word [ss:BUF_HASH_COUNT] ;LB. get remainder ;AN000; 625 ADD DX,DX ;LB. 8 bytes per entry ;AN000; 626 ADD DX,DX ;LB. ;AN000; 627 ADD DX,DX ;LB. times 8 ;AN000; 628 629 LDS DI,[ss:BUF_HASH_PTR] ;LB. get Hash Table addr ;AN000; 630 ADD DI,DX ;LB position to entry ;AN000; 631 Dirty_Count equ DIRTY_COUNT ; NASM port equate 632 CMP byte [DI + Dirty_Count],0 ;LB dirty hash entry ? ;AN000; 633 JNZ yesdirty ;LB yes and map it ;AN000; 634 %endif 0 00003D19 5B POP BX ;LB. ;AN000; 0 00003D1A 58 POP AX ;LB. ;AN000; 0 00003D1B 5A POP DX ;LB. ;AN000; 638 %IFN BUFFERFLAG 639 JMP SHORT end_scan ;LB. ;AN000; 640 %ELSE 641 END_SCAN equ end_scan ; NASM port label 0 00003D1C EB62 JMP END_SCAN 643 %ENDIF 644 645 yesdirty: 646 %ifdef BUF2 0 00003D1E 36C53E[0000] lds di, [ss:BUFFHEAD] 648 LASTBUFFER equ LastBuffer ; NASM port label 0 00003D23 36830E[0000]FF or WORD PTR [ss:LASTBUFFER], -1 ;LB. invalidate last buffer ;AN000; 650 %else 651 MOV WORD PTR [ss:CurHashEntry+2],DS ;LB. update current Hash entry ptr ;AN000; 652 MOV WORD PTR [ss:CurHashEntry],DI ;LB. ;AN000; 653 LASTBUFFER equ LastBuffer ; NASM port label 654 MOV WORD PTR [ss:LASTBUFFER],-1 ;LB. invalidate last buffer ;AN000; 655 MOV BX,[DI + EMS_PAGE_NUM] ;LB. logical page ;AN000; 656 657 %IFN BUFFERFLAG 658 LDS DI,[DI + BUFFER_BUCKET] ;LB. ds:di is 1st buffer addr ;AN000; 659 invalid instruction fixme 660 ; ldos: need seg override? 661 MOV [FIRST_BUFF_ADDR],DI ;LB. save first buff addr 1/19/88 ;AN000; 662 invoke SET_MAP_PAGE ;LB. activate handle if EMS there ;AN000; 663 %ELSE 664 ; int 3 665 push ds 666 push di ; save hash ptr 667 668 LDS DI,[DI + BUFFER_BUCKET] ;ds:di is 1st buffer addr 669 POP AX ; Recall transfer address 670 PUSH AX 671 PUSH DI ; Save search environment 672 PUSH DX ; F.C. no need for high sector, <64K 673 push cx 674 675 MOV DX,[ss:TEMP_VAR2] ;LB. get 1st sector # 676 SUB DX,WORD PTR [DI + buf_sector] ; How far into transfer? 677 NEG DX 678 MOV DI,AX 679 MOV AX,DX 680 MOV CX,[ES:BP + dpb_sector_size] 681 MUL CX 682 ADD DI,AX ; Put the buffer here 683 mov [ss:CURADD], di 684 685 pop cx 686 pop dx 687 pop di 688 689 invoke SET_MAP_PAGE ;LB. activate handle if EMS there ;AN000; 690 pop di ; restore hash ptr. 691 pop ds 692 LDS DI,[DI + BUFFER_BUCKET] ;LB. ds:di is 1st buffer addr ;AN000; 693 MOV [ss:FIRST_BUFF_ADDR],DI ;LB. save first buff addr 1/19/88 ;AN000; 694 %ENDIF 695 ;AN000; 696 %endif ; BUF2 0 00003D29 5B POP BX ;LB. ;AN000; 0 00003D2A 58 POP AX ;LB. ;AN000; 0 00003D2B 5A POP DX ;LB. ;AN000; 700 701 702 Assert ISDPB,,"DISKREAD/RdLp" 0 00003D2C 268A4600 MOV AL,[ES:BP + dpb_drive] 704 NXTBUF: ; Must see if one of these sectors is buffered 0 00003D30 E8[0000] invoke BUFF_RANGE_CHECK ;F.C. >32mb 0 00003D33 7305 JNC inrange ;LB. ;AN000; 707 %ifdef BUF2 0 00003D35 C53D lds di, [di + NEXTBUF] 709 %else 710 mov DI,[DI + buf_next] ;LB. get next buffer 1/19/88 ;AN000; 711 %endif 0 00003D37 EB42 JMP DONXTBUF ;LB. ;AN000; 0 00003D39 90 nop ; identicalise 714 inrange: 0 00003D3A F6450540 TEST byte [DI + buf_flags],buf_dirty 0 00003D3E 7438 JZ CLBUFF ; Buffer is clean, so OK 717 ; A sector has been read in when a dirty copy of it is in a buffer 718 ; The buffered sector must now be read into the right place 0 00003D40 58 POP AX ; Recall transfer address 0 00003D41 50 PUSH AX 0 00003D42 57 PUSH DI ; Save search environment 0 00003D43 52 PUSH DX ; F.C. no need for high sector, <64K 723 0 00003D44 368B16[0000] MOV DX,[ss:TEMP_VAR2] ;LB. get 1st sector # 0 00003D49 2B5508 SUB DX,WORD PTR [DI + buf_sector] ; How far into transfer? 0 00003D4C F7DA NEG DX 0 00003D4E 89FE MOV SI,DI 0 00003D50 89C7 MOV DI,AX 0 00003D52 89D0 MOV AX,DX 0 00003D54 268B4E02 MOV CX,[ES:BP + dpb_sector_size] 0 00003D58 F7E1 MUL CX 0 00003D5A 01C7 ADD DI,AX ; Put the buffer here 0 00003D5C 8D7410 LEA SI,[SI + BUFINSIZ] 0 00003D5F D1E9 SHR CX,1 0 00003D61 06 PUSH ES 0 00003D62 368E06[0200] MOV ES,WORD PTR [ss:DMAADD+2] 0 00003D67 F3A5 REP MOVSW 0 00003D69 7301 JNC EVENMOV 0 00003D6B A4 MOVSB 740 EVENMOV: 0 00003D6C 07 POP ES 0 00003D6D 5A POP DX 0 00003D6E 5F POP DI 0 00003D6F 268A4600 MOV AL,[ES:BP + dpb_drive] 0 00003D73 E8[0000] invoke SCANPLACE ;LB. done with this chain ;AN000; 0 00003D76 EB08 JMP SHORT end_scan ;LB. ;AN000; 747 CLBUFF: 0 00003D78 E8[0000] invoke SCANPLACE 749 DONXTBUF: 750 %ifdef BUF2 0 00003D7B 83FFFF cmp di, -1 752 %else 753 CMP DI,[ss:FIRST_BUFF_ADDR] ;LB. end of buffers ;AN000; 754 %endif 0 00003D7E 75B0 JNZ NXTBUF 756 end_scan: 0 00003D80 83C201 ADD DX,1 ;LB. next sector # ;AN000; 0 00003D83 368316[0000]00 ADC word [ss:HIGH_SECTOR],0 ;LB. ;AN000; 0 00003D89 36FF0E[0000] DEC word [ss:TEMP_VAR] ;LB. decrement count ;AN000; 0 00003D8E 7403 JZ SCAN_DONE ;LB. scan next sector ;AN000; 0 00003D90 E97BFF JMP SCAN_NEXT ;LB. scan next sector ;AN000; 762 SCAN_DONE: 0 00003D93 161F Context DS 0 00003D95 59 POP CX 0 00003D96 59 POP CX 0 00003D97 5B POP BX 0 00003D98 E30E JCXZ RDLAST 0 00003D9A E8[0000] invoke IsEOF ; test for eof on fat size 0 00003D9D 7326 JAE SETSFT 0 00003D9F B200 MOV DL,0 0 00003DA1 FF06[0000] INC word [LASTPOS] ; We'll be using next cluster 0 00003DA5 E940FF JMP RDLP 773 774 RDLAST: 0 00003DA8 A1[0000] MOV AX,[BYTCNT2] 0 00003DAB 09C0 OR AX,AX 0 00003DAD 7416 JZ SETSFT 0 00003DAF A3[0000] MOV [BYTCNT1],AX 0 00003DB2 E8[0000] invoke NEXTSEC 0 00003DB5 720E JC SETSFT 0 00003DB7 C706[0000]0000 MOV word [BYTSECPOS],0 0 00003DBD E8[0000] invoke BUFRD 0 00003DC0 7303 JNC SETSFT 0 00003DC2 E9E9FE JMP SET_ACC_ERR_DS 785 786 ; Inputs: 787 ; [NEXTADD],[CLUSNUM],[LASTPOS] set to determine transfer size 788 ; and set cluster fields 789 ; Function: 790 ; Update [THISSFT] based on the transfer 791 ; Outputs: 792 ; sf_position, sf_lstclus, and sf_cluspos updated 793 ; ES:DI points to [THISSFT] 794 ; CX No. of bytes transferred 795 ; Carry clear 796 797 entry SETSFT 798 DOSAssume CS,,"SetSFT" 799 ASSUME ES:NOTHING 800 0 00003DC5 C43E[0000] LES DI,[THISSFT] 802 803 ; Same as SETSFT except ES:DI already points to SFT 804 entry SETCLUS 805 DOSAssume CS,,"SetClus" 806 ASSUME ES:NOTHING 807 808 Assert ISSFT,,"SetClus" 0 00003DC9 8B0E[0000] MOV CX,[NEXTADD] 0 00003DCD 2B0E[0000] SUB CX,WORD PTR [DMAADD] ; Number of bytes transfered 0 00003DD1 26F745058000 TEST word [ES:DI + sf_flags],devid_device 812 ADDREC equ AddRec ; NASM port label 0 00003DD7 750E JNZ ADDREC ; don't set clusters if device 0 00003DD9 A1[0000] MOV AX,[CLUSNUM] 0 00003DDC 26894535 MOV [ES:DI + sf_lstclus],AX 0 00003DE0 A1[0000] MOV AX,[LASTPOS] 0 00003DE3 26894519 MOV [ES:DI + sf_cluspos],AX 818 819 ; Inputs: 820 ; ES:DI points to SFT 821 ; CX is No. Bytes transferred 822 ; Function: 823 ; Update the SFT offset based on the transfer 824 ; Outputs: 825 ; sf_position updated to point to first byte after transfer 826 ; ES:DI points to SFT 827 ; CX No. of bytes transferred 828 ; Carry clear 829 830 entry AddRec 831 DOSAssume CS,,"AddRec" 832 ASSUME ES:NOTHING 833 834 Assert ISSFT,,"AddRec" 0 00003DE7 E309 JCXZ RET28 ; If no records read, don't change position 0 00003DE9 26014D15 ADD WORD PTR [ES:DI + sf_position],CX ; Update current position 0 00003DED 2683551700 ADC WORD PTR [ES:DI + sf_position+2],0 0 00003DF2 F8 RET28: CLC 0 00003DF3 C3 return 840 EndProc DISKREAD 841 842 END 843 844 === Trace listing source: ../DOS/disk3.lst 1 ; SCCSID = @(#)disk3.asm 1.3 85/07/26 2 ; SCCSID = @(#)disk3.asm 1.3 85/07/26 3 ;TITLE DISK3 - Disk utility routines 4 ;NAME Disk3 5 ; Low level Read and write routines for local SFT I/O on files and devs 6 ; 7 ; DISKWRITE 8 ; WRTERR 9 ; 10 ; Revision history: 11 ; 12 ; AN000 version 4.00 Jan. 1988 13 ; 14 15 ; 16 ; get the appropriate segment definitions 17 ; 18 [list -] === Switch to base=008400h -> "DOSCODECODE" 22 section DOSCODECODE 23 [list -] 23 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 23 ****************** warning: out: BPB.INC... [-w+user] 23 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 23 ****************** warning: out: DEVSYM.INC... [-w+user] 23 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 31 32 %iassign Installed TRUE 33 34 i_need THISSFT,DWORD 35 i_need DMAADD,DWORD 36 i_need SecClusPos,BYTE 37 i_need ClusNum,WORD 38 i_need Trans,BYTE 39 i_need BytPos,4 40 i_need SecPos,DWORD ;F.C. >32mb ;AN000; 41 i_need BytSecPos,WORD 42 i_need BytCnt1,WORD 43 i_need BytCnt2,WORD 44 i_need SecCnt_DOS,WORD 45 i_need ThisDPB,DWORD 46 i_need LastPos,WORD 47 i_need ValSec,WORD ;F.C. >32mb ;AN000; 48 i_need GrowCnt,DWORD 49 i_need ALLOWED,BYTE 50 I_need JShare,DWORD 51 I_need FSeek_drive,BYTE ; DOS 4.00 ;AN000; 52 I_need FSeek_firclus,WORD ; DOS 4.00 ;AN000; 53 I_need FSeek_logclus,WORD ; DOS 4.00 ;AN000; 54 I_need HIGH_SECTOR,WORD ;F.C. >32mb ;AN000; 55 I_need HIGH_SECTOR_TEMP,WORD ;F.C. >32mb ;AN000; 56 I_need EXTERR,WORD ; DOS 4.00 ;AN000; 57 I_need EXTERR_LOCUS,BYTE ; DOS 4.00 ;AN000; 58 I_need EXTERR_ACTION,BYTE ; DOS 4.00 ;AN000; 59 I_need EXTERR_CLASS,BYTE ; DOS 4.00 ;AN000; 60 I_need EXITHOLD,DWORD ; DOS 4.00 ;AN000; 61 I_need DISK_FULL,BYTE ; DOS 4.00 ;AN000; 62 I_need SC_DRIVE,BYTE ; DOS 4.00 ;AN000; 63 I_need SC_CACHE_COUNT,WORD ; DOS 4.00 ;AN000; 64 I_need ThisDRV,BYTE ; DOS 4.00 ;AN000; 65 I_need User_In_AX,WORD ; DOS 4.00 ;AN000; 66 I_need DOS34_FLAG,WORD ; DOS 4.00 ;AN000; 67 I_need FIRST_BUFF_ADDR,WORD ; DOS 4.00 ;AN000; 68 69 %ifndef BUF2 70 %IF BUFFERFLAG 71 EXTRN SAVE_MAP:NEAR 72 EXTRN RESTORE_MAP:NEAR 73 EXTRN SAVE_USER_MAP:NEAR 74 EXTRN RESTORE_USER_MAP:NEAR 75 i_need BUF_EMS_SAFE_FLAG,BYTE 76 i_need BUF_EMS_MODE,BYTE 77 %ENDIF 78 %else 79 i_need BUFFHEAD,dword 80 %endif 81 82 83 Break 84 85 ; Inputs: 86 ; Outputs of SETUP 87 ; Function: 88 ; Perform disk write 89 ; Outputs: 90 ; Carry clear 91 ; CX = No. of bytes read 92 ; ES:DI point to SFT 93 ; SFT offset and cluster pointers updated 94 ; Carry set 95 ; CX = 0 96 ; ES:DI point to SFT 97 ; AX has error code 98 99 procedure DISKWRITE,NEAR 99 ****************** warning: proc DISKWRITE... [-w+user] 100 DOSAssume CS,,"DiskWrite" 101 ASSUME ES:NOTHING 102 103 Assert ISSFT,,"DiskWrite" 0 00003DF4 26FF750B PUSH word [ES:DI + sf_firclus] ; set up 1st cluster # for FastSeek 0 00003DF8 8F06[0000] POP word [FSeek_firclus] 106 0 00003DFC E8[0000] invoke CHECK_WRITE_LOCK ;IFS. check write lock ;AN000; 0 00003DFF 7304 JNC WRITE_OK ;IFS. lock check ok ;AN000; 0 00003E01 C3 return 110 111 WRTEOFJ: 0 00003E02 E93A02 JMP WRTEOF 113 114 WRITE_OK: 0 00003E05 26816505BFBF AND word [ES:DI + sf_flags],~ (sf_close_nodate | devid_file_clean) 116 ; Mark file as dirty, clear no date on close 117 THISDPB equ ThisDPB ; NASM port label 0 00003E0B C42E[0000] LES BP,[THISDPB] 119 Assert ISDPB,,"DiskWrite/WriteOk" 0 00003E0F 268A4600 MOV AL,[ES:BP + dpb_drive] ; set up drive # for FastSeek 0 00003E13 A2[0000] MOV [FSeek_drive],AL ; 11/5/86 DOS 4.00 122 0 00003E16 E8[0000] invoke BREAKDOWN 124 BYTPOS equ BytPos ; NASM port label 0 00003E19 A1[0000] MOV AX,WORD PTR [BYTPOS] 0 00003E1C 8B16[0200] MOV DX,WORD PTR [BYTPOS+2] 0 00003E20 E3E0 JCXZ WRTEOFJ ;Make the file length = sf_position 0 00003E22 01C8 ADD AX,CX 0 00003E24 83D200 ADC DX,0 ; AX:DX=byte after last byte accessed 130 ; 131 ; Make sure divide won't overflow 132 ; 0 00003E27 268B5E02 MOV BX,[ES:BP + dpb_sector_size] 134 ; CMP DX,BX ;F.C. >32mb 16 bit sector check ;AN000; 135 ; JAE WrtErr ;F.C. >32mb ;AN000; 136 0 00003E2B E8A402 CALL DIV32 ;F.C. perform 32 bit divide ;AN000; 0 00003E2E 89C3 MOV BX,AX ; Save last full sector 0 00003E30 09D2 OR DX,DX 0 00003E32 7508 JNZ CALCLUS 0 00003E34 83E801 SUB AX,1 ; AX must be zero base indexed ;AC000; 0 00003E37 831E[0000]00 SBB word [HIGH_SECTOR],0 ;F.C. >32mb ;AN000; 143 CALCLUS: 0 00003E3C FF36[0000] PUSH word [HIGH_SECTOR] ;F.C. >32mb ;AN000; 0 00003E40 E89E02 CALL SHR32 ;F.C. >32mb ;AN000; 0 00003E43 8F06[0000] POP word [HIGH_SECTOR] ;F.C. >32mb ;AN000; 147 148 ; SHR AX,CL ; Last cluster to be accessed 0 00003E47 50 PUSH AX 0 00003E48 52 PUSH DX ; Save the size of the "tail" 0 00003E49 06 PUSH ES 0 00003E4A C43E[0000] LES DI,[THISSFT] 153 Assert ISSFT,,"DiskWrite/CalClus" 0 00003E4E 268B4511 MOV AX,WORD PTR [ES:DI + sf_size] 0 00003E52 268B5513 MOV DX,WORD PTR [ES:DI + sf_size+2] 0 00003E56 07 POP ES 157 158 159 0 00003E57 50 PUSH AX ;F.C. >32mb ;AN000; 0 00003E58 89D0 MOV AX,DX ;F.C. >32mb ;AN000; 0 00003E5A 31D2 XOR DX,DX ;F.C. >32mb ;AN000; 0 00003E5C 26F77602 DIV word [ES:BP + dpb_sector_size] ;F.C. >32mb ;AN000; 0 00003E60 A3[0000] MOV [HIGH_SECTOR_TEMP],AX ;F.C. >32mb ;AN000; 0 00003E63 58 POP AX ;F.C. >32mb ;AN000; 166 0 00003E64 26F77602 DIV word [ES:BP + dpb_sector_size] 0 00003E68 89C1 MOV CX,AX ; Save last full sector of current file 0 00003E6A 09D2 OR DX,DX 0 00003E6C 7408 JZ NORNDUP 0 00003E6E 83C001 ADD AX,1 ; Round up if any remainder ;AC000; 0 00003E71 8316[0000]00 ADC word [HIGH_SECTOR_TEMP],0 ;F.C. >32mb ;AN000; 173 NORNDUP: 0 00003E76 FF36[0000] PUSH word [HIGH_SECTOR_TEMP] ;F.C. >32mb ;AN000; 175 VALSEC equ ValSec ; NASM port label 0 00003E7A 8F06[0200] POP WORD PTR [VALSEC+2] ;F.C. >32mb ;AN000; 0 00003E7E A3[0000] MOV WORD PTR [VALSEC],AX ;Number of sectors that have been written 0 00003E81 31C0 XOR AX,AX 179 GROWCNT equ GrowCnt ; NASM port label 0 00003E83 A3[0000] MOV WORD PTR [GROWCNT],AX 0 00003E86 A3[0200] MOV WORD PTR [GROWCNT+2],AX 0 00003E89 58 POP AX 183 0 00003E8A 8B3E[0000] MOV DI,[HIGH_SECTOR] ;F.C. >32mb ;AN000; 0 00003E8E 3B3E[0000] CMP DI,[HIGH_SECTOR_TEMP] ;F.C. >32mb ;AN000; 0 00003E92 7277 JB NOGROW ;F.C. >32mb ;AN000; 0 00003E94 7409 JZ lowsec ;F.C. >32mb ;AN000; 0 00003E96 29CB SUB BX,CX ;F.C. >32mb ;AN000; 0 00003E98 1B3E[0000] SBB DI,[HIGH_SECTOR_TEMP] ;F.C. >32mb di:bx no. of sectors ;AN000; 0 00003E9C EB0A JMP yesgrow ;F.C. >32mb ;AN000; 0 00003E9E 90 nop ; identicalise 192 lowsec: 0 00003E9F BF0000 MOV DI,0 ;F.C. >32mb 0 00003EA2 29CB SUB BX,CX ; Number of full sectors 0 00003EA4 7265 JB NOGROW 0 00003EA6 7456 JZ TESTTAIL 197 yesgrow: 0 00003EA8 89D1 MOV CX,DX 0 00003EAA 93 XCHG AX,BX 0 00003EAB 26F76602 MUL word [ES:BP + dpb_sector_size] ; Bytes of full sector growth 0 00003EAF 8916[0000] MOV [HIGH_SECTOR],DX ;F.C. >32mb save dx ;AN000; 0 00003EB3 A3[0000] MOV [HIGH_SECTOR_TEMP],AX ;F.C. >32mb save ax ;AN000; 0 00003EB6 89F8 MOV AX,DI ;F.C. >32mb ;AN000; 0 00003EB8 26F76602 MUL word [ES:BP + dpb_sector_size] ;F.C. >32mb do higher word multiply ;AN000; 0 00003EBC 0306[0000] ADD AX,[HIGH_SECTOR] ;F.C. >32mb add lower value ;AN000; 0 00003EC0 89C2 MOV DX,AX ;F.C. >32mb DX:AX is the result of ;AN000; 0 00003EC2 A1[0000] MOV AX,[HIGH_SECTOR_TEMP] ;F.C. >32mb a 32 bit multiply ;AN000; 208 0 00003EC5 29C8 SUB AX,CX ; Take off current "tail" 0 00003EC7 83DA00 SBB DX,0 ; 32-bit extension 0 00003ECA 01D8 ADD AX,BX ; Add on new "tail" 0 00003ECC 83D200 ADC DX,0 ; ripple tim's head off 0 00003ECF EB33 JMP SHORT SETGRW 214 HAVSTART: 215 ;int 3 0 00003ED1 89C1 MOV CX,AX 0 00003ED3 E8[0000] invoke SKPCLP 0 00003ED6 E320 JCXZ DOWRTJ 219 ;;; 11/5/86 FastSeek 0 00003ED8 8916[0000] MOV [FSeek_logclus],DX ; delete EOF (FFFFH) 0 00003EDC FF06[0000] INC word [FSeek_logclus] 0 00003EE0 E8[0000] invoke FastSeek_Truncate ; 223 ;;; 11/5/86 FastSeek 0 00003EE3 E8[0000] invoke ALLOCATE 0 00003EE6 7310 JNC DOWRTJ 226 227 entry WRTERR 228 DOSAssume CS,,"DiskWrite/WrtErr" 229 ASSUME ES:NOTHING 230 0 00003EE8 B40F MOV AH,0FH ;MS. write/data/fail/abort ;AN000; 232 entry WRTERR22 233 THISDRV equ ThisDRV ; NASM port label 0 00003EEA A0[0000] MOV AL,[THISDRV] ;MS. ;AN000; 0 00003EED E80302 CALL File_Handle_Fail_Error ;MS. issue disk full I24 0 00003EF0 B90000 MOV CX,0 ;No bytes transferred 237 ; XOR CX,CX ; will be deleted 0 00003EF3 C43E[0000] LES DI,[THISSFT] 239 Assert ISSFT,,"DiskWrite/WrtErr" 240 ; CLC 0 00003EF7 C3 return 242 0 00003EF8 EB66 DOWRTJ: JMP DOWRT 0 00003EFA 90 nop ; identicalise 245 246 ACC_ERRWJ: 0 00003EFB E93E01 JMP SET_ACC_ERRW 248 249 TESTTAIL: 0 00003EFE 29D0 SUB AX,DX 0 00003F00 7609 JBE NOGROW 0 00003F02 31D2 XOR DX,DX 253 SETGRW: 0 00003F04 A3[0000] MOV WORD PTR [GROWCNT],AX 0 00003F07 8916[0200] MOV WORD PTR [GROWCNT+2],DX 256 NOGROW: 0 00003F0B 58 POP AX 258 CLUSNUM equ ClusNum ; NASM port label 0 00003F0C 8B0E[0000] MOV CX,[CLUSNUM] ; First cluster accessed 0 00003F10 E8[0000] invoke FNDCLUS 0 00003F13 72E6 JC ACC_ERRWJ 0 00003F15 891E[0000] MOV [CLUSNUM],BX 263 LASTPOS equ LastPos ; NASM port label 0 00003F19 8916[0000] MOV [LASTPOS],DX 265 ;;; 11/5/86 FastSeek 0 00003F1D A3[0000] MOV [FSeek_logclus],AX ; set up last position 0 00003F20 29D0 SUB AX,DX ; Last cluster minus current cluster 0 00003F22 743C JZ DOWRT ; If we have last clus, we must have first 0 00003F24 E3AB JCXZ HAVSTART ; See if no more data 0 00003F26 51 PUSH CX ; No. of clusters short of first 0 00003F27 89C1 MOV CX,AX 272 273 ;;; 11/5/86 FastSeek 0 00003F29 833E[0000]00 CMP word [CLUSNUM],0 ;FS. null file ;AN000; 0 00003F2E 740B JZ NULL_FILE ;FS. yes ;AN000; 0 00003F30 8916[0000] MOV [FSeek_logclus],DX ;FS. delete EOF (FFFFH) ;AN000; 0 00003F34 FF06[0000] INC word [FSeek_logclus] ;FS. ;AN000; 0 00003F38 E8[0000] invoke FastSeek_Truncate ;FS. ;AN000; 279 NULL_FILE: 280 ;;; 11/5/86 FastSeek 0 00003F3B E8[0000] invoke ALLOCATE 0 00003F3E 58 POP AX 0 00003F3F 72A7 JC WRTERR 0 00003F41 89C1 MOV CX,AX 0 00003F43 8B16[0000] MOV DX,[LASTPOS] 0 00003F47 42 INC DX 0 00003F48 49 DEC CX 0 00003F49 740D JZ NOSKIP 289 ;;; 11/5/86 FastSeek 0 00003F4B 8916[0000] MOV [FSeek_logclus],DX ; 0 00003F4F 010E[0000] ADD [FSeek_logclus],CX ; set up last position 0 00003F53 E8[0000] invoke SKPCLP 0 00003F56 72A3 JC ACC_ERRWJ 294 NOSKIP: 0 00003F58 891E[0000] MOV [CLUSNUM],BX 0 00003F5C 8916[0000] MOV [LASTPOS],DX 297 DOWRT: 298 BYTCNT1 equ BytCnt1 ; NASM port label 0 00003F60 833E[0000]00 CMP word [BYTCNT1],0 0 00003F65 7409 JZ WRTMID 0 00003F67 8B1E[0000] MOV BX,[CLUSNUM] 0 00003F6B E8[0000] invoke BUFWRT 0 00003F6E 728B JC ACC_ERRWJ 304 WRTMID: 305 SECCNT_DOS equ SecCnt_DOS ; NASM port label 0 00003F70 A1[0000] MOV AX,[SECCNT_DOS] 0 00003F73 09C0 OR AX,AX 0 00003F75 7503 JNZ havemid 0 00003F77 E98500 JMP WRTLAST 310 havemid: 311 SECPOS equ SecPos ; NASM port label 0 00003F7A 0106[0000] ADD WORD PTR [SECPOS],AX 0 00003F7E 8316[0200]00 ADC WORD PTR [SECPOS+2],0 ;F.C. >32mb ;AN000; 0 00003F83 E8[0000] invoke NEXTSEC 0 00003F86 7303 JNC gotok 0 00003F88 E970FF JMP ACC_ERRWJ 317 gotok: 318 TRANS equ Trans ; NASM port label 0 00003F8B C606[0000]01 MOV BYTE PTR [TRANS],1 ; A transfer is taking place 320 SECCLUSPOS equ SecClusPos ; NASM port label 0 00003F90 8A16[0000] MOV DL,[SECCLUSPOS] 0 00003F94 8B1E[0000] MOV BX,[CLUSNUM] 0 00003F98 8B0E[0000] MOV CX,[SECCNT_DOS] 324 WRTLP: 0 00003F9C E8[0000] invoke OPTIMIZE 0 00003F9F 7303 JNC wokok 0 00003FA1 E957FF JMP ACC_ERRWJ 328 wokok: 0 00003FA4 57 PUSH DI 0 00003FA5 50 PUSH AX 0 00003FA6 52 PUSH DX 0 00003FA7 53 PUSH BX 333 Assert ISDPB,,"DiskWrite/WrtLp" 0 00003FA8 268A4600 MOV AL,[ES:BP + dpb_drive] 0 00003FAC A2[0000] MOV [SC_DRIVE],AL ;LB. save it for INVALIDATE_SC ;AN000; 0 00003FAF 51 PUSH CX ;LB. ;AN000; 0 00003FB0 FF36[0000] PUSH word [HIGH_SECTOR] ;LB. ;AN000; 338 %ifndef BUF2 339 SCANNEXT: ;LB. ;AN000; 340 invoke GETCURHEAD ;LB. ;AN000; 341 %else 0 00003FB4 36C53E[0000] lds di, [ss:BUFFHEAD] 343 %endif 344 ASSUME DS:NOTHING 345 NEXTBUFF: ; Search for buffers 346 %ifndef BUF2 347 CMP word [ss:SC_CACHE_COUNT],0 ;LB. SC support ? ;AN000; 348 JZ nosc ;LB. no ;AN000; 349 PUSH AX ;LB. save reg ;AN000; 350 PUSH CX ;LB. save reg ;AN000; 351 PUSH DX ;LB. save reg ;AN000; 352 invoke INVALIDATE_SC ;LB. invalidate SC ;AN000; 353 POP DX ;LB. save reg ;AN000; 354 POP CX ;LB. save reg ;AN000; 355 POP AX ;LB. save reg ;AN000; 356 nosc: 357 %endif 0 00003FB9 E8AE01 CALL BUFF_RANGE_CHECK ;F.C. >32mb ;AN000; 0 00003FBC 7305 JNC inrange2 ;F.C. >32mb ;AN000; 360 %ifdef BUF2 0 00003FBE C53D lds di, [di + NEXTBUF] 362 %else 363 mov DI,[DI + buf_next] ;LB. get next buffer 1/19/88 ;AN000; 364 %endif 0 00003FC0 EB12 JMP DONEXTBUFF ;LB. ;AN000; 0 00003FC2 90 nop ; identicalise 367 inrange2: 0 00003FC3 F6450540 TEST byte [DI + buf_flags],buf_dirty ;LB. if dirty ;AN000; 0 00003FC7 7403 JZ not_dirty ;LB. ;AN000; 0 00003FC9 E8[0000] invoke DEC_DIRTY_COUNT ;LB. then decrement dirty count ;AN000; 371 not_dirty: 372 %ifdef BUF2 0 00003FCC C74504FF00 MOV WORD PTR [DI + BUFDRV], 00FFH 374 ; Free the buffer, it is being over written 375 %else 376 MOV WORD PTR [DI + buf_ID], 00FFH ; Free the buffer, it is being over written 377 %endif 0 00003FD1 E8[0000] invoke SCANPLACE 379 DONEXTBUFF: 380 %ifdef BUF2 0 00003FD4 83FFFF cmp di, -1 382 %else 383 CMP DI,[ss:FIRST_BUFF_ADDR] ;LB. end of chain ;AN000; 384 %endif 0 00003FD7 75E0 JNZ NEXTBUFF ;LB. no ;AN000; 386 %ifndef BUF2 387 ADD DX,1 ;LB. next sector number ;AN000; 388 ADC word [ss:HIGH_SECTOR],0 ;LB. ;AN000; 389 LOOP SCANNEXT ;LB. check again ;AN000; 390 %endif 0 00003FD9 368F06[0000] POP word [ss:HIGH_SECTOR] ;LB. ;AN000; 0 00003FDE 59 POP CX ;LB. get count back ;AN000; 393 0 00003FDF 5B POP BX 0 00003FE0 5A POP DX 0 00003FE1 368E1E[0200] MOV DS,WORD PTR [ss:DMAADD+2] 397 allowed_RETRY equ Allowed_RETRY ; NASM port equate 398 allowed_FAIL equ Allowed_FAIL ; NASM port equate 399 allowed_IGNORE equ Allowed_IGNORE ; NASM port equate 0 00003FE6 36C606[0000]38 MOV byte [ss:ALLOWED],allowed_RETRY + allowed_FAIL + allowed_IGNORE 401 402 %ifndef BUF2 403 %IF BUFFERFLAG 404 pushf 405 cmp byte [ss:BUF_EMS_MODE], -1 406 je safe_write 407 save_map equ SAVE_MAP ; NASM port label 408 call save_map 409 restore_user_map equ RESTORE_USER_MAP ; NASM port label 410 call restore_user_map 411 safe_write: 412 popf 413 %ENDIF 414 %endif 415 0 00003FEC E8[0000] invoke DWRITE 417 418 %ifndef BUF2 419 %IF BUFFERFLAG 420 pushf 421 cmp byte [ss:BUF_EMS_MODE], -1 422 je safe_map 423 save_user_map equ SAVE_USER_MAP ; NASM port label 424 call save_user_map 425 restore_map equ RESTORE_MAP ; NASM port label 426 call restore_map 427 safe_map: 428 popf 429 %ENDIF 430 %endif 431 0 00003FEF 59 POP CX 0 00003FF0 5B POP BX 0 00003FF1 161F Context DS 0 00003FF3 7247 JC SET_ACC_ERRW 0 00003FF5 E308 JCXZ WRTLAST 0 00003FF7 B200 MOV DL,0 0 00003FF9 FF06[0000] INC word [LASTPOS] ; We'll be using next cluster 0 00003FFD EB9D JMP WRTLP 440 441 WRTLAST: 442 BYTCNT2 equ BytCnt2 ; NASM port label 0 00003FFF A1[0000] MOV AX,[BYTCNT2] 0 00004002 09C0 OR AX,AX 0 00004004 7413 JZ FINWRT 0 00004006 A3[0000] MOV [BYTCNT1],AX 0 00004009 E8[0000] invoke NEXTSEC 0 0000400C 722E JC SET_ACC_ERRW 449 BYTSECPOS equ BytSecPos ; NASM port label 0 0000400E C706[0000]0000 MOV word [BYTSECPOS],0 0 00004014 E8[0000] invoke BUFWRT 0 00004017 7223 JC SET_ACC_ERRW 453 FINWRT: 0 00004019 C43E[0000] LES DI,[THISSFT] 455 Assert ISSFT,,"DiskWrite/FinWrt" 0 0000401D A1[0000] MOV AX,WORD PTR [GROWCNT] 0 00004020 8B0E[0200] MOV CX,WORD PTR [GROWCNT+2] 0 00004024 09C0 OR AX,AX 459 UPDATE_size equ Update_size ; NASM port label 0 00004026 7502 JNZ UPDATE_size 0 00004028 E30F JCXZ SAMSIZ 462 Update_size: 0 0000402A 26014511 ADD WORD PTR [ES:DI + sf_size],AX 0 0000402E 26114D13 ADC WORD PTR [ES:DI + sf_size+2],CX 465 ; 466 ; Make sure that all other SFT's see this growth also. 467 ; 0 00004032 B80100 MOV AX,1 469 %if installed 0 00004035 FF1E[3800] call far [JShare + 14 * 4] 471 %else 472 Call ShSU 473 %endif 474 SAMSIZ: 0 00004039 E9[0000] transfer SETCLUS ; ES:DI already points to SFT 476 477 SET_ACC_ERRW: 0 0000403C E9[0000] transfer SET_ACC_ERR_DS 479 480 WRTEOF: 0 0000403F 89C1 MOV CX,AX 0 00004041 09D1 OR CX,DX 0 00004043 7452 JZ KILLFIL 0 00004045 83E801 SUB AX,1 0 00004048 83DA00 SBB DX,0 486 0 0000404B 53 PUSH BX 0 0000404C 268B5E02 MOV BX,[ES:BP + dpb_sector_size] ;F.C. >32mb ;AN000; 0 00004050 E87F00 CALL DIV32 ;F.C. >32mb ;AN000; 0 00004053 5B POP BX ;F.C. >32mb ;AN000; 0 00004054 E88A00 CALL SHR32 ;F.C. >32mb ;AN000; 492 493 494 ; SHR AX,CL 0 00004057 89C1 MOV CX,AX 0 00004059 E8[0000] invoke FNDCLUS 497 SET_ACC_ERRWJ2: 0 0000405C 72DE JC SET_ACC_ERRW 499 ;;; 11/5/86 FastSeek 0 0000405E 8916[0000] MOV [FSeek_logclus],DX ; truncate clusters starting from DX 0 00004062 E8[0000] invoke FastSeek_Truncate 502 ;;; 11/5/86 FastSeek 0 00004065 E326 JCXZ RELFILE 0 00004067 E8[0000] invoke ALLOCATE 0 0000406A 721E JC WRTERRJ ;;;;;;;;; disk full 506 UPDATE: 0 0000406C C43E[0000] LES DI,[THISSFT] 508 Assert ISSFT,,"DiskWrite/update" 0 00004070 A1[0000] MOV AX,WORD PTR [BYTPOS] 0 00004073 26894511 MOV WORD PTR [ES:DI + sf_size],AX 0 00004077 A1[0200] MOV AX,WORD PTR [BYTPOS+2] 0 0000407A 26894513 MOV WORD PTR [ES:DI + sf_size+2],AX 513 ; 514 ; Make sure that all other SFT's see this growth also. 515 ; 0 0000407E B80200 MOV AX,2 517 %if installed 0 00004081 FF1E[3800] Call far [JShare + 14 * 4] 519 %else 520 Call ShSU 521 %endif 0 00004085 31C9 XOR CX,CX 0 00004087 E9[0000] transfer ADDREC 524 0 0000408A E95BFE WRTERRJ: JMP WRTERR 526 ;;;;;;;;;;;;;;;; 7/18/86 527 ;;;;;;;;;;;;;;;;; 528 RELFILE: 0 0000408D BAFFFF MOV DX,0FFFFH 0 00004090 E8[0000] invoke RELBLKS 531 Set_Acc_ERRWJJ: 0 00004093 72C7 JC SET_ACC_ERRWJ2 0 00004095 EBD5 JMP SHORT UPDATE 534 535 KILLFIL: 0 00004097 31DB XOR BX,BX 0 00004099 06 PUSH ES 0 0000409A C43E[0000] LES DI,[THISSFT] 539 Assert ISSFT,,"DiskWrite/KillFil" 0 0000409E 26895D19 MOV [ES:DI + sf_cluspos],BX 0 000040A2 26895D35 MOV [ES:DI + sf_lstclus],BX 0 000040A6 26875D0B XCHG BX,[ES:DI + sf_firclus] 0 000040AA 07 POP ES 544 ;; 11/5/86 FastSeek 0 000040AB E8[0000] invoke Delete_FSeek ; delete fastseek entry 546 0 000040AE 09DB OR BX,BX 548 UPDATEJ equ UpDateJ ; NASM port label 0 000040B0 741E JZ UPDATEJ 550 ;; 10/23/86 FastOpen update 0 000040B2 06 PUSH ES ; since first cluster # is 0 0 000040B3 55 PUSH BP ; we must delete the old cache entry 0 000040B4 50 PUSH AX 0 000040B5 51 PUSH CX 0 000040B6 52 PUSH DX 0 000040B7 C42E[0000] LES BP,[THISDPB] ; get current DPB 0 000040BB 268A5600 MOV DL,[ES:BP + dpb_drive] ; get current drive 0 000040BF 89D9 MOV CX,BX ; first cluster # 0 000040C1 B402 MOV AH,2 ; delete cache entry by drive:firclus 0 000040C3 E8[0000] invoke FastOpen_Update ; call fastopen 0 000040C6 5A POP DX 0 000040C7 59 POP CX 0 000040C8 58 POP AX 0 000040C9 5D POP BP 0 000040CA 07 POP ES 566 ;; 10/23/86 FastOpen update 567 0 000040CB E8[0000] invoke RELEASE 569 SET_ACC_ERRWJJ equ Set_Acc_ERRWJJ ; NASM port label 0 000040CE 72C3 JC SET_ACC_ERRWJJ 571 UpDateJ: 0 000040D0 EB9A JMP UPDATE 573 EndProc DISKWRITE 574 575 576 577 Break 578 579 ; Inputs: 580 ; DX:AX = 32 bit dividend BX= divisor 581 ; Function: 582 ; Perform 32 bit division 583 ; Outputs: 584 ; [HIGH_SECTOR]:AX = quotiend , DX= remainder 585 586 procedure DIV32,NEAR 586 ****************** warning: proc DIV32... [-w+user] 587 ASSUME DS:NOTHING,ES:NOTHING 588 589 0 000040D2 50 PUSH AX ;F.C. >32mb ;AN000; 0 000040D3 89D0 MOV AX,DX ;F.C. >32mb ;AN000; 0 000040D5 31D2 XOR DX,DX ;F.C. >32mb ;AN000; 0 000040D7 F7F3 DIV BX ;F.C. >32mb ;AN000; 0 000040D9 36A3[0000] MOV [ss:HIGH_SECTOR],AX ;F.C. >32mb ;AN000; 0 000040DD 58 POP AX ;F.C. >32mb ;AN000; 596 597 0 000040DE F7F3 DIV BX ; AX=last sector accessed 0 000040E0 C3 return 600 601 EndProc DIV32 602 603 Break 604 605 ; Inputs: 606 ; [HIGH_SECTOR]:AX = 32 bit sector number 607 ; Function: 608 ; Perform 32 bit shift right 609 ; Outputs: 610 ; AX= cluster number 611 612 procedure SHR32,NEAR 612 ****************** warning: proc SHR32... [-w+user] 613 ASSUME DS:NOTHING,ES:NOTHING 614 0 000040E1 31C9 xor cx, cx 0 000040E3 268A4E05 MOV CL,[ES:BP + dpb_cluster_shift] 617 entry ROTASHFT ;F.C. >32mb ;AN000; 0 000040E7 E309 jcxz norota ;F.C. >32mb ;AN000; 619 ROTASHFT2: 0 000040E9 36D12E[0000] shr word [ss:HIGH_SECTOR],1 ;F.C. >32mb ;AN000; 0 000040EE D1D8 RCR AX,1 ;F.C. >32mb ;AN000; 0 000040F0 E2F7 LOOP ROTASHFT2 ;F.C. >32mb: ;AN000; 623 norota: 0 000040F2 C3 return 625 626 EndProc SHR32 627 628 629 ; Issue File Handle Fail INT 24 Critical Error 630 ; Input: Disk_Full=0 ok 631 ; 1 disk full or EOF 632 ; Function: issue critical error for disk full or EOF error 633 ; 634 ; OutPut: carry clear , no I24 635 ; carry set, fail from I24 636 637 procedure File_Handle_Fail_Error,NEAR ;AN000; 637 ****************** warning: proc File_Handle_Fail_Error... [-w+user] 638 ASSUME ES:NOTHING,DS:NOTHING ;AN000; 639 ;AN000; 0 000040F3 36803E[0000]00 CMP byte [ss:DISK_FULL],0 ;MS. disk full or EOF ;AN000; 0 000040F9 746D JZ Fexit ;MS. no ;AN000; 0 000040FB 36F706[0000]4000 TEST word [ss:DOS34_FLAG],Disable_EOF_I24 ;MS. check input status ? ;AN000; 0 00004102 7564 JNZ Fexit ;MS. yes ;AN000; 644 ;AN000; 0 00004104 36C43E[0000] LES DI,[ss:THISSFT] ;MS. get current SFT ;AN000; 646 ; LES DI,[ES:DI.sf_DEVPTR];MS. get device header ;AN000; 0 00004109 26F745050001 TEST word [ES:DI + sf_flags],Handle_Fail_I24 ;MS. gen I24 ? ;AN000; 0 0000410F 7457 JZ Fexit ;MS. no ;AN000; 0 00004111 1E PUSH DS ;MS. save DS ;AN000; 0 00004112 F6C401 TEST AH,1 ;MS. READ ? ;AN000; 0 00004115 7409 JZ readeof ;MS. yes ;AN000; 652 error_Handle_Disk_Full equ error_handle_Disk_Full ; NASM port equate 0 00004117 36C706[0000]2700 MOV word [ss:EXTERR],error_Handle_Disk_Full ;MS. set extended error ;AN000; 0 0000411E EB07 JMP SHORT errset ;MS. set extended error ;AN000; 655 readeof: 656 error_Handle_EOF equ error_handle_EOF ; NASM port equate 0 00004120 36C706[0000]2600 MOV word [ss:EXTERR],error_Handle_EOF ;MS. set extended error ;AN000; 658 errset: 0 00004127 36C606[0000]01 MOV byte [ss:EXTERR_CLASS],errCLASS_OutRes ;MS. set class ;AN000; 0 0000412D 36C606[0000]04 MOV byte [ss:EXTERR_ACTION],errACT_Abort ;MS. set action ;AN000; 0 00004133 36C606[0000]01 MOV byte [ss:EXTERR_LOCUS],errLOC_Unk ;MS. set locus ;AN000; 0 00004139 368C06[0200] MOV word ptr [ss:EXITHOLD + 2],ES ;MS. save es:bp in exithold ;AN000; 0 0000413E 36892E[0000] MOV word ptr [ss:EXITHOLD],BP ;MS. ;AN000; 0 00004143 26F745058000 TEST word [ES:DI + sf_flags],devid_device ;MS. device ? ;AN000; 0 00004149 7509 JNZ chardev2 ;MS. yes ;AN000; 666 sf_DEVPTR equ sf_devptr ; NASM port equate 0 0000414B 26C57507 LDS SI,[ES:DI + sf_DEVPTR] ;MS. get dpb ;AN000; 0 0000414F C57413 LDS SI,[SI + dpb_driver_addr] ;MS. get drive device haeder ;AN000; 0 00004152 EB04 JMP SHORT doi24 ;MS. gen I24 ? ;AN000; 670 chardev2: 0 00004154 26C57507 LDS SI,[ES:DI + sf_DEVPTR] ;MS. get chr dev header ;AN000; 672 doi24: 0 00004158 8CDD MOV BP,DS ;MS. bp:si -> device header ;AN000; 0 0000415A BF0C00 MOV DI,error_I24_gen_failure ;MS. general error ;AN000; 0 0000415D E8[0000] invoke NET_I24_ENTRY ;MS. issue I24 ;AN000; 0 00004160 F9 STC ;MS. must be fail ;AN000; 0 00004161 1F POP DS ;MS. restore DS ;AN000; 0 00004162 36A1[0000] MOV AX,[ss:EXTERR] ;MS. set error ;AN000; 0 00004166 EB01 JMP SHORT Fend ;MS. exit ;AN000; 680 Fexit: ;AN000; 0 00004168 F8 CLC ;MS. clear carry ;AN000; 682 Fend: ;AN000; 0 00004169 C3 return ;MS. ;AN000; 684 ;AN000; 685 EndProc File_Handle_Fail_Error ;AN000; 686 687 688 Break 689 690 ; Inputs: 691 ; DS:DI -> buffer. AL= drive # 692 ; [HIGH_SECTOR]:DX = sector # 693 ; Function: 694 ; check if sector is in the buffer 695 ; Outputs: 696 ; carry clear= in the range 697 ; set = not in the range 698 699 procedure BUFF_RANGE_CHECK,NEAR 699 ****************** warning: proc BUFF_RANGE_CHECK... [-w+user] 700 ASSUME DS:NOTHING,ES:NOTHING 701 0 0000416A 395508 CMP WORD PTR [DI + buf_sector],DX ;AN000; 0 0000416D 750F JNZ DONEXTBUFF2 ; not this sector ;F.C. >32mb ;AN000; 0 0000416F 368B36[0000] MOV SI,[ss:HIGH_SECTOR] ;F.C. >32mb ;AN000; 0 00004174 39750A CMP WORD PTR [DI + buf_sector+2],SI ;F.C. >32mb ;AN000; 0 00004177 7505 JNZ DONEXTBUFF2 ; Not for this drive 0 00004179 3A4504 CMP AL,[DI + buf_ID] 0 0000417C 7401 JZ secfound ; Buffer has the sector ;AN000; 709 DONEXTBUFF2: 0 0000417E F9 STC 711 secfound: 0 0000417F C3 return 713 714 EndProc BUFF_RANGE_CHECK 715 716 END 717 718 === Trace listing source: ../DOS/dir.lst 1 ; SCCSID = @(#)dir.asm 1.1 85/04/10 2 ; SCCSID = @(#)dir.asm 1.1 85/04/10 3 ;TITLE DIR - Directory and path cracking 4 ;NAME Dir 5 ; Main Path cracking routines, low level search routines 6 ; 7 ; FindEntry 8 ; SEARCH 9 ; Srch 10 ; NEXTENT 11 ; MetaCompare 12 ; NEXTENTRY 13 ; GETENTRY 14 ; GETENT 15 ; SETDIRSRCH 16 ; SETROOTSRCH 17 ; 18 ; Revision history: 19 ; 20 ; A000 version 4.00 Jan. 1988 21 ; 22 23 ; 24 ; get the appropriate segment definitions 25 ; 26 [list -] === Switch to base=008400h -> "DOSCODECODE" 31 section DOSCODECODE 32 [list -] 32 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 32 ****************** warning: out: BPB.INC... [-w+user] 32 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 38 39 %ifndef Kanji 40 %iassign Kanji 0 41 %endif 42 43 i_need EntFree,WORD 44 i_need DirStart,WORD 45 i_need LastEnt,WORD 46 i_need ClusNum,WORD 47 i_need CurBuf,DWORD 48 i_need Attrib,BYTE 49 i_need DelAll,BYTE 50 i_need VolID,BYTE 51 i_need Name1,BYTE 52 i_need ThisDPB,DWORD 53 i_need EntLast,WORD 54 i_need Creating,BYTE 55 i_need SecClusPos,BYTE 56 i_need ClusFac,BYTE 57 i_need Cluster_Factor_EDR,WORD 58 i_need NxtClusNum,WORD 59 i_need DirSec,DWORD ;AN000; 60 I_need FastOpenFlg,BYTE ;AN000; 61 I_need HIGH_SECTOR,WORD ;AN000; 62 63 Break 64 65 ; Inputs: 66 ; [THISDPB] set 67 ; [SECCLUSPOS] = 0 68 ; [DIRSEC] = Starting directory sector number 69 ; [CLUSNUM] = Next cluster of directory 70 ; [CLUSFAC] = Sectors/Cluster 71 ; [NAME1] = Name to look for 72 ; Function: 73 ; Find file name in disk directory. 74 ; "?" matches any character. 75 ; Outputs: 76 ; Carry set if name not found 77 ; ELSE 78 ; Zero set if attributes match (always except when creating) 79 ; AH = Device ID (bit 7 set if not disk) 80 ; [THISDPB] = Base of drive parameters 81 ; DS = DOSGROUP 82 ; ES = DOSGROUP 83 ; [CURBUF+2]:BX = Pointer into directory buffer 84 ; [CURBUF+2]:SI = Pointer to First Cluster field in directory entry 85 ; [CURBUF] has directory record with match 86 ; [NAME1] has file name 87 ; [LASTENT] is entry number of the entry 88 ; All other registers destroyed. 89 90 procedure SEARCH,near 90 ****************** warning: proc SEARCH... [-w+user] 91 92 entry FindEntry 93 DOSAssume CS,,"FindEntry" 94 ASSUME ES:NOTHING 95 0 00004180 E8[0000] invoke STARTSRCH 0 00004183 A0[0000] MOV AL,[Attrib] 0 00004186 249E AND AL,~ attr_ignore ; Ignore useless bits 0 00004188 3C08 CMP AL,attr_volume_id ; Looking for vol ID only ? 0 0000418A 7503 JNZ NOTVOLSRCH ; No 0 0000418C E88F01 CALL SETROOTSRCH ; Yes force search of root 102 NOTVOLSRCH: 0 0000418F E81601 CALL GETENTRY 0 00004192 7303 JNC Srch 0 00004194 E9A000 JMP SETESRET 106 107 entry Srch 108 0 00004197 1E PUSH DS 110 CURBUF equ CurBuf ; NASM port label 0 00004198 8E1E[0200] MOV DS,WORD PTR [CURBUF+2] 112 ASSUME DS:NOTHING 0 0000419C 8A27 MOV AH,BYTE PTR [BX] 0 0000419E 08E4 OR AH,AH ; End of directory? 0 000041A0 7440 JZ FREE 116 DELALL equ DelAll ; NASM port label 0 000041A2 363A26[0000] CMP AH,BYTE PTR [ss:DELALL] ; Free entry? 0 000041A7 7439 JZ FREE 0 000041A9 F6470B08 TEST BYTE PTR [BX+11],attr_volume_id 120 ; Volume ID file? 0 000041AD 740B JZ CHKFNAM ; NO 0 000041AF F6470BD7 test byte [bx + 11], ~ (attr_volume_id | attr_archive) 0 000041B3 7505 jnz CHKFNAM ; possible LFN ? then skip --> 124 VOLID equ VolID ; NASM port label 0 000041B5 36FE06[0000] INC BYTE PTR [ss:VOLID] 126 CHKFNAM: 127 ; Context ES 128 ASSUME ES:DOSGroup 0 000041BA 8CD6 MOV SI,SS 0 000041BC 8EC6 MOV ES,SI 0 000041BE 89DE MOV SI,BX 132 NAME1 equ Name1 ; NASM port label 0 000041C0 BF[0000] MOV DI,OFFSET NAME1 wrt DOSGROUP 134 ;;;;; 7/29/86 0 000041C3 36803E[0000]E5 CMP BYTE PTR [ss:NAME1],0E5H ; special char check 0 000041C9 7506 JNZ NO_E5 0 000041CB 36C606[0000]05 MOV BYTE PTR [ss:NAME1],05H 138 NO_E5: 139 ;;;;; 7/29/86 0 000041D1 E86600 CALL MetaCompare 0 000041D4 7428 JZ FOUND 0 000041D6 1F POP DS 143 144 entry NEXTENT 145 DOSAssume CS,,"NextEnt" 146 147 Assert ISDPB,<,>,"NextEnt" 148 THISDPB equ ThisDPB ; NASM port label 0 000041D7 C42E[0000] LES BP,[THISDPB] 150 ASSUME ES:NOTHING 151 NEXTENTRY equ NextEntry ; NASM port label 0 000041DB E86B00 CALL NEXTENTRY 153 SRCH equ Srch ; NASM port label 0 000041DE 73B7 JNC SRCH 0 000041E0 EB55 JMP SHORT SETESRET 156 157 FREE: 0 000041E2 1F POP DS 159 DOSAssume CS,,"DIR/Free" 160 LASTENT equ LastEnt ; NASM port label 0 000041E3 8B0E[0000] MOV CX,[LASTENT] 162 ENTFREE equ EntFree ; NASM port label 0 000041E7 3B0E[0000] CMP CX,[ENTFREE] 0 000041EB 7304 JAE TSTALL 0 000041ED 890E[0000] MOV [ENTFREE],CX 166 TSTALL: 0 000041F1 3A26[0000] CMP AH,BYTE PTR [DELALL] ; At end of directory? 168 NextEntJ: 0 000041F5 74E0 JZ NEXTENT ; No - continue search 170 ENTLAST equ EntLast ; NASM port label 0 000041F7 890E[0000] MOV [ENTLAST],CX 0 000041FB F9 STC 0 000041FC EB39 JMP SHORT SETESRET 174 175 FOUND: 176 ; 177 ; We have a file with a matching name. We must now consider the attributes: 178 ; ATTRIB Action 179 ; ------ ------ 180 ; Volume_ID Is Volume_ID in test? 181 ; Otherwise If no create then Is ATTRIB+extra superset of test? 182 ; If create then Is ATTRIB equal to test? 183 ; 0 000041FE 8A2C MOV CH,[SI] ; Attributes of file 0 00004200 1F POP DS 186 DOSAssume CS,,"DIR/found" 0 00004201 8A26[0000] MOV AH,[Attrib] ; Attributes of search 0 00004205 80E49E AND AH,~ attr_ignore 189 Dir_First equ dir_first ; NASM port equate 190 Dir_Attr equ dir_attr ; NASM port equate 0 00004208 8D740F LEA SI,[SI+Dir_First-Dir_Attr] ; point to firclus field 0 0000420B F6C508 TEST CH,attr_volume_id ; Volume ID file? 0 0000420E 740E JZ check_one_volume_id ; Nope check other attributes 0 00004210 F6C408 TEST AH,attr_volume_id ; Can we find Volume ID? 195 NEXTENTJ equ NextEntJ ; NASM port label 0 00004213 74E0 JZ NEXTENTJ ; Nope, (not even $FCB_CREATE) 0 00004215 F6C5D7 test ch, ~ (attr_volume_id | attr_archive) 198 ; possible LFN ? 0 00004218 75BD jnz NEXTENT ; yes, skip --> 0 0000421A 30E4 XOR AH,AH ; Set zero flag for $FCB_CREATE 0 0000421C EB11 JMP SHORT RETFF ; Found Volume ID 202 check_one_volume_id: 0 0000421E 80FC08 CMP AH,attr_volume_id ; Looking only for Volume ID? 0 00004221 74D2 JZ NEXTENTJ ; Yes, continue search 0 00004223 E8[0000] invoke MatchAttributes 0 00004226 7407 JZ RETFF 207 CREATING equ Creating ; NASM port label 0 00004228 F606[0000]FF TEST BYTE PTR [CREATING],-1 ; Pass back mismatch if creating 0 0000422D 74C6 JZ NEXTENTJ ; Otherwise continue searching 210 RETFF: 0 0000422F C42E[0000] LES BP,[THISDPB] 0 00004233 268A6600 MOV AH,[ES:BP + dpb_drive] 213 SETESRET: 0 00004237 16 PUSH SS 0 00004238 07 POP ES 0 00004239 C3 return 217 EndProc Search 218 219 ; Inputs: 220 ; DS:SI -> 11 character FCB style name NO '?' 221 ; Typically this is a directory entry. It MUST be in upper case 222 ; ES:DI -> 11 character FCB style name with possible '?' 223 ; Typically this is a FCB or SFT. It MUST be in upper case 224 ; Function: 225 ; Compare FCB style names allowing for ? match to any char 226 ; Outputs: 227 ; Zero if match else NZ 228 ; Destroys CX,SI,DI all others preserved 229 230 procedure MetaCompare,near 230 ****************** warning: proc MetaCompare... [-w+user] 231 ASSUME DS:NOTHING,ES:NOTHING 0 0000423A B90B00 MOV CX,11 233 %IF DBCS ;AN000; 234 ;-------------------- Start of DBCS ;AN000; 235 CMP BYTE PTR [SI],05H ;AN000;; Special case for lead byte of 05h 236 JNE WILDCRD2 ;AN000;; Compare as normal if not an 05h 237 CMP BYTE PTR [ES:DI],0E5H ;AN000;; 05h and 0E5h equivalent for lead byte 238 JNE WILDCRD2 ;AN000;; Compare as normal if not an 05h 239 DEC CX ;AN000;; One less byte to compare 240 INC SI ;AN000;; Bypass lead byte in source and 241 INC DI ;AN000;; destination when 05h and 0E5h found. 242 WILDCRD2: ;AN000; 243 PUSH AX ;AN000;;KK. save ax 244 cagain: ;AN000;;KK. 245 CMP CX,0 ;AN000;;KK. end of compare ? 246 JLE metaend2 ;AN000;;KK. yes 247 MOV AL,[SI] ;AN000;;KK. is it a Kanji 248 invoke testkanj ;AN000;;KK. 249 JZ notdb ;AN000;;KK. no 250 MOV AX,'??' ;AN000;;KK. 251 CMP [ES:DI],AX ;AN000;;KK. is es:di pointing to '??' 252 JNZ metaend3 ;AN000;;KK. no 253 ADD SI,2 ;AN000;;KK. 254 ADD DI,2 ;AN000;;KK. update pointers and count 255 subcx: ;AN000; 256 SUB CX,2 ;AN000;;KK. 257 JMP cagain ;AN000;;KK. 258 metaend3: ;AN000;;KK. 259 CMPSW ;AN000;;KK. 260 JNZ metaend2 ;AN000;;KK. 261 JMP subcx ;AN000;;KK. 262 notdb: ;AN000; 263 CMPSB ;AN000;;KK. same code ? 264 JZ sameco ;AN000;;KK. yes 265 CMP BYTE PTR [ES:DI-1],"?" ;AN000;;KK. ? 266 JNZ metaend2 ;AN000;;KK. no 267 sameco: ;AN000; 268 DEC CX ;AN000;;KK. decrement count 269 JMP cagain ;AN000;;KK. 270 271 metaend2: ;AN000; 272 POP AX ;AN000;;KK. 273 ;-------------------- End of DBCS ;AN000; KK. 274 %ELSE ;AN000; 275 WILDCRD: 0 0000423D F3A6 REPE CMPSB 0 0000423F 7407 JZ MetaRet ; most of the time we will fail. 278 CHECK_META: 0 00004241 26807DFF3F CMP BYTE PTR [ES:DI-1],"?" 280 WildCrd equ WILDCRD ; NASM port label 0 00004246 74F5 JZ WildCrd 282 MetaRet: 283 %ENDIF ;AN000; 0 00004248 C3 return ; Zero set, Match 285 EndProc MetaCompare 286 287 Break 288 289 ; Inputs: 290 ; Same as outputs of GETENTRY, above 291 ; Function: 292 ; Update BX, and [LASTENT] for next directory entry. 293 ; Carry set if no more. 294 295 Procedure NextEntry 295 ****************** warning: proc NextEntry... [-w+user] 296 DOSAssume CS,,"NextEntry" 297 ASSUME ES:NOTHING 298 0 00004249 A1[0000] MOV AX,[LASTENT] 0 0000424C 3B06[0000] CMP AX,[ENTLAST] 0 00004250 7426 JZ NONE 0 00004252 40 INC AX 0 00004253 8D5F20 LEA BX,[BX+32] 0 00004256 39D3 CMP BX,DX 0 00004258 7220 JB HAVIT 0 0000425A B700 mov bh, 0 307 SECCLUSPOS equ SecClusPos ; NASM port label 0 0000425C 8A1E[0000] MOV BL,BYTE PTR [SECCLUSPOS] 0 00004260 43 inc bx 310 CLUSTER_FACTOR_EDR equ Cluster_Factor_EDR ; NASM port label 0 00004261 3B1E[0000] cmp bx, word ptr [CLUSTER_FACTOR_EDR] 0 00004265 7218 JB SAMECLUS 313 NXTCLUSNUM equ NxtClusNum ; NASM port label 0 00004267 8B1E[0000] MOV BX,[NXTCLUSNUM] 0 0000426B E8[0000] Invoke IsEOF 0 0000426E 7308 JAE NONE 0 00004270 83FB02 CMP BX,2 0 00004273 7203 JB NONE 0 00004275 EB34 JMP GETENT 0 00004277 90 nop ; identicalise 321 322 NONE: 0 00004278 F9 STC 0 00004279 C3 return 325 326 HAVIT: 0 0000427A A3[0000] MOV [LASTENT],AX 0 0000427D F8 CLC 0 0000427E C3 return 330 331 SAMECLUS: 0 0000427F 881E[0000] MOV BYTE PTR [SECCLUSPOS],BL 0 00004283 A3[0000] MOV [LASTENT],AX 0 00004286 1E PUSH DS 0 00004287 C53E[0000] LDS DI,[CURBUF] 336 ASSUME DS:NOTHING 0 0000428B 8B550A MOV DX,WORD PTR [DI + buf_sector+2] ;AN000; >32mb 0 0000428E 368916[0000] MOV [ss:HIGH_SECTOR],DX ;AN000; >32mb 0 00004293 8B5508 MOV DX,WORD PTR [DI + buf_sector] ;AN000; >32mb 340 0 00004296 83C201 ADD DX,1 ;AN000; >32mb 0 00004299 368316[0000]00 ADC word [ss:HIGH_SECTOR],0 ;AN000; >32mb 0 0000429F 1F POP DS 344 DOSAssume CS,,"DIR/SameClus" 0 000042A0 E8[0000] invoke FIRSTCLUSTER 0 000042A3 31DB XOR BX,BX 0 000042A5 EB25 JMP SETENTRY 0 000042A7 90 nop ; identicalise 349 EndProc NextEntry 350 351 ; Inputs: 352 ; [LASTENT] has directory entry 353 ; ES:BP points to drive parameters 354 ; [DIRSEC],[CLUSNUM],[CLUSFAC],[ENTLAST] set for DIR involved 355 ; Function: 356 ; Locates directory entry in preparation for search 357 ; GETENT provides entry for passing desired entry in AX 358 ; Outputs: 359 ; [CURBUF+2]:BX = Pointer to next directory entry in CURBUF 360 ; [CURBUF+2]:DX = Pointer to first byte after end of CURBUF 361 ; [LASTENT] = New directory entry number 362 ; [NXTCLUSNUM],[SECCLUSPOS] set via DIRREAD 363 ; Carry set if error (currently user FAILed to I 24) 364 365 Procedure GETENTRY,NEAR 365 ****************** warning: proc GETENTRY... [-w+user] 366 DOSAssume CS,,"GetEntry" 367 ASSUME ES:NOTHING 368 0 000042A8 A1[0000] MOV AX,[LASTENT] 370 371 entry GETENT 372 373 Assert ISDPB,,"GetEntry/GetEnt" 0 000042AB A3[0000] MOV [LASTENT],AX 375 ; 376 ; Convert the entry number in AX into a byte offset from the beginning of the 377 ; directory. 378 ; 0 000042AE B105 mov cl,5 ; shift left by 5 = mult by 32 0 000042B0 D3C0 rol ax,cl ; keep hight order bits 0 000042B2 89C2 mov dx,ax 0 000042B4 83E0E0 and ax, ~ (32-1) ; mask off high order bits 0 000042B7 83E21F and dx, 32-1 ; mask off low order bits 384 ; 385 ; DX:AX contain the byte offset of the required directory entry from the 386 ; beginning of the directory. Convert this to a sector number. Round the 387 ; sector size down to a multiple of 32. 388 ; 0 000042BA 268B5E02 MOV BX,[ES:BP + dpb_sector_size] 0 000042BE 80E3E0 AND BL,255-31 ; Must be multiple of 32 0 000042C1 F7F3 DIV BX 0 000042C3 89D3 MOV BX,DX ; Position within sector 0 000042C5 53 PUSH BX 0 000042C6 E8[0000] invoke DIRREAD 0 000042C9 5B POP BX 0 000042CA 72B2 retc 397 SETENTRY: 0 000042CC 8B16[0000] MOV DX,WORD PTR [CURBUF] 0 000042D0 83C210 ADD DX,BUFINSIZ 0 000042D3 01D3 ADD BX,DX 0 000042D5 26035602 ADD DX,[ES:BP + dpb_sector_size] ; Always clears carry 0 000042D9 C3 return 403 EndProc GetEntry 404 405 Break 406 407 ; Inputs: 408 ; BX cluster number of start of directory 409 ; ES:BP Points to DPB 410 ; DI next cluster number from fastopen extended info. DOS 3.3 only 411 ; Function: 412 ; Set up a directory search 413 ; Outputs: 414 ; [DIRSTART] = BX 415 ; [CLUSFAC],[CLUSNUM],[SECCLUSPOS],[DIRSEC] set 416 ; Carry set if error (currently user FAILed to I 24) 417 ; destroys AX,DX,BX 418 419 procedure SETDIRSRCH 419 ****************** warning: proc SETDIRSRCH... [-w+user] 420 DOSAssume CS,,"SetDirSrch" 421 ASSUME ES:NOTHING 422 423 Assert ISDPB,,"SetDirSrch" 0 000042DA 09DB OR BX,BX 0 000042DC 7440 JZ SETROOTSRCH 426 DIRSTART equ DirStart ; NASM port label 0 000042DE 891E[0000] MOV [DIRSTART],BX 0 000042E2 31C0 xor ax, ax 0 000042E4 268A4604 MOV AL,[ES:BP + dpb_cluster_mask] 0 000042E8 40 inc ax 431 CLUSFAC equ ClusFac ; NASM port label 0 000042E9 A2[0000] MOV BYTE PTR [CLUSFAC],AL 0 000042EC A3[0000] mov word ptr [CLUSTER_FACTOR_EDR], ax 434 ; DOS 3.3 for FastOPen F.C. 6/12/86 0 000042EF 56 SaveReg 0 000042F0 F606[0000]02 TEST byte [FastOpenFlg],Lookup_Success 0 000042F5 7507 JNZ UNP_OK 438 439 ; DOS 3.3 for FastOPen F.C. 6/12/86 0 000042F7 E8[0000] invoke UNPACK 0 000042FA 7302 JNC UNP_OK 0 000042FC 5E RestoreReg 0 000042FD C3 return 444 445 UNP_OK: 446 CLUSNUM equ ClusNum ; NASM port label 0 000042FE 893E[0000] MOV [CLUSNUM],DI 0 00004302 89DA MOV DX,BX 0 00004304 30DB XOR BL,BL 0 00004306 881E[0000] MOV BYTE PTR [SECCLUSPOS],BL 0 0000430A E8[0000] invoke FIGREC 0 0000430D 5E RestoreReg 0 0000430E 52 PUSH DX ;AN000; >32mb 0 0000430F 8B16[0000] MOV DX,[HIGH_SECTOR] ;AN000; >32mb 455 DIRSEC equ DirSec ; NASM port label 0 00004313 8916[0200] MOV WORD PTR [DIRSEC+2],DX ;AN000; >32mb 0 00004317 5A POP DX ;AN000; >32mb 0 00004318 8916[0000] MOV WORD PTR [DIRSEC],DX 0 0000431C F8 CLC 0 0000431D C3 return 461 462 entry SETROOTSRCH 463 DOSAssume CS,,"SetRootSrch" 464 ASSUME ES:NOTHING 0 0000431E 31C0 XOR AX,AX 0 00004320 A3[0000] MOV [DIRSTART],AX 0 00004323 A2[0000] MOV BYTE PTR [SECCLUSPOS],AL 0 00004326 48 DEC AX 0 00004327 A3[0000] MOV [CLUSNUM],AX 0 0000432A 268B460B MOV AX,[ES:BP + dpb_first_sector] 0 0000432E 268B5611 MOV DX,[ES:BP + dpb_dir_sector] 0 00004332 29D0 SUB AX,DX 0 00004334 A2[0000] MOV BYTE PTR [CLUSFAC],AL 0 00004337 A3[0000] mov word ptr [CLUSTER_FACTOR_EDR], ax 0 0000433A 8916[0000] MOV WORD PTR [DIRSEC],DX ;F.C. >32mb 0 0000433E 8326[0200]00 and WORD PTR [DIRSEC+2],0 ;F.C. >32mb 477 ; NC from and 0 00004343 C3 return 479 EndProc SETDIRSRCH 479 ****************** warning: ***** Possible stack size error in SETDIRSRCH ***** [-w+user] 480 481 END === Trace listing source: ../DOS/dir2.lst 1 ; SCCSID = @(#)dir2.asm 1.2 85/07/23 2 ; SCCSID = @(#)dir2.asm 1.2 85/07/23 3 ;TITLE DIR2 - Directory and path cracking 4 ;NAME Dir2 5 ; Main Path cracking routines, low level search routines and device 6 ; name detection routines 7 ; 8 ; GETPATH 9 ; GetPathNoSet 10 ; CHKDEV 11 ; ROOTPATH 12 ; FINDPATH 13 ; StartSrch 14 ; MatchAttributes 15 ; DEVNAME 16 ; Build_device_ent 17 ; Validate_CDS 18 ; CheckThisDevice 19 ; 20 ; Revision history: 21 ; 22 ; A000 version 4.00 Jan. 1988 23 ; A001 PTM 3564 -- search using fastopen 24 25 ; 26 ; get the appropriate segment definitions 27 ; 28 [list -] === Switch to base=008400h -> "DOSCODECODE" 32 section DOSCODECODE 33 [list -] 33 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 33 ****************** warning: out: BPB.INC... [-w+user] 33 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 33 ****************** warning: out: DEVSYM.INC... [-w+user] 41 42 %ifndef Kanji 43 %iassign Kanji 0 44 %endif 45 46 i_need NoSetDir,BYTE 47 i_need EntFree,WORD 48 i_need DirStart,WORD 49 i_need LastEnt,WORD 50 i_need WFP_START,WORD 51 i_need CURR_DIR_END,WORD 52 i_need CurBuf,DWORD 53 i_need THISCDS,DWORD 54 i_need Attrib,BYTE 55 i_need SAttrib,BYTE 56 i_need VolID,BYTE 57 i_need Name1,BYTE 58 i_need ThisDPB,DWORD 59 i_need EntLast,WORD 60 i_need Creating,BYTE 61 i_need NULDEV,DWORD 62 i_need DEVPT,DWORD 63 i_need DEVFCB,BYTE 64 i_need ALLOWED,BYTE 65 i_need EXTERR_LOCUS,BYTE 66 I_need FastOpenFlg,BYTE ;DOS 3.3 67 I_need FastOpenTable,BYTE ;DOS 3.3 68 I_need Dir_Info_Buff,BYTE ;DOS 3.3 69 I_need FastOpen_Ext_Info,BYTE ;DOS 3.3 70 I_need CLUSNUM,WORD ;DOS 3.3 71 I_need Next_Element_Start,WORD ;DOS 3.3 72 I_need HIGH_SECTOR,WORD ;AN000;>32mb 73 I_need DOS34_FLAG,WORD ;AN000;>32mb 74 75 76 Break 77 78 ; Inputs: 79 ; [WFP_START] Points to WFP string ("d:\" must be first 3 chars, NUL 80 ; terminated; d:/ (note forward slash) indicates a real device). 81 ; [CURR_DIR_END] Points to end of Current dir part of string 82 ; ( = -1 if current dir not involved, else 83 ; Points to first char after last "/" of current dir part) 84 ; [THISCDS] Points to CDS being used 85 ; [SATTRIB] Is attribute of search, determines what files can be found 86 ; [NoSetDir] set 87 ; [THISDPB] set to DPB if disk otherwise garbage. 88 ; Function: 89 ; Crack the path 90 ; Outputs: 91 ; Sets EXTERR_LOCUS = errLOC_Disk if disk file 92 ; Sets EXTERR_LOCUS = errLOC_Unk if char device 93 ; ID1 field of [THISCDS] updated appropriately 94 ; [ATTRIB] = [SATTRIB] 95 ; ES:BP Points to DPB 96 ; Carry set if bad path 97 ; SI Points to path element causing failure 98 ; Zero set 99 ; [DIRSTART],[DIRSEC],[CLUSNUM], and [CLUSFAC] are set up to 100 ; start a search on the last directory 101 ; CL is zero if there is a bad name in the path 102 ; CL is non-zero if the name was simply not found 103 ; [ENTFREE] may have free spot in directory 104 ; [NAME1] is the name. 105 ; CL = 81H if '*'s or '?' in NAME1, 80H otherwise 106 ; Zero reset 107 ; File in middle of path or bad name in path or attribute mismatch 108 ; or path too long or malformed path 109 ; ELSE 110 ; [CurBuf] = -1 if root directory 111 ; [CURBUF] contains directory record with match 112 ; [CURBUF+2]:BX Points into [CURBUF] to start of entry 113 ; [CURBUF+2]:SI Points into [CURBUF] to dir_first field for entry 114 ; AH = device ID 115 ; bit 7 of AH set if device SI and BX 116 ; will point DOSGROUP relative The firclus 117 ; field of the device entry contains the device pointer 118 ; [NAME1] Has name looked for 119 ; If last element is a directory zero is set and: 120 ; [DIRSTART],[SECCLUSPOS],[DIRSEC],[CLUSNUM], and [CLUSFAC] 121 ; are set up to start a search on it. 122 ; unless [NoSetDir] is non zero in which case the return is 123 ; like that for a file (except for zero flag) 124 ; If last element is a file zero is reset 125 ; [DIRSEC],[CLUSNUM],[CLUSFAC],[NXTCLUSNUM],[SECCLUSPOS], 126 ; [LASTENT], [ENTLAST] are set to continue search of last 127 ; directory for furthur matches on NAME1 via the NEXTENT 128 ; entry point in FindEntry (or GETENT entry in GETENTRY in 129 ; which case [NXTCLUSNUM] and [SECCLUSPOS] need not be valid) 130 ; DS preserved, Others destroyed 131 132 procedure GETPATH,near 132 ****************** warning: proc GETPATH... [-w+user] 133 DOSAssume CS,,"GetPath" 134 ASSUME ES:NOTHING 135 136 CREATING equ Creating ; NASM port label 0 00004344 C706[0000]00E5 MOV WORD PTR [CREATING],0E500H ; Not Creating, not DEL *.* 138 139 ;Same as GetPath only CREATING and DELALL already set 140 entry GetPathNoSet 0 0000434A C606[0000]02 MOV byte [EXTERR_LOCUS],errLOC_Disk 0 0000434F C706[0000]FFFF MOV WORD [CurBuf],-1 ; initial setting 143 ; 144 ; See if the input indicates a device that has already been detected. If so, 145 ; go build the guy quickly. Otherwise, let findpath find the device. 146 ; 147 Wfp_Start equ WFP_START ; NASM port label 0 00004355 8B3E[0000] MOV DI,[Wfp_Start] ; point to the beginning of the name 0 00004359 817D013A5C CMP WORD PTR [DI+1],('\' << 8) + ':' 0 0000435E 743A JZ CrackIt 151 ; 152 ; Let ChkDev find it in the device list 153 ; 0 00004360 83C703 ADD DI,3 0 00004363 89FE MOV SI,DI ; let CHKDEV see the original name 156 CHKDEV equ ChkDev ; NASM port label 0 00004365 E8B400 CALL CHKDEV 0 00004368 722E JC InternalError 159 Build_devJ: 0 0000436A A0[0000] MOV AL,[SAttrib] 0 0000436D A2[0000] MOV [Attrib],AL 0 00004370 C606[0000]01 MOV byte [EXTERR_LOCUS],errLOC_Unk ; In the particular case of 163 ; "finding" a char device 164 ; set LOCUS to Unknown. This makes 165 ; certain idiotic problems reported 166 ; by a certain 3 letter OEM go away. 167 ; 168 ; Take name in name1 and pack it back into where wfp_start points. This 169 ; guarantees wfp_start pointing to a canonical representation of a device. 170 ; We are allowed to do this as GetPath is *ALWAYS* called before entering a 171 ; wfp into the share set. 172 ; 173 ; We copy chars from name1 to wfp_start remembering the position of the last 174 ; non-space seen +1. This position is kept in DX. 175 ; 0 00004375 1607 Context ES 177 DOSGroup equ DOSGROUP ; NASM port equate 0 00004377 BE[0000] mov si,offset Name1 wrt DOSGroup 179 wfp_start equ WFP_START ; NASM port label 0 0000437A 8B3E[0000] mov di,[wfp_start] 0 0000437E 89FA mov dx,di 0 00004380 B90800 mov cx,8 ; 8 chars in device name 183 MoveLoop: 0 00004383 AC lodsb 0 00004384 AA stosb 0 00004385 3C20 cmp al," " 187 nosave equ NoSave ; NASM port label 0 00004387 7402 jz nosave 189 %IF DBCS ;AN000;; 190 ; cmp al,81h ;AN000;; 2/23/KK 191 ; jne notKanji ;AN000;; 2/23/KK 192 ; cmp cx,1 ;AN000; 2/23/KK 193 ; je notKanji ;AN000; 2/23/KK 194 ; cmp byte ptr [si],40h ;AN000; 2/23/KK 195 ; jne notKanji ;AN000;; 2/23/KK 196 ; lodsb ;AN000;; 2/23/KK 197 ; stosb ;AN000;; 2/23/KK 198 ; dec cx ;AN000;; 2/23/KK 199 ; jmp nosave ;AN000;; 2/23/KK 200 ;notKanji: ;AN000;; 2/23/KK 201 %ENDIF 0 00004389 89FA mov dx,di 203 NoSave: 0 0000438B E2F6 loop MoveLoop 205 ; 206 ; DX is the position of the last seen non-space + 1. We terminate the name 207 ; at this point. 208 ; 0 0000438D 89D7 mov di,dx 0 0000438F C60500 mov byte ptr [di],0 ; end of string 0 00004392 E8DE02 invoke Build_device_ent ; Clears carry sets zero 0 00004395 FEC0 INC AL ; reset zero 0 00004397 C3 return 214 215 assume es:nothing 216 217 InternalError: 0 00004398 EBFE JMP InternalError ; freeze 219 220 ; 221 ; Start off at the correct spot. Optimize if the current dir part is valid. 222 ; 223 CrackIt: 0 0000439A 8B36[0000] MOV SI,[CURR_DIR_END] ; get current directory pointer 0 0000439E 83FEFF CMP SI,-1 ; valid? 0 000043A1 7503 JNZ LOOK_SING ; Yes, use it. 0 000043A3 8D7503 LEA SI,[DI+3] ; skip D:\. 228 LOOK_SING: 229 Assert ISDPB,<,>,"Crackit" 0 000043A6 C606[0000]16 MOV byte [Attrib],attr_directory+attr_system+attr_hidden 231 ; Attributes to search through Dirs 0 000043AB C43E[0000] LES DI,[THISCDS] 0 000043AF B8FFFF MOV AX,-1 0 000043B2 268B5D49 MOV BX,[ES:DI + curdir_ID] 0 000043B6 8B36[0000] MOV SI,[CURR_DIR_END] 236 ; 237 ; AX = -1 238 ; BX = cluster number of current directory. THis number is -1 if the media 239 ; has been uncertainly changed. 240 ; SI = offset in DOSGroup into path to end of current directory text. This 241 ; may be -1 if no current directory part has been used. 242 ; 0 000043BA 39C6 CMP SI,AX ; if Current directory is not part 0 000043BC 7440 JZ NO_CURR_D ; then we must crack from root 0 000043BE 39C3 CMP BX,AX ; is the current directory cluster valid 246 247 ; DOS 3.3 6/25/86 0 000043C0 743C JZ NO_CURR_D ; no, crack form the root 0 000043C2 F606[0000]01 TEST byte [FastOpenFlg],FastOpen_Set ; for fastopen ? 0 000043C7 7443 JZ GOT_SEARCH_CLUSTER ; no 0 000043C9 06 PUSH ES ; save registers 0 000043CA 57 PUSH DI 0 000043CB 51 PUSH CX 0 000043CC FF74FF PUSH word [SI-1] ; save \ and 1st char of next element 0 000043CF 56 PUSH SI 0 000043D0 53 PUSH BX 257 0 000043D1 C644FF00 MOV BYTE PTR [SI-1],0 ; call fastopen to look up cur dir info 0 000043D5 8B36[0000] MOV SI,[Wfp_Start] 0 000043D9 BB[0000] MOV BX,OFFSET FastOpenTable wrt DOSGROUP 0 000043DC BF[0000] MOV DI,OFFSET Dir_Info_Buff wrt DOSGROUP 0 000043DF B9[0000] MOV CX,OFFSET FastOpen_Ext_Info wrt DOSGROUP 263 FONC_look_up equ FONC_Look_up ; NASM port equate 0 000043E2 B001 MOV AL,FONC_look_up 0 000043E4 1E PUSH DS 0 000043E5 07 POP ES 267 FASTOPEN_NAME_CACHING equ Fastopen_Name_Caching ; NASM port equate 0 000043E6 FF5F02 CALL far [BX + FASTOPEN_NAME_CACHING] 0 000043E9 7208 JC GO_Chk_end1 ;fastopen not installed, or wrong drive. Go to Got_Srch_cluster 0 000043EB 803C00 CMP BYTE PTR [SI],0 ;fastopen has current dir info? 0 000043EE 7404 JE GO_Chk_end ;yes. Go to got_serch_cluster 0 000043F0 F9 stc 0 000043F1 EB01 jmp short GO_Chk_end ;Go to No_Curr_D 274 GO_Chk_end1: 0 000043F3 F8 clc 276 GO_Chk_end: ; restore registers 0 000043F4 5B POP BX 0 000043F5 5E POP SI 0 000043F6 8F44FF POP word [SI-1] 0 000043F9 59 POP CX 0 000043FA 5F POP DI 0 000043FB 07 POP ES 0 000043FC 730E JNC GOT_SEARCH_CLUSTER ; crack based on cur dir 284 285 ; DOS 3.3 6/25/86 286 ; 287 ; We must cract the path beginning at the root. Advance pointer to beginning 288 ; of path and go crack from root. 289 ; 290 NO_CURR_D: 0 000043FE 8B36[0000] MOV SI,[WFP_START] 0 00004402 8D7403 LEA SI,[SI+3] ; Skip "d:/" 293 THISDPB equ ThisDPB ; NASM port label 0 00004405 C42E[0000] LES BP,[THISDPB] ; Get ES:BP 0 00004409 EB41 JMP ROOTPATH 0 0000440B 90 nop ; identicalise 297 ; 298 ; We are able to crack from the current directory part. Go set up for search 299 ; of specified cluster. 300 ; 301 GOT_SEARCH_CLUSTER: 0 0000440C C42E[0000] LES BP,[THISDPB] ; Get ES:BP 0 00004410 E8[0000] invoke SETDIRSRCH 0 00004413 7203 JC SETFERR 0 00004415 EB46 JMP FINDPATH 0 00004417 90 nop ; identicalise 307 308 SETFERR: 0 00004418 30C9 XOR CL,CL ; set zero 0 0000441A F9 STC 0 0000441B C3 Return 312 313 EndProc GETPATH 314 315 ; Check to see if the name at DS:DI is a device. Returns carry set if not a 316 ; device. 317 ; Blasts CX,SI,DI,AX,BX 318 319 Procedure ChkDev,NEAR 319 ****************** warning: proc ChkDev... [-w+user] 320 ASSUME ES:Nothing,DS:NOTHING 321 0 0000441C 89FE MOV SI,DI 0 0000441E 8CD7 MOV DI,SS 0 00004420 8EC7 MOV ES,DI 325 ASSUME ES:DOSGroup ; Now here is where ES is DOSGroup 326 327 NAME1 equ Name1 ; NASM port label 0 00004422 BF[0000] MOV DI,OFFSET NAME1 wrt DOSGROUP 0 00004425 B90900 MOV CX,9 330 TESTLOOP: 0 00004428 E8[0000] invoke GETLET 332 %IF DBCS ;AN000; 333 invoke Testkanj ;AN000;; 2/13/KK 334 jz Notkanja ;AN000;; 2/13/KK 335 stosb ;AN000;; Skip second byte 2/13/KK 336 dec cx ;AN000;; 2/13/KK 337 notdev equ NOTDEV ; NASM port label 338 jcxz notdev ;AN000;; 2/13/KK 339 lodsb ;AN000;; 2/13/KK 340 jmp short stowit ;AN000;; 2/13/KK 341 Notkanja: ;AN000; 342 %ENDIF ;AN000; 0 0000442B 3C2E CMP AL,'.' 0 0000442D 740E JZ TESTDEVICE 0 0000442F E8[0000] invoke PATHCHRCMP 0 00004432 7407 JZ NOTDEV 0 00004434 08C0 OR AL,AL 0 00004436 7405 JZ TESTDEVICE 349 stowit: 0 00004438 AA STOSB 0 00004439 E2ED LOOP TESTLOOP 352 NOTDEV: 0 0000443B F9 STC 0 0000443C C3 return 355 356 TESTDEVICE: 0 0000443D 83C102 ADD CX,2 0 00004440 B020 MOV AL,' ' 0 00004442 F3AA REP STOSB 0 00004444 8CD0 MOV AX,SS 0 00004446 8ED8 MOV DS,AX 0 00004448 E8C801 invoke DEVNAME 0 0000444B C3 return 364 EndProc ChkDev 365 366 Break 367 368 ; Inputs: 369 ; Same as FINDPATH but, 370 ; SI Points to asciz string of path which is assumed to start at 371 ; the root (no leading '/'). 372 ; Function: 373 ; Search from root for path 374 ; Outputs: 375 ; Same as FINDPATH but: 376 ; If root directory specified, [CURBUF] and [NAME1] are NOT set, and 377 ; [NoSetDir] is ignored. 378 379 procedure ROOTPATH,near 379 ****************** warning: proc ROOTPATH... [-w+user] 380 381 DOSAssume CS,,"RootPath" 382 ASSUME ES:NOTHING 383 0 0000444C E8[0000] invoke SETROOTSRCH 0 0000444F 803C00 CMP BYTE PTR [SI],0 0 00004452 7509 JNZ FINDPATH 387 388 ; Root dir specified 0 00004454 A0[0000] MOV AL,[SAttrib] 0 00004457 A2[0000] MOV [Attrib],AL 0 0000445A 30E4 XOR AH,AH ; Sets "device ID" byte, sets zero 392 ; (dir), clears carry. 0 0000445C C3 return 394 395 ; Inputs: 396 ; [ATTRIB] Set to get through directories 397 ; [SATTRIB] Set to find last element 398 ; ES:BP Points to DPB 399 ; SI Points to asciz string of path (no leading '/'). 400 ; [SECCLUSPOS] = 0 401 ; [DIRSEC] = Phys sec # of first sector of directory 402 ; [CLUSNUM] = Cluster # of next cluster 403 ; [CLUSFAC] = Sectors per cluster 404 ; [NoSetDir] set 405 ; [CURR_DIR_END] Points to end of Current dir part of string 406 ; ( = -1 if current dir not involved, else 407 ; Points to first char after last "/" of current dir part) 408 ; [THISCDS] Points to CDS being used 409 ; [CREATING] and [DELALL] set 410 ; Function: 411 ; Parse path name 412 ; Outputs: 413 ; ID1 field of [THISCDS] updated appropriately 414 ; [ATTRIB] = [SATTRIB] 415 ; ES:BP Points to DPB 416 ; [THISDPB] = ES:BP 417 ; Carry set if bad path 418 ; SI Points to path element causing failure 419 ; Zero set 420 ; [DIRSTART],[DIRSEC],[CLUSNUM], and [CLUSFAC] are set up to 421 ; start a search on the last directory 422 ; CL is zero if there is a bad name in the path 423 ; CL is non-zero if the name was simply not found 424 ; [ENTFREE] may have free spot in directory 425 ; [NAME1] is the name. 426 ; CL = 81H if '*'s or '?' in NAME1, 80H otherwise 427 ; Zero reset 428 ; File in middle of path or bad name in path 429 ; or path too long or malformed path 430 ; ELSE 431 ; [CURBUF] contains directory record with match 432 ; [CURBUF+2]:BX Points into [CURBUF] to start of entry 433 ; [CURBUF+2]:SI Points to fcb_FIRCLUS field for entry 434 ; [NAME1] Has name looked for 435 ; AH = device ID 436 ; bit 7 of AH set if device SI and BX 437 ; will point DOSGROUP relative The firclus 438 ; field of the device entry contains the device pointer 439 ; If last element is a directory zero is set and: 440 ; [DIRSTART],[SECCLUSPOS],[DIRSEC],[CLUSNUM], and [CLUSFAC] 441 ; are set up to start a search on it, 442 ; unless [NoSetDir] is non zero in which case the return is 443 ; like that for a file (except for zero flag) 444 ; If last element is a file zero is reset 445 ; [DIRSEC],[CLUSNUM],[CLUSFAC],[NXTCLUSNUM],[SECCLUSPOS], 446 ; [LASTENT], [ENTLAST] are set to continue search of last 447 ; directory for furthur matches on NAME1 via the NEXTENT 448 ; entry point in FindEntry (or GETENT entry in GETENTRY in 449 ; which case [NXTCLUSNUM] and [SECCLUSPOS] need not be valid) 450 ; Destroys all other registers 451 452 entry FINDPATH 453 DOSAssume CS,,"FindPath" 454 ASSUME ES:NOTHING 455 456 Assert ISDPB,,"FindPath" 0 0000445D 06 PUSH ES ; Save ES:BP 0 0000445E 56 PUSH SI 0 0000445F 89F7 MOV DI,SI 460 DIRSTART equ DirStart ; NASM port label 0 00004461 8B0E[0000] MOV CX,[DIRSTART] ; Get start clus of dir being searched 0 00004465 833E[0000]FF CMP word [CURR_DIR_END],-1 0 0000446A 740E JZ NOIDS ; No current dir part 0 0000446C 3B3E[0000] CMP DI,[CURR_DIR_END] 0 00004470 7508 JNZ NOIDS ; Not to current dir end yet 0 00004472 C43E[0000] LES DI,[THISCDS] 0 00004476 26894D49 MOV [ES:DI + curdir_ID],CX ; Set current directory currency 468 NOIDS: 469 ; 470 ; Parse the name off of DS:SI into NAME1. AL = 1 if there was a meta 471 ; character in the string. CX,DI may be destroyed. 472 ; 473 ; invoke NAMETRANS 474 ; MOV CL,AL 475 ; 476 ; The above is the slow method. The name has *already* been munged by 477 ; TransPath so no special casing needs to be done. All we do is try to copy 478 ; the name until ., \ or 0 is hit. 479 ; 0 0000447A 8CD0 MOV AX,SS 0 0000447C 8EC0 MOV ES,AX 0 0000447E BF[0000] MOV DI,OFFSET Name1 wrt DOSGroup 0 00004481 B82020 MOV AX,' ' 0 00004484 AA STOSB 0 00004485 AB STOSW 0 00004486 AB STOSW 0 00004487 AB STOSW 0 00004488 AB STOSW 0 00004489 AB STOSW 0 0000448A BF[0000] MOV DI,OFFSET Name1 wrt DOSGroup 0 0000448D 30E4 XOR AH,AH ; bits for CL 492 %IF DBCS ;AN000; 493 ;-------------------------- Start of DBC;AN000;S 2/13/KK 494 XOR CL,CL ;AN000;; clear count for volume id 495 LODSB ;AN000;;IBMJ fix 9/04/86 496 CMP AL,05h ;AN000;;IBMJ fix 9/04/86 497 JNE GetNam2 ;AN000;;IBMJ fix 9/04/86 498 PUSH AX ;AN000; ;IBMJ fix 9/04/86 499 MOV AL,0E5h ;AN000;;IBMJ fix 9/04/86 500 Invoke TestKanj ;AN000;;IBMJ fix 9/04/86 501 POP AX ;AN000; ;IBMJ fix 9/04/86 502 JZ Notkanjb ;AN000; ;IBMJ fix 9/04/86 503 JMP SHORT GetNam3 ;AN000;;IBMJ fix 9/04/86 504 ;-------------------------- End of DBCS ;AN000;2/13/KK 505 %ENDIF 506 GetNam: 0 0000448F FEC1 INC CL ;AN000; KK incrment volid count 0 00004491 AC LODSB 509 %IF DBCS ;AN000; 510 GetNam2: ;AN000;; 2/13/KK 511 invoke Testkanj ;AN000;; 2/13/KK 512 jz Notkanjb ;AN000;; 2/13/KK 513 GetNam3: ;AN000;; 2/13/KK 514 STOSB ;AN000;; 2/13/KK 515 INC CL ;AN000;; KK incrment volid count 516 LODSB ;AN000;; 2/13/KK 517 TEST word [DOS34_FLAG],DBCS_VOLID ;AN000;; 2/13/KK 518 JZ notvol ;AN000;; 2/13/KK 519 CMP CL,8 ;AN000;; 2/13/KK 520 JNZ notvol ;AN000;; 2/13/KK 521 CMP AL,'.' ;AN000;; 2/13/KK 522 JNZ notvol ;AN000;; 2/13/KK 523 LODSB ;AN000;; 2/13/KK 524 notvol: ;AN000; 525 jmp short StoNam ;AN000;; 2/13/KK 526 Notkanjb: ;AN000;; 2/13/KK 527 %ENDIF ;AN000; 0 00004492 3C2E CMP AL,'.' 529 setExt equ SetExt ; NASM port label 0 00004494 7412 JZ setExt 0 00004496 08C0 OR AL,AL 0 00004498 7424 JZ GetDone 0 0000449A 3C5C CMP AL,'\' 0 0000449C 7420 JZ GetDone 0 0000449E 3C3F CMP AL,'?' 0 000044A0 7503 JNZ StoNam 0 000044A2 80CC01 OR AH,1 0 000044A5 AA StoNam: STOSB 0 000044A6 EBE7 JMP GetNam 540 SetExt: 0 000044A8 BF[0800] MOV DI,OFFSET Name1+8 wrt DOSGroup 542 GetExt: 0 000044AB AC LODSB 544 %IF DBCS ;AN000; 545 invoke TestKanj ;AN000;; 2/13/KK 546 jz Notkanjc ;AN000;; 2/13/KK 547 STOSB ;AN000;; 2/13/KK 548 LODSB ;AN000;; 2/13/KK 549 jmp short StoExt ;AN000;; 2/13/KK 550 Notkanjc: ;AN000;; 2/13/KK 551 %ENDIF ;AN000; 0 000044AC 08C0 OR AL,AL 0 000044AE 740E JZ GetDone 0 000044B0 3C5C CMP AL,'\' 0 000044B2 740A JZ GetDone 0 000044B4 3C3F CMP AL,'?' 0 000044B6 7503 JNZ StoExt 0 000044B8 80CC01 OR AH,1 0 000044BB AA StoExt: STOSB 0 000044BC EBED JMP GetExt 561 GetDone: 0 000044BE 4E DEC SI 0 000044BF 88E1 MOV CL,AH 564 565 0 000044C1 80C980 OR CL,80H 0 000044C4 5F POP DI ; Start of this element 0 000044C5 07 POP ES ; Restore ES:BP 0 000044C6 39FE CMP SI,DI 0 000044C8 7503 JNZ check_device 0 000044CA E9ED00 JMP BADPATH ; NUL parse (two delims most likely) 572 check_device: 0 000044CD 56 PUSH SI ; Start of next element 0 000044CE 8A04 MOV AL,BYTE PTR [SI] 0 000044D0 08C0 OR AL,AL 0 000044D2 7508 JNZ NOT_LAST 577 578 ; 579 ; for last element of the path switch to the correct search attributes 580 ; 0 000044D4 8A3E[0000] MOV BH,[SAttrib] 0 000044D8 883E[0000] MOV [Attrib],BH 583 NOT_LAST: 584 585 ; 586 ; check name1 to see if we have a device... 587 ; 0 000044DC 06 PUSH ES ; Save ES:BP 0 000044DD 1607 context ES 0 000044DF E83101 invoke DEVNAME ; blast BX 0 000044E2 07 POP ES ; Restore ES:BP 592 ASSUME ES:NOTHING 0 000044E3 720B JC FindFile ; Not a device 0 000044E5 08C0 OR AL,AL ; Test next char again 0 000044E7 7403 JZ GO_BDEV 596 FileInPath equ FILEINPATH ; NASM port label 0 000044E9 E9D200 JMP FileInPath ; Device name in middle of path 598 599 GO_BDEV: 0 000044EC 5E POP SI ; Points to NUL at end of path 0 000044ED E97AFE JMP Build_devJ 602 603 FindFile: 604 ASSUME ES:NOTHING 605 ;;;; 7/28/86 0 000044F0 803E[0000]E5 CMP BYTE PTR [NAME1],0E5H ; if 1st char = E5 0 000044F5 7505 JNZ NOE5 ; no 0 000044F7 C606[0000]05 MOV BYTE PTR [NAME1],05H ; change it to 05 609 NOE5: 610 611 ;;;; 7/28/86 0 000044FC 57 PUSH DI ; Start of this element 0 000044FD 06 PUSH ES ; Save ES:BP 0 000044FE 51 PUSH CX ; CL return from NameTrans 615 ;DOS 3.3 FastOPen 6/12/86 F.C. 616 0 000044FF E89C02 CALL LookupPath ; call fastopen to get dir entry 0 00004502 7303 JNC DIR_FOUND ; found dir entry 619 620 ;DOS 3.3 FastOPen 6/12/86 F.C. 0 00004504 E8[0000] invoke FINDENTRY 622 DIR_FOUND: 0 00004507 59 POP CX 0 00004508 07 POP ES 0 00004509 5F POP DI 0 0000450A 7303 JNC LOAD_BUF 0 0000450C E9D400 JMP BADPATHPOP 628 629 LOAD_BUF: 630 CURBUF equ CurBuf ; NASM port label 0 0000450F C53E[0000] LDS DI,[CURBUF] 632 ASSUME DS:NOTHING 0 00004513 F6470B10 TEST BYTE PTR [BX+dir_attr],attr_directory 0 00004517 7503 JNZ GO_NEXT ; DOS 3.3 0 00004519 E9A200 JMP FileInPath ; Error or end of path 636 ; 637 ; if we are not setting the directory, then check for end of string 638 ; 639 GO_NEXT: 0 0000451C 36803E[0000]00 CMP BYTE PTR [ss:NoSetDir],0 0 00004522 7426 JZ SetDir 0 00004524 89FA MOV DX,DI ; Save pointer to entry 0 00004526 8CD9 MOV CX,DS 0 00004528 161F context DS 0 0000452A 5F POP DI ; Start of next element 0 0000452B F606[0000]01 TEST byte [FastOpenFlg],FastOpen_Set ;only DOSOPEN can take advantage of 0 00004530 740B JZ nofast ; the FastOpen 0 00004532 F606[0000]02 TEST byte [FastOpenFlg],Lookup_Success ; Lookup just happened 0 00004537 7404 JZ nofast ; no 0 00004539 8B3E[0000] MOV DI,[Next_Element_Start] ; no need to insert it again 651 nofast: 0 0000453D 803D00 CMP BYTE PTR [DI],0 0 00004540 7503 JNZ NEXT_ONE ; DOS 3.3 654 SetRet equ SETRET ; NASM port label 0 00004542 E99D00 JMP SetRet ; Got it 656 NEXT_ONE: 0 00004545 57 PUSH DI ; Put start of next element back on stack 0 00004546 89D7 MOV DI,DX 0 00004548 8ED9 MOV DS,CX ; Get back pointer to entry 660 ASSUME DS:NOTHING 661 662 SetDir: 0 0000454A 8B14 MOV DX,[SI] ; Dir_first 664 665 ;DOS 3.3 FastOPen 6/12/86 F.C. 666 0 0000454C 1E PUSH DS ; save [curbuf+2] 0 0000454D 161F context DS ; set DS Dosgroup 0 0000454F F606[0000]02 TEST byte [FastOpenFlg],Lookup_Success ; 0 00004554 7411 JZ DO_NORMAL ; fastopen not in memory or path not 0 00004556 89D3 MOV BX,DX ; not found 0 00004558 8B3E[0000] MOV DI,[CLUSNUM] ; clusnum was set in LookupPath 0 0000455C 50 PUSH AX ; save device id (AH) 0 0000455D E8[0000] invoke SETDIRSRCH 0 00004560 58 POP AX ; restore device id (AH) 0 00004561 83C402 ADD SP,2 ; pop ds in stack 0 00004564 EB3E JMP FAST_OPEN_SKIP 0 00004566 90 nop ; identicalise 679 680 DO_NORMAL: 681 ASSUME DS:NOTHING 0 00004567 1F POP DS ; DS = [curbuf + 2] 683 ;DOS 3.3 FastOPen 6/12/86 F.C. 684 0 00004568 29FB SUB BX,DI ; Offset into sector of start of entry 0 0000456A 29FE SUB SI,DI ; Offset into sector of dir_first 0 0000456C 53 PUSH BX 0 0000456D 50 PUSH AX 0 0000456E 56 PUSH SI 0 0000456F 51 PUSH CX 0 00004570 FF7508 PUSH WORD PTR [DI + buf_sector] ;AN000;>32mb 0 00004573 FF750A PUSH WORD PTR [DI + buf_sector+2] ;AN000;>32mb 0 00004576 89D3 MOV BX,DX 0 00004578 161F context DS 0 0000457A E8[0000] invoke SETDIRSRCH ; This uses UNPACK which might blow 696 ; the entry sector buffer 0 0000457D 8F06[0000] POP word [HIGH_SECTOR] 0 00004581 5A POP DX 0 00004582 720A JC SKIP_GETB 700 allowed_RETRY equ Allowed_RETRY ; NASM port equate 701 allowed_FAIL equ Allowed_FAIL ; NASM port equate 0 00004584 C606[0000]18 MOV byte [ALLOWED],allowed_RETRY + allowed_FAIL 0 00004589 30C0 XOR AL,AL 0 0000458B E8[0000] invoke GETBUFFR ; Get the entry buffer back 705 SKIP_GETB: 0 0000458E 59 POP CX 0 0000458F 5E POP SI 0 00004590 58 POP AX 0 00004591 5B POP BX 0 00004592 7305 JNC SET_THE_BUF 0 00004594 5F POP DI ; Start of next element 0 00004595 89FE MOV SI,DI ; Point with SI 0 00004597 EB21 JMP SHORT BADPATH 714 715 SET_THE_BUF: 0 00004599 E8[0000] invoke SET_BUF_AS_DIR 0 0000459C 8B3E[0000] MOV DI,WORD PTR [CURBUF] 0 000045A0 01FE ADD SI,DI ; Get the offsets back 0 000045A2 01FB ADD BX,DI 720 ; DOS 3.3 FasOpen 6/12/86 F.C. 721 722 FAST_OPEN_SKIP: 723 0 000045A4 5F POP DI ; Start of next element 0 000045A5 E89302 CALL InsertPath ; insert dir entry info 726 727 ; DOS 3.3 FasOpen 6/12/86 F.C. 728 729 0 000045A8 8A05 MOV AL,[DI] 0 000045AA 08C0 OR AL,AL 0 000045AC 7434 JZ SETRET ; At end 0 000045AE 47 INC DI ; Skip over "/" 0 000045AF 89FE MOV SI,DI ; Point with SI 0 000045B1 E8[0000] invoke PATHCHRCMP 0 000045B4 7503 JNZ find_bad_name ; oops 0 000045B6 E9A4FE JMP FINDPATH ; Next element 738 739 find_bad_name: 0 000045B9 4E DEC SI ; Undo above INC to get failure point 741 BADPATH: 0 000045BA 30C9 XOR CL,CL ; Set zero 0 000045BC EB2C JMP SHORT BADPRET 744 745 FILEINPATH: 0 000045BE 5F POP DI ; Start of next element 0 000045BF 161F context DS ; Got to from one place with DS gone 748 ; DOS 3.3 FastOpen 749 0 000045C1 F606[0000]01 TEST byte [FastOpenFlg],FastOpen_Set ; do this here is we don't want to 0 000045C6 740B JZ NO_FAST ; device info to fastopen 0 000045C8 F606[0000]02 TEST byte [FastOpenFlg],Lookup_Success 0 000045CD 7404 JZ NO_FAST 0 000045CF 8B3E[0000] MOV DI,[Next_Element_Start] ; This takes care of one time lookup 755 ; success 756 NO_FAST: 757 758 ; DOS 3.3 FastOpen 759 0 000045D3 8A05 MOV AL,[DI] 0 000045D5 08C0 OR AL,AL 0 000045D7 7404 JZ INCRET 0 000045D9 89FE MOV SI,DI ; Path too long 0 000045DB EB0D JMP SHORT BADPRET 765 766 INCRET: 767 ; DOS 3.3 FasOpen 6/12/86 F.C. 768 0 000045DD E85B02 CALL InsertPath ; insert dir entry info 770 771 ; DOS 3.3 FasOpen 6/12/86 F.C. 0 000045E0 FEC0 INC AL ; Reset zero 773 SETRET: 0 000045E2 C3 return 775 776 BADPATHPOP: 0 000045E3 5E POP SI ; Start of next element 0 000045E4 8A04 MOV AL,[SI] 0 000045E6 89FE MOV SI,DI ; Start of bad element 0 000045E8 08C0 OR AL,AL ; zero if bad element is last, non-zero if path too long 781 BADPRET: 0 000045EA A0[0000] MOV AL,[SAttrib] 0 000045ED A2[0000] MOV [Attrib],AL ; Make sure return correct 0 000045F0 F9 STC 0 000045F1 C3 return 786 EndProc ROOTPATH 787 788 Break 789 790 ; Inputs: 791 ; [THISDPB] Set 792 ; Function: 793 ; Set up a search for GETENTRY and NEXTENTRY 794 ; Outputs: 795 ; ES:BP = Drive parameters 796 ; Sets up LASTENT, ENTFREE=ENTLAST=-1, VOLID=0 797 ; Destroys ES,BP,AX 798 799 procedure StartSrch,NEAR 799 ****************** warning: proc StartSrch... [-w+user] 800 DOSAssume CS,,"StartSrch" 801 ASSUME ES:NOTHING 802 803 Assert ISDPB,<,>,"StartSrch" 0 000045F2 C42E[0000] LES BP,[THISDPB] 0 000045F6 31C0 XOR AX,AX 806 LASTENT equ LastEnt ; NASM port label 0 000045F8 A3[0000] MOV [LASTENT],AX 808 VOLID equ VolID ; NASM port label 0 000045FB A2[0000] MOV BYTE PTR [VOLID],AL ; No volume ID found 0 000045FE 48 DEC AX 811 ENTFREE equ EntFree ; NASM port label 0 000045FF A3[0000] MOV [ENTFREE],AX 813 ENTLAST equ EntLast ; NASM port label 0 00004602 A3[0000] MOV [ENTLAST],AX 0 00004605 C3 return 816 EndProc StartSrch 817 818 BREAK 819 820 ; 821 ; Input: [Attrib] = attribute to search for 822 ; CH = found attribute 823 ; Output: JZ 824 ; JNZ 825 ; Registers modified: noneski 826 procedure MatchAttributes,near 826 ****************** warning: proc MatchAttributes... [-w+user] 827 ASSUME DS:NOTHING,ES:NOTHING 0 00004606 50 PUSH AX 0 00004607 36A0[0000] MOV AL,[ss:Attrib] ; AL <- SearchSet 0 0000460B F6D0 NOT AL ; AL <- SearchSet' 0 0000460D 20E8 AND AL,CH ; AL <- SearchSet' and FoundSet 0 0000460F 2416 AND AL,attr_all ; AL <- SearchSet' and FoundSet and Important 833 ; 834 ; the result is non-zero if an attribute is not in the search set 835 ; and in the found set and in the important set. This means that we do not 836 ; have a match. Do a JNZ or JZ 837 ; 0 00004611 58 POP AX 0 00004612 C3 return 840 EndProc MatchAttributes 841 842 Break 843 844 ; Inputs: 845 ; DS,ES:DOSGROUP 846 ; Filename in NAME1 847 ; ATTRIB set so that we can error out if looking for Volume IDs 848 ; Function: 849 ; Determine if file is in list of I/O drivers 850 ; Outputs: 851 ; Carry set if not a device 852 ; ELSE 853 ; Zero flag set 854 ; BH = Bit 7,6 = 1, bit 5 = 0 (cooked mode) 855 ; bits 0-4 set from low byte of attribute word 856 ; DEVPT = DWORD pointer to Device header of device 857 ; BX destroyed, others preserved 858 859 procedure DEVNAME,NEAR 859 ****************** warning: proc DEVNAME... [-w+user] 860 DOSAssume CS,,"DEVNAME" 861 0 00004613 56 PUSH SI 0 00004614 57 PUSH DI 0 00004615 51 PUSH CX 0 00004616 50 PUSH AX 866 867 ; E5 special code 0 00004617 FF36[0000] PUSH WORD PTR [NAME1] 0 0000461B 803E[0000]05 CMP byte [NAME1],5 0 00004620 7505 JNZ NOKTR 0 00004622 C606[0000]E5 MOV byte [NAME1],0E5H 872 NOKTR: 873 0 00004627 F606[0000]08 TEST byte [Attrib],attr_volume_id ; If looking for VOL id don't find devs 0 0000462C 7522 JNZ RET31 0 0000462E BE[0000] MOV SI,OFFSET NULDEV wrt DOSGROUP 877 LOOKIO: 878 ASSUME DS:NOTHING 0 00004631 F744040080 TEST word [SI + SDEVATT],DEVTYP 0 00004636 7411 JZ SKIPDEV ; Skip block devices (NET and LOCAL) 0 00004638 89F0 MOV AX,SI 0 0000463A 83C60A ADD SI,SDEVNAME 0 0000463D BF[0000] MOV DI,OFFSET NAME1 wrt DOSGROUP 0 00004640 B90400 MOV CX,4 ; All devices are 8 letters 0 00004643 F3A7 REPE CMPSW ; Check for name in list 0 00004645 89C6 MOV SI,AX 0 00004647 7415 JZ IOCHK ; Found it? 888 SKIPDEV: 0 00004649 C534 LDS SI,[SI] ; Get address of next device 0 0000464B 83FEFF CMP SI,-1 ; At end of list? 0 0000464E 75E1 JNZ LOOKIO 0 00004650 F9 RET31: STC ; Not found 0 00004651 8CD1 RETNV: MOV CX,SS 0 00004653 8ED9 MOV DS,CX 895 ASSUME DS:DOSGroup 0 00004655 8F06[0000] POP WORD PTR [NAME1] 0 00004659 58 POP AX 0 0000465A 59 POP CX 0 0000465B 5F POP DI 0 0000465C 5E POP SI 0 0000465D C3 RET 902 903 IOCHK: 904 ASSUME DS:NOTHING 0 0000465E 368C1E[0200] MOV WORD PTR [ss:DEVPT+2],DS ; Save pointer to device 0 00004663 8A7C04 MOV BH,BYTE PTR [SI + SDEVATT] 0 00004666 80CFC0 OR BH,0C0H 0 00004669 80E7DF AND BH,~ 020H ; Clears Carry 0 0000466C 368936[0000] MOV WORD PTR [ss:DEVPT],SI 0 00004671 EBDE JMP RETNV 911 EndProc DEVNAME 912 913 BREAK 914 915 ; Inputs: 916 ; [NAME1] has name 917 ; BH is attribute field (supplied by DEVNAME) 918 ; [DEVPT] points to device header (supplied by DEVNAME) 919 ; Function: 920 ; Build a directory entry for a device at DEVFCB 921 ; Outputs: 922 ; BX points to DEVFCB 923 ; SI points to dir_first field 924 ; AH = input BH 925 ; AL = 0 926 ; dir_first = DEVPT 927 ; Zero Set, Carry Clear 928 ; DS,ES,BP preserved, others destroyed 929 930 procedure Build_device_ent,near 930 ****************** warning: proc Build_device_ent... [-w+user] 931 DOSAssume CS,,"Build_Device_Ent" 932 0 00004673 B82020 MOV AX," " 0 00004676 BF[0800] MOV DI,OFFSET DEVFCB+8 wrt DOSGROUP ; Point to extent field 935 ; 936 ; Fill dir_ext 937 ; 0 00004679 AB STOSW 0 0000467A AA STOSB ; Blank out extent field 0 0000467B B040 MOV AL,attr_device 941 ; 942 ; Fill Dir_attr 943 ; 0 0000467D AA STOSB ; Set attribute field 0 0000467E 31C0 XOR AX,AX 0 00004680 B90A00 MOV CX,10 947 ; 948 ; Fill dir_pad 949 ; 0 00004683 F3AB REP STOSW ; Fill rest with zeros 0 00004685 E8[0000] invoke DATE16 0 00004688 BF[1600] MOV DI,OFFSET DEVFCB+dir_time wrt DOSGROUP 0 0000468B 92 XCHG AX,DX 954 ; 955 ; Fill dir_time 956 ; 0 0000468C AB STOSW 0 0000468D 92 XCHG AX,DX 959 ; 960 ; Fill dir_date 961 ; 0 0000468E AB STOSW 0 0000468F 89FE MOV SI,DI ; SI points to dir_first field 0 00004691 A1[0000] MOV AX,WORD PTR [DEVPT] 965 ; 966 ; Fill dir_first 967 ; 0 00004694 AB STOSW ; Dir_first points to device 0 00004695 A1[0200] MOV AX,WORD PTR [DEVPT+2] 970 ; 971 ; Fill dir_size_l 972 ; 0 00004698 AB STOSW 0 00004699 88FC MOV AH,BH ; Put device atts in AH 0 0000469B BB[0000] MOV BX,OFFSET DEVFCB wrt DOSGROUP 0 0000469E 30C0 XOR AL,AL ; Set zero, clear carry 0 000046A0 C3 return 978 EndProc Build_device_ent 979 980 Break 981 982 ; 983 ; ValidateCDS - Get current CDS. Splice it. Call FatReadCDS to check 984 ; media. If media has been changed, do DOS_Chdir to validate path. If 985 ; invalid, reset original CDS to root. 986 ; 987 ; Inputs: ThisCDS points to CDS of interest 988 ; SS:DI points to temp buffer 989 ; Outputs: The current directory string is validated on the appropriate 990 ; drive 991 ; ThisDPB changed 992 ; ES:DI point to CDS 993 ; Carry set if error (currently user FAILed to I 24) 994 ; Registers modified: all 995 996 Procedure ValidateCDS,NEAR 996 ****************** warning: proc ValidateCDS... [-w+user] 997 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 998 Public DIR2001S,DIR2001E 999 DIR2001S: 1000 LocalVar Temp,WORD 1001 LocalVar SaveCDS,DWORD 1002 DIR2001E: 0 000046A1 5589E583EC06 Enter 0 000046A7 897EFE MOV [Temp],DI 1005 ThisCDS equ THISCDS ; NASM port label 0 000046AA 36C536[0000] LDS SI,[ss:ThisCDS] 0 000046AF 8976FA MOV [SaveCDSL],SI 0 000046B2 8C5EFC MOV [SaveCDSH],DS 0 000046B5 E8[0000] EnterCrit critDisk 0 000046B8 F744430080 TEST word [SI + curdir_flags],curdir_isnet ; Clears carry 0 000046BD 7403 JZ DoSplice 0 000046BF E99300 JMP FatFail 1013 DoSplice: 0 000046C2 30D2 XOR DL,DL 0 000046C4 368616[0000] XCHG DL,[ss:NoSetDir] 0 000046C9 1607 Context ES 0 000046CB E8[0000] Invoke FStrcpy 0 000046CE 8B76FE MOV SI,[Temp] 0 000046D1 161F Context DS 0 000046D3 E8[0000] Invoke Splice 1021 ASSUME DS:NOTHING 0 000046D6 161F Context DS ; FatReadCDS (ThisCDS); 0 000046D8 8816[0000] MOV [NoSetDir],DL 0 000046DC C43E[0000] LES DI,[ThisCDS] 0 000046E0 55 SaveReg 0 000046E1 E8[0000] Invoke FatRead_CDS 0 000046E4 5D RestoreReg 0 000046E5 726E JC FatFail 0 000046E7 C536[0000] LDS SI,[ThisCDS] ; if (ThisCDS->ID == -1) { 1030 ASSUME DS:NOTHING 0 000046EB 837C49FF CMP word [SI + curdir_ID],-1 0 000046EF 7556 JNZ RestoreCDS 0 000046F1 1607 Context ES 0 000046F3 36FF36[0000] SaveReg ; t = wfp_Start; 0 000046F8 3B76FA CMP SI,[SaveCDSL] ; if not spliced 0 000046FB 750B JNZ DoChdir 0 000046FD 8B7EFE MOV DI,[Temp] 1038 wfp_Start equ WFP_START ; NASM port label 0 00004700 36893E[0000] MOV [ss:wfp_Start],DI ; wfp_start = d; 0 00004705 E8[0000] Invoke FStrCpy ; strcpy (d, ThisCDS->Text); 1041 DoChdir: 0 00004708 161F Context DS 0 0000470A FF36[0000]55 SaveReg <,BP> ; c = DOSChDir (); 0 0000470F E8[0000] Invoke DOS_ChDir 0 00004712 5D5B8F06[0000] RestoreReg ; wfp_Start = t; 0 00004718 881E[0000] MOV [SAttrib],BL 0 0000471C C576FA LDS SI,[SaveCDS] 1048 ASSUME DS:NOTHING 0 0000471F 730F JNC SetCluster ; if (c == -1) { 0 00004721 368936[0000] MOV WORD PTR [ss:ThisCDS],SI ; ThisCDS = TmpCDS; 0 00004726 368C1E[0200] MOV WORD PTR [ss:ThisCDS+2],DS 0 0000472B 31C9 XOR CX,CX ; TmpCDS->text[3] = c = 0; 0 0000472D 884C03 MOV [SI+3],CL ; } 1054 SetCluster: 0 00004730 C74449FFFF MOV word [SI + curdir_ID],-1 ; TmpCDS->ID = -1; 0 00004735 36C536[0000] LDS SI,[ss:ThisCDS] ; ThisCDS->ID = c; 0 0000473A F744430020 TEST word [SI + curdir_flags],curdir_splice ;AN000;;MS. for Join and Subst 0 0000473F 7403 JZ setdirclus ;AN000;;MS. 0 00004741 B9FFFF MOV CX,-1 ;AN000;;MS. 1060 setdirclus: 0 00004744 894C49 MOV [SI + curdir_ID],CX ; } 1062 RestoreCDS: 0 00004747 C47EFA LES DI,[SaveCDS] 0 0000474A 36893E[0000] MOV WORD PTR [ss:ThisCDS],DI 0 0000474F 368C06[0200] MOV WORD PTR [ss:ThisCDS+2],ES 0 00004754 F8 CLC 1067 FatFail: 0 00004755 E8[0000] LeaveCrit critDisk 0 00004758 C47EFA LES DI,[SaveCDS] 0 0000475B 89EC5D Leave 0 0000475E C3 return 1072 EndProc ValidateCDS 1073 1074 Break 1075 1076 ; 1077 ; CheckThisDevice - Examine the area at DS:SI to see if there is a valid 1078 ; device specified. We will return carry if there is a device present. The 1079 ; forms of devices we will recognize are: 1080 ; 1081 ; [path]device 1082 ; 1083 ; Note that the drive letter has *already* been removed. All other forms 1084 ; are not considered to be devices. If such a device is found we change the 1085 ; source pointer to point to the device component. 1086 ; 1087 ; Inputs: ES is DOSGroup 1088 ; DS:SI contains name 1089 ; Outputs: ES is DOSGroup 1090 ; DS:SI point to name or device 1091 ; Carry flag set if device was found 1092 ; Carry flag reset otherwise 1093 ; Registers Modified: all except ES:DI, DS 1094 1095 %if FALSE 1096 Procedure CheckThisDevice,NEAR 1097 DOSAssume CS,,"CheckThisDevice" 1098 ASSUME DS:NOTHING 1099 SaveReg 1100 ; 1101 ; Advance to after the final path character. 1102 ; 1103 MOV DI,SI ; remember first character 1104 PathSkip: 1105 LODSB 1106 OR AL,AL 1107 JZ FoundEnd 1108 %IF DBCS ;AN000; 1109 invoke Testkanj ;AN000;; 2/13/KK 1110 Notkanje equ NotKanje ; NASM port label 1111 jz Notkanje ;AN000;; 2/13/KK 1112 lodsb ;AN000;; 2/13/KK 1113 or al,al ;AN000;; Skip second byte 2/13/KK removed 1114 jz FoundEnd ;AN000;; 2/13/KK removed 1115 Pathskip equ PathSkip ; NASM port label 1116 jmp Short Pathskip ;AN000;; Ignore missing second byte for now. 1117 NotKanje: ;AN000; 1118 %ENDIF ;AN000; 1119 ;kanji load of next char too 2/13/KK 1120 %IF Kanji 1121 kanji load of next char too 1122 %ENDIF 1123 invoke PathChrCmp ; is it a path char? 1124 JNZ PathSkip 1125 MOV DI,SI 1126 JMP PathSkip 1127 FoundEnd: 1128 MOV SI,DI 1129 ; 1130 ; Parse the name 1131 ; 1132 SaveReg ; preserve the source pointer 1133 invoke NameTrans ; advance DS:SI 1134 CMP BYTE PTR [SI],0 ; parse entire string? 1135 STC ; simulate a Carry return from DEVNAME 1136 JNZ SkipSearch ; no parse. simulate a file return. 1137 Context DS 1138 Invoke DEVNAME 1139 ASSUME DS:NOTHING 1140 SkipSearch: 1141 RestoreReg 1142 ; 1143 ; DS:SI points to the beginning of the potential device. If we have a device 1144 ; then we do not change SI. If we have a file, then we reset SI back to the 1145 ; original value. At this point Carry set indicates FILE. 1146 ; 1147 RestoreReg ; get original SI 1148 JNC CheckDone ; if device then do not reset pointer 1149 MOV SI,DI 1150 CheckDone: 1151 RestoreReg 1152 CMC ; invert carry. Carry => device 1153 return 1154 %else 1155 Procedure CheckThisDevice,NEAR 1155 ****************** warning: proc CheckThisDevice... [-w+user] 1156 DOSAssume CS,,"CheckThisDevice" 1157 ASSUME DS:NOTHING 0 0000475F 5756 SaveReg 0 00004761 89F7 MOV DI,SI 1160 ; 1161 ; Check for presence of \dev\ (Dam multiplan!) 1162 ; 0 00004763 8A04 MOV AL,[SI] 0 00004765 E8[0000] Invoke PathChrCmp ; is it a path char? 0 00004768 7517 JNZ ParseDev ; no, go attempt to parse device 0 0000476A 46 INC SI ; simulate LODSB 1167 ; 1168 ; We have the leading path separator. Look for DEV part. 1169 ; 0 0000476B AD LODSW 0 0000476C 0D2020 OR AX,2020h 0 0000476F 3D6465 CMP AX,("e" << 8) + "d" 0 00004772 7527 JNZ NotDevice ; not "de", assume not device 0 00004774 AC LODSB 0 00004775 0C20 OR AL,20h 0 00004777 3C76 CMP AL,"v" ; Not "v", assume not device 0 00004779 7520 JNZ NotDevice 0 0000477B AC LODSB 0 0000477C E8[0000] invoke PathChrCmp ; do we have the last path separator? 0 0000477F 751A JNZ NotDevice ; no. go for it. 1181 ; 1182 ; DS:SI now points to a potential drive. Preserve them as NameTrans advances 1183 ; SI and DEVNAME may destroy DS. 1184 ; 1185 ParseDev: 0 00004781 1E56 SaveReg ; preserve the source pointer 0 00004783 E8[0000] invoke NameTrans ; advance DS:SI 0 00004786 803C00 CMP BYTE PTR [SI],0 ; parse entire string? 0 00004789 F9 STC ; simulate a Carry return from DEVNAME 0 0000478A 7505 JNZ SkipSearch ; no parse. simulate a file return. 0 0000478C 161F Context DS 0 0000478E E882FE Invoke DEVNAME 1193 ASSUME DS:NOTHING 1194 SkipSearch: 0 00004791 5E1F RestoreReg 1196 ; 1197 ; SI points to the beginning of the potential device. If we have a device 1198 ; then we do not change SI. If we have a file, then we reset SI back to the 1199 ; original value. At this point Carry set indicates FILE. 1200 ; 1201 CheckReturn: 0 00004793 5F RestoreReg ; get original SI 0 00004794 7302 JNC CheckDone ; if device then do not reset pointer 0 00004796 89FE MOV SI,DI 1205 CheckDone: 0 00004798 5F RestoreReg 0 00004799 F5 CMC ; invert carry. Carry => device 0 0000479A C3 return 1209 NotDevice: 0 0000479B F9 STC 0 0000479C EBF5 JMP CheckReturn 1212 %endif 1213 1214 EndProc CheckThisDevice 1215 1216 BREAK 1217 1218 ; 1219 ; Output DS:SI -> path name, 1220 ; ES:DI -> dir entry info buffer 1221 ; ES:CX -> extended dir info buffer 1222 ; 1223 ; carry flag clear : tables pointed by ES:DI and ES:CX are filled by 1224 ; FastOpen, DS:SI points to char just one after 1225 ; the last char of path name which is fully or 1226 ; partially found in FastOPen 1227 ; carry flag set : FastOpen not in memory or path name not found 1228 ; 1229 procedure LookupPath,NEAR 1229 ****************** warning: proc LookupPath... [-w+user] 1230 ASSUME ES:NOTHING 1231 1232 ; PUSH AX 0 0000479E 36F606[0000]01 TEST byte [ss:FastOpenFlg],FastOpen_Set ; flg is set in DOSPEN 0 000047A4 7503 JNZ FASTINST ; and this routine is 1235 NOLOOK: 0 000047A6 E99000 JMP NOLOOKUP ; executed once 1237 FASTINST: 0 000047A9 36F606[0000]08 TEST byte [ss:FastOpenFlg],No_Lookup ; no more lookup? 0 000047AF 75F5 JNZ NOLOOK ; yes 1240 0 000047B1 BB[0000] MOV BX,OFFSET FastOpenTable wrt DOSGROUP ; get fastopen related tab 0 000047B4 368B36[0000] MOV SI,[ss:Wfp_Start] ; si points to path name 0 000047B9 BF[0000] MOV DI,OFFSET Dir_Info_Buff wrt DOSGROUP 0 000047BC B9[0000] MOV CX,OFFSET FastOpen_Ext_Info wrt DOSGROUP 0 000047BF B001 MOV AL,FONC_look_up ; al = 1 0 000047C1 1E PUSH DS 0 000047C2 07 POP ES 0 000047C3 FF5F02 CALL far [BX + FASTOPEN_NAME_CACHING] ;call fastopen 0 000047C6 7260 JC NOTFOUND ; fastopen not in memory 1250 0 000047C8 8D5CFE LEA BX,[SI-2] 0 000047CB 363B1E[0000] CMP BX,[ss:Wfp_Start] ; path found ? 0 000047D0 7456 JZ NOTFOUND ; no 1254 ; fully or partially found 0 000047D2 803C00 CMP BYTE PTR [SI],0 ;AN000;FO. 0 000047D5 751A JNZ parfnd ;AN000;FO.; partiallyfound 0 000047D7 51 PUSH CX ;AN000;FO.; is attribute matched ? 0 000047D8 368A0E[0000] MOV CL,[ss:Attrib] ;AN000;FO.; 1259 Sattrib equ SAttrib ; NASM port label 0 000047DD 368A2E[0000] MOV CH,[ss:Sattrib] ;AN000;FO.; attrib=sattrib 0 000047E2 36882E[0000] MOV [ss:Attrib],CH ;AN000;FO.; 0 000047E7 268A6D0B MOV CH,[ES:DI + dir_attr] ;AN000;FO.; 0 000047EB E818FE invoke MatchAttributes ;AN000;FO.; 1264 ;;; MOV Attrib,CL ;AN001;FO.; retore attrib 0 000047EE 59 POP CX ;AN000;FO.; 0 000047EF 7548 JNZ NOLOOKUP ;AN000;FO.; not matched 1267 parfnd: 0 000047F1 368936[0000] MOV [ss:Next_Element_Start],SI ; save si 0 000047F6 89CB MOV BX,CX 0 000047F8 8B4707 MOV AX,[BX + FEI_lastent] ;AN000;;FO. restore lastentry 0 000047FB 36A3[0000] MOV [ss:LASTENT],AX ;AN000;;FO. 0 000047FF 8B4709 MOV AX,[BX + FEI_dirstart] ;AN001;;FO. restore dirstart 0 00004802 36A3[0000] MOV [ss:DIRSTART],AX ;AN001;;FO. 0 00004806 8B4705 MOV AX,[BX + FEI_clusnum] ; restore next cluster num 0 00004809 36A3[0000] MOV [ss:CLUSNUM],AX ; 1276 0 0000480D 06 PUSH ES ; save ES 0 0000480E 36C41E[0000] LES BX,[ss:THISDPB] ; put drive id 0 00004813 268A27 MOV AH,[ES:BX + dpb_drive] ; in AH for DOOPEN 0 00004816 07 POP ES ; pop ES 1281 0 00004817 368C06[0200] MOV WORD PTR [ss:CURBUF+2],ES ; [curbuf+2].bx points to 0 0000481C 89FB MOV BX,DI ; start of entry 0 0000481E 8D751A LEA SI,[DI + dir_first] ; [curbuf+2]:si points to 1285 ; dir_first field in the 1286 ; dir entry 1287 set_for_search equ Set_For_Search ; NASM port equate 0 00004821 36800E[0000]12 OR byte [ss:FastOpenFlg],Lookup_Success + set_for_search 1289 ; POP AX 0 00004827 C3 RET 1291 NOTFOUND: 0 00004828 83F8FF CMP AX,-1 ; not in memory ? 0 0000482B 7506 JNZ Partial_Success ; yes, in memory 0 0000482D 36C606[0000]00 MOV byte [ss:FastOpenFlg],0 ; no more fastopen 1295 Partial_Success: 0 00004833 368026[0000]FB AND byte [ss:FastOpenFlg],Special_Fill_Reset 1297 NOLOOKUP: 1298 ; POP AX 0 00004839 F9 STC 0 0000483A C3 RET 1301 EndProc LookupPath 1302 1303 BREAK 1304 1305 ; 1306 ; Input: FastOpen_Set flag set when from DOSOPEN otherwise 0 1307 ; Lookup_Success flag set when got dir entry info from FASTOPEN 1308 ; DS = DOSGROUP 1309 ; Output: FastOPen_Ext_Info is set and path dir info is inserted 1310 ; 1311 procedure InsertPath,NEAR 1311 ****************** warning: proc InsertPath... [-w+user] 1312 ASSUME ES:NOTHING 1313 0 0000483B 9C PUSHF 0 0000483C 36F606[0000]01 TEST byte [ss:FastOpenFlg],FastOpen_Set ;only DOSOPEN can take advantage of 0 00004842 747A JZ GET_NEXT_ELEMENT ; the FastOpen 0 00004844 36F606[0000]02 TEST byte [ss:FastOpenFlg],Lookup_Success ; Lookup just happened 0 0000484A 740E JZ INSERT_DIR_INFO ; no 0 0000484C 368026[0000]FD AND byte [ss:FastOpenFlg],Lookup_Reset ; we got dir info from fastopen so 0 00004852 368B3E[0000] MOV DI,[ss:Next_Element_Start] ; no need to insert it again 0 00004857 EB5F JMP GET_NEXT2 0 00004859 90 nop ; identicalise 1323 INSERT_DIR_INFO: ; save registers 0 0000485A 1E PUSH DS 0 0000485B 06 PUSH ES 0 0000485C 53 PUSH BX 0 0000485D 56 PUSH SI 0 0000485E 57 PUSH DI 0 0000485F 51 PUSH CX 0 00004860 50 PUSH AX 1331 ; int 3 0 00004861 36C53E[0000] LDS DI,[ss:CURBUF] ; DS:DI -> buffer header 1333 ASSUME DS:NOTHING 0 00004866 BE[0000] MOV SI,OFFSET FastOpen_Ext_Info wrt DOSGROUP 0 00004869 8B4508 MOV AX,WORD PTR [DI + buf_sector] ; get directory sector 0 0000486C 36894401 MOV WORD PTR [ss:SI + FEI_dirsec],AX ;AN000; >32mb save dir sector 0 00004870 8B450A MOV AX,WORD PTR [DI + buf_sector+2] ;AN000; >32mb 0 00004873 161F context DS 0 00004875 894403 MOV WORD PTR [SI + FEI_dirsec+2],AX ;AN000;>32mb save high dir sector 0 00004878 A1[0000] MOV AX,[CLUSNUM] ; save next cluster number 0 0000487B 894405 MOV [SI + FEI_clusnum],AX 0 0000487E A1[0000] MOV AX,[LASTENT] ;AN000;FO. save lastentry for search first 0 00004881 894407 MOV [SI + FEI_lastent],AX ;AN000;FO. 0 00004884 A1[0000] MOV AX,[DIRSTART] ;AN001;FO. save for search first 0 00004887 894409 MOV [SI + FEI_dirstart],AX ;AN001;FO. 1346 0 0000488A 89D8 MOV AX,BX 0 0000488C 83C710 ADD DI,BUFINSIZ ; DS:DI -> start of data in buffer 0 0000488F 29F8 SUB AX,DI ; AX=BX relative to start of sector 0 00004891 B120 MOV CL,dir_entry_struc_size 1351 ;invoke debug_DOS 0 00004893 F6F1 DIV CL 0 00004895 8804 MOV [SI + FEI_dirpos],AL ; save directory entry # in buffer 1354 0 00004897 1E PUSH DS 0 00004898 07 POP ES 1357 0 00004899 8E1E[0200] MOV DS,WORD PTR [CURBUF+2] 0 0000489D 89DF MOV DI,BX ; DS:DI -> dir entry info 1360 ASSUME DS:NOTHING 0 0000489F 837D1A00 CMP word [DI + dir_first],0 ; never insert info when file is empty 0 000048A3 740C JZ SKIP_INSERT ; e.g. newly created file 1363 0 000048A5 56 PUSH SI ; ES:BX -> extended info 0 000048A6 5B POP BX 1366 0 000048A7 B002 MOV AL,FONC_insert ; call fastopen insert operation 0 000048A9 BE[0000] MOV SI,OFFSET FastOpenTable wrt DOSGROUP 0 000048AC 26FF5C02 CALL far [ES:SI + FASTOPEN_NAME_CACHING] 1370 0 000048B0 F8 CLC 1372 SKIP_INSERT: 0 000048B1 58 POP AX 0 000048B2 59 POP CX ; restore registers 0 000048B3 5F POP DI 0 000048B4 5E POP SI 0 000048B5 5B POP BX 0 000048B6 07 POP ES 0 000048B7 1F POP DS 1380 GET_NEXT2: 0 000048B8 36800E[0000]08 OR byte [ss:FastOpenFlg],No_Lookup ; we got dir info from fastopen so 1382 GET_NEXT_ELEMENT: 0 000048BE 9D POPF 0 000048BF C3 RET 1385 EndProc InsertPath 1386 1387 CODE ENDS 1388 END === Trace listing source: ../DOS/dev.lst 1 ; SCCSID = @(#)dev.asm 1.2 85/07/23 2 ; SCCSID = @(#)dev.asm 1.2 85/07/23 3 ;TITLE DEV - Device call routines 4 ;NAME Dev 5 ; Misc Routines to do 1-12 low level I/O and call devices 6 ; 7 ; IOFUNC 8 ; DEVIOCALL 9 ; SETREAD 10 ; SETWRITE 11 ; DEVIOCALL2 12 ; DEV_OPEN_SFT 13 ; DEV_CLOSE_SFT 14 ; RW_SC 15 ; IN_SC 16 ; INVALIDATE_SC 17 ; VIRREAD 18 ; SC2BUF 19 ; 20 ; Revision history: 21 ; 22 ; A000 version 4.00 Jan. 1988 23 ; A010 disable change line for SHARE /NC 24 25 ; 26 ; get the appropriate segment definitions 27 ; 28 [list -] === Switch to base=008400h -> "DOSCODECODE" 32 section DOSCODECODE 33 [list -] 33 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 33 ****************** warning: out: BPB.INC... [-w+user] 33 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 33 ****************** warning: out: DEVSYM.INC... [-w+user] 33 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 41 42 i_need IOXAD,DWORD 43 i_need IOSCNT,WORD 44 i_need DEVIOBUF,4 45 i_need IOCALL,BYTE 46 i_need IOMED,BYTE 47 i_need IORCHR,BYTE 48 i_need CALLSCNT,WORD 49 i_need DMAAdd,DWORD 50 i_need CallDevAd,DWORD 51 i_need CallXAD,DWORD 52 i_need DPBHead,DWORD 53 i_need ThisSFT,DWORD 54 i_need ThisDPB,DWORD 55 i_need DevCall,DWORD 56 i_need VerFlg,BYTE 57 i_need HIGH_SECTOR,WORD ;AN000; 58 i_need CALLSSEC,WORD ;AN000; 59 i_need CALLNEWSC,DWORD ;AN000; 60 i_need SC_CACHE_COUNT,WORD ;AN000; 61 i_need SC_CACHE_PTR,DWORD ;AN000; 62 i_need CURSC_SECTOR,WORD ;AN000; 63 i_need SEQ_SECTOR,DWORD ;AN000; 64 i_need SC_SECTOR_SIZE,WORD ;AN000; 65 i_need CURSC_DRIVE,BYTE ;AN000; 66 i_need SC_DRIVE,BYTE ;AN000; 67 i_need SC_STATUS,WORD ;AN000; 68 i_need SC_FLAG,BYTE ;AN000; 69 i_need TEMP_VAR,WORD ;AN000; 70 i_need TEMP_VAR2,WORD ;AN000; 71 i_need InterChar,BYTE ;AN000; interim character flag 2/13/KK 72 i_need InterCon,BYTE ;AN000; Console mode flag(1:interim mode) 2/13/KK 73 i_need SaveCurFlg,BYTE ;AN000; Console out mode(1:print & don't adv cursor) 2 /13/KK 74 i_need DDMOVE,BYTE ;AN000; flag for DWORD move 75 i_need DOS34_FLAG,WORD ;AN000; 76 i_need fshare,BYTE ;AN010; share flag 77 78 Break 79 80 ; Inputs: 81 ; DS:SI Points to SFT 82 ; AH is function code 83 ; = 0 Input 84 ; = 1 Input Status 85 ; = 2 Output 86 ; = 3 Output Status 87 ; = 4 Flush 88 ; = 5 Input Status - System WAIT invoked for K09 if no char 89 ; present. 90 ; AL = character if output 91 ; Function: 92 ; Perform indicated I/O to device or file 93 ; Outputs: 94 ; AL is character if input 95 ; If a status call 96 ; zero set if not ready 97 ; zero reset if ready (character in AL for input status) 98 ; For regular files: 99 ; Input Status 100 ; Gets character but restores position 101 ; Zero set on EOF 102 ; Input 103 ; Gets character advances position 104 ; Returns ^Z on EOF 105 ; Output Status 106 ; Always ready 107 ; AX altered, all other registers preserved 108 109 procedure IOFUNC,NEAR 109 ****************** warning: proc IOFUNC... [-w+user] 110 ASSUME DS:NOTHING,ES:NOTHING 111 112 Assert ISSFT,,"IOFUNC" 0 000048C0 368C16[0200] MOV WORD PTR [ss:IOXAD+2],SS 0 000048C5 36C706[0000][0000] MOV WORD PTR [ss:IOXAD],OFFSET DEVIOBUF wrt DOSGROUP 0 000048CC 36C706[0000]0100 MOV WORD PTR [ss:IOSCNT],1 0 000048D3 36A3[0000] MOV WORD PTR [ss:DEVIOBUF],AX 0 000048D7 F744050080 TEST word [SI + sf_flags],sf_isnet 0 000048DC 7403 JZ IOTO22 ;AN000; 0 000048DE E9A000 JMP IOTOFILE ;AN000; 120 IOTO22: 0 000048E1 F744058000 TEST word [SI + sf_flags],devid_device 122 IOTo33 equ IOTO33 ; NASM port label 0 000048E6 7503 JNZ IOTo33 ;AN000; 0 000048E8 E99600 JMP IOTOFILE ;AN000; 125 IOTO33: 0 000048EB E8[0000] invoke save_world 0 000048EE 8CDA MOV DX,DS 0 000048F0 8CD3 MOV BX,SS 0 000048F2 8EDB MOV DS,BX 0 000048F4 8EC3 MOV ES,BX 131 ASSUME DS:DOSGroup 0 000048F6 31DB XOR BX,BX 0 000048F8 80FC05 cmp ah,5 ; system wait enabled? 0 000048FB 7504 jnz no_sys_wait 0 000048FD 81CB0004 or bx,0400H ; Set bit 10 in status word for driver 136 ; It is up to device driver to carry out 137 ; appropriate action. 138 no_sys_wait: 0 00004901 891E[0300] MOV [IOCALL + REQSTAT],BX 0 00004905 31DB XOR BX,BX 0 00004907 881E[0000] MOV BYTE PTR [IOMED],BL 142 === Switch to base=008400h -> "DOSCODETABLE" 143 section DOSCODETABLE 144 DEV001S equ DEV001s ; NASM port label 145 Public DEV001S, DEV001E ; Pathgen labels 146 DEV001s: 147 ; length of packets 0 0000046E 160E160D0F0E LenTab DB DRDWRHL, DRDNDHL, DRDWRHL, DSTATHL, DFLSHL, DRDNDHL 149 150 ; Error Function 151 0 00000474 8604 CmdTab DB 86h, DEVRD ; 0 input 0 00000476 8605 DB 86h, DEVRDND ; 1 input status 0 00000478 8708 DB 87h, DEVWRT ; 2 output 0 0000047A 870A DB 87h, DEVOST ; 3 output status 0 0000047C 8607 DB 86h, DEVIFL ; 4 input flush 0 0000047E 8605 DB 86H, DEVRDND ; 5 input status with system WAIT 158 DEV001E: === Switch to base=008400h -> "DOSCODECODE" 159 DOSCODETABLE ENDS === Switch to base=008400h -> "DOSCODECODE" 160 section DOSCODECODE 161 0 0000490B 88E3 MOV BL,AH ; get function 0 0000490D 2E8AA7[0000] MOV AH,[cs:LenTab + BX] 0 00004912 D1E3 SHL BX,1 0 00004914 2E8B8F[0600] MOV CX,WORD PTR [cs:CmdTab + BX] 166 0 00004919 BB[0000] MOV BX,OFFSET IOCALL wrt DOSGROUP 168 0 0000491C 8826[0000] MOV [IOCALL + REQLEN],AH 0 00004920 882E[0200] MOV [IOCALL + REQFUNC],CH 171 %IF DBCS ;AN000; 172 ;----------------------------- Start of DBCS 2/13/KK 173 PUSH CX ;AN000; 174 MOV CL, [InterCon] ;AN000; 175 CMP CH, DEVRD ;AN000; 0 input 176 JZ SETIN ;AN000; 177 CMP CH, DEVRDND ;AN000; 1(5) input status without(with) system WAIT 178 JZ SETIN ;AN000; 179 SaveCurflg equ SaveCurFlg ; NASM port label 180 MOV CL, [SaveCurflg] ;AN000; 181 CMP CH, DEVWRT ;AN000; 2 output 182 JZ CHKERROUT ;AN000; 183 XOR CL,CL ;AN000; else, do normal 184 SETIN: ;AN000; 185 IoMed equ IOMED ; NASM port label 186 MOV BYTE PTR [IoMed], CL ;AN000; set interim I/O indication 187 POP CX ;AN000; 188 ;----------------------------- End of DBCS 2/13/KK 189 %ENDIF ;AN000; 0 00004924 8EDA MOV DS,DX 191 ASSUME DS:NOTHING 0 00004926 E86701 CALL DEVIOCALL 0 00004929 368B3E[0300] MOV DI,[ss:IOCALL + REQSTAT] 0 0000492E F7C70080 TEST DI,STERR 0 00004932 7520 JNZ DevErr 196 OkDevIO: 0 00004934 8CD0 MOV AX,SS 0 00004936 8ED8 MOV DS,AX 199 ASSUME DS:DOSGroup 200 %IF DBCS ;AN000; 201 MOV byte [InterChar],0 ;AN000; reset interim character flag 2/13/KK 202 TEST DI,Ddkey ;AN000; is this a dead key (interim char)? 2/13/KK 203 JZ NotInterim ;AN000; no, flag already reset... 2/13/KK 204 INC byte [InterChar] ;AN000; yes, set flag for future 2/13/KK 205 NotInterim: ;AN000; 2/13/KK 206 %ENDIF ;AN000; 0 00004938 80FD05 CMP CH,DEVRDND 0 0000493B 7506 JNZ DNODRD 0 0000493D A0[0000] MOV AL,BYTE PTR [IORCHR] 0 00004940 A2[0000] MOV [DEVIOBUF],AL 211 0 00004943 8A26[0400] DNODRD: MOV AH,BYTE PTR [IOCALL + REQSTAT+1] 0 00004947 F6D4 NOT AH ; Zero = busy, not zero = ready 0 00004949 80E402 AND AH,STBUI >> 8 215 216 QuickReturn: ;AN000; 2/13/KK 0 0000494C E8[0000] invoke restore_world 218 ASSUME DS:NOTHING 0 0000494F 36A1[0000] MOV AX,WORD PTR [ss:DEVIOBUF] 0 00004953 C3 return 221 222 ;IOTOFILEJ: 223 ; JMP SHORT IOTOFILE 224 %IF DBCS ;AN000; 225 ;------------------------------ Start of DBCS 2/13/KK 226 CHKERROUT: ;AN000; 227 MOV DS, DX ;AN000; 228 TEST word [SI + sf_flags], devid_device_con_out ;AN000; output to console ? 229 JNZ GOOD ;AN000; yes 230 CMP CL, 01 ;AN000; write interim ? 231 JNZ GOOD ;AN000; no, 232 POP CX ;AN000; 233 JMP SHORT QuickReturn ;AN000; avoid writting interims to other than 234 ;AN000; console device 235 GOOD: ;AN000; 236 PUSH SS ;AN000; 237 POP DS ;AN000; 238 JMP SETIN ;AN000; 239 ;------------------------------ End of DBCS 2/13/KK 240 %ENDIF ;AN000; 241 DevErr: 242 X25_Special equ X25_special ; NASM port equate 0 00004954 36F706[0000]0008 TEST word [ss:DOS34_FLAG],X25_Special ;AN000; from disk.asm 0 0000495B 740D JZ notx25 ;AN000; no 0 0000495D 50 PUSH AX ;AN000; unknown command ? 0 0000495E 89F8 MOV AX,DI ;AN000; 0 00004960 83E003 AND AX,error_I24_bad_command ;AN000; 0 00004963 3C03 CMP AL,error_I24_bad_command ;AN000; 0 00004965 58 POP AX ;AN000; 0 00004966 7502 JNZ notx25 ;AN000; no, then error 251 okDevIO equ OkDevIO ; NASM port label 0 00004968 EBCA JMP okDevIO ;AN000; 253 notx25: 0 0000496A 88CC MOV AH,CL 0 0000496C E8[0000] invoke CHARHARD 0 0000496F 3C01 CMP AL,1 0 00004971 7506 JNZ NO_RETRY 0 00004973 E8[0000] invoke restore_world 0 00004976 E947FF JMP IOFUNC 260 261 NO_RETRY: 262 ; Know user must have wanted Ignore OR Fail. Make sure device shows ready 263 ; so that DOS doesn't get caught in a status loop when user simply wants 264 ; to ignore the error. 0 00004979 368026[0400]FD AND BYTE PTR [ss:IOCALL + REQSTAT+1], ~ (STBUI >> 8) 266 OKDevIO equ OkDevIO ; NASM port label 0 0000497F EBB3 JMP OKDevIO 268 269 IOTOFILE: 270 ASSUME DS:NOTHING 0 00004981 08E4 OR AH,AH 0 00004983 7423 JZ IOIN 0 00004985 FECC DEC AH 0 00004987 7405 JZ IOIST 0 00004989 FECC DEC AH 0 0000498B 7411 JZ IOUT 0 0000498D C3 return ; NON ZERO FLAG FOR OUTPUT STATUS 278 279 IOIST: 0 0000498E FF7415 PUSH WORD PTR [SI + sf_position] ; Save position 0 00004991 FF7417 PUSH WORD PTR [SI + sf_position+2] 0 00004994 E81100 CALL IOIN 0 00004997 8F4417 POP WORD PTR [SI + sf_position+2] ; Restore position 0 0000499A 8F4415 POP WORD PTR [SI + sf_position] 0 0000499D C3 return 286 287 IOUT: 0 0000499E E82700 CALL SETXADDR 0 000049A1 E8[0000] invoke DOS_WRITE 0 000049A4 E85400 CALL RESTXADDR ; If you change this into a jmp don't 0 000049A7 C3 return ; come crying to me when things don't 292 ; work ARR 293 294 IOIN: 0 000049A8 E81D00 CALL SETXADDR 0 000049AB 36830E[0000]40 OR word [ss:DOS34_FLAG],Disable_EOF_I24 ;AN000; 0 000049B1 E8[0000] invoke DOS_READ 0 000049B4 368326[0000]BF AND word [ss:DOS34_FLAG],NO_Disable_EOF_I24 ;AN000; 0 000049BA 09C9 OR CX,CX ; Check EOF 0 000049BC E83C00 CALL RESTXADDR 0 000049BF 36A0[0000] MOV AL,[ss:DEVIOBUF] ; Get byte from trans addr 0 000049C3 75E2 retnz 0 000049C5 B01A MOV AL,1AH ; ^Z if no bytes 0 000049C7 C3 return 305 306 SETXADDR: 0 000049C8 368F06[0000] POP WORD PTR [ss:CALLSCNT] ; Return address 0 000049CD E8[0000] invoke save_world 309 DMAADD equ DMAAdd ; NASM port label 0 000049D0 36FF36[0000] PUSH WORD PTR [ss:DMAADD] ; Save Disk trans addr 0 000049D5 36FF36[0200] PUSH WORD PTR [ss:DMAADD+2] 312 THISSFT equ ThisSFT ; NASM port label 0 000049DA 368C1E[0200] MOV WORD PTR [ss:THISSFT+2],DS 0 000049DF 161F Context DS 0 000049E1 8936[0000] MOV WORD PTR [THISSFT],SI ; Finish setting SFT pointer 0 000049E5 8B0E[0200] MOV CX,WORD PTR [IOXAD+2] 0 000049E9 890E[0200] MOV WORD PTR [DMAADD+2],CX 0 000049ED 8B0E[0000] MOV CX,WORD PTR [IOXAD] 0 000049F1 890E[0000] MOV WORD PTR [DMAADD],CX ; Set byte trans addr 0 000049F5 8B0E[0000] MOV CX,[IOSCNT] ; ioscnt specifies length of buffer 0 000049F9 EB0F JMP SHORT RESTRET ; RETURN ADDRESS 322 323 RESTXADDR: 324 DOSAssume CS,,"RestXAddr" 0 000049FB 8F06[0000] POP WORD PTR [CALLSCNT] ; Return address 0 000049FF 8F06[0200] POP WORD PTR [DMAADD+2] ; Restore Disk trans addr 0 00004A03 8F06[0000] POP WORD PTR [DMAADD] 0 00004A07 E8[0000] invoke restore_world 329 ASSUME DS:NOTHING 0 00004A0A 36FF26[0000] RESTRET:JMP WORD PTR [ss:CALLSCNT] ; Return address 331 EndProc IOFUNC 332 333 Break 334 335 ; Inputs: 336 ; ES:DI Points to SFT 337 ; Function: 338 ; Issue an OPEN call to the correct device 339 ; Outputs: 340 ; None 341 ; ALL preserved 342 343 procedure DEV_OPEN_SFT,NEAR 343 ****************** warning: proc DEV_OPEN_SFT... [-w+user] 344 ASSUME DS:NOTHING,ES:NOTHING 345 346 Assert ISSFT,,"Dev_Open_SFT" 0 00004A0F E8[0000] invoke Save_World 0 00004A12 B00D MOV AL,DEVOPN 0 00004A14 EB05 JMP SHORT DO_OPCLS 350 351 EndProc DEV_OPEN_SFT 352 353 ; Inputs: 354 ; ES:DI Points to SFT 355 ; Function: 356 ; Issue a CLOSE call to the correct device 357 ; Outputs: 358 ; None 359 ; ALL preserved 360 361 procedure DEV_CLOSE_SFT,NEAR 361 ****************** warning: proc DEV_CLOSE_SFT... [-w+user] 362 ASSUME DS:NOTHING,ES:NOTHING 363 364 Assert ISSFT,,"Dev_Close_SFT" 0 00004A16 E8[0000] invoke Save_World 0 00004A19 B00E MOV AL,DEVCLS 367 368 ; 369 ; Main entry for device open and close. AL contains the function requested. 370 ; Subtlety: if Sharing is NOT loaded then we do NOT issue open/close to block 371 ; devices. This allows networks to function but does NOT hang up with bogus 372 ; change-line code. 373 ; 374 entry DO_OPCLS 375 ; 376 ; Is the SFT for the net? If so, no action necessary. 377 ; 0 00004A1B E8[0000] invoke Test_IFS_Remote ;AC000; 0 00004A1E 756C JNZ OPCLS_DONE ; NOP on net SFTs 0 00004A20 30E4 XOR AH,AH ; Unit 0 00004A22 26F745058000 TEST word [ES:DI + sf_flags],devid_device 0 00004A28 26C47D07 LES DI,[ES:DI + sf_devptr] ; Get DPB or device 383 Got_Dev_Addr equ GOT_DEV_ADDR ; NASM port label 0 00004A2C 7513 JNZ Got_Dev_Addr 385 ; 386 ; We are about to call device open/close on a block driver. If no sharing 387 ; then just short circuit to done. 388 ; 389 ;;;;; invoke CheckShare 0 00004A2E 36803E[0000]01 CMP byte [ss:fshare],1 ;AN010; /NC or no SHARE 391 opCLs_Done equ OPCLS_DONE ; NASM port label 0 00004A34 7656 JBE opCLs_Done ;AN010; yes 0 00004A36 268A6501 MOV AH,[ES:DI + dpb_UNIT] 0 00004A3A 268A0D MOV CL,[ES:DI + dpb_drive] 0 00004A3D 26C47D13 LES DI,[ES:DI + dpb_driver_addr] ; Get device 396 GOT_DEV_ADDR: ; ES:DI -> device 0 00004A41 26F745040008 TEST word [ES:DI + SDEVATT],DEVOPCL 0 00004A47 7443 JZ OPCLS_DONE ; Device can't 0 00004A49 06 PUSH ES 0 00004A4A 1F POP DS 0 00004A4B 89FE MOV SI,DI ; DS:SI -> device 402 OPCLS_RETRY: 0 00004A4D 1607 Context ES 404 DEVCALL equ DevCall ; NASM port label 0 00004A4F BF[0000] MOV DI,OFFSET DEVCALL wrt DOSGROUP 0 00004A52 89FB MOV BX,DI 0 00004A54 50 PUSH AX 0 00004A55 B00D MOV AL,DOPCLHL 0 00004A57 AA STOSB ; Length 0 00004A58 58 POP AX 0 00004A59 86E0 XCHG AH,AL 0 00004A5B AA STOSB ; Unit 0 00004A5C 86E0 XCHG AH,AL 0 00004A5E AA STOSB ; Command 0 00004A5F 26C7050000 MOV WORD PTR [ES:DI],0 ; Status 0 00004A64 50 PUSH AX ; Save Unit,Command 0 00004A65 E82B00 invoke DEVIOCALL2 0 00004A68 268B7F03 MOV DI,[ES:BX + REQSTAT] 0 00004A6C F7C70080 TEST DI,STERR 0 00004A70 7419 JZ OPCLS_DONEP ; No error 0 00004A72 F744040080 TEST word [SI + SDEVATT],DEVTYP 0 00004A77 7404 JZ BLKDEV 0 00004A79 B486 MOV AH,86H ; Read error in data, Char dev 0 00004A7B EB04 JMP SHORT HRDERR 425 426 BLKDEV: 0 00004A7D 88C8 MOV AL,CL ; Drive # in AL 0 00004A7F B406 MOV AH,6 ; Read error in data, Blk dev 429 HRDERR: 0 00004A81 E8[0000] invoke CHARHARD 0 00004A84 3C01 CMP AL,1 0 00004A86 7503 JNZ OPCLS_DONEP ; IGNORE or FAIL 433 ; Note that FAIL is essentually IGNORED 0 00004A88 58 POP AX ; Get back Unit, Command 0 00004A89 EBC2 JMP OPCLS_RETRY 436 437 OPCLS_DONEP: 0 00004A8B 58 POP AX ; Clean stack 439 OPCLS_DONE: 0 00004A8C E8[0000] invoke Restore_World 0 00004A8F C3 return 442 443 EndProc DEV_CLOSE_SFT 444 445 Break 446 447 ; Inputs: 448 ; DS:SI Points to device SFT 449 ; ES:BX Points to request data 450 ; Function: 451 ; Call the device 452 ; Outputs: 453 ; DS:SI -> Device driver 454 ; DS:SI,AX destroyed, others preserved 455 456 procedure DEVIOCALL,NEAR 456 ****************** warning: proc DEVIOCALL... [-w+user] 457 ASSUME DS:NOTHING,ES:NOTHING 458 459 Assert ISSFT,,"DevIOCall" 0 00004A90 C57407 LDS SI,[SI + sf_devptr] 461 462 entry DEVIOCALL2 463 0 00004A93 E8[0000] EnterCrit critDevice 465 466 DevTyp equ DEVTYP ; NASM port equate 0 00004A96 F744040080 TEST word [SI + SDEVATT],DevTyp ;AN000; >32mb block device ? 0 00004A9B 754F JNZ chardev2 ;AN000; >32mb no 0 00004A9D 26807F0204 CMP byte [ES:BX + REQFUNC],DEVRD ;AN000; >32mb read ? 0 00004AA2 740E JZ chkext ;AN000; >32mb yes 0 00004AA4 26807F0208 CMP byte [ES:BX + REQFUNC],DEVWRT ;AN000; >32mb write ? 0 00004AA9 7407 JZ chkext ;AN000; >32mb yes 0 00004AAB 26807F0209 CMP byte [ES:BX + REQFUNC],DEVWRTV;AN000; >32mb write/verify ? 0 00004AB0 753A JNZ chardev2 ;AN000; >32mb no 475 chkext: 0 00004AB2 E89C00 CALL RW_SC ;AN000;LB. use secondary cache if there 0 00004AB5 7257 JC dev_exit ;AN000;LB. done 478 0 00004AB7 F744040200 TEST word [SI + SDEVATT],EXTDRVR ;AN000;>32mb extended driver? 0 00004ABC 741E JZ chksector ;AN000;>32mb no 0 00004ABE 26800708 ADD BYTE PTR [ES:BX],8 ;AN000;>32mb make length to 30 0 00004AC2 36A1[0000] MOV AX,[ss:CALLSSEC] ;AN000;>32mb 0 00004AC6 36C706[0000]FFFF MOV word [ss:CALLSSEC],-1 ;AN000;>32mb old sector =-1 0 00004ACD 36A3[0000] MOV WORD PTR [ss:CALLNEWSC],AX ;AN000;>32mb new sector = 0 00004AD1 36A1[0000] MOV AX,[ss:HIGH_SECTOR] ;AN000; >32mb low sector,high sector 0 00004AD5 36A3[0200] MOV WORD PTR [ss:CALLNEWSC+2],AX ;AN000; >32mb 0 00004AD9 EB11 JMP chardev2 ;AN000; >32mb 0 00004ADB 90 nop ; identicalise 489 chksector: ;AN000; >32mb 0 00004ADC 36833E[0000]00 CMP word [ss:HIGH_SECTOR],0 ;AN000; >32mb if >32mb 0 00004AE2 7408 JZ chardev2 ;AN000; >32mb then fake error 492 ERROR_I24_NOT_DOS_DISK equ error_I24_not_DOS_disk ; NASM port equate 0 00004AE4 26C747030781 MOV word [ES:BX + REQSTAT],STERR+STDON+ERROR_I24_NOT_DOS_DISK ;AN000; >32mb 0 00004AEA EB22 JMP SHORT dev_exit ;AN000; >32mb 495 496 chardev2: ;AN000; 497 ; As above only DS:SI points to device header on entry, and DS:SI is preserved 0 00004AEC 8B4406 MOV AX,[SI + SDEVSTRAT] 499 CALLDEVAD equ CallDevAd ; NASM port label 0 00004AEF 36A3[0000] MOV WORD PTR [ss:CALLDEVAD],AX 0 00004AF3 368C1E[0200] MOV WORD PTR [ss:CALLDEVAD+2],DS 0 00004AF8 36FF1E[0000] CALL far [ss:CALLDEVAD] 0 00004AFD 8B4408 MOV AX,[SI + SDEVINT] 0 00004B00 36A3[0000] MOV WORD PTR [ss:CALLDEVAD],AX 0 00004B04 36FF1E[0000] CALL far [ss:CALLDEVAD] 0 00004B09 E85B00 CALL VIRREAD ;AN000;LB. move data from SC to buffer 0 00004B0C 72DE JC chardev2 ;AN000;LB. bad sector or exceeds max sec 508 dev_exit: 0 00004B0E E8[0000] LeaveCrit critDevice 0 00004B11 C3 return 511 EndProc DEVIOCALL 512 513 Break 514 515 ; Inputs: 516 ; DS:BX = Transfer Address 517 ; CX = Record Count 518 ; DX = Starting Record 519 ; AH = Media Byte 520 ; AL = Unit Code 521 ; Function: 522 ; Set up the device call header at DEVCALL 523 ; Output: 524 ; ES:BX Points to DEVCALL 525 ; No other registers effected 526 527 procedure SETREAD,NEAR 527 ****************** warning: proc SETREAD... [-w+user] 528 ASSUME DS:NOTHING,ES:NOTHING 529 0 00004B12 57 PUSH DI 0 00004B13 51 PUSH CX 0 00004B14 50 PUSH AX 0 00004B15 B104 MOV CL,DEVRD 534 SETCALLHEAD: 0 00004B17 B016 MOV AL,DRDWRHL 0 00004B19 16 PUSH SS 0 00004B1A 07 POP ES 0 00004B1B BF[0000] MOV DI,OFFSET DEVCALL wrt DOSGROUP 0 00004B1E AA STOSB ; length 0 00004B1F 58 POP AX 0 00004B20 AA STOSB ; Unit 0 00004B21 50 PUSH AX 0 00004B22 88C8 MOV AL,CL 0 00004B24 AA STOSB ; Command code 0 00004B25 31C0 XOR AX,AX 0 00004B27 AB STOSW ; Status 0 00004B28 83C708 ADD DI,8 ; Skip link fields 0 00004B2B 58 POP AX 0 00004B2C 86E0 XCHG AH,AL 0 00004B2E AA STOSB ; Media byte 0 00004B2F 86C4 XCHG AL,AH 0 00004B31 50 PUSH AX 0 00004B32 89D8 MOV AX,BX 0 00004B34 AB STOSW 0 00004B35 8CD8 MOV AX,DS 0 00004B37 AB STOSW ; Transfer addr 0 00004B38 59 POP CX ; Real AX 0 00004B39 58 POP AX ; Real CX 0 00004B3A AB STOSW ; Count 0 00004B3B 92 XCHG AX,DX ; AX=Real DX, DX=real CX, CX=real AX 0 00004B3C AB STOSW ; Start 0 00004B3D 91 XCHG AX,CX 0 00004B3E 87D1 XCHG DX,CX 0 00004B40 5F POP DI 0 00004B41 BB[0000] MOV BX,OFFSET DEVCALL wrt DOSGROUP 0 00004B44 C3 return 567 568 entry SETWRITE 569 ASSUME DS:NOTHING,ES:NOTHING 570 571 ; Inputs: 572 ; DS:BX = Transfer Address 573 ; CX = Record Count 574 ; DX = Starting Record 575 ; AH = Media Byte 576 ; AL = Unit Code 577 ; Function: 578 ; Set up the device call header at DEVCALL 579 ; Output: 580 ; ES:BX Points to DEVCALL 581 ; No other registers effected 582 0 00004B45 57 PUSH DI 0 00004B46 51 PUSH CX 0 00004B47 50 PUSH AX 0 00004B48 B108 MOV CL,DEVWRT 587 VERFLG equ VerFlg ; NASM port label 0 00004B4A 36020E[0000] ADD CL,[ss:VERFLG] 0 00004B4F EBC6 JMP SHORT SETCALLHEAD 590 EndProc SETREAD 591 592 593 Break 594 595 ; Inputs: 596 ; [SC_CACHE_COUNT]= secondary cache count 597 ; [SC_STATUS]= SC validity status 598 ; [SEQ_SECTOR]= last sector read 599 ; Function: 600 ; Read from or write through secondary cache 601 ; Output: 602 ; ES:BX Points to DEVCALL 603 ; carry clear, I/O is not done 604 ; [SC_FLAG]=1 if continuos sectors will be read 605 ; carry set, I/O is done 606 607 608 procedure RW_SC,NEAR ;AN000; 608 ****************** warning: proc RW_SC... [-w+user] 609 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 610 611 %ifndef BUF2 612 CMP word [ss:SC_CACHE_COUNT],0 ;AN000;LB. secondary cache exists? 613 JZ scexit4 ;AN000;LB. no, do nothing 614 CMP word [ss:CALLSCNT],1 ;AN000;LB. sector count = 1 (buffer I/O) 615 JNZ scexit4 ;AN000;LB. no, do nothing 616 PUSH CX ;AN000;;LB. 617 PUSH DX ;AN000;;LB. yes 618 PUSH DS ;AN000;;LB. save registers 619 PUSH SI ;AN000;;LB. 620 PUSH ES ;AN000;;LB. 621 PUSH DI ;AN000;;LB. 622 MOV DX,WORD PTR [ss:CALLSSEC] ;AN000;;LB. starting sector 623 CMP BYTE PTR [ss:DEVCALL + REQFUNC],DEVRD ;AN000;LB. read ? ;AN000; 624 JZ doread ;AN000;LB. yes ;AN000; 625 CALL INVALIDATE_SC ;AN000;LB. invalidate SC ;AN000; 626 JMP strict near scexit2 ;AN000;LB. back to normal ;AN000; 627 %endif 628 scexit4: ;AN000; ;AN000; 0 00004B51 F8 CLC ;AN000;LB. I/O not done yet ;AN000; 0 00004B52 C3 return ;AN000;LB. ;AN000; 631 %ifndef BUF2 632 doread: ;AN000; ;AN000; 633 CALL SC2BUF ;AN000;LB. check if in SC ;AN000; 634 JC readSC ;AN000;LB. ;AN000; 635 MOV word [ss:DEVCALL + REQSTAT],STDON ;AN000;LB. fake done and ok ;AN000; 636 STC ;AN000;LB. set carry ;AN000; 637 JMP saveseq ;AN000;LB. save seq. sector # ;AN000; 638 nop ; identicalise 639 readSC: ;AN000; 640 MOV AX,WORD PTR [ss:HIGH_SECTOR] ;AN000;;LB. subtract sector num from 641 MOV CX,WORD PTR [ss:CALLSSEC] ;AN000;;LB. saved sequential sector 642 SUB CX,WORD PTR [ss:SEQ_SECTOR] ;AN000;;LB. number 643 SBB AX,WORD PTR [ss:SEQ_SECTOR+2] ;AN000;;LB. 644 CMP AX,0 ;AN000;;LB. greater than 64K 645 JNZ saveseq2 ;AN000;;LB. yes,save seq. sector # 646 chklow: ;AN000; 647 CMP CX,1 ;AN000;;LB. <= 1 648 JA saveseq2 ;AN000;;LB. no, not sequential 649 MOV word [ss:SC_STATUS],-1 ;AN000;;LB. prsume all SC valid 650 MOV AX,[ss:SC_CACHE_COUNT] ;AN000;;LB. yes, sequential 651 MOV [ss:CALLSCNT],AX ;AN000;;LB. read continuous sectors 652 readsr: 653 CALLXAD equ CallXAD ; NASM port label 654 MOV AX,WORD PTR [ss:CALLXAD+2] ;AN000;;LB. save buffer addr 655 MOV [ss:TEMP_VAR2],AX ;AN000;;LB. in temp vars 656 MOV AX,WORD PTR [ss:CALLXAD] ;AN000;;LB. 657 MOV [ss:TEMP_VAR],AX ;AN000;;LB. 658 ;AN000; 659 MOV AX,WORD PTR [ss:SC_CACHE_PTR] ;AN000;LB. use SC cache addr as ;AN000; 660 MOV WORD PTR [ss:CALLXAD],AX ;AN000;LB. transfer addr ;AN000; 661 MOV AX,WORD PTR [ss:SC_CACHE_PTR+2] ;AN000;LB. ;AN000; 662 MOV WORD PTR [ss:CALLXAD+2],AX ;AN000;LB. ;AN000; 663 MOV byte [ss:SC_FLAG],1 ;AN000;LB. flag it for later ;AN000; 664 MOV AL,[ss:SC_DRIVE] ;AN000;;LB. current drive 665 MOV [ss:CURSC_DRIVE],AL ;AN000;;LB. set current drive 666 MOV AX,WORD PTR [ss:CALLSSEC] ;AN000;;LB. current sector 667 MOV [ss:CURSC_SECTOR],AX ;AN000;;LB. set current sector 668 MOV AX,WORD PTR [ss:HIGH_SECTOR] ;AN000;;LB. 669 MOV [ss:CURSC_SECTOR+2],AX ;AN000;;LB. 670 saveseq2: ;AN000; 671 CLC ;AN000;LB. clear carry ;AN000; 672 saveseq: ;AN000; ;AN000; 673 MOV AX,[ss:HIGH_SECTOR] ;AN000;LB. save current sector # ;AN000; 674 MOV WORD PTR [ss:SEQ_SECTOR+2],AX ;AN000;LB. for access mode ref. ;AN000; 675 MOV AX,[ss:CALLSSEC] ;AN000;LB. ;AN000; 676 MOV WORD PTR [ss:SEQ_SECTOR],AX ;AN000;LB. ;AN000; 677 JMP scexit ;AN000;LB. ;AN000; 678 nop ; identicalise 679 ;AN000; 680 scexit2: ;AN000;LB. ;AN000; 681 CLC ;AN000;LB. clear carry ;AN000; 682 scexit: ;AN000; ;AN000; 683 POP DI ;AN000;;LB. 684 POP ES ;AN000;;LB. restore registers 685 POP SI ;AN000;;LB. 686 POP DS ;AN000;;LB. 687 POP DX ;AN000;;LB. 688 POP CX ;AN000;;LB. 689 return ;AN000;;LB. 690 %endif 691 ;AN000; 692 EndProc RW_SC ;AN000; 693 694 Break 695 696 ; Inputs: [SC_DRIVE]= requesting drive 697 ; [CURSC_DRIVE]= current SC drive 698 ; [CURSC_SECTOR] = starting scetor # of SC 699 ; [SC_CACHE_COUNT] = SC count 700 ; [HIGH_SECTOR]:DX= sector number 701 ; Function: 702 ; Check if the sector is in secondary cache 703 ; Output: 704 ; carry clear, in SC 705 ; CX= the index in the secondary cache 706 ; carry set, not in SC 707 ; 708 709 procedure IN_SC,NEAR ;AN000; 709 ****************** warning: proc IN_SC... [-w+user] 710 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 711 712 %ifndef BUF2 713 MOV AL,[ss:SC_DRIVE] ;AN000;;LB. current drive 714 CMP AL,[ss:CURSC_DRIVE] ;AN000;;LB. same as SC drive 715 JNZ outrange2 ;AN000;;LB. no 716 MOV AX,WORD PTR [ss:HIGH_SECTOR] ;AN000;;LB. subtract sector num from 717 MOV CX,DX ;AN000;;LB. secondary starting sector 718 SUB CX,WORD PTR [ss:CURSC_SECTOR] ;AN000;;LB. number 719 SBB AX,WORD PTR [ss:CURSC_SECTOR+2] ;AN000;;LB. 720 CMP AX,0 ;AN000;;LB. greater than 64K 721 JNZ outrange2 ;AN000;;LB. yes 722 CMP CX,[ss:SC_CACHE_COUNT] ;AN000;;LB. greater than SC count 723 JAE outrange2 ;AN000;;LB. yes 724 CLC ;AN000;;LB. clear carry 725 JMP short inexit ;AN000;;LB. in SC 726 outrange2: ;AN000;;LB. set carry 727 %endif 0 00004B53 F9 STC ;AN000;;LB. 729 inexit: ;AN000;;LB. 0 00004B54 C3 return ;AN000;;LB. 731 732 EndProc IN_SC ;AN000; 733 734 Break 735 736 ; Inputs: [SC_DRIVE]= requesting drive 737 ; [CURSC_DRIVE]= current SC drive 738 ; [CURSC_SECTOR] = starting scetor # of SC 739 ; [SC_CACHE_COUNT] = SC count 740 ; [SC_STAUS] = SC status word 741 ; [HIGH_SECTOR]:DX= sceotor number 742 ; 743 ; Function: 744 ; invalidate secondary cache if in there 745 ; Output: 746 ; [SC_STATUS] is updated 747 ; 748 749 procedure INVALIDATE_SC,NEAR ;AN000; 749 ****************** warning: proc INVALIDATE_SC... [-w+user] 750 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 751 0 00004B55 E8FBFF CALL IN_SC ;AN000;;LB. in secondary cache 0 00004B58 720C JC outrange ;AN000;;LB. no 0 00004B5A B80100 MOV AX,1 ;AN000;;LB. invalidate the sector 0 00004B5D D3E0 SHL AX,CL ;AN000;;LB. in the secondary cache 0 00004B5F F7D0 NOT AX ;AN000;;LB. 0 00004B61 362106[0000] AND [ss:SC_STATUS],AX ;AN000;;LB. save the status 758 outrange: ;AN000;;LB. 0 00004B66 C3 return ;AN000;;LB. 760 761 EndProc INVALIDATE_SC ;AN000; 762 763 764 Break 765 766 ; Inputs: SC_FLAG = 0 , no sectors were read into SC 767 ; 1, continous sectors were read into SC 768 ; Function: 769 ; Move data from SC to buffer 770 ; Output: 771 ; carry clear, data is moved to buffer 772 ; carry set, bad sector or exceeds maximum sector 773 ; SC_FLAG =0 774 ; CALLSCNT=1 775 ; SC_STATUS= -1 if succeeded 776 ; 0 if failed 777 778 procedure VIRREAD,NEAR ;AN000; 778 ****************** warning: proc VIRREAD... [-w+user] 779 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 780 781 %ifndef BUF2 782 CMP byte [ss:SC_FLAG],0 ;AN000;;LB. from SC fill 783 JZ sc2end ;AN000;;LB. no 784 MOV AX,[ss:TEMP_VAR2] ;AN000;;LB. restore buffer addr 785 MOV WORD PTR [ss:CALLXAD+2],AX ;AN000;;LB. 786 MOV AX,[ss:TEMP_VAR] ;AN000;;LB. 787 MOV WORD PTR [ss:CALLXAD],AX ;AN000;;LB. 788 MOV byte [ss:SC_FLAG],0 ;AN000;;LB. reset sc_flag 789 MOV word [ss:CALLSCNT],1 ;AN000;;LB. one sector transferred 790 791 TEST word [ss:DEVCALL + REQSTAT],STERR ;AN000;;LB. error? 792 JNZ scerror ;AN000;;LB. yes 793 PUSH DS ;AN000;;LB. 794 PUSH SI ;AN000;;LB. 795 PUSH ES ;AN000;;LB. 796 PUSH DI ;AN000;;LB. 797 PUSH DX ;AN000;;LB. 798 PUSH CX ;AN000;;LB. 799 XOR CX,CX ;AN000;;LB. we want first sector in SC 800 CALL SC2BUF2 ;AN000;;LB. move data from SC to buffer 801 POP CX ;AN000;;LB. 802 POP DX ;AN000;;LB. 803 POP DI ;AN000;;LB. 804 POP ES ;AN000;;LB. 805 POP SI ;AN000;;LB. 806 POP DS ;AN000;;LB. 807 JMP SHORT sc2end ;AN000;;LB. return 808 809 scerror: ;AN000; 810 MOV word [ss:CALLSCNT],1 ;AN000;;LB. reset sector count to 1 811 MOV word [ss:SC_STATUS],0 ;AN000;;LB. invalidate all SC sectors 812 MOV byte [ss:CURSC_DRIVE],-1 ;AN000;;LB. invalidate drive 813 STC ;AN000;;LB. carry set 814 return ;AN000;;LB. 815 816 %endif 817 sc2end: ;AN000; 0 00004B67 F8 CLC ;AN000;;LB. carry clear 0 00004B68 C3 return ;AN000;;LB. 820 821 EndProc VIRREAD ;AN000; 822 823 Break 824 825 ; Inputs: [SC_STATUS] = SC validity status 826 ; [SC_SECTOR_SIZE] = request sector size 827 ; [SC_CACHE_PTR] = pointer to SC 828 ; Function: 829 ; Move data from SC to buffer 830 ; Output: 831 ; carry clear, in SC and data is moved 832 ; carry set, not in SC and data is not moved 833 834 procedure SC2BUF,NEAR ;AN000; 834 ****************** warning: proc SC2BUF... [-w+user] 835 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 836 0 00004B69 E8E7FF CALL IN_SC ;AN000;;LB. in secondary cache 838 %ifndef BUF2 839 JC noSC ;AN000;;LB. no 840 MOV AX,1 ;AN000;;LB. check if valid sector 841 SHL AX,CL ;AN000;;LB. in the secondary cache 842 TEST [ss:SC_STATUS],AX ;AN000;;LB. 843 JZ noSC ;AN000;;LB. invalid 844 entry SC2BUF2 ;AN000; 845 MOV AX,CX ;AN000;;LB. times index with 846 MUL word [ss:SC_SECTOR_SIZE] ;AN000;;LB. sector size 847 ADD AX,WORD PTR [ss:SC_CACHE_PTR] ;AN000;;LB. add SC starting addr 848 ADC DX,WORD PTR [ss:SC_CACHE_PTR+2];AN000;;LB. 849 MOV DS,DX ;AN000; ;LB. DS:SI-> SC sector addr 850 MOV SI,AX ;AN000; ;LB. 851 MOV ES,WORD PTR [ss:CALLXAD+2] ;AN000; ;LB. ES:DI-> buffer addr 852 MOV DI,WORD PTR [ss:CALLXAD] ;AN000; ;LB. 853 MOV CX,[ss:SC_SECTOR_SIZE] ;AN000; ;LB. count= sector size 854 SHR CX,1 ;AN000; ;LB. may use DWORD move for 386 855 entry MOVWORDS ;AN000; 856 CMP byte [ss:DDMOVE],0 ;AN000; ;LB. 386 ? 857 JZ nodd ;AN000; ;LB. no 858 SHR CX,1 ;AN000; ;LB. words/2 859 DB 66H ;AN000; ;LB. use double word move 860 nodd: 861 REP MOVSW ;AN000; ;LB. move to buffer 862 CLC ;AN000; ;LB. clear carry 863 return ;AN000; ;LB. exit 864 %endif 865 noSC: ;AN000; 0 00004B6C F9 STC ;AN000; ;LB. set carry 867 sexit: ;AN000; 0 00004B6D C3 return ;AN000; ;LB. 869 870 EndProc SC2BUF 871 END 872 873 === Trace listing source: ../DOS/mknode.lst 1 ; SCCSID = @(#)mknode.asm 1.5 85/08/29 2 ;TITLE MKNODE - Node maker 3 ;NAME MKNODE 4 ; Low level routines for making a new local file system node 5 ; and filling in an SFT from a directory entry 6 ; 7 ; BUILDDIR 8 ; SETDOTENT 9 ; MakeNode 10 ; NEWENTRY 11 ; FREEENT 12 ; NEWDIR 13 ; DOOPEN 14 ; RENAME_MAKE 15 ; CHECK_VIRT_OPEN 16 ; 17 ; Revision history: 18 ; 19 ; AN000 version 4.0 Jan. 1988 20 ; A004 PTM 3680 --- Make SFT NAME field offset same as 3.30 21 22 ; 23 ; get the appropriate segment definitions 24 ; 25 [list -] === Switch to base=008400h -> "DOSCODECODE" 31 section DOSCODECODE 32 [list -] 32 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 32 ****************** warning: out: BPB.INC... [-w+user] 32 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 32 ****************** warning: out: DEVSYM.INC... [-w+user] 39 40 i_need EntFree,WORD 41 i_need DirStart,WORD 42 i_need LastEnt,WORD 43 i_need ClusNum,WORD 44 i_need CurBuf,DWORD 45 i_need Attrib,BYTE 46 i_need VolID,BYTE 47 i_need Name1,BYTE 48 i_need ThisDPB,DWORD 49 i_need EntLast,WORD 50 i_need Creating,BYTE 51 i_need SecClusPos,BYTE 52 i_need ClusFac,BYTE 53 i_need Cluster_Factor_EDR,WORD 54 i_need NxtClusNum,WORD 55 i_need DirSec,WORD 56 i_need NoSetDir,BYTE 57 i_need THISSFT,DWORD 58 i_need SATTRIB,BYTE 59 i_need ALLOWED,BYTE 60 i_need FAILERR,BYTE 61 i_need VIRTUAL_OPEN 62 I_need FastOpen_Ext_info,BYTE ; DOS 3.3 63 I_need FastOpenFlg,BYTE ; DOS 3.3 64 I_need CPSWFLAG,BYTE ;FT. DOS 3.4 ;AN000; 65 I_need EXTOPEN_ON,BYTE ;FT. DOS 3.4 ;AN000; 66 I_need EXTOPEN_FLAG,WORD ;FT. DOS 3.4 ;AN000; 67 I_need EXTOPEN_IO_MODE,WORD ;FT. DOS 3.4 ;AN000; 68 I_need HIGH_SECTOR,WORD ;>32mb ;AN000; 69 %ifndef BUF2 70 I_need ACT_PAGE,WORD ;>32mb ;AN000; 71 %endif 72 73 Break 74 75 ; Inputs: 76 ; ES:BP Points to DPB 77 ; [THISSFT] Set if using NEWDIR entry point 78 ; (used by ALLOCATE) 79 ; [LASTENT] current last valid entry number in directory if no free 80 ; entries 81 ; [DIRSTART] Points to first cluster of dir (0 means root) 82 ; Function: 83 ; Grow directory if no free entries and not root 84 ; Outputs: 85 ; CARRY SET IF FAILURE 86 ; ELSE 87 ; AX entry number of new entry 88 ; If a new dir [DIRSTART],[CLUSFAC],[CLUSNUM],[DIRSEC] set 89 ; AX = first entry of new dir 90 ; GETENT should be called to set [LASTENT] 91 92 procedure BUILDDIR,NEAR 92 ****************** warning: proc BUILDDIR... [-w+user] 93 DOSAssume CS,,"BuildDir" 94 ASSUME ES:NOTHING 95 96 ENTFREE equ EntFree ; NASM port label 0 00004B6E A1[0000] MOV AX,[ENTFREE] 0 00004B71 83F8FF CMP AX,-1 0 00004B74 7402 JZ CHECK_IF_ROOT 0 00004B76 F8 CLC 0 00004B77 C3 return 102 103 CHECK_IF_ROOT: 104 DIRSTART equ DirStart ; NASM port label 0 00004B78 833E[0000]00 CMP word [DIRSTART],0 0 00004B7D 7502 JNZ NEWDIR 0 00004B7F F9 STC 0 00004B80 C3 return ; Can't grow root 109 110 entry NEWDIR 0 00004B81 8B1E[0000] MOV BX,[DIRSTART] 0 00004B85 09DB OR BX,BX 0 00004B87 7405 JZ NULLDIR 0 00004B89 E8[0000] invoke GETEOF 0 00004B8C 72F2 retc ; Screw up 116 NULLDIR: 0 00004B8E B90100 MOV CX,1 0 00004B91 E8[0000] invoke ALLOCATE 0 00004B94 72EA retc 0 00004B96 8B16[0000] MOV DX,[DIRSTART] 0 00004B9A 09D2 OR DX,DX 0 00004B9C 750D JNZ ADDINGDIR 0 00004B9E E8[0000] invoke SETDIRSRCH 0 00004BA1 72DD retc 125 LASTENT equ LastEnt ; NASM port label 0 00004BA3 C706[0000]FFFF MOV word [LASTENT],-1 0 00004BA9 EB2B JMP SHORT GOTDIRREC 128 ADDINGDIR: 0 00004BAB 53 PUSH BX 0 00004BAC 8B1E[0000] MOV BX,[ClusNum] 0 00004BB0 E8[0000] Invoke IsEof 0 00004BB3 5B POP BX 0 00004BB4 7219 JB NOTFIRSTGROW 134 ;;;; 10/17/86 update CLUSNUM in the fastopen cache 135 CLUSNUM equ ClusNum ; NASM port label 0 00004BB6 891E[0000] MOV [CLUSNUM],BX 0 00004BBA 51 PUSH CX 0 00004BBB 50 PUSH AX 0 00004BBC 55 PUSH BP 0 00004BBD B401 MOV AH,1 ; CLUSNUM update 0 00004BBF 268A5600 MOV DL,[ES:BP + dpb_drive] ; drive # 0 00004BC3 8B0E[0000] MOV CX,[DIRSTART] ; first cluster # 0 00004BC7 89DD MOV BP,BX ; CLUSNUM 0 00004BC9 E8[0000] invoke FastOpen_Update 0 00004BCC 5D POP BP 0 00004BCD 58 POP AX 0 00004BCE 59 POP CX 148 149 ;;;; 10/17/86 update CLUSNUM in the fastopen cache 150 NOTFIRSTGROW: 0 00004BCF 89DA MOV DX,BX 0 00004BD1 30DB XOR BL,BL 0 00004BD3 E8[0000] invoke FIGREC 154 GOTDIRREC: 0 00004BD6 268A4E04 MOV CL,[ES:BP + dpb_cluster_mask] 0 00004BDA 30ED XOR CH,CH 0 00004BDC 41 inc cx 158 ZERODIR: 0 00004BDD 51 PUSH CX 160 allowed_FAIL equ Allowed_FAIL ; NASM port equate 161 allowed_RETRY equ Allowed_RETRY ; NASM port equate 0 00004BDE C606[0000]18 MOV byte [ALLOWED],allowed_FAIL + allowed_RETRY 0 00004BE3 B0FF MOV AL,0FFH 0 00004BE5 E8[0000] invoke GETBUFFR 0 00004BE8 7302 JNC GET_SSIZE 0 00004BEA 59 POP CX 0 00004BEB C3 return 168 169 GET_SSIZE: 0 00004BEC 268B4E02 MOV CX,[ES:BP + dpb_sector_size] 0 00004BF0 06 PUSH ES 172 CURBUF equ CurBuf ; NASM port label 0 00004BF1 C43E[0000] LES DI,[CURBUF] 0 00004BF5 26804D0504 OR byte [ES:DI + buf_flags],buf_isDIR 0 00004BFA 57 PUSH DI 0 00004BFB 83C710 ADD DI,BUFINSIZ 0 00004BFE 31C0 XOR AX,AX 0 00004C00 D1E9 SHR CX,1 0 00004C02 F3AB REP STOSW 0 00004C04 7301 JNC EVENZ 0 00004C06 AA STOSB 182 EVENZ: 0 00004C07 5F POP DI 184 0 00004C08 26F6450540 TEST byte [ES:DI + buf_flags],buf_dirty ;LB. if already dirty ;AN000; 0 00004C0D 7508 JNZ yesdirty ;LB. don't increment dirty count ;AN000; 0 00004C0F E8[0000] invoke INC_DIRTY_COUNT ;LB. ;AN000; 0 00004C12 26804D0540 OR byte [ES:DI + buf_flags],buf_dirty 189 yesdirty: 0 00004C17 07 POP ES 0 00004C18 59 POP CX 0 00004C19 42 INC DX 0 00004C1A 7504 jnz @F 0 00004C1C FF06[0000] inc word ptr [HIGH_SECTOR] 195 @@: 0 00004C20 E2BB LOOP ZERODIR 0 00004C22 A1[0000] MOV AX,[LASTENT] 0 00004C25 40 INC AX 0 00004C26 F8 CLC 0 00004C27 C3 return 201 202 EndProc BUILDDIR 203 204 ; 205 ; set up a . or .. directory entry for a directory. 206 ; 207 ; Inputs: ES:DI point to the beginning of a directory entry. 208 ; AX contains ". " or ".." 209 ; DX contains first cluster of entry 210 ; 211 procedure SETDOTENT,NEAR 211 ****************** warning: proc SETDOTENT... [-w+user] 212 DOSAssume CS,,"SetDotEnt" 213 ; 214 ; Fill in name field 215 ; 0 00004C28 AB STOSW 0 00004C29 B90400 MOV CX,4 0 00004C2C B82020 MOV AX," " 0 00004C2F F3AB REP STOSW 0 00004C31 AA STOSB 221 ; 222 ; Set up attribute 223 ; 0 00004C32 B010 MOV AL,attr_directory 225 errnz dir_attr-(dir_name+11) 0 00004C34 AA STOSB 227 ; 228 ; Initialize time and date of creation 229 ; 0 00004C35 83C70A ADD DI,10 0 00004C38 8B36[0000] MOV SI,WORD PTR [THISSFT] 0 00004C3C 8B440D MOV AX,[SI + sf_time] 233 errnz dir_time-(dir_attr+1+10) 0 00004C3F AB STOSW 0 00004C40 8B440F MOV AX,[SI + sf_date] 236 errnz dir_date-(dir_time+2) 0 00004C43 AB STOSW 238 ; 239 ; Set up first cluster field 240 ; 0 00004C44 89D0 MOV AX,DX 242 errnz dir_first-(dir_date+2) 0 00004C46 AB STOSW 244 ; 245 ; 0 file size 246 ; 0 00004C47 31C0 XOR AX,AX 248 errnz dir_size_l-(dir_first+2) 0 00004C49 AB STOSW 0 00004C4A AB STOSW 251 errnz <(dir_entry_struc_size)-(dir_size_l+4)> 0 00004C4B C3 return 253 EndProc SETDOTENT 254 255 Break 256 257 ; Inputs: 258 ; AL - attribute to create 259 ; AH = 0 if it is ok to truncate a file already by this name 260 ; AH = Non 0 if this is an error 261 ; (AH ignored on dirs and devices) 262 ; NOTE: When making a DIR or volume ID, AH need not be set since 263 ; a name already existant is ALWAYS an error in these cases. 264 ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL 265 ; terminated) 266 ; [CURR_DIR_END] Points to end of Current dir part of string 267 ; ( = -1 if current dir not involved, else 268 ; Points to first char after last "/" of current dir part) 269 ; [THISCDS] Points to CDS being used 270 ; [THISSFT] Points to an empty SFT. EXCEPT sf_mode filled in. 271 ; Function: 272 ; Make a new node 273 ; Outputs: 274 ; Sets EXTERR_LOCUS = errLOC_Disk or errLOC_Unk via GetPathNoset 275 ; CARRY SET IF ERROR 276 ; AX = 1 A node by this name exists and is a directory 277 ; AX = 2 A new node could not be created 278 ; AX = 3 A node by this name exists and is a disk file 279 ; (AH was NZ on input) 280 ; AX = 4 Bad Path 281 ; SI return from GetPath maintained 282 ; AX = 5 Attribute mismatch 283 ; AX = 6 Sharing Violation 284 ; (INT 24 generated ALWAYS since create is always compat mode 285 ; AX = 7 file not found for Extended Open (not exists and fails) 286 ; ELSE 287 ; AX = 0 Disk Node 288 ; AX = 3 Device Node (error in some cases) 289 ; [DIRSTART],[DIRSEC],[CLUSFAC],[CLUSNUM] set to directory 290 ; containing new node. 291 ; [CURBUF+2]:BX Points to entry 292 ; [CURBUF+2]:SI Points to entry.dir_first 293 ; [THISSFT] is filled in 294 ; sf_mode = unchanged. 295 ; Attribute byte in entry is input AL 296 ; DS preserved, others destroyed 297 298 procedure MakeNode,NEAR 298 ****************** warning: proc MakeNode... [-w+user] 299 DOSAssume CS,,"MakeNode" 300 ASSUME ES:NOTHING 301 302 CREATING equ Creating ; NASM port label 0 00004C4C C706[0000]FFE5 MOV WORD PTR [CREATING],0E5FFH ; Creating, not DEL *.* 0 00004C52 50 PUSH AX ; Save AH value 0 00004C53 C606[0000]00 MOV byte [NoSetDir],0 0 00004C58 A2[0000] MOV [SATTRIB],AL 0 00004C5B E8[0000] invoke GetPathNoSet 0 00004C5E 88CA MOV DL,CL ; Save CL info 0 00004C60 89C1 MOV CX,AX ; Device ID to CH 0 00004C62 58 POP AX ; Get back AH 0 00004C63 7330 JNC make_exists ; File existed 0 00004C65 7505 JNZ make_err_4 ; Path bad 0 00004C67 80FA80 CMP DL,80H ; Check "CL" return from GETPATH 0 00004C6A 7406 JZ make_type ; Name simply not found, and no metas 315 make_err_4: 0 00004C6C B004 MOV AL,4 ; case 1 bad path 317 make_err_ret: 0 00004C6E 30E4 XOR AH,AH 0 00004C70 F9 STC 0 00004C71 C3 return 321 322 entry RENAME_MAKE ; Used by DOS_RENAME to "copy" a node 323 324 make_type: 325 ;Extended Open hooks 0 00004C72 F606[0000]01 TEST byte [EXTOPEN_ON],ext_open_on ;FT. from extended open ;AN000; 0 00004C77 7412 JZ make_type2 ;FT. no ;AN000; 0 00004C79 800E[0000]04 OR byte [EXTOPEN_ON],ext_file_not_exists ;FT. set for extended open ;AN000; 0 00004C7E F706[0000]F000 TEST word [EXTOPEN_FLAG],0F0H ;FT. not exists and fails ;AN000; 0 00004C84 7505 JNZ make_type2 ;FT. no ;AN000; 0 00004C86 F9 STC ;FT. set carry ;AN000; 0 00004C87 B80700 MOV AX,7 ;FT. file not found ;AN000; 0 00004C8A C3 return ;FT. ;AN000; 334 make_type2: 335 ;Extended Open hooks 0 00004C8B C43E[0000] LES DI,[THISSFT] 337 ; MOV [ES:DI.sf_mode],sharing_compat + open_for_both 0 00004C8F 31C0 XOR AX,AX ; nothing exists Disk Node 0 00004C91 F9 STC ; Not found 0 00004C92 EB5B JMP make_new 0 00004C94 90 nop ; identicalise 342 343 ; 344 ; The node exists. It may be either a device, directory or file: 345 ; Zero set => directory 346 ; High bit of CH on => device 347 ; else => file 348 make_exists: 0 00004C95 7448 JZ make_exists_dir 0 00004C97 B003 MOV AL,3 ; file exists type 3 (error or device node) 351 ATTRIB equ Attrib ; NASM port label 0 00004C99 F606[0000]18 TEST BYTE PTR [ATTRIB],(attr_volume_id+attr_directory) 0 00004C9E 753B JNZ make_err_ret_5 ; Cannot already exist as Disk or Device Node 354 ; if making DIR or Volume ID 0 00004CA0 08ED OR CH,CH 0 00004CA2 781A JS make_share ; No further checks on attributes if device 0 00004CA4 08E4 OR AH,AH 0 00004CA6 75C6 JNZ make_err_ret ; truncating NOT OK (AL = 3) 0 00004CA8 51 PUSH CX ; Save device ID 0 00004CA9 8E06[0200] MOV ES,WORD PTR [CURBUF+2] 0 00004CAD 268A6F0B MOV CH,[ES:BX+dir_attr] ; Get file attributes 0 00004CB1 F6C501 TEST CH,attr_read_only 0 00004CB4 7524 JNZ make_err_ret_5P ; Cannot create on read only files 0 00004CB6 E8[0000] invoke MatchAttributes 0 00004CB9 59 POP CX ; Devid back in CH 0 00004CBA 751F JNZ make_err_ret_5 ; Attributes not ok 0 00004CBC 30C0 XOR AL,AL ; AL = 0, Disk Node 368 make_share: 0 00004CBE 30E4 XOR AH,AH 0 00004CC0 50 PUSH AX ; Save Disk or Device node 0 00004CC1 51 PUSH CX ; Save Device ID 0 00004CC2 88EC MOV AH,CH ; Device ID to AH 0 00004CC4 E84701 CALL DOOPEN ; Fill in SFT for share check 0 00004CC7 C43E[0000] LES DI,[THISSFT] 375 ; MOV [ES:DI.sf_mode],sharing_compat + open_for_both 0 00004CCB 5653 SaveReg ; Save CURBUF pointers 0 00004CCD E8[0000] invoke ShareEnter 0 00004CD0 735A jnc MakeEndShare 379 ; 380 ; User failed request. 381 ; 0 00004CD2 5B5E5958 RestoreReg 383 Make_Share_ret: 0 00004CD6 B006 MOV AL,6 0 00004CD8 EB94 JMP make_err_ret 386 387 make_err_ret_5P: 0 00004CDA 59 POP CX ; Get back device ID 389 make_err_ret_5: 0 00004CDB B005 MOV AL,5 ; Attribute mismatch 0 00004CDD EB8F JMP make_err_ret 392 393 make_exists_dir: 0 00004CDF B001 MOV AL,1 ; exists as directory, always an error 0 00004CE1 EB8B JMP make_err_ret 396 397 make_save: 0 00004CE3 50 PUSH AX ; Save whether Disk or File 0 00004CE4 89C8 MOV AX,CX ; Device ID to AH 400 NewEntry equ NEWENTRY ; NASM port label 0 00004CE6 E87400 CALL NewEntry 0 00004CE9 58 POP AX ; 0 if Disk, 3 if File 0 00004CEA 739E retnc 0 00004CEC B002 MOV AL,2 ; create failed case 2 0 00004CEE C3 return 406 407 make_new: 0 00004CEF E8F1FF call make_save 0 00004CF2 72FA retc ; case 2 fail 0 00004CF4 F606[0000]10 TEST BYTE PTR [ATTRIB],attr_directory 0 00004CF9 75F3 retnz ; Don't "open" directories, so don't 412 ; tell the sharer about them 0 00004CFB 505356 SaveReg ; Save AL code 0 00004CFE E8[0000] invoke ShareEnter 0 00004D01 5E5B58 RestoreReg 0 00004D04 73E8 retnc 417 ; 418 ; We get here by having the user FAIL a share problem. Typically a failure of 419 ; this nature is an out-of-space or an internal error. We clean up as best as 420 ; possible: delete the newly created directory entry and return share_error. 421 ; 0 00004D06 50 PUSH AX 0 00004D07 C43E[0000] LES DI,[CurBuf] 0 00004D0B 26C607E5 MOV BYTE PTR [ES:BX],0E5H ; nuke newly created entry. 425 0 00004D0F 26F6450540 TEST byte [ES:DI + buf_flags],buf_dirty ;LB. if already dirty ;AN000; 0 00004D14 7508 JNZ yesdirty2 ;LB. don't increment dirty count ;AN000; 0 00004D16 E8[0000] invoke INC_DIRTY_COUNT ;LB. ;AN000; 0 00004D19 26804D0540 OR byte [ES:DI + buf_flags],buf_dirty ; flag buffer as dirty 430 yesdirty2: 0 00004D1E C42E[0000] LES BP,[ThisDPB] 432 DPB_Drive equ dpb_drive ; NASM port equate 0 00004D22 268A4600 MOV AL,[ES:BP + DPB_Drive] ; get drive for flush 0 00004D26 E8[0000] Invoke FlushBuf ; write out buffer. 0 00004D29 58 POP AX 436 make_Share_ret equ Make_Share_ret ; NASM port label 0 00004D2A EBAA jmp make_Share_ret 438 ; 439 ; We have found an existing file. We have also entered it into the share set. 440 ; At this point we need to call newentry to correctly address the problem of 441 ; getting rid of old data (create an existing file) or creating a new 442 ; directory entry (create a new file). Unfortunately, this operation may 443 ; result in an INT 24 that the user doesn't return from, thus locking the file 444 ; irretrievably into the share set. The correct solution is for us to LEAVE 445 ; the share set now, do the operation and then reassert the share access. 446 ; 447 ; We are allowed to do this! There is no window! After all, we are in 448 ; critDisk here and for someone else to get in, they must enter critDisk also. 449 ; 450 MakeEndShare: 451 ThisSFT equ THISSFT ; NASM port label 0 00004D2C C43E[0000] LES DI,[ThisSFT] ; grab SFT 0 00004D30 31C0 XOR AX,AX 0 00004D32 E8[0000] EnterCrit critSFT 0 00004D35 268705 XCHG AX,[ES:DI + sf_ref_count] 0 00004D38 505706 SaveReg 0 00004D3B 9C PUSHF 0 00004D3C E8[0000] invoke ShareEnd ; remove sharing 0 00004D3F 9D POPF 0 00004D40 075F268F05 RestoreReg 0 00004D45 E8[0000] LeaveCrit critSFT 0 00004D48 5B5E5958 RestoreReg 0 00004D4C E894FF CALL make_save 464 ; 465 ; If the user failed, we do not reenter into the sharing set. 466 ; 0 00004D4F 729D retc ; bye if error 0 00004D51 505356 SaveReg 0 00004D54 9C PUSHF 0 00004D55 E8[0000] invoke ShareEnter 0 00004D58 9D POPF 0 00004D59 5E5B58 RestoreReg 473 ; 474 ; If Share_check fails, then we have an internal ERROR!!!!! 475 ; 0 00004D5C C3 return 477 EndProc MakeNode 477 ****************** warning: ***** Possible stack size error in MakeNode ***** [-w+user] 478 479 ; Inputs: 480 ; [THISSFT] set 481 ; [THISDPB] set 482 ; [LASTENT] current last valid entry number in directory if no free 483 ; entries 484 ; [VOLID] set if a volume ID was found during search 485 ; [ATTRIB] Contains attributes for new file 486 ; [DIRSTART] Points to first cluster of dir (0 means root) 487 ; CARRY FLAG INDICATES STATUS OF SEARCH FOR FILE 488 ; NC means file existed (device) 489 ; C means file did not exist 490 ; AH = Device ID byte 491 ; If FILE 492 ; [CURBUF+2]:BX points to start of directory entry 493 ; [CURBUF+2]:SI points to dir_first of directory entry 494 ; If device 495 ; DS:BX points to start of "fake" directory entry 496 ; DS:SI points to dir_first of "fake" directory entry 497 ; (has DWORD pointer to device header) 498 ; Function: 499 ; Make a new directory entry 500 ; If an old one existed it is truncated first 501 ; Outputs: 502 ; Carry set if error 503 ; Can't grow dir, atts didn't match, attempt to make 2nd 504 ; vol ID, user FAILed to I 24 505 ; else 506 ; outputs of DOOPEN 507 ; DS, BX, SI preserved (meaning on SI BX, not value), others destroyed 508 509 procedure NEWENTRY,NEAR 509 ****************** warning: proc NEWENTRY... [-w+user] 510 DOSAssume CS,,"NewEntry" 511 ASSUME ES:NOTHING 512 513 THISDPB equ ThisDPB ; NASM port label 0 00004D5D C42E[0000] LES BP,[THISDPB] 515 ASSUME ES:NOTHING 0 00004D61 7316 JNC EXISTENT 0 00004D63 803E[0000]00 CMP byte [FAILERR],0 0 00004D68 F9 STC 0 00004D69 75F1 retnz ; User FAILed, node might exist 0 00004D6B E800FE CALL BUILDDIR ; Try to build dir 0 00004D6E 72EC retc ; Failed 0 00004D70 E8[0000] invoke GETENT ; Point at that free entry 0 00004D73 72E7 retc ; Failed 0 00004D75 EB0E JMP SHORT FREESPOT 525 526 ERRRET3: 0 00004D77 F9 STC 0 00004D78 C3 return 529 530 EXISTENT: 531 DOSAssume CS,,"MKNODE/ExistEnt" 0 00004D79 08E4 OR AH,AH ; Check if file is I/O device 0 00004D7B 7903 JNS NOT_DEV1 0 00004D7D E98E00 JMP DOOPEN ; If so, proceed with open 535 536 NOT_DEV1: 0 00004D80 E82A01 invoke FREEENT ; Free cluster chain 0 00004D83 72F3 retc ; Failed 539 FREESPOT: 0 00004D85 F606[0000]08 TEST BYTE PTR [ATTRIB],attr_volume_id 0 00004D8A 7407 JZ NOTVOLID 542 VOLID equ VolID ; NASM port label 0 00004D8C 803E[0000]00 CMP BYTE PTR [VOLID],0 0 00004D91 75E4 JNZ ERRRET3 ; Can't create a second volume ID 545 NOTVOLID: 0 00004D93 8E06[0200] MOV ES,WORD PTR [CURBUF+2] 0 00004D97 89DF MOV DI,BX 548 NAME1 equ Name1 ; NASM port label 0 00004D99 BE[0000] MOV SI,OFFSET NAME1 wrt DOSGROUP 0 00004D9C B90500 MOV CX,5 0 00004D9F F3A5 REP MOVSW 0 00004DA1 A4 MOVSB ; Move name into dir entry 0 00004DA2 A0[0000] MOV AL,[ATTRIB] 554 errnz dir_attr-(dir_name+11) 0 00004DA5 AA STOSB ; Attributes 556 ;; File Tagging for Create DOS 4.00 0 00004DA6 B105 MOV CL,5 ;FT. assume normal ;AN000; 558 ; CMP [CPSWFLAG],0 ;FT. code page matching on ;AN000; 559 ; JZ NORMFT ;FT. no, make null code page ;AN000; 560 ; invoke Get_Global_CdPg ;FT. get global code page ;AN000; 561 ; STOSW ;FT. tag this file with global code page ;AN000; 562 ; DEC CL ;FT. only 4 ;AN000; 563 ;NORMFT: ;FT. ;AN000; 564 565 ;; File Tagging for Create DOS 4.00 0 00004DA8 31C0 XOR AX,AX 0 00004DAA F3AB REP STOSW ; Zero pad 0 00004DAC E8[0000] invoke DATE16 0 00004DAF 92 XCHG AX,DX 570 errnz dir_time-(dir_attr+1+2*5) 0 00004DB0 AB STOSW ; dir_time 0 00004DB1 92 XCHG AX,DX 573 errnz dir_date-(dir_time+2) 0 00004DB2 AB STOSW ; dir_date 0 00004DB3 31C0 XOR AX,AX 0 00004DB5 57 PUSH DI ; Correct SI input value (recomputed for new buffer) 577 578 errnz dir_first-(dir_date+2) 0 00004DB6 AB STOSW ; Zero dir_first and size 580 errnz dir_size_l-(dir_first+2) 0 00004DB7 AB STOSW 0 00004DB8 AB STOSW 583 updnxt: 584 errnz <(dir_entry_struc_size)-(dir_size_l+4)> 0 00004DB9 8B36[0000] MOV SI,WORD PTR [CURBUF] 586 0 00004DBD 26F6440540 TEST byte [ES:SI + buf_flags],buf_dirty ;LB. if already dirty ;AN000; 0 00004DC2 7508 JNZ yesdirty3 ;LB. don't increment dirty count ;AN000; 0 00004DC4 E8[0000] invoke INC_DIRTY_COUNT ;LB. ;AN000; 0 00004DC7 26804C0540 OR byte [ES:SI + buf_flags],buf_dirty 591 yesdirty3: 0 00004DCC C42E[0000] LES BP,[THISDPB] 0 00004DD0 268A4600 MOV AL,[ES:BP + dpb_drive] ; Sets AH value again (in AL) 0 00004DD4 50 PUSH AX 0 00004DD5 53 PUSH BX 596 ; If we have a file, we need to increment the open ref. count so that 597 ; we have some protection against invalid media changes if an Int 24 598 ; error occurs. 599 ; Do nothing for a device. 0 00004DD6 0657 SaveReg 0 00004DD8 C43E[0000] LES DI,[THISSFT] 0 00004DDC 26F745058000 test word [es:di + sf_flags],devid_device 0 00004DE2 751A jnz GotADevice 0 00004DE4 1E53 SaveReg 0 00004DE6 C51E[0000] LDS BX,[THISDPB] 0 00004DEA 26895D07 MOV word ptr [ES:DI + sf_devptr],BX 0 00004DEE 8CDB MOV BX,DS 0 00004DF0 26895D09 MOV word ptr [ES:DI + sf_devptr+2],BX 0 00004DF4 5B1F RestoreReg ; need to use DS for segment later on 0 00004DF6 E8[0000] invoke Dev_Open_SFT ; increment ref. count 0 00004DF9 C606[0000]01 mov byte [VIRTUAL_OPEN],1; set flag 612 GotADevice: 0 00004DFE 5F07 RestoreReg 614 615 %ifdef BUF2 0 00004E00 E8[0000] invoke FLUSHBUF 617 %else 618 PUSH word [ACT_PAGE] ;LB. save EMS page for curbuf ;AN000; 619 invoke FLUSHBUF 620 POP BX ;LB. restore EMS page for curbuf ;AN000; 621 PUSHF ;LB. save flushbuf falg ;AN000; 622 CMP BX,-1 ;BL-NETWORK PTM #-? 623 JE Page_ok ;BL-NETWORK PTM #-? 624 invoke SET_MAP_PAGE ;LB. remap curbuf ;AN000; 625 Page_ok: ;BL-NETWORK PTM #-? 626 POPF ;LB. restore flush flag ;AN000; 627 %endif 0 00004E03 E8F900 Call CHECK_VIRT_OPEN ; decrement ref. count ;AN000; 0 00004E06 5B POP BX 0 00004E07 58 POP AX 0 00004E08 5E POP SI ; Get SI input back 0 00004E09 88C4 MOV AH,AL ; Get I/O driver number back 0 00004E0B 7301C3 retc ; Failed 634 635 636 ;NOTE FALL THROUGH 637 638 ; Inputs: 639 ; [THISDPB] points to DPB if file 640 ; [THISSFT] points to SFT being used 641 ; AH = Device ID byte 642 ; If FILE 643 ; [CURBUF+2]:BX points to start of directory entry 644 ; [CURBUF+2]:SI points to dir_first of directory entry 645 ; If device 646 ; DS:BX points to start of "fake" directory entry 647 ; DS:SI points to dir_first of "fake" directory entry 648 ; (has DWORD pointer to device header) 649 ; Function: 650 ; Fill in SFT from dir entry 651 ; Outputs: 652 ; CARRY CLEAR 653 ; sf_ref_count and sf_mode fields not altered 654 ; sf_flags high byte = 0 655 ; sf_flags low byte = AH except 656 ; sf_flags Bit 6 set (not dirty or not EOF) 657 ; sf_attr sf_date sf_time sf_name set from entry 658 ; sf_position = 0 659 ; If device 660 ; sf_devptr = dword at dir_first (pointer to device header) 661 ; sf_size = 0 662 ; If file 663 ; sf_firclus sf_size set from entry 664 ; sf_devptr = [THISDPB] 665 ; sf_cluspos = 0 666 ; sf_lstclus = sf_firclus 667 ; sf_dirsec sf_dirpos set 668 ; DS,SI,BX preserved, others destroyed 669 670 entry DOOPEN 671 DOSAssume CS,,"DoOpen" 672 ASSUME ES:NOTHING 673 674 ; 675 ; Generate and store attribute 676 ; 0 00004E0E 88E6 MOV DH,AH ; AH to different place 0 00004E10 C43E[0000] LES DI,[THISSFT] 0 00004E14 83C704 ADD DI,sf_attr ; Skip ref_count and mode fields 0 00004E17 30C0 XOR AL,AL ; Assume it's a device, devices have an 681 ; attribute of 0 (for R/O testing etc). 0 00004E19 08F6 OR DH,DH ; See if our assumption good. 0 00004E1B 7807 JS DEV_SFT1 ; If device DS=DOSGROUP 0 00004E1D 8E1E[0200] MOV DS,WORD PTR [CURBUF+2] 685 ASSUME DS:NOTHING 0 00004E21 8A470B MOV AL,[BX + dir_attr] ; If file, get attrib from dir entry 687 DEV_SFT1: 0 00004E24 AA STOSB ; sf_attr, ES:DI -> sf_flags 689 ; 690 ; Generate and store flags word 691 ; 0 00004E25 31C0 XOR AX,AX 0 00004E27 88F0 MOV AL,DH 0 00004E29 0C40 OR AL,devid_file_clean 0 00004E2B AB STOSW ; sf_flags, ES:DI -> sf_devptr 696 ; 697 ; Generate and store device pointer 698 ; 0 00004E2C 1E PUSH DS 0 00004E2D C5471A LDS AX,[BX + dir_first] ; Assume device 0 00004E30 08F6 OR DH,DH 0 00004E32 7805 JS DEV_SFT2 0 00004E34 36C506[0000] LDS AX,[ss:THISDPB] ; Was file 704 DEV_SFT2: 0 00004E39 AB STOSW ; store offset 0 00004E3A 8CD8 MOV AX,DS 0 00004E3C 1F POP DS 0 00004E3D AB STOSW ; store segment 709 ; ES:DI -> sf_firclus 710 ; 711 ; Generate pointer to, generate and store first cluster (irrelevant for 712 ; devices) 713 ; 0 00004E3E 56 PUSH SI ; Save pointer to dir_first 0 00004E3F A5 MOVSW ; dir_first -> sf_firclus 716 ; DS:SI -> dir_size_l, ES:DI -> sf_time 717 ; 718 ; Copy time/date of last modification 719 ; 0 00004E40 83EE06 SUB SI,dir_size_l - dir_time ; DS:SI->dir_time 0 00004E43 A5 MOVSW ; dir_time -> sf_time 722 ; DS:SI -> dir_date, ES:DI -> sf_date 0 00004E44 A5 MOVSW ; dir_date -> sf_date 724 ; DS:SI -> dir_first, ES:DI -> sf_size 725 ; 726 ; Generate and store file size (0 for devices) 727 ; 0 00004E45 AD LODSW ; skip dir_first, DS:SI -> dir_size_l 0 00004E46 AD LODSW ; dir_size_l in AX , DS:SI -> dir_size_h 0 00004E47 89C1 MOV CX,AX ; dir_size_l in CX 0 00004E49 AD LODSW ; dir_size_h (size AX:CX), DS:SI -> ???? 0 00004E4A 08F6 OR DH,DH 0 00004E4C 7904 JNS FILE_SFT1 0 00004E4E 31C0 XOR AX,AX 0 00004E50 89C1 MOV CX,AX ; Devices are open ended 736 FILE_SFT1: 0 00004E52 91 XCHG AX,CX 0 00004E53 AB STOSW ; Low word of sf_size 0 00004E54 91 XCHG AX,CX 0 00004E55 AB STOSW ; High word of sf_size 741 ; ES:DI -> sf_position 742 ; 743 ; Initialize position to 0 744 ; 0 00004E56 31C0 XOR AX,AX 0 00004E58 AB STOSW 0 00004E59 AB STOSW ; sf_position 748 ; ES:DI -> sf_cluspos 749 ; 750 ; Generate cluster optimizations for files 751 ; 0 00004E5A 08F6 OR DH,DH 0 00004E5C 7840 JS DEV_SFT3 0 00004E5E AB STOSW ; sf_cluspos 0 00004E5F 8B471A MOV AX,[BX + dir_first] 756 ;;;; STOSW ; sf_lstclus 0 00004E62 2689451A MOV [ES:DI - sf_dirsec + sf_lstclus],AX ;AN004; save it 758 759 760 ; DOS 3.3 FastOpen 6/13/86 761 0 00004E66 1E PUSH DS 0 00004E67 161F context DS 0 00004E69 F606[0000]04 TEST byte [FastOpenFlg],Special_Fill_Set 0 00004E6E 7412 JZ Not_FastOpen 766 FastOpen_Ext_Info equ FastOpen_Ext_info ; NASM port label 0 00004E70 BE[0000] MOV SI,OFFSET FastOpen_Ext_Info wrt DOSGROUP 0 00004E73 8B4401 MOV AX,WORD PTR [SI + FEI_dirsec] 0 00004E76 AB STOSW ; sf_dirsec 0 00004E77 8B4403 MOV AX,WORD PTR [SI + FEI_dirsec+2] ;;; changed for >32mb 0 00004E7A AB STOSW ; sf_dirsec 0 00004E7B 8A04 MOV AL,[SI + FEI_dirpos] 0 00004E7D AA STOSB ; sf_dirpos 0 00004E7E 1F POP DS 0 00004E7F EB1B JMP Next_Name 0 00004E81 90 nop ; identicalise 777 778 ; DOS 3.3 FastOpen 6/13/86 779 780 Not_FastOpen: 0 00004E82 1F POP DS ; normal path 782 ASSUME DS:NOTHING 0 00004E83 368B36[0000] MOV SI,WORD PTR [ss:CURBUF] ; DS:SI->buffer header 0 00004E88 8B4408 MOV AX,WORD PTR [SI + buf_sector] ;F.C. >32mb ;AN000; 0 00004E8B AB STOSW ; sf_dirsec ;F.C. >32mb ;AN000; 0 00004E8C 8B440A MOV AX,WORD PTR [SI + buf_sector+2] ;F.C. >32mb ;AN000; 0 00004E8F AB STOSW ; sf_dirsec ;F.C. >32mb ;AN000; 0 00004E90 89D8 MOV AX,BX 0 00004E92 83C610 ADD SI,BUFINSIZ ; DS:SI-> start of data in buffer 0 00004E95 29F0 SUB AX,SI ; AX = BX relative to start of sector 0 00004E97 B120 MOV CL,dir_entry_struc_size 0 00004E99 F6F1 DIV CL 0 00004E9B AA STOSB ; sf_dirpos 794 795 Next_Name: 796 errnz sf_name-(sf_dirpos+1) 0 00004E9C EB03 JMP SHORT FILE_SFT2 798 799 DEV_SFT3: 0 00004E9E 83C707 ADD DI,sf_name - sf_cluspos 801 FILE_SFT2: 802 ; 803 ; Copy in the object's name 804 ; 0 00004EA1 89DE MOV SI,BX ; DS:SI points to dir_name 0 00004EA3 B90B00 MOV CX,11 0 00004EA6 F3A4 REP MOVSB ; sf_name 0 00004EA8 5E POP SI ; recover DS:SI -> dir_first 809 ;; File tagging , code page and XA cluster must be after name 810 ; MOV AX,[BX.dir_CODEPG] ;FT. set file's code page ;AN000; 811 ; STOSW ;FT. ;AN000; 812 ; MOV AX,[BX.dir_EXTCLUSTER] ;FT. set XA cluster ;AN000; 813 ; STOSW ;FT. ;AN000; 814 ; MOV AX,[EXTOPEN_IO_MODE] ;FT. extended open ;AN000; 815 ; STOSW ;FT. ;AN000; 816 ; MOV AL,[BX.dir_attr2] ;FT. high attribute ;AN000; 817 ; STOSB ;FT. ;AN000; 818 819 ;; File tagging , code page and XA cluster must be after name 820 0 00004EA9 161F context DS 0 00004EAB F8 CLC 0 00004EAC C3 return 824 825 EndProc NEWENTRY 826 827 ; Inputs: 828 ; ES:BP -> DPB 829 ; [CURBUF] Set 830 ; [CURBUF+2]:BX points to directory entry 831 ; [CURBUF+2]:SI points to above dir_first 832 ; Function: 833 ; Free the cluster chain for the entry if present 834 ; Outputs: 835 ; Carry set if error (currently user FAILed to I 24) 836 ; (NOTE dir_firclus and dir_size_l/h are wrong) 837 ; DS BX SI ES BP preserved (BX,SI in meaning, not value) others destroyed 838 839 procedure FREEENT,NEAR 839 ****************** warning: proc FREEENT... [-w+user] 840 DOSAssume CS,,"FreeEnt" 841 ASSUME ES:NOTHING 842 0 00004EAD 1E PUSH DS 0 00004EAE C53E[0000] LDS DI,[CURBUF] 845 ASSUME DS:NOTHING 0 00004EB2 8B0C MOV CX,[SI] ; Get pointer to clusters 0 00004EB4 8B550A MOV DX,WORD PTR [DI + buf_sector+2] ;F.C. >32mb ;AN000; 0 00004EB7 368916[0000] MOV [ss:HIGH_SECTOR],DX ;F.C. >32mb ;AN000; 0 00004EBC 8B5508 MOV DX,WORD PTR [DI + buf_sector] 0 00004EBF 1F POP DS 851 DOSAssume CS,,"MKNODE/FreeEnt" 0 00004EC0 83F902 CMP CX,2 0 00004EC3 7238 JB RET1 ; Was 0 length file (or mucked Firclus if CX=1) 0 00004EC5 263B4E0D CMP CX,[ES:BP + dpb_max_cluster] 0 00004EC9 7732 JA RET1 ; Treat like zero length file (firclus mucked) 0 00004ECB 29FB SUB BX,DI 0 00004ECD 53 PUSH BX ; Save offset 0 00004ECE FF36[0000] PUSH word [HIGH_SECTOR] ;F.C. >32mb ;AN000; 0 00004ED2 52 PUSH DX ; Save sector number 860 0 00004ED3 89CB MOV BX,CX 0 00004ED5 E8[0000] invoke Delete_FSeek ; FS. delete Fastseek Clusters ;AN000; 0 00004ED8 E8[0000] invoke RELEASE ; Free any data allocated 0 00004EDB 5A POP DX 0 00004EDC 8F06[0000] POP word [HIGH_SECTOR] ;F.C. >32mb ;AN000; 0 00004EE0 7302 JNC GET_BUF_BACK 0 00004EE2 5B POP BX 0 00004EE3 C3 return ; Screw up 869 870 GET_BUF_BACK: 871 0 00004EE4 C606[0000]18 MOV byte [ALLOWED],allowed_RETRY + allowed_FAIL 0 00004EE9 30C0 XOR AL,AL 0 00004EEB E8[0000] invoke GETBUFFR ; Get sector back 0 00004EEE 5B POP BX ; Get offset back 0 00004EEF 72F2 retc 0 00004EF1 E8[0000] invoke SET_BUF_AS_DIR 0 00004EF4 031E[0000] ADD BX,WORD PTR [CURBUF] ; Correct it for new buffer 0 00004EF8 89DE MOV SI,BX 0 00004EFA 83C61A ADD SI,dir_first ; Get corrected SI 881 RET1: 0 00004EFD F8 CLC 0 00004EFE C3 return 884 EndProc FREEENT 885 886 ; 887 ; CHECK_VIRT_OPEN checks to see if we had performed a "virtual open" (by 888 ; examining the flag [VIRTUAL_OPEN] to see if it is 1). If we did, then 889 ; it calls Dev_Close_SFT to decrement the ref. count. It also resets the 890 ; flag [VIRTUAL_OPEN]. 891 ; No registers affected (including flags). 892 ; On input, [THISSFT] points to current SFT. 893 ; 894 Procedure CHECK_VIRT_OPEN,NEAR 894 ****************** warning: proc CHECK_VIRT_OPEN... [-w+user] 895 DOSAssume CS,,"Check_Virt_Open" 896 0 00004EFF 50 PUSH AX 0 00004F00 9F lahf ; preserve flags 0 00004F01 803E[0000]00 CMP byte [VIRTUAL_OPEN],0 0 00004F06 7410 JZ ALL_CLOSED 0 00004F08 C606[0000]00 mov byte [VIRTUAL_OPEN],0 ; reset flag 0 00004F0D 0657 SaveReg 0 00004F0F C43E[0000] LES DI,[THISSFT] 0 00004F13 E8[0000] INVOKE DEV_CLOSE_SFT 0 00004F16 5F07 RestoreReg 906 907 ALL_CLOSED: 0 00004F18 9E sahf ; restore flags 0 00004F19 58 POP AX 0 00004F1A C3 return 911 912 EndProc CHECK_VIRT_OPEN 913 914 END 915 916 === Trace listing source: ../DOS/rom.lst 1 ; SCCSID = @(#)rom.asm 1.1 85/04/10 2 ;TITLE ROM - Miscellaneous routines 3 ;NAME ROM 4 ; Misc Low level routines for doing simple FCB computations, Cache 5 ; reads and writes, I/O optimization, and FAT allocation/deallocation 6 ; 7 ; SKPCLP 8 ; FNDCLUS 9 ; BUFSEC 10 ; BUFRD 11 ; BUFWRT 12 ; NEXTSEC 13 ; OPTIMIZE 14 ; FIGREC 15 ; ALLOCATE 16 ; RESTFATBYT 17 ; RELEASE 18 ; RELBLKS 19 ; GETEOF 20 ; 21 ; Modification history: 22 ; 23 ; Created: ARR 30 March 1983 24 ; 25 26 ; 27 ; get the appropriate segment definitions 28 ; 29 [list -] 29 ****************** warning: out: ... CLONE version build switch on ... [-w+user] === Switch to base=008400h -> "DOSCODECODE" 37 section DOSCODECODE 38 [list -] 38 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 38 ****************** warning: out: BPB.INC... [-w+user] 38 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 38 ****************** warning: out: DEVSYM.INC... [-w+user] 46 47 i_need CLUSNUM,WORD 48 i_need NEXTADD,WORD 49 i_need LASTPOS,WORD 50 i_need SECCLUSPOS,BYTE 51 i_need FATBYT,WORD 52 i_need THISSFT,DWORD 53 i_need TRANS,BYTE 54 i_need BYTCNT1,WORD 55 i_need CURBUF,DWORD 56 i_need BYTSECPOS,WORD 57 i_need DMAADD,WORD 58 i_need SECPOS,DWORD ;F.C. >32mb 59 i_need VALSEC,DWORD ;F.C. >32mb 60 i_need ALLOWED,BYTE 61 i_need FSeek_drive,BYTE ; DOS 3.4 62 i_need FSeek_firclus,WORD ; DOS 3.4 63 i_need FSeek_logclus,WORD ; DOS 3.4 64 i_need FSeek_logsave,WORD ; DOS 3.4 65 i_need FastSeekFlg,BYTE ; DOS 3.4 66 i_need XA_condition,BYTE ; DOS 3.4 67 i_need HIGH_SECTOR,WORD ; DOS 3.4 68 i_need DISK_FULL,BYTE ; DOS 3.4 69 i_need Temp_VAR2,WORD ; DOS 3.4 70 i_need Cluster_Next_EDR,WORD 71 72 73 74 Break 75 76 ; Inputs: 77 ; CX = No. of clusters to skip 78 ; ES:BP = Base of drive parameters 79 ; [THISSFT] point to SFT 80 ; Outputs: 81 ; BX = Last cluster skipped to 82 ; CX = No. of clusters remaining (0 unless EOF) 83 ; DX = Position of last cluster 84 ; Carry set if error (currently user FAILed to I 24) 85 ; DI destroyed. No other registers affected. 86 87 procedure FNDCLUS,NEAR 87 ****************** warning: proc FNDCLUS... [-w+user] 88 DOSAssume CS,,"FndClus" 89 ASSUME ES:NOTHING 90 91 Assert ISDPB,,"FndCLus" 92 ;; 10/31/86 FastSeek 0 00004F1B 06 PUSH ES 0 00004F1C C43E[0000] LES DI,[THISSFT] 95 Assert ISSFT,,"FndClus" 0 00004F20 890E[0000] MOV [FSeek_logclus],CX ; presume CX is the position ;AN000; 0 00004F24 268B5D35 MOV BX,[ES:DI + sf_lstclus] 0 00004F28 268B5519 MOV DX,[ES:DI + sf_cluspos] 99 ;; 10/31/86 FastSeek 0 00004F2C 85DB test BX,BX 0 00004F2E 7503 JNZ YCLUS 0 00004F30 E9A000 JMP NOCLUS 103 YCLUS: 0 00004F33 29D1 SUB CX,DX 0 00004F35 7308 JNB FINDIT 0 00004F37 01D1 ADD CX,DX 0 00004F39 31D2 XOR DX,DX 0 00004F3B 268B5D0B MOV BX,[ES:DI + sf_firclus] 109 FINDIT: 110 ;; 10/31/86 FastSeek 111 112 0 00004F3F 07 POP ES 0 00004F40 85C9 test CX,CX 115 skpclp equ SKPCLP ; NASM port label 0 00004F42 7503 JNZ skpclp 0 00004F44 E98500 JMP RET10 118 119 entry SKPCLP 120 FastSeekflg equ FastSeekFlg ; NASM port label 0 00004F47 F606[0000]80 TEST byte [FastSeekflg],Fast_yes ; fastseek installed? ;AN000; 0 00004F4C 745E JZ do_norm ; no ;AN000; 0 00004F4E F606[0000]01 TEST byte [FastSeekflg],FS_begin ; do fastseek ;AN000; 0 00004F53 7457 JZ do_norm ; no ;AN000; 0 00004F55 F606[0000]02 TEST byte [FastSeekflg],FS_insert ; is in insert mode ? ;AN000; 0 00004F5A 7550 JNZ do_norm ; yes ;AN000; 127 Temp_Var2 equ Temp_VAR2 ; NASM port label 0 00004F5C 891E[0000] MOV [Temp_Var2],BX ; save physical cluster ;AN000; 129 ; PTR P005079 130 SKPCLP2: 0 00004F60 E8[0000] invoke FastSeek_Lookup ; ask for next cluster # ;AN000; 0 00004F63 7373 JNC clusfound ; yes, we got it ;AN000; 0 00004F65 83FF01 CMP DI,1 ; valid drive ,e.g. C,D... ;AN000; 0 00004F68 7507 JNZ par_found ; yes, ;AN000; 0 00004F6A 8026[0000]80 AND byte [FastSeekflg],Fast_yes ; no more, fastseek ;AN000; 0 00004F6F EB3B JMP SHORT do_norm ;AN000; 137 ;AN000; 138 par_found: 139 FS_Trunc_EOF equ FS_TRUNC_EOF ; NASM port label 0 00004F71 E8A403 CALL FS_Trunc_EOF ; check EOF and truncate ;AN000; 0 00004F74 73EA JNC SKPCLP2 ; redo lookup ;AN000; 142 noteof: 0 00004F76 800E[0000]02 OR byte [FastSeekflg],FS_insert ; no, start to insert ;AN000; 0 00004F7B 3B16[0000] CMP DX,[FSeek_logsave] ; is current better than new? ;AN000; 0 00004F7F 7613 JBE OnCache ; no, let's use new ;AN000; 0 00004F81 8916[0000] MOV [FSeek_logclus],DX ; use current ;AN000; 0 00004F85 8B1E[0000] MOV BX,[Temp_Var2] ; retore pysical cluster ;AN000; 0 00004F89 89DF MOV DI,BX ; insert cureent cluster ;AN000; 0 00004F8B E8[0000] invoke FastSeek_Insert ; insert cluster # to ;AN000; 0 00004F8E FF06[0000] INC word [FSeek_logclus] ; get next inserted position ;AN000; 0 00004F92 EB18 JMP SHORT do_norm 152 OnCache: 0 00004F94 8B0E[0000] MOV CX,[FSeek_logclus] ; get the number of clusters ;AN000; 0 00004F98 2B0E[0000] SUB CX,[FSeek_logsave] ; we need to skip ;AN000; 0 00004F9C 8B16[0000] MOV DX,[FSeek_logsave] ; cluster position ;AN000; 156 dodo: 0 00004FA0 FF06[0000] INC word [FSeek_logsave] ; get next inserted position ;AN000; 0 00004FA4 FF36[0000] PUSH word [FSeek_logsave] ; logclus=logsave ;AN000; 0 00004FA8 8F06[0000] POP word [FSeek_logclus] ;AN000; 160 161 do_norm: 162 0 00004FAC E8[0000] invoke UNPACK 0 00004FAF 7301C3 retc 165 0 00004FB2 E8[0000] invoke FastSeek_Insert ; insert cluster # to ;AN000; 167 cluss: ;AN000; 0 00004FB5 53 PUSH BX ; FastSeek ;AN000; 0 00004FB6 89FB MOV BX,DI 0 00004FB8 E8[0000] Invoke IsEOF 0 00004FBB 5B POP BX 0 00004FBC 730E JAE RET10 0 00004FBE 87DF XCHG BX,DI 0 00004FC0 42 INC DX 0 00004FC1 FF06[0000] INC word [FSeek_logclus] ; increment for next inserted ;AN000; 0 00004FC5 E202 LOOP SKPCLPX 0 00004FC7 EB03 JMP short RET10 178 SKPCLPX: 0 00004FC9 E97BFF JMP SKPCLP 180 RET10: ;AN000; 0 00004FCC 8026[0000]FD AND byte [FastSeekflg],FS_no_insert ; clear insert mode 0 00004FD1 F8 CLC 0 00004FD2 C3 return 184 NOCLUS: 0 00004FD3 07 POP ES 0 00004FD4 41 INC CX 0 00004FD5 4A DEC DX 0 00004FD6 F8 CLC 0 00004FD7 C3 return 190 clusfound: 0 00004FD8 8B16[0000] MOV DX,[FSeek_logclus] ; get cluster position ;AN000; 0 00004FDC 8B1E[0000] MOV BX,[FSeek_logsave] ; bx=previous cluster # PTM ;AN000; 0 00004FE0 4A DEC DX ;AN000; 0 00004FE1 B90100 MOV CX,1 ; we found it ;AN000; 0 00004FE4 EBCF JMP cluss ;AN000; 196 197 EndProc FNDCLUS 198 199 Break 200 201 ; Inputs: 202 ; AH = priority of buffer 203 ; AL = 0 if buffer must be read, 1 if no pre-read needed 204 ; ES:BP = Base of drive parameters 205 ; [CLUSNUM] = Physical cluster number 206 ; [SECCLUSPOS] = Sector position of transfer within cluster 207 ; [BYTCNT1] = Size of transfer 208 ; Function: 209 ; Insure specified sector is in buffer, flushing buffer before 210 ; read if necessary. 211 ; Outputs: 212 ; ES:DI = Pointer to buffer 213 ; SI = Pointer to transfer address 214 ; CX = Number of bytes 215 ; [NEXTADD] updated 216 ; [TRANS] set to indicate a transfer will occur 217 ; Carry set if error (user FAILed to I 24) 218 219 procedure BUFSEC,NEAR 219 ****************** warning: proc BUFSEC... [-w+user] 220 DOSAssume CS,,"BufSec" 221 ASSUME ES:NOTHING 222 223 Assert ISDPB,,"BufSec" 0 00004FE6 8B16[0000] MOV DX,[CLUSNUM] 0 00004FEA 8A1E[0000] MOV BL,[SECCLUSPOS] 226 allowed_FAIL equ Allowed_FAIL ; NASM port equate 227 allowed_RETRY equ Allowed_RETRY ; NASM port equate 228 allowed_IGNORE equ Allowed_IGNORE ; NASM port equate 0 00004FEE C606[0000]38 MOV byte [ALLOWED],allowed_FAIL + allowed_RETRY + allowed_IGNORE 0 00004FF3 E8EA01 CALL FIGREC 0 00004FF6 E8[0000] invoke GETBUFFR 0 00004FF9 72DC retc 0 00004FFB C606[0000]01 MOV BYTE PTR [TRANS],1 ; A transfer is taking place 0 00005000 8B36[0000] MOV SI,[NEXTADD] 0 00005004 89F7 MOV DI,SI 0 00005006 8B0E[0000] MOV CX,[BYTCNT1] 0 0000500A 01CF ADD DI,CX 0 0000500C 893E[0000] MOV [NEXTADD],DI 0 00005010 C43E[0000] LES DI,[CURBUF] 240 Assert ISBUF,,"BufSec" 0 00005014 26804D0508 OR byte [ES:DI + buf_flags],buf_isDATA 0 00005019 8D7D10 LEA DI,[DI + BUFINSIZ] ; Point to buffer 0 0000501C 033E[0000] ADD DI,[BYTSECPOS] 0 00005020 F8 CLC 0 00005021 C3 return 246 EndProc BUFSEC 247 248 Break 249 250 ; Do a partial sector read via one of the system buffers 251 ; ES:BP Points to DPB 252 ; Carry set if error (currently user FAILed to I 24) 253 254 procedure BUFRD,NEAR 254 ****************** warning: proc BUFRD... [-w+user] 255 DOSAssume CS,,"BufRd" 256 ASSUME ES:NOTHING 257 258 Assert ISDPB,,"BufRd" 0 00005022 06 PUSH ES 0 00005023 B80000 MOV AX,0 0 00005026 E8BDFF CALL BUFSEC 0 00005029 7303 JNC BUF_OK 263 BUF_IO_FAIL: 0 0000502B 07 POP ES 0 0000502C EB29 JMP SHORT RBUFPLACED 266 267 BUF_OK: 0 0000502E 8CC3 MOV BX,ES 0 00005030 8E06[0200] MOV ES,[DMAADD+2] 0 00005034 8EDB MOV DS,BX 271 ASSUME DS:NOTHING 0 00005036 87FE XCHG DI,SI 0 00005038 D1E9 SHR CX,1 0 0000503A 7301 JNC EVENRD 0 0000503C A4 MOVSB 276 EVENRD: 0 0000503D F3A5 REP MOVSW 0 0000503F 07 POP ES 0 00005040 36C53E[0000] LDS DI,[ss:CURBUF] 280 Assert ISBUF,,"BufRD/EvenRD" 281 BufInSiz equ BUFINSIZ ; NASM port equate 0 00005045 8D5D10 LEA BX,[DI + BufInSiz] 0 00005048 29DE SUB SI,BX ; Position in buffer 0 0000504A E8[0000] invoke PLACEBUF 285 Assert ISDPB,,"BufRD/EvenRD" 0 0000504D 263B7602 CMP SI,[ES:BP + dpb_sector_size] ; Read Last byte? 0 00005051 7203 JB RBUFPLACEDC ; No, leave buf where it is 0 00005053 E8[0000] invoke PLACEHEAD ; Make it prime candidate for chucking 289 ; even though it is MRU. 290 RBUFPLACEDC: 0 00005056 F8 CLC 292 RBUFPLACED: 0 00005057 16 PUSH SS 0 00005058 1F POP DS 0 00005059 C3 return 296 EndProc BUFRD 297 298 ; Do a partial sector write via one of the system buffers 299 ; ES:BP Points to DPB 300 ; Carry set if error (currently user FAILed to I 24) 301 302 procedure BUFWRT,NEAR 302 ****************** warning: proc BUFWRT... [-w+user] 303 DOSAssume CS,,"BufWrt" 304 ASSUME ES:NOTHING 305 306 Assert ISDPB,,"BufWrt" 0 0000505A A1[0000] MOV AX,WORD PTR [SECPOS] 0 0000505D 83C001 ADD AX,1 ; Set for next sector 0 00005060 A3[0000] MOV WORD PTR [SECPOS],AX ;F.C. >32mb ;AN000; 0 00005063 8316[0200]00 ADC WORD PTR [SECPOS+2],0 ;F.C. >32mb ;AN000; 0 00005068 A1[0200] MOV AX,WORD PTR [SECPOS+2] ;F.C. >32mb ;AN000; 0 0000506B 3B06[0200] CMP AX,WORD PTR [VALSEC+2] ;F.C. >32mb ;AN000; 0 0000506F B001 MOV AL,1 ;F.C. >32mb ;AN000; 0 00005071 770F JA NOREAD ;F.C. >32mb ;AN000; 0 00005073 720B JB doread ;F.C. >32mb ;AN000; 0 00005075 A1[0000] MOV AX,WORD PTR [SECPOS] ;F.C. >32mb ;AN000; 0 00005078 3B06[0000] CMP AX,WORD PTR [VALSEC] ; Has sector been written before? 0 0000507C B001 MOV AL,1 0 0000507E 7702 JA NOREAD ; Skip preread if SECPOS>VALSEC 320 doread: 0 00005080 30C0 XOR AL,AL 322 NOREAD: 0 00005082 06 PUSH ES 0 00005083 E860FF CALL BUFSEC 0 00005086 72A3 JC BUF_IO_FAIL 0 00005088 8E1E[0200] MOV DS,[DMAADD+2] 327 ASSUME DS:NOTHING 0 0000508C D1E9 SHR CX,1 0 0000508E 7301 JNC EVENWRT 0 00005090 A4 MOVSB 331 EVENWRT: 0 00005091 F3A5 REP MOVSW 0 00005093 07 POP ES 0 00005094 36C51E[0000] LDS BX,[ss:CURBUF] 335 Assert ISBUF,,"BufWrt/EvenWrt" 336 0 00005099 F6470540 TEST byte [BX + buf_flags],buf_dirty ;LB. if already dirty ;AN000; 0 0000509D 7507 JNZ yesdirty ;LB. don't increment dirty count ;AN000; 0 0000509F E8[0000] invoke INC_DIRTY_COUNT ;LB. ;AN000; 0 000050A2 804F0540 OR byte [BX + buf_flags],buf_dirty 341 yesdirty: 0 000050A6 8D7710 LEA SI,[BX + BufInSiz] 0 000050A9 29F7 SUB DI,SI ; Position in buffer 0 000050AB 89FE MOV SI,DI 0 000050AD 89DF MOV DI,BX 0 000050AF E8[0000] invoke PLACEBUF 347 Assert ISDPB,,"BufWrt/EvenWrt" 0 000050B2 263B7602 CMP SI,[ES:BP + dpb_sector_size] ; Written last byte? 0 000050B6 7203 JB WBUFPLACED ; No, leave buf where it is 0 000050B8 E8[0000] invoke PLACEHEAD ; Make it prime candidate for chucking 351 ; even though it is MRU. 352 WBUFPLACED: 0 000050BB F8 CLC 0 000050BC 16 PUSH SS 0 000050BD 1F POP DS 0 000050BE C3 return 357 EndProc BUFWRT 358 359 Break 360 361 ; Compute the next sector to read or write 362 ; ES:BP Points to DPB 363 364 procedure NEXTSEC,NEAR 364 ****************** warning: proc NEXTSEC... [-w+user] 365 DOSAssume CS,,"NextSec" 366 ASSUME ES:NOTHING 367 368 Assert ISDPB,,"NextSec" 0 000050BF F606[0000]FF TEST BYTE PTR [TRANS],-1 0 000050C4 7467 JZ CLRET 0 000050C6 A0[0000] MOV AL,[SECCLUSPOS] 0 000050C9 FEC0 inc al 0 000050CB 7406 jz @F 0 000050CD 263A4604 CMP AL,[ES:BP + dpb_cluster_mask] 0 000050D1 7657 JBE SAVPOS 376 @@: 0 000050D3 8B1E[0000] MOV BX,[CLUSNUM] 0 000050D7 E8[0000] Invoke IsEOF 0 000050DA 7353 JAE NONEXT 380 ;; 11/5/86 FastSeek 0 000050DC F606[0000]80 TEST byte [FastSeekflg],Fast_yes ; fastseek installed? ;AN000; 0 000050E1 7430 JZ do_norm2 ; no ;AN000; 0 000050E3 FF36[0000] PUSH word [LASTPOS] ; save logical cluster # ;AN000; 0 000050E7 8F06[0000] POP word [FSeek_logclus] ;AN000; 0 000050EB FF06[0000] INC word [FSeek_logclus] ; get next cluster ;AN000; 386 ;AN000; 0 000050EF F606[0000]01 TEST byte [FastSeekflg],FS_begin ; from R/W ;AN000; 0 000050F4 741D JZ do_norm2 ; no ;AN000; 389 look2: ;AN000; 0 000050F6 E8[0000] invoke FastSeek_Lookup ; call lookup ;AN000; 0 000050F9 7325 JNC clusgot ; found one ;AN000; 392 0 000050FB 83FF01 CMP DI,1 ; valid drive ,e.g. C,D... ;AN000; 0 000050FE 7507 JNZ parfound2 ; yes, ;AN000; 0 00005100 8026[0000]80 AND byte [FastSeekflg],Fast_yes ; no more, fastseek ;AN000; 0 00005105 EB0C JMP SHORT do_norm2 ;AN000; 397 parfound2: 0 00005107 E80E02 CALL FS_TRUNC_EOF ; check EOF ;AN000; 0 0000510A 8B1E[0000] MOV BX,[CLUSNUM] ; don't need partially found cluster 0 0000510E 800E[0000]02 OR byte [FastSeekflg],FS_insert ; prepared for cluster insertion ;AN000; 401 ; use the old bx ;AN000; 402 ;AN000; 403 do_norm2: 0 00005113 E8[0000] invoke UNPACK 0 00005116 7217 JC NONEXT 0 00005118 E8[0000] invoke FastSeek_Insert ; call insert ;AN000; 0 0000511B 8026[0000]FD AND byte [FastSeekflg],FS_no_insert ; clear insert flag ;AN000; 408 ;AN000; 409 clusgot: 410 ;; 11/5/86 FastSeek 0 00005120 893E[0000] MOV [CLUSNUM],DI 0 00005124 FF06[0000] INC word [LASTPOS] 0 00005128 B000 MOV AL,0 414 SAVPOS: 0 0000512A A2[0000] MOV [SECCLUSPOS],AL 416 CLRET: 0 0000512D F8 CLC 0 0000512E C3 return 419 NONEXT: 0 0000512F F9 STC 0 00005130 C3 return 422 EndProc NEXTSEC 423 424 Break 425 426 ; Inputs: 427 ; BX = Physical cluster 428 ; CX = No. of records 429 ; DL = sector within cluster 430 ; ES:BP = Base of drives parameters 431 ; [NEXTADD] = transfer address 432 ; Outputs: 433 ; AX = No. of records remaining 434 ; BX = Transfer address 435 ; CX = No. or records to be transferred 436 ; DX = Physical sector address (LOW) 437 ; [HIGH_SECTOR] = Physical sector address (HIGH) 438 ; DI = Next cluster 439 ; [CLUSNUM] = Last cluster accessed 440 ; [NEXTADD] updated 441 ; Carry set if error (currently user FAILed to I 24) 442 ; ES:BP unchanged. Note that segment of transfer not set. 443 444 procedure OPTIMIZE,NEAR 444 ****************** warning: proc OPTIMIZE... [-w+user] 445 DOSAssume CS,,"Optimize" 446 ASSUME ES:NOTHING 447 448 Assert ISDPB,,"Optimize" 0 00005131 52 PUSH DX 0 00005132 53 PUSH BX 0 00005133 B400 mov ah, 0 0 00005135 268A4604 mov al, [ES:BP + dpb_cluster_mask] 0 00005139 40 inc ax ; Number of sectors per cluster 0 0000513A A3[0000] mov word ptr [Cluster_Next_EDR], ax 0 0000513D B600 mov dh, 0 0 0000513F 29D0 sub ax, dx ; ax = Number of sectors left in first cluster 0 00005141 89CA MOV DX,CX 0 00005143 31C9 xor cx, cx 459 ;;; 11/5/86 FastSeek 0 00005145 FF36[0000] PUSH word [LASTPOS] ; save logical cluster # ;AN000; 0 00005149 8F06[0000] POP word [FSeek_logclus] ;AN000; 0 0000514D FF06[0000] INC word [FSeek_logclus] ; get next cluster ;AN000; 463 ;AN000; 464 OPTCLUS: 465 ; lDOS obsolete: 466 ; AL has number of sectors available in current cluster 467 ; AH has number of sectors available in next cluster 468 ; lDOS update: 469 ; ax = number of sectors available in current cluster 470 ; [Cluster_Next_EDR] = number of sectors available in next cluster 471 472 ; BX has current physical cluster 473 ; CX has number of sequential sectors found so far 474 ; DX has number of sectors left to transfer 475 ; ES:BP Points to DPB 476 ; ES:SI has FAT pointer 477 0 00005151 F606[0000]80 TEST byte [FastSeekflg],Fast_yes ; fastseek installed? ;AN000; 0 00005156 7429 JZ do_norm3 ; no ;AN000; 0 00005158 F606[0000]01 TEST byte [FastSeekflg],FS_begin ; from R/W ;AN000; 0 0000515D 7422 JZ do_norm3 ; no ;AN000; 0 0000515F F606[0000]02 TEST byte [FastSeekflg],FS_insert ; is in insert mode ? ;AN000; 0 00005164 751B JNZ do_norm3 ; yes ;AN000; 0 00005166 E8[0000] invoke FastSeek_Lookup ; call lookup ;AN000; 0 00005169 731B JNC clusgot2 ; found one ;AN000; 486 0 0000516B 83FF01 CMP DI,1 ; valid drive ,e.g. C,D... ;AN000; 0 0000516E 7507 JNZ par_found3 ; yes, ;AN000; 0 00005170 8026[0000]80 AND byte [FastSeekflg],Fast_yes ; no more, fastseek ;AN000; 0 00005175 EB0A JMP SHORT do_norm3 ;AN000; 491 par_found3: 0 00005177 53 PUSH BX 0 00005178 E89D01 CALL FS_TRUNC_EOF ; file entry not existing ;AN000; 0 0000517B 5B POP BX ;AN000; 0 0000517C 800E[0000]02 OR byte [FastSeekflg],FS_insert ; prepare for insertion ;AN000; 496 ; use old bx ;AN000; 497 do_norm3: 0 00005181 E8[0000] invoke UNPACK 0 00005184 7241 JC OP_ERR 500 clusgot2: 0 00005186 E8[0000] invoke FastSeek_Insert ; call insert ;AN000; 0 00005189 FF06[0000] INC word [FSeek_logclus] ; insert to next position ;AN000; 503 ;;; 11/5/86 FastSeek ;AN000; 0 0000518D 01C1 add cx, ax 0 0000518F 39D1 CMP CX,DX 0 00005191 733E JAE BLKDON 0 00005193 A1[0000] MOV ax, word ptr [Cluster_Next_EDR] 0 00005196 43 INC BX 0 00005197 39DF CMP DI,BX 0 00005199 74B6 JZ OPTCLUS 0 0000519B 4B DEC BX 512 FINCLUS: 0 0000519C 891E[0000] MOV [CLUSNUM],BX ; Last cluster accessed 0 000051A0 29CA SUB DX,CX ; Number of sectors still needed 0 000051A2 52 PUSH DX 0 000051A3 89C8 MOV AX,CX 0 000051A5 26F76602 MUL word [ES:BP + dpb_sector_size] ; Number of sectors times sector size 0 000051A9 8B36[0000] MOV SI,[NEXTADD] 0 000051AD 01F0 ADD AX,SI ; Adjust by size of transfer 0 000051AF A3[0000] MOV [NEXTADD],AX 0 000051B2 58 POP AX ; Number of sectors still needed 0 000051B3 5A POP DX ; Starting cluster 0 000051B4 29D3 SUB BX,DX ; Number of new clusters accessed 0 000051B6 011E[0000] ADD [LASTPOS],BX 0 000051BA 5B POP BX ; BL = sector postion within cluster 0 000051BB E82200 invoke FIGREC 0 000051BE 89F3 MOV BX,SI 0 000051C0 8026[0000]FD AND byte [FastSeekflg],FS_no_insert ; clear insert flag 0 000051C5 F8 CLC 0 000051C6 C3 return 531 532 OP_ERR: 0 000051C7 83C404 ADD SP,4 0 000051CA 8026[0000]FD AND byte [FastSeekflg],FS_no_insert ; clear insert flag 0 000051CF F9 STC 0 000051D0 C3 return 537 538 BLKDON: 0 000051D1 29D1 SUB CX,DX ; Number of sectors in cluster we don't want 0 000051D3 A1[0000] mov ax, word ptr [Cluster_Next_EDR] 0 000051D6 29C8 sub ax, cx ; Number of sectors in cluster we accepted 0 000051D8 48 dec ax ; Adjust to mean position within cluster 0 000051D9 A2[0000] MOV [SECCLUSPOS], al 0 000051DC 89D1 MOV CX,DX ; Anyway, make the total equal to the request 0 000051DE EBBC JMP SHORT FINCLUS 546 EndProc OPTIMIZE 547 548 Break 549 550 ; Inputs: 551 ; DX = Physical cluster number 552 ; BL = Sector postion within cluster 553 ; ES:BP = Base of drive parameters 554 ; Outputs: 555 ; DX = physical sector number (LOW) 556 ; [HIGH_SECTOR] Physical sector address (HIGH) 557 ; No other registers affected. 558 559 procedure FIGREC,NEAR 559 ****************** warning: proc FIGREC... [-w+user] 560 ASSUME DS:NOTHING,ES:NOTHING 561 562 Assert ISDPB,,"FigRec" 0 000051E0 51 PUSH CX 0 000051E1 31C9 xor cx, cx 0 000051E3 268A4E05 MOV CL,[ES:BP + dpb_cluster_shift] 0 000051E7 4A DEC DX 0 000051E8 4A DEC DX 0 000051E9 36C706[0000]0000 MOV word [ss:HIGH_SECTOR],0 ;F.C. >32mb 0 000051F0 E309 jcxz noshift ;F.C. >32mb 570 rotleft: ;F.C. >32mb 0 000051F2 D1E2 shl DX,1 ;F.C. >32mb 0 000051F4 36D116[0000] RCL word [ss:HIGH_SECTOR],1 ;F.C. >32mb 0 000051F9 E2F7 LOOP rotleft ;F.C. >32mb 574 noshift: 575 576 ; SHL DX,CL 0 000051FB 08DA OR DL,BL 0 000051FD 2603560B ADD DX,[ES:BP + dpb_first_sector] 0 00005201 368316[0000]00 ADC word [ss:HIGH_SECTOR],0 ;F.C. >32mb 0 00005207 59 POP CX 0 00005208 C3 return 582 EndProc FIGREC 583 584 Break 585 586 ;*** ALLOCATE - Allocate Disk Space 587 ; 588 ; ALLOCATE is called to allocate disk clusters. The new clusters are 589 ; FAT-chained onto the end of the existing file. 590 ; 591 ; The DPB contains the cluster # of the last free cluster allocated 592 ; (dpb_next_free). We start at this cluster and scan towards higher 593 ; numbered clusters, looking for the necessary free blocks. 594 ; 595 ; Once again, fancy terminology gets in the way of corrct coding. When 596 ; using next_free, start scanning AT THAT POINT and not the one following it. 597 ; This fixes the boundary condition bug when only free = next_free = 2. 598 ; 599 ; If we get to the end of the disk without satisfaction: 600 ; 601 ; if (dpb_next_free == 2) then we've scanned the whole disk. 602 ; return (insufficient_disk_space) 603 ; ELSE 604 ; dpb_next_free = 2; start scan over from the beginning. 605 ; 606 ; Note that there is no multitasking interlock. There is no race when 607 ; examining the entrys in an in-core FAT block since there will be no 608 ; context switch. When UNPACK context switches while waiting for a FAT read 609 ; we are done with any in-core FAT blocks, so again there is no race. The 610 ; only special concern is that V2 and V3 MSDOS left the last allocated 611 ; cluster as "00"; marking it EOF only when the entire alloc request was 612 ; satisfied. We can't allow another activation to think this cluster is 613 ; free, so we give it a special temporary mark to show that it is, indeed, 614 ; allocated. 615 ; 616 ; Note that when we run out of space this algorithem will scan from 617 ; dpb_next_free to the end, then scan from cluster 2 through the end, 618 ; redundantly scanning the later part of the disk. This only happens when 619 ; we run out of space, so sue me. 620 ; 621 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 622 ; C A V E A T P A T T E R S O N ; 623 ; ; 624 ; The use of FATBYT and RESTFATBYT is somewhat mysterious. Here is the 625 ; explanation: 626 ; 627 ; In the NUL file case (sf_firclus currently 0) ALLOCATE is called with 628 ; entry BX = 0. What needs to be done in this case is to stuff the cluster 629 ; number of the first cluster allocated in sf_firclus when the ALLOCATE is 630 ; complete. THIS VALUE IS SAVED TEMPORARILY IN CLUSTER 0, HENCE THE CURRENT 631 ; VALUE IN CLUSTER 0 MUST BE SAVED AND RESTORED. This is a side effect of 632 ; the fact that PACK and UNPACK don't treat requests for clusters 0 and 1 as 633 ; errors. This "stuff" is done by the call to PACK which is right before 634 ; the 635 ; LOOP findfre ; alloc more if needed 636 ; instruction when the first cluster is allocated to the nul file. The 637 ; value is recalled from cluster 0 and stored at sf_firclus at ads4: 638 ; 639 ; This method is obviously useless (because it is non-reentrant) for 640 ; multitasking, and will have to be changed. Storing the required value on 641 ; the stack is recommended. Setting sf_firclus at the PACK of cluster 0 642 ; (instead of actually doing the PACK) is BAD because it doesn't handle 643 ; problems with INT 24 well. 644 ; 645 ; C A V E A T P A T T E R S O N ; 646 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 647 ; ; 648 ; ENTRY BX = Last cluster of file (0 if null file) 649 ; CX = No. of clusters to allocate 650 ; ES:BP = Base of drive parameters 651 ; [THISSFT] = Points to SFT 652 ; 653 ; EXIT 'C' set if insufficient space 654 ; [FAILERR] can be tested to see the reason for failure 655 ; CX = max. no. of clusters that could be added to file 656 ; 'C' clear if space allocated 657 ; BX = First cluster allocated 658 ; FAT is fully updated 659 ; sf_FIRCLUS field of SFT set if file was null 660 ; 661 ; USES ALL but SI, BP 662 663 PROCEDURE ALLOCATE,NEAR 663 ****************** warning: proc ALLOCATE... [-w+user] 664 665 DOSAssume CS,,"Allocate" 666 ASSUME ES:NOTHING 667 668 Assert ISDPB,,"Allocate" 0 00005209 53 PUSH BX ; save (bx) 0 0000520A 31DB XOR BX,BX 0 0000520C E8[0000] invoke UNPACK 0 0000520F 893E[0000] MOV [FATBYT],DI ; save correct cluster 0 value 0 00005213 5B POP BX 0 00005214 72F2 retc ; abort if error [INTERR?] 675 0 00005216 51 PUSH CX 0 00005217 53 PUSH BX 678 0 00005218 89DA MOV DX,BX 680 Assert ISDPB,,"Allocate/Unpack" 0 0000521A 268B5E1D mov bx,[es:bp + dpb_next_free] 0 0000521E 83FB02 cmp bx,2 683 findfre equ FINDFRE ; NASM port label 0 00005221 7709 ja findfre 685 686 ; couldn't find enough free space beyond dpb_next_free, or dpb_next_free is 687 ; <2 or >dpb_max_clus. Reset it and restart the scan 688 689 ads1: 690 Assert ISDPB,,"Alloc/ads1" 0 00005223 26C7461D0200 mov word [es:bp + dpb_next_free],2 0 00005229 BB0100 mov bx,1 ; Counter next instruction so first 693 ; cluster examined is 2 694 695 ; Scanning both forwards and backwards for a free cluster 696 ; 697 ; (BX) = forwards scan pointer 698 ; (CX) = clusters remaining to be allocated 699 ; (DX) = current last cluster in file 700 ; (TOS) = last cluster of file 701 702 FINDFRE: 0 0000522C 43 INC BX 704 Assert ISDPB,,"Alloc/findfre" 0 0000522D 263B5E0D CMP BX,[ES:BP + dpb_max_cluster] 0 00005231 7603 JBE aupk 0 00005233 EB77 jmp ads7 ; at end of disk 0 00005235 90 nop ; identicalise 709 aupk: 0 00005236 E8[0000] invoke UNPACK ; check out this cluster 0 00005239 722F jc ads4 ; FAT error [INTERR?] 0 0000523B 75EF jnz findfre ; not free, keep on truckin 713 714 ; Have found a free cluster. Chain it to the file 715 ; 716 ; (BX) = found free cluster # 717 ; (DX) = current last cluster in file 718 0 0000523D 26895E1D mov [es:bp + dpb_next_free],bx ; next time start search here 0 00005241 92 xchg ax,dx ; save (dx) in ax 0 00005242 BA0100 mov dx,1 ; mark this free guy as "1" 0 00005245 E8[0000] invoke PACK ; set special "temporary" mark 0 00005248 7220 jc ads4 ; FAT error [INTERR?] 0 0000524A 26837E1FFF CMP word [ES:BP + dpb_free_cnt],-1 ; Free count valid? 0 0000524F 7404 JZ NO_ALLOC ; No 0 00005251 26FF4E1F DEC word [ES:BP + dpb_free_cnt] ; Reduce free count by 1 727 NO_ALLOC: 0 00005255 92 xchg ax,dx ; (dx) = current last cluster in file 0 00005256 87DA XCHG BX,DX 0 00005258 89D0 MOV AX,DX 0 0000525A E8[0000] invoke PACK ; link free cluster onto file 732 ; CAVEAT.. On Nul file, first pass stuffs 733 ; cluster 0 with FIRCLUS value. 0 0000525D 720B jc ads4 ; FAT error [INTERR?] 0 0000525F 93 xchg BX,AX ; (BX) = last one we looked at 0 00005260 89DA mov dx,bx ; (dx) = current end of file 0 00005262 E2C8 LOOP findfre ; alloc more if needed 738 739 ; We've successfully extended the file. Clean up and exit 740 ; 741 ; (BX) = last cluster in file 742 0 00005264 BAFFFF MOV DX,0FFFFH 0 00005267 E8[0000] invoke PACK ; mark last cluster EOF 745 746 ; Note that FAT errors jump here to clean the stack and exit. this saves us 747 ; 2 whole bytes. Hope its worth it... 748 ; 749 ; 'C' set iff error 750 ; calling (BX) and (CX) pushed on stack 751 0 0000526A 5B ads4: POP BX 0 0000526B 59 POP CX ; Don't need this stuff since we're successful 0 0000526C 729A retc 0 0000526E E8[0000] invoke UNPACK ; Get first cluster allocated for return 756 ; CAVEAT... In nul file case, UNPACKs cluster 0. 0 00005271 7295 retc 0 00005273 E85400 invoke RESTFATBYT ; Restore correct cluster 0 value 0 00005276 7290 retc 0 00005278 87DF XCHG BX,DI ; (DI) = last cluster in file upon our entry 0 0000527A 09FF OR DI,DI ; clear 'C' 0 0000527C 758A retnz ; we were extending an existing file 763 764 ; We were doing the first allocation for a new file. Update the SFT cluster 765 ; info 766 ;; Extended Attributes 767 ; TEST [XA_condition],XA_No_SFT ;FT. don't update SFT when from ;AN000; 768 ; JZ dofastk ;FT. GetSet_XA ;AN000; 769 ; AND [XA_condition],not XA_No_SFT ;FT. clear the bit ;AN000; 770 ; CLC ;FT. ;AN000; 771 ; ret ;FT. ;AN000; 772 ;; 11/6/86 FastSeek 773 dofastk: 0 0000527E 52 PUSH DX 0 0000527F 268A5600 MOV DL,[ES:BP + dpb_drive] ; get drive # 776 0 00005283 06 PUSH ES 0 00005284 C43E[0000] LES DI,[THISSFT] 779 Assert ISSFT,,"Allocate/ads4" 0 00005288 26895D0B MOV [ES:DI + sf_firclus],BX 0 0000528C 26895D35 MOV [ES:DI + sf_lstclus],BX 782 0 00005290 F606[0000]80 TEST byte [FastSeekflg],Fast_yes ; fastseek installed 0 00005295 7412 JZ do_norm5 ; no 0 00005297 F606[0000]01 TEST byte [FastSeekflg],FS_begin ; do fastseek 0 0000529C 740B JZ do_norm5 ; no 0 0000529E 51 PUSH CX 0 0000529F 89D9 MOV CX,BX ; set up firclus # 0 000052A1 891E[0000] MOV [FSeek_firclus],BX ; update firclus varible 0 000052A5 E8[0000] invoke FastSeek_Open ; create this file entry 0 000052A8 59 POP CX 792 do_norm5: 0 000052A9 07 POP ES 794 ;; 11/6/86 FastSeek 0 000052AA 5A POP DX 0 000052AB C3 return 797 798 799 ;** we're at the end of the disk, and not satisfied. See if we've scanned ALL 800 ; of the disk... 801 0 000052AC 26837E1D02 ads7: cmp word [es:bp + dpb_next_free],2 803 %ifn debug 0 000052B1 7403 jz tmplab2 ; 0 000052B3 E96DFF jmp ads1 ; start scan from front of disk 806 tmplab2: 807 %else 808 jz tmplab 809 jmp ads1 810 tmplab: 811 %endif 812 813 ; Sorry, we've gone over the whole disk, with insufficient luck. Lets give 814 ; the space back to the free list and tell the caller how much he could have 815 ; had. We have to make sure we remove the "special mark" we put on the last 816 ; cluster we were able to allocate, so it doesn't become orphaned. 817 ; 818 ; (CX) = clusters remaining to be allocated 819 ; (TOS) = last cluster of file (before call to ALLOCATE) 820 ; (TOS+1) = # of clusters wanted to allocate 821 822 0 000052B6 5B POP BX ; (BX) = last cluster of file 0 000052B7 BAFFFF MOV DX,0FFFFH 0 000052BA E81F00 invoke RELBLKS ; give back any clusters just alloced 0 000052BD 58 POP AX ; No. of clusters requested 827 ; Don't "retc". We are setting Carry anyway, 828 ; Alloc failed, so proceed with return CX 829 ; setup. 0 000052BE 29C8 SUB AX,CX ; AX=No. of clusters allocated 0 000052C0 E80700 invoke RESTFATBYT ; Don't "retc". We are setting Carry anyway, 832 ; Alloc failed. 833 ; fmt <>,<>,<"$p: disk full in allocate\n"> 0 000052C3 C606[0000]01 MOV byte [DISK_FULL],1 ;MS. indicating disk full 0 000052C8 F9 STC 0 000052C9 C3 return 837 838 EndProc ALLOCATE 839 840 ; SEE ALLOCATE CAVEAT 841 ; Carry set if error (currently user FAILed to I 24) 842 843 procedure RESTFATBYT,NEAR 843 ****************** warning: proc RESTFATBYT... [-w+user] 844 DOSAssume CS,,"RestFATByt" 845 ASSUME ES:NOTHING 846 0 000052CA 53 PUSH BX 0 000052CB 52 PUSH DX 0 000052CC 57 PUSH DI 0 000052CD 31DB XOR BX,BX 0 000052CF 8B16[0000] MOV DX,[FATBYT] 0 000052D3 E8[0000] invoke PACK 0 000052D6 5F POP DI 0 000052D7 5A POP DX 0 000052D8 5B POP BX 0 000052D9 C3 return 857 EndProc RESTFATBYT 858 859 Break 860 861 ; Inputs: 862 ; BX = Cluster in file 863 ; ES:BP = Base of drive parameters 864 ; Function: 865 ; Frees cluster chain starting with [BX] 866 ; Carry set if error (currently user FAILed to I 24) 867 ; AX,BX,DX,DI all destroyed. Other registers unchanged. 868 869 procedure RELEASE,NEAR 869 ****************** warning: proc RELEASE... [-w+user] 870 DOSAssume CS,,"Release" 871 ASSUME ES:NOTHING 872 0 000052DA 31D2 XOR DX,DX 874 entry RELBLKS 875 DOSAssume CS,,"RelBlks" 876 Assert ISDPB,,"RelBlks" 877 878 ; Enter here with DX=0FFFFH to put an end-of-file mark in the first cluster 879 ; and free the rest in the chain. 880 0 000052DC E8[0000] invoke UNPACK 0 000052DF 72F8 retc 0 000052E1 74F6 retz 0 000052E3 89F8 MOV AX,DI 0 000052E5 52 PUSH DX 0 000052E6 E8[0000] invoke PACK 0 000052E9 5A POP DX 0 000052EA 72ED retc 0 000052EC 09D2 OR DX,DX 0 000052EE 750B JNZ NO_DEALLOC ; Was putting EOF mark 0 000052F0 26837E1FFF CMP word [ES:BP + dpb_free_cnt],-1 ; Free count valid? 0 000052F5 7404 JZ NO_DEALLOC ; No 0 000052F7 26FF461F INC word [ES:BP + dpb_free_cnt] ; Increase free count by 1 894 NO_DEALLOC: 0 000052FB 89C3 MOV BX,AX 0 000052FD 48 dec ax ; check for "1" 0 000052FE 74D9 retz ; is last cluster of incomplete chain 0 00005300 E8[0000] Invoke IsEOF 0 00005303 72D5 JB RELEASE ; Carry clear if JMP not taken 0 00005305 C3 ret12: return 901 EndProc RELEASE 902 903 Break 904 905 ; Inputs: 906 ; ES:BP Points to DPB 907 ; BX = Cluster in a file 908 ; DS = CS 909 ; Outputs: 910 ; BX = Last cluster in the file 911 ; Carry set if error (currently user FAILed to I 24) 912 ; DI destroyed. No other registers affected. 913 914 procedure GETEOF,NEAR 914 ****************** warning: proc GETEOF... [-w+user] 915 DOSAssume CS,,"GetEOF" 916 ASSUME ES:NOTHING 917 918 Assert ISDPB,,"GetEof" 0 00005306 E8[0000] invoke UNPACK 0 00005309 72FA retc 0 0000530B 53 PUSH BX 0 0000530C 89FB MOV BX,DI 0 0000530E E8[0000] Invoke IsEOF 0 00005311 5B POP BX 925 RET12 equ ret12 ; NASM port label 0 00005312 73F1 JAE RET12 ; Carry clear if jmp 0 00005314 89FB MOV BX,DI 0 00005316 EBEE JMP GETEOF 929 EndProc GETEOF 930 931 Break 932 933 ; Inputs: 934 ; ES:BP Points to DPB 935 ; BX = Cluster in a file 936 ; Functions: if BX=EOF then truncate it from Fastseek Cache 937 ; Outputs: 938 ; carry set: not EOF 939 ; carry clear: EOF and do truncate 940 941 procedure FS_TRUNC_EOF,NEAR 941 ****************** warning: proc FS_TRUNC_EOF... [-w+user] 942 ASSUME ES:NOTHING,DS:NOTHING 943 0 00005318 89FB MOV BX,DI ; get beginning physical# ;AN000; 0 0000531A E8[0000] invoke IsEOF ; is EOF ;AN000; 0 0000531D 7218 JB noteof2 ; no ;AN000; 0 0000531F 36FF36[0000] PUSH word [ss:FSeek_logclus] ; ;AN000; 0 00005324 36FF36[0000] PUSH word [ss:FSeek_logsave] ; logclus=logsave ;AN000; 0 00005329 368F06[0000] POP word [ss:FSeek_logclus] ; delete EOF ;AN000; 0 0000532E E8[0000] invoke FastSeek_Truncate ; ;AN000; 0 00005331 368F06[0000] POP word [ss:FSeek_logclus] ; redo the look up ;AN000; 0 00005336 F8 CLC ;AN000; 953 noteof2: ;AN000; 0 00005337 C3 return ;AN000; 955 EndProc FS_TRUNC_EOF ;AN000; 956 957 END 958 959 === Trace listing source: ../DOS/fcb.lst 1 ; SCCSID = @(#)fcb.asm 1.2 85/07/23 2 ; SCCSID = @(#)fcb.asm 1.2 85/07/23 3 ;TITLE FCB - FCB parse calls for MSDOS 4 ;NAME FCB 5 ; Low level routines for parsing names into FCBs and analyzing 6 ; filename characters 7 ; 8 ; MakeFcb 9 ; NameTrans 10 ; PATHCHRCMP 11 ; GetLet 12 ; TESTKANJ 13 ; NORMSCAN 14 ; DELIM_DOS 15 ; 16 ; Revision history: 17 ; 18 ; A000 version 4.00 Jan. 1988 19 ; 20 21 ; 22 ; get the appropriate segment definitions 23 ; 24 [list -] === Switch to base=008400h -> "DOSCODECODE" 31 section DOSCODECODE 32 [list -] 32 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 32 ****************** warning: out: BPB.INC... [-w+user] 32 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 32 ****************** warning: out: DEVSYM.INC... [-w+user] 40 41 i_need Name1,BYTE 42 i_need Creating,BYTE 43 i_need Attrib,BYTE 44 i_need SpaceFlag,BYTE 45 i_need FILE_UCASE_TAB,byte ;DOS 3.3 46 i_need COUNTRY_CDPG,byte ;AN000; 2/12/KK 47 i_need DrvErr,BYTE ;AN000; 2/12/KK 48 i_need DOS34_FLAG,WORD ;AN000; 2/12/KK 49 50 procedure MakeFcb,NEAR 50 ****************** warning: proc MakeFcb... [-w+user] 51 ScanSeparator equ 1 52 DRVBIT EQU 2 53 NAMBIT EQU 4 54 EXTBIT EQU 8 0 00005338 36C606[0000]00 MOV BYTE PTR [ss:SpaceFlag],0 0 0000533E 30D2 XOR DL,DL ; Flag--not ambiguous file name 0 00005340 A802 TEST AL,DRVBIT ; Use current drive field if default? 0 00005342 7504 JNZ DEFDRV 0 00005344 26C60500 MOV BYTE PTR [ES:DI],0 ; No - use default drive 60 DEFDRV: 0 00005348 47 INC DI 0 00005349 B90800 MOV CX,8 0 0000534C A804 TEST AL,NAMBIT ; Use current name fields as defualt? 0 0000534E 93 XCHG AX,BX ; Save bits in BX 0 0000534F B020 MOV AL," " 0 00005351 7404 JZ FILLB ; If not, go fill with blanks 0 00005353 01CF ADD DI,CX 0 00005355 31C9 XOR CX,CX ; Don't fill any 69 FILLB: 0 00005357 F3AA REP STOSB 0 00005359 B103 MOV CL,3 0 0000535B F6C308 TEST BL,EXTBIT ; Use current extension as default 0 0000535E 7404 JZ FILLB2 0 00005360 01CF ADD DI,CX 0 00005362 31C9 XOR CX,CX 76 FILLB2: 0 00005364 F3AA REP STOSB 0 00005366 91 XCHG AX,CX ; Put zero in AX 0 00005367 AB STOSW 0 00005368 AB STOSW ; Initialize two words after to zero 0 00005369 83EF10 SUB DI,16 ; Point back at start 0 0000536C F6C301 TEST BL,ScanSeparator; Scan off separators if not zero 0 0000536F 7409 JZ SKPSPC 0 00005371 E88A00 CALL SCANB ; Peel off blanks and tabs 0 00005374 E8E200 CALL DELIM_DOS ; Is it a one-time-only delimiter? 0 00005377 7504 JNZ NOSCAN 0 00005379 46 INC SI ; Skip over the delimiter 88 SKPSPC: 0 0000537A E88100 CALL SCANB ; Always kill preceding blanks and tabs 90 NOSCAN: 91 GETLET equ GetLet ; NASM port label 0 0000537D E8B300 CALL GETLET 0 00005380 761E JBE NODRV ; Quit if termination character 94 %IF DBCS ;AN000; 95 CALL TESTKANJ ;AN000;; 2/18/KK 96 JNE NODRV ;AN000;; 2/18/KK 97 %ENDIF ;AN000; 0 00005382 803C3A CMP BYTE PTR [SI],":" ; Check for potential drive specifier 0 00005385 7519 JNZ NODRV 0 00005387 46 INC SI ; Skip over colon 0 00005388 2C40 SUB AL,"@" ; Convert drive letter to drive number (A=1) 0 0000538A 760F JBE BADDRV ; Drive letter out of range 103 0 0000538C 50 PUSH AX 0 0000538D E8[0000] Invoke GetVisDrv 0 00005390 58 POP AX 107 HavDrv equ HAVDRV ; NASM port label 0 00005391 730A JNC HavDrv 0 00005393 36803E[0000]1A CMP byte [ss:DrvErr],error_not_DOS_disk ; if not FAt drive ;AN000; 0 00005399 7402 JZ HavDrv ; assume ok ;AN000; 111 BADDRV: 0 0000539B B2FF MOV DL,-1 113 HAVDRV: 0 0000539D AA STOSB ; Put drive specifier in first byte 0 0000539E 46 INC SI 0 0000539F 4F DEC DI ; Counteract next two instructions 117 NODRV: 0 000053A0 4E DEC SI ; Back up 0 000053A1 47 INC DI ; Skip drive byte 120 121 entry NORMSCAN 122 0 000053A2 B90800 MOV CX,8 0 000053A5 E82200 CALL GETWORD ; Get 8-letter file name 0 000053A8 803C2E CMP BYTE PTR [SI],"." 0 000053AB 7516 JNZ NODOT 0 000053AD 46 INC SI ; Skip over dot if present 0 000053AE 36F706[0000]0001 TEST word [ss:DOS34_FLAG],DBCS_VOLID2 ;AN000; 0 000053B5 7406 JZ VOLOK ;AN000; 0 000053B7 A4 MOVSB ; 2nd byte of DBCS ;AN000; 0 000053B8 B90200 MOV CX,2 ;AN000; 0 000053BB EB03 JMP SHORT contvol ;AN000; 133 VOLOK: 0 000053BD B90300 MOV CX,3 ; Get 3-letter extension 135 contvol: 0 000053C0 E80D00 CALL MUSTGETWORD 137 NODOT: 0 000053C3 88D0 MOV AL,DL 0 000053C5 C3 return 140 141 NONAM: 0 000053C6 01CF ADD DI,CX 0 000053C8 4E DEC SI 0 000053C9 C3 return 145 146 GETWORD: 0 000053CA E86600 CALL GETLET 0 000053CD 76F7 JBE NONAM ; Exit if invalid character 0 000053CF 4E DEC SI 150 ; 151 ; UGH!!! Horrible bug here that should be fixed at some point: 152 ; If the name we are scanning is longer than CX, we keep on reading! 153 ; 154 MUSTGETWORD: 0 000053D0 E86000 CALL GETLET 156 ; 157 ; If spaceFlag is set then we allow spaces in a pathname 158 ; 0 000053D3 7223 JB FILLNAM 0 000053D5 750C JNZ MustCheckCX 0 000053D7 36F606[0000]FF TEST BYTE PTR [ss:SpaceFlag],0FFh 0 000053DD 7419 JZ FILLNAM 0 000053DF 3C20 CMP AL," " 0 000053E1 7515 JNZ FILLNAM 165 166 MustCheckCX: 0 000053E3 E3EB JCXZ MUSTGETWORD 0 000053E5 49 DEC CX 0 000053E6 3C2A CMP AL,"*" ; Check for ambiguous file specifier 0 000053E8 7504 JNZ NOSTAR 0 000053EA B03F MOV AL,"?" 0 000053EC F3AA REP STOSB 173 NOSTAR: 0 000053EE AA STOSB 175 176 %IF DBCS ;AN000; 177 CALL TESTKANJ ;AN000; 178 JZ NOTDUAL3 ;AN000; 179 JCXZ BNDERR ; Attempt to straddle boundry ;AN000; 180 MOVSB ; Transfer second byte ;AN000; 181 DEC CX ;AN000; 182 JMP MUSTGETWORD ;AN000; 183 BNDERR: ;AN000; 184 TEST word [ss:DOS34_FLAG],DBCS_VOLID ;AN000; 185 JZ notvolumeid ;AN000; 186 TEST word [ss:DOS34_FLAG],DBCS_VOLID2 ;AN000; 187 JNZ notvolumeid ;AN000; 188 OR word [ss:DOS34_FLAG],DBCS_VOLID2 ;AN000; 189 JMP MUSTGETWORD ;AN000; 190 191 notvolumeid: 192 ;; INC CX ; Undo the store of the first byte 193 DEC DI 194 MOV AL," " ;PTM. ;AN000; 195 STOSB ;PTM. ;AN000; 196 INC SI ;PTM. ;AN000; 197 JMP MUSTGETWORD ;PTM. ;AN000; 198 199 NOTDUAL3: ;AN000; 200 %ENDIF ;AN000; 201 0 000053EF 3C3F CMP AL,"?" 0 000053F1 75DD JNZ MUSTGETWORD 0 000053F3 80CA01 OR DL,1 ; Flag ambiguous file name 0 000053F6 EBD8 JMP MUSTGETWORD 206 FILLNAM: 0 000053F8 B020 MOV AL," " 0 000053FA F3AA REP STOSB 0 000053FC 4E DEC SI 0 000053FD C3 return 211 212 SCANB: 0 000053FE AC LODSB 0 000053FF E86300 CALL SPCHK 0 00005402 74FA JZ SCANB 216 %IF DBCS ;AN000; ;AN000; 217 CMP AL,81H ;AN000;; 1ST BYTE OF DBCS BLANK 2/18/KK ;AN000; 218 JNE SCANB_EXIT ;AN000;; 2/18/KK 3/31/KK revoved ;AN000; 219 CALL TESTKANJ ;AN000;; 2/23/KK 3/31/KK revoved ;AN000; 220 JE SCANB_EXIT ;AN000;; 2/18/KK 3/31/KK revoved ;AN000; 221 CMP BYTE PTR [SI],40H;AN000;H ; 2ND BYTE OF DBCS BLANK 2/18/KK 3/31/KK revove;AN000; 222 JNE SCANB_EXIT ;AN000;; 2/18/KK 3/31/KK revoved ;AN000; 223 INC SI ;AN000;; 2/18/KK 3/31/KK revoved ;AN000; 224 JMP SCANB ;AN000;; 2/18/KK 3/31/KK revoved ;AN000; 225 SCANB_EXIT: ;AN000;; 2/18/KK 3/31/KK revoved ;AN000; 226 %ENDIF ;AN000; 0 00005404 4E DEC SI 0 00005405 C3 return 229 EndProc MakeFCB 230 231 ; 232 ; NameTrans is used by FindPath to scan off an element of a path. We must 233 ; allow spaces in pathnames 234 ; 235 ; Inputs: DS:SI points to start of path element 236 ; Outputs: Name1 has unpacked name, uppercased 237 ; ES = DOSGroup 238 ; DS:SI advanced after name 239 ; Registers modified: DI,AX,DX,CX 240 procedure NameTrans,near 240 ****************** warning: proc NameTrans... [-w+user] 241 ASSUME DS:NOTHING,ES:NOTHING 0 00005406 36C606[0000]01 MOV BYTE PTR [ss:SpaceFlag],1 0 0000540C 1607 context ES 244 NAME1 equ Name1 ; NASM port label 0 0000540E BF[0000] MOV DI,OFFSET NAME1 wrt DOSGROUP 0 00005411 57 PUSH DI 0 00005412 B82020 MOV AX,' ' 0 00005415 B90500 MOV CX,5 0 00005418 AA STOSB 0 00005419 F3AB REP STOSW ; Fill "FCB" at NAME1 with spaces 0 0000541B 30C0 XOR AL,AL ; Set stuff for NORMSCAN 0 0000541D 88C2 MOV DL,AL 0 0000541F AA STOSB 0 00005420 5F POP DI 255 0 00005421 E87EFF CALL NORMSCAN 257 %IF DBCS ;AN000;;KK. 258 MOV AL,[ss:NAME1] ;AN000;;KK. check 1st char 259 testkanj equ TESTKANJ ; NASM port label 260 invoke testkanj ;AN000;;KK. dbcs ? 261 JZ notdbcs ;AN000;;KK. no 262 return ;AN000;;KK. yes 263 notdbcs: ;AN000; 264 %ENDIF ;AN000; 0 00005424 36803E[0000]E5 CMP byte [ss:NAME1],0E5H 0 0000542A 75D9 retnz 0 0000542C 36C606[0000]05 MOV byte [ss:NAME1],5 ; Magic name translation 0 00005432 C3 return 269 270 EndProc nametrans 271 272 Break 273 274 %If TableLook 275 276 ; NASM original macros 277 278 %push 279 280 %macro ChType 2.nolist 281 %assign %%index %1 282 detectstripangles %%token, %%opening, %%closing, %2 283 %assign tableentry%[%%index] ? %+ %%token 284 %endmacro 285 286 ChType ".", <255 & (~ ( fChk))> 287 ChType '"', <255 & (~ (fFCB+fChk))> 288 ChType "/", <255 & (~ (fFCB+fChk))> 289 ChType "\", <255 & (~ (fFCB+fChk))> 290 ChType "[", <255 & (~ (fFCB+fChk))> 291 ChType "]", <255 & (~ (fFCB+fChk))> 292 ChType ":", <255 & (~ (fFCB+fChk+fDelim))> 293 ChType "<", <255 & (~ (fFCB+fChk+fDelim))> 294 ChType "|", <255 & (~ (fFCB+fChk+fDelim))> 295 ChType ">", <255 & (~ (fFCB+fChk+fDelim))> 296 ChType "+", <255 & (~ (fFCB+fChk+fDelim))> 297 ChType "=", <255 & (~ (fFCB+fChk+fDelim))> 298 ChType ";", <255 & (~ (fFCB+fChk+fDelim))> 299 ChType ",", <255 & (~ (fFCB+fChk+fDelim))> 300 ChType 0, <255 & (~ (fFCB+fChk))> ; NUL 301 ChType 1, <255 & (~ (fFCB+fChk))> ; ^A 302 ChType 2, <255 & (~ (fFCB+fChk))> ; ^b 303 ChType 3, <255 & (~ (fFCB+fChk))> ; ^c 304 ChType 4, <255 & (~ (fFCB+fChk))> ; ^d 305 ChType 5, <255 & (~ (fFCB+fChk))> ; ^e 306 ChType 6, <255 & (~ (fFCB+fChk))> ; ^f 307 ChType 7, <255 & (~ (fFCB+fChk))> ; ^g 308 ChType 8, <255 & (~ (fFCB+fChk))> ; ^h 309 ChType 9, <255 & (~ (fFCB+fChk+fDelim+fSpChk))> ; Tab 310 ChType 10, <255 & (~ (fFCB+fChk))> ; ^j 311 ChType 11, <255 & (~ (fFCB+fChk))> ; ^k 312 ChType 12, <255 & (~ (fFCB+fChk))> ; ^l 313 ChType 13, <255 & (~ (fFCB+fChk))> ; ^m 314 ChType 14, <255 & (~ (fFCB+fChk))> ; ^n 315 ChType 15, <255 & (~ (fFCB+fChk))> ; ^o 316 ChType 16, <255 & (~ (fFCB+fChk))> ; ^p 317 ChType 17, <255 & (~ (fFCB+fChk))> ; ^q 318 ChType 18, <255 & (~ (fFCB+fChk))> ; ^r 319 ChType 19, <255 & (~ (fFCB+fChk))> ; ^s 320 ChType 20, <255 & (~ (fFCB+fChk))> ; ^t 321 ChType 21, <255 & (~ (fFCB+fChk))> ; ^u 322 ChType 22, <255 & (~ (fFCB+fChk))> ; ^v 323 ChType 23, <255 & (~ (fFCB+fChk))> ; ^w 324 ChType 24, <255 & (~ (fFCB+fChk))> ; ^x 325 ChType 25, <255 & (~ (fFCB+fChk))> ; ^y 326 ChType 26, <255 & (~ (fFCB+fChk))> ; ^z 327 ChType 27, <255 & (~ (fFCB+fChk))> ; ^[ 328 ChType 28, <255 & (~ (fFCB+fChk))> ; ^\. 329 ChType 29, <255 & (~ (fFCB+fChk))> ; ^] 330 ChType 30, <255 & (~ (fFCB+fChk))> ; ^^ 331 ChType 31, <255 & (~ (fFCB+fChk))> ; ^_ 332 ChType " ", <255 & (~ ( fChk+fDelim+fSpChk))> 333 ChType 255, -1 334 === Switch to base=008400h -> "DOSCODETABLE" 335 section DOSCODETABLE 336 PUBLIC CharType 337 Public FCB001S,FCB001E 338 FCB001S label byte 339 CharType label byte 340 341 %assign %$index 0 342 %rep 256 343 %ifndef tableentry%[%$index] 344 %assign tableentry%[%$index] 255 345 %endif 346 %assign %$index %$index + 1 347 %endrep 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 343 <1> %ifndef tableentry%[%$index] 344 <1> %assign tableentry%[%$index] 255 345 <1> %endif 346 <1> %assign %$index %$index + 1 348 349 %assign %$index 0 350 %rep 256 351 db tableentry%[%$index] 352 %assign %$index %$index + 1 353 %endrep 0 00000480 F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000481 F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000482 F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000483 F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000484 F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000485 F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000486 F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000487 F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000488 F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000489 F0 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000048A F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000048B F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000048C F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000048D F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000048E F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000048F F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000490 F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000491 F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000492 F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000493 F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000494 F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000495 F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000496 F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000497 F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000498 F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000499 F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000049A F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000049B F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000049C F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000049D F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000049E F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000049F F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004A0 F8 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004A1 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004A2 F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004A3 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004A4 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004A5 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004A6 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004A7 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004A8 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004A9 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004AA FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004AB F4 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004AC F4 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004AD FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004AE FE db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004AF F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004B0 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004B1 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004B2 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004B3 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004B4 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004B5 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004B6 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004B7 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004B8 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004B9 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004BA F4 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004BB F4 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004BC F4 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004BD F4 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004BE F4 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004BF FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004C0 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004C1 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004C2 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004C3 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004C4 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004C5 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004C6 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004C7 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004C8 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004C9 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004CA FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004CB FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004CC FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004CD FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004CE FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004CF FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004D0 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004D1 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004D2 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004D3 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004D4 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004D5 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004D6 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004D7 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004D8 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004D9 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004DA FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004DB F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004DC F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004DD F6 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004DE FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004DF FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004E0 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004E1 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004E2 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004E3 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004E4 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004E5 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004E6 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004E7 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004E8 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004E9 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004EA FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004EB FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004EC FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004ED FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004EE FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004EF FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004F0 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004F1 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004F2 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004F3 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004F4 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004F5 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004F6 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004F7 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004F8 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004F9 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004FA FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004FB FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004FC F4 db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004FD FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004FE FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 000004FF FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000500 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000501 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000502 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000503 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000504 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000505 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000506 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000507 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000508 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000509 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000050A FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000050B FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000050C FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000050D FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000050E FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000050F FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000510 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000511 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000512 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000513 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000514 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000515 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000516 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000517 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000518 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000519 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000051A FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000051B FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000051C FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000051D FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000051E FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000051F FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000520 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000521 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000522 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000523 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000524 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000525 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000526 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000527 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000528 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000529 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000052A FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000052B FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000052C FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000052D FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000052E FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000052F FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000530 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000531 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000532 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000533 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000534 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000535 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000536 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000537 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000538 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000539 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000053A FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000053B FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000053C FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000053D FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000053E FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000053F FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000540 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000541 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000542 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000543 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000544 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000545 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000546 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000547 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000548 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000549 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000054A FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000054B FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000054C FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000054D FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000054E FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000054F FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000550 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000551 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000552 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000553 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000554 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000555 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000556 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000557 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000558 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000559 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000055A FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000055B FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000055C FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000055D FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000055E FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000055F FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000560 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000561 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000562 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000563 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000564 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000565 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000566 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000567 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000568 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000569 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000056A FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000056B FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000056C FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000056D FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000056E FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000056F FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000570 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000571 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000572 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000573 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000574 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000575 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000576 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000577 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000578 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 00000579 FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000057A FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000057B FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000057C FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000057D FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000057E FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 0 0000057F FF db tableentry%[%$index] 352 <1> %assign %$index %$index + 1 354 FCB001E label byte 355 %pop 356 === Switch to base=008400h -> "DOSCODECODE" 357 section DOSCODECODE 358 359 ; end of NASM original macros 360 %ENDIF 361 ; 362 ; Get a byte from [SI], convert it to upper case, and compare for delimiter. 363 ; ZF set if a delimiter, CY set if a control character (other than TAB). 364 ; 365 ; DOS 3.3 modification for file char upper case. F.C. 5/29/86 366 procedure GetLet,NEAR 366 ****************** warning: proc GetLet... [-w+user] 0 00005433 AC LODSB 368 entry GetLet2 ;AN000;; called by uCase 0 00005434 53 PUSH BX 0 00005435 BB[0200] MOV BX,OFFSET FILE_UCASE_TAB+2 wrt DOSGROUP 371 getget: 0 00005438 3C61 CMP AL,"a" 0 0000543A 7206 JB CHK1 0 0000543C 3C7A CMP AL,"z" 0 0000543E 7702 JA CHK1 0 00005440 2C20 SUB AL,20H ; Convert to upper case 377 CHK1: 0 00005442 3C80 CMP AL,80H ; DOS 3.3 0 00005444 7205 JB GOTIT ; DOS 3.3 0 00005446 2C80 SUB AL,80H ;translate to upper case with this index 381 ; 0 00005448 E82600 call xlatb_in_dosdata 383 %If TableLook 384 GOTIT: 0 0000544B 50 PUSH AX 0 0000544C BB[0000] MOV BX,OFFSET CharType 0 0000544F 2ED7 cs xlatb 388 0 00005451 A801 TEST AL,fChk 0 00005453 58 POP AX 0 00005454 5B POP BX 0 00005455 C3 RET 393 entry GetLet3 ;AN000; called by uCase 0 00005456 53 PUSH BX ;AN000; 0 00005457 EBDF JMP getget ;AN000; 396 397 %ELSE 398 GOTIT: 399 POP BX 400 CMP AL,"." 401 retz 402 CMP AL,'"' 403 retz 404 CALL PATHCHRCMP 405 retz 406 CMP AL,"[" 407 retz 408 CMP AL,"]" 409 retz 410 %ENDIF 411 412 entry DELIM_DOS 413 414 %IF TableLook 0 00005459 50 PUSH AX 0 0000545A 53 PUSH BX 417 DOSGroup equ DOSGROUP ; NASM port equate 0 0000545B BB[0000] MOV BX,OFFSET CharType 0 0000545E 2ED7 cs xlatb 0 00005460 A802 TEST AL,fDelim 0 00005462 5B POP BX 0 00005463 58 POP AX 0 00005464 C3 RET 424 %ELSE 425 CMP AL,":" 426 retz 427 428 CMP AL,"<" 429 retz 430 CMP AL,"|" 431 retz 432 CMP AL,">" 433 retz 434 435 CMP AL,"+" 436 retz 437 CMP AL,"=" 438 retz 439 CMP AL,";" 440 retz 441 CMP AL,"," 442 retz 443 %ENDIF 444 entry SPCHK 445 %IF TableLook 0 00005465 50 PUSH AX 0 00005466 53 PUSH BX 0 00005467 BB[0000] MOV BX,OFFSET CharType 0 0000546A 2ED7 CS xlatb 0 0000546C A804 TEST AL,fSpChk 0 0000546E 5B POP BX 0 0000546F 58 POP AX 0 00005470 C3 RET 454 %ELSE 455 CMP AL,9 ; Filter out tabs too 456 retz 457 ; WARNING! " " MUST be the last compare 458 CMP AL," " 459 return 460 %ENDIF 461 EndProc GetLet 462 463 464 xlatb_in_dosdata: 0 00005471 1E push ds 466 extern doscode_getdosdata 467 0 00005472 50 push ax 0 00005473 E8[0000] call doscode_getdosdata 0 00005476 8ED8 mov ds, ax 0 00005478 58 pop ax 472 0 00005479 D7 xlatb 0 0000547A 1F pop ds 0 0000547B C3 retn 476 477 478 Procedure PATHCHRCMP,NEAR 478 ****************** warning: proc PATHCHRCMP... [-w+user] 0 0000547C 3C2F CMP AL,'/' 0 0000547E 7606 JBE PathRet 0 00005480 3C5C CMP AL,'\' 0 00005482 C3 return 483 GotFor: 0 00005483 B05C MOV AL,'\' 0 00005485 C3 return 486 PathRet: 0 00005486 74FB JZ GotFor 0 00005488 C3 return 489 EndProc PathChrCMP 490 491 492 %IF DBCS 493 ;--------------------- 2/12/KK 494 ; Function: Check if an input byte is in the ranges of DBCS vectors. 495 ; 496 ; Input: AL ; Code to be examined 497 ; 498 ; Output: ZF = 1 : AL is SBCS ZF = 0 : AL is a DBCS leading byte 499 ; 500 ; Register: All registers are unchanged except FL 501 ; 502 procedure TESTKANJ,NEAR ;AN000; 503 call Chk_DBCS ;AN000; 504 jc TK_DBCS ;AN000; 505 cmp AL,AL ; set ZF ;AN000; 506 return ;AN000; 507 TK_DBCS: 508 PUSH AX ;AN000; 509 XOR AX,AX ;Set ZF ;AN000; 510 INC AX ;Reset ZF ;AN000; 511 POP AX ;AN000; 512 return ;AN000; 513 EndProc TESTKANJ ;AN000; 514 ; 515 Chk_DBCS PROC ;AN000; 516 PUSH DS ;AN000; 517 PUSH SI ;AN000; 518 PUSH BX ;AN000; 519 Context DS ;AN000; 520 MOV BX,offset COUNTRY_CDPG + ccSetDBCS wrt DOSGROUP ;AN000; 521 LDS SI,[BX+1] ; set EV address to DS:SI ;AN000; 522 ADD SI,2 ; Skip length ;AN000; 523 DBCS_LOOP: 524 CMP WORD PTR [SI],0 ; terminator ? ;AN000; 525 JE NON_DBCS ; if yes, no DBCS ;AN000; 526 CMP AL,[SI] ; else ;AN000; 527 JB DBCS01 ; check if AL is ;AN000; 528 CMP AL,[SI+1] ; in a range of Ev ;AN000; 529 JA DBCS01 ; if yes, DBCS ;AN000; 530 STC ; else ;AN000; 531 JMP DBCS_EXIT ; try next DBCS Ev ;AN000; 532 DBCS01: 533 ADD SI,2 ;AN000; 534 JMP DBCS_LOOP ;AN000; 535 NON_DBCS: 536 CLC ;AN000; 537 DBCS_EXIT: 538 POP BX ;AN000; 539 POP SI ;AN000; 540 POP DS ;AN000; 541 RET ;AN000; 542 Chk_DBCS ENDP ;AN000; 543 %ENDIF ;AN000; 544 END 545 ;AN000; === Trace listing source: ../DOS/msctrlc.lst 1 ; SCCSID = @(#)ibmctrlc.asm 1.1 85/04/10 2 ; 3 ; ^C and error handler for MSDOS 4 ; 5 6 [list -] 6 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 13 14 ;TITLE Control C detection, Hard error and EXIT routines 15 ;NAME IBMCTRLC 16 17 ;=== Push trace listing source: ctrlc.nas 18 %include "ctrlc.nas" ; NASM included file 1 <1> ; SCCSID = @(#)ctrlc.asm 1.4 85/08/16 2 <1> ; Low level routines for detecting special characters on CON input, 3 <1> ; the ^C exit/int code, the Hard error INT 24 code, the 4 <1> ; process termination code, and the INT 0 divide overflow handler. 5 <1> ; 6 <1> ; FATAL 7 <1> ; FATAL1 8 <1> ; reset_environment 9 <1> ; DSKSTATCHK 10 <1> ; SPOOLINT 11 <1> ; STATCHK 12 <1> ; CNTCHAND 13 <1> ; DIVOV 14 <1> ; CHARHARD 15 <1> ; HardErr_DOS 16 <1> ; 17 <1> ; Revision history: 18 <1> ; 19 <1> ; AN000 version 4.0 Jan 1988 20 <1> ; A002 PTM -- dir >lpt3 hangs 21 <1> ; A003 PTM 3957- fake version for IBMCAHE.COM 22 <1> 23 <1> ; 24 <1> ; get the appropriate segment definitions 25 <1> ; 26 <1> [list -] === Switch to base=008400h -> "DOSCODECODE" 30 <1> section DOSCODECODE 31 <1> [list -] 31 ****************** <1> warning: out: ... for DOS Version 4.00 ... [-w+user] 31 ****************** <1> warning: out: BPB.INC... [-w+user] 31 ****************** <1> warning: out: ... CLONE version build switch on ... [-w+user] 31 ****************** <1> warning: out: DEVSYM.INC... [-w+user] 31 ****************** <1> warning: out: ... CLONE version build switch on ... [-w+user] 39 <1> 40 <1> I_need SFN,WORD 41 <1> I_NEED pJFN,DWORD 42 <1> i_need DevIOBuf,BYTE 43 <1> i_need DidCTRLC,BYTE 44 <1> i_need INDOS,BYTE 45 <1> i_need DSKSTCOM,BYTE 46 <1> i_need DSKSTCALL,BYTE 47 <1> i_need DSKSTST,WORD 48 <1> i_need BCON,DWORD 49 <1> i_need DSKCHRET,BYTE 50 <1> i_need DSKSTCNT,WORD 51 <1> i_need IDLEINT,BYTE 52 <1> i_need CONSWAP,BYTE 53 <1> i_need user_SS,WORD 54 <1> i_need user_SP,WORD 55 <1> i_need User_In_AX,WORD 56 <1> i_need ERRORMODE,BYTE 57 <1> i_need ConC_spsave,WORD 58 <1> i_need Exit_type,BYTE 59 <1> i_need PFLAG,BYTE 60 <1> i_need ExitHold,DWORD 61 <1> i_need WPErr,BYTE 62 <1> i_need ReadOp,BYTE 63 <1> i_need CONTSTK,WORD 64 <1> i_need Exit_Code,WORD 65 <1> i_need CurrentPDB,WORD 66 <1> i_need DIVMES,BYTE 67 <1> i_need DivMesLen,WORD 68 <1> i_need ALLOWED,BYTE 69 <1> i_need FAILERR,BYTE 70 <1> i_need EXTERR,WORD 71 <1> i_need ERR_TABLE_24,BYTE 72 <1> I_need ErrMap24,BYTE 73 <1> I_need ErrMap24End,BYTE 74 <1> I_need fAborting,BYTE 75 <1> I_need AUXStack,BYTE 76 <1> I_need SCAN_FLAG,BYTE 77 <1> I_need EXTOPEN_ON,BYTE ;AN000; DOS 4.0 78 <1> I_need InterCon,BYTE ;AN000; DOS 4.0 79 <1> I_need DOS34_FLAG,WORD ;AN000; DOS 4.0 80 <1> %ifndef BUF2 81 <1> I_need ACT_PAGE,WORD ;AN000; DOS 4.0 82 <1> %endif 83 <1> I_need Special_Version,WORD ;AN007; DOS 4.0 84 <1> %if debug 85 <1> I_need BugLev,WORD 86 <1> I_need BugTyp,WORD 87 <1> %include "bugtyp.nas" 88 <1> %endif 89 <1> %ifndef BUF2 90 <1> %IF BUFFERFLAG 91 <1> extrn restore_user_map:near 92 <1> %ENDIF 93 <1> %endif 94 <1> 95 <1> Break 96 <1> 97 <1> ASSUME DS:NOTHING,ES:NOTHING 98 <1> 99 <1> procedure DSKSTATCHK,NEAR ; Check for ^C if only one level in 99 ****************** <1> warning: proc DSKSTATCHK... [-w+user] 0 00005489 36803E[0000]01 CMP BYTE PTR [ss:INDOS],1 0 0000548F 7401C3 retnz ; Do NOTHING 0 00005492 51 PUSH CX 0 00005493 06 PUSH ES 0 00005494 53 PUSH BX 0 00005495 1E PUSH DS 0 00005496 56 PUSH SI 0 00005497 16 PUSH ss 0 00005498 07 POP ES 0 00005499 161F Context DS 110 <1> DOSAssume CS,,"DskStatChk" 0 0000549B C606[0000]05 MOV BYTE PTR [DSKSTCOM],DEVRDND 0 000054A0 C606[0000]0E MOV BYTE PTR [DSKSTCALL],DRDNDHL 0 000054A5 C706[0000]0000 MOV word [DSKSTST],0 114 <1> %IF DBCS ;AN000; 115 <1> MOV AL, [InterCon] ;AN000;get type of status read 2/13/KK 116 <1> MOV BYTE PTR [DSKCHRET],AL ;AN000; load interim flag into packet 117 <1> %ENDIF ;AN000; 0 000054AB BB[0000] MOV BX,OFFSET DSKSTCALL wrt DOSGROUP 0 000054AE C536[0000] LDS SI,[BCON] 120 <1> ASSUME DS:NOTHING 0 000054B2 E8[0000] invoke DEVIOCALL2 0 000054B5 36F706[0000]0002 TEST word [ss:DSKSTST],STBUI 0 000054BC 7408 JZ GotCh ; No characters available 0 000054BE 30C0 XOR AL,AL ; Set zero 125 <1> RET36: 0 000054C0 5E POP SI 0 000054C1 1F POP DS 0 000054C2 5B POP BX 0 000054C3 07 POP ES 0 000054C4 59 POP CX 0 000054C5 C3 return 132 <1> 133 <1> GotCh: 0 000054C6 36A0[0000] MOV AL,BYTE PTR [ss:DSKCHRET] 135 <1> DSK1: 0 000054CA 3C03 CMP AL,"C"-"@" 0 000054CC 75F2 JNZ RET36 0 000054CE 36C606[0000]04 MOV BYTE PTR [ss:DSKSTCOM],DEVRD 0 000054D4 36C606[0000]16 MOV BYTE PTR [ss:DSKSTCALL],DRDWRHL 0 000054DA 36880E[0000] MOV BYTE PTR [ss:DSKCHRET],CL 0 000054DF 36C706[0000]0000 MOV word [ss:DSKSTST],0 0 000054E6 36C706[0000]0100 MOV word [ss:DSKSTCNT],1 0 000054ED E8[0000] invoke DEVIOCALL2 ; Eat the ^C 0 000054F0 5E POP SI 0 000054F1 1F POP DS 0 000054F2 5B POP BX ; Clean stack 0 000054F3 07 POP ES 0 000054F4 59 POP CX 0 000054F5 E9C200 JMP CNTCHAND 150 <1> 151 <1> NOSTOP: 0 000054F8 3C10 CMP AL,"P"-"@" 0 000054FA 7509 JNZ check_next 0 000054FC 36803E[0000]00 CMP BYTE PTR [ss:SCAN_FLAG],0 ; ALT_Q ? 0 00005502 7406 JZ INCHKJ ; no 0 00005504 C3 return 157 <1> check_next: 158 <1> %IFN TOGLPRN 159 <1> CMP AL,"N"-"@" 160 <1> JZ INCHKJ 161 <1> %ENDIF 162 <1> 0 00005505 3C03 CMP AL,"C"-"@" 0 00005507 7401 JZ INCHKJ 165 <1> check_end: 0 00005509 C3 return 167 <1> 168 <1> INCHKJ: 0 0000550A E99700 JMP INCHK 170 <1> 171 <1> EndProc DSKSTATCHK 172 <1> 173 <1> ; 174 <1> ; SpoolInt - signal processes that the DOS is truly idle. We are allowed to 175 <1> ; do this ONLY if we are working on a 1-12 system call AND if we are not in 176 <1> ; the middle of an INT 24. 177 <1> ; 178 <1> procedure SPOOLINT,NEAR 178 ****************** <1> warning: proc SPOOLINT... [-w+user] 0 0000550D 9C PUSHF 180 <1> IdleInt equ IDLEINT ; NASM port label 0 0000550E 36F606[0000]FF test byte [ss:IdleInt],-1 182 <1> POPFRet equ POPFRET ; NASM port label 0 00005514 7414 jz POPFRet 184 <1> ErrorMode equ ERRORMODE ; NASM port label 0 00005516 36F606[0000]FF test byte [ss:ErrorMode],-1 0 0000551C 750C jnz POPFRet 187 <1> ; 188 <1> ; Note that we are going to allow an external program to issue system calls 189 <1> ; at this time. We MUST preserve IdleInt across this. 190 <1> ; 0 0000551E 36FF36[0000] PUSH WORD [ss:IdleInt] 0 00005523 CD28 INT int_spooler 0 00005525 368F06[0000] POP WORD [ss:IdleInt] 194 <1> POPFRET: 0 0000552A 9D POPF 0 0000552B C3 return 197 <1> EndProc SPOOLINT 198 <1> 199 <1> procedure STATCHK,NEAR 199 ****************** <1> warning: proc STATCHK... [-w+user] 200 <1> 0 0000552C E85AFF invoke DSKSTATCHK ; Allows ^C to be detected under 202 <1> ; input redirection 0 0000552F 53 PUSH BX 0 00005530 31DB XOR BX,BX 0 00005532 E8[0000] invoke GET_IO_SFT 0 00005535 5B POP BX 0 00005536 72F3 retc 0 00005538 B401 MOV AH,1 0 0000553A E8[0000] invoke IOFUNC 0 0000553D 74CE JZ SPOOLINT 0 0000553F 3C13 CMP AL,"S"-"@" 0 00005541 75B5 JNZ NOSTOP 213 <1> 0 00005543 36803E[0000]00 CMP BYTE PTR [ss:SCAN_FLAG],0 ;AN000; ALT_R ? 0 00005549 75BE JNZ check_end ;AN000; yes 0 0000554B 30E4 XOR AH,AH 0 0000554D E8[0000] invoke IOFUNC ; Eat Cntrl-S 0 00005550 EB4B JMP SHORT PAUSOSTRT 219 <1> PRINTOFF: 220 <1> PRINTON: 0 00005552 36F616[0000] NOT BYTE PTR [ss:PFLAG] 0 00005557 53 PUSH BX 0 00005558 BB0400 MOV BX,4 0 0000555B E8[0000] invoke GET_IO_SFT 0 0000555E 5B POP BX 0 0000555F 72CA retc 0 00005561 06 PUSH ES 0 00005562 57 PUSH DI 0 00005563 1E PUSH DS 0 00005564 07 POP ES 0 00005565 89F7 MOV DI,SI ; ES:DI -> SFT 0 00005567 26F745050008 TEST word [ES:DI + sf_flags],sf_net_spool 0 0000556D 7418 JZ NORM_PR ; Not redirected, echo is OK 234 <1> MultNet equ MultNET ; NASM port equate 0 0000556F 50B82611CD2F58 Callinstall NetSpoolEchoCheck,MultNet,38,, ; See if allowed 0 00005576 730F JNC NORM_PR ; Echo is OK 0 00005578 36C606[0000]00 MOV BYTE PTR [ss:PFLAG],0 ; If not allowed, disable echo 0 0000557E 50B82411CD2F58 Callinstall NetSpoolClose,MultNet,36,, ; and close 0 00005585 EB10 JMP SHORT RETP6 240 <1> 241 <1> NORM_PR: 0 00005587 36803E[0000]00 CMP BYTE PTR [ss:PFLAG],0 0 0000558D 7505 JNZ PRNOPN 0 0000558F E8[0000] invoke DEV_CLOSE_SFT 0 00005592 EB03 JMP SHORT RETP6 246 <1> 247 <1> PRNOPN: 0 00005594 E8[0000] invoke DEV_OPEN_SFT 249 <1> RETP6: 0 00005597 5F POP DI 0 00005598 07 POP ES 0 00005599 C3 return 253 <1> 254 <1> PAUSOLP: 0 0000559A E870FF CALL SPOOLINT 256 <1> PAUSOSTRT: 0 0000559D B401 MOV AH,1 0 0000559F E8[0000] invoke IOFUNC 0 000055A2 74F6 JZ PAUSOLP 260 <1> INCHK: 0 000055A4 53 PUSH BX 0 000055A5 31DB XOR BX,BX 0 000055A7 E8[0000] invoke GET_IO_SFT 0 000055AA 5B POP BX 0 000055AB 72EC retc 0 000055AD 30E4 XOR AH,AH 0 000055AF E8[0000] invoke IOFUNC 0 000055B2 3C10 CMP AL,"P"-"@" 269 <1> ;;;;; 7/14/86 ALT_Q key fix 270 <1> 0 000055B4 749C JZ PRINTON ; no! must be CTRL_P 272 <1> 273 <1> NOPRINT: 274 <1> ;;;;; 7/14/86 ALT_Q key fix 275 <1> %IFN TOGLPRN 276 <1> CMP AL,"N"-"@" 277 <1> JZ PRINTOFF 278 <1> %ENDIF 0 000055B6 3C03 CMP AL,"C"-"@" 0 000055B8 75DF retnz 281 <1> EndProc STATCHK 282 <1> 283 <1> procedure CNTCHAND,NEAR 283 ****************** <1> warning: proc CNTCHAND... [-w+user] 284 <1> ; Ctrl-C handler. 285 <1> ; "^C" and CR/LF is printed. Then the user registers are restored and the 286 <1> ; user CTRL-C handler is executed. At this point the top of the stack has 1) 287 <1> ; the interrupt return address should the user CTRL-C handler wish to allow 288 <1> ; processing to continue; 2) the original interrupt return address to the code 289 <1> ; that performed the function call in the first place. If the user CTRL-C 290 <1> ; handler wishes to continue, it must leave all registers unchanged and RET 291 <1> ; (not IRET) with carry CLEAR. If carry is SET then an terminate system call 292 <1> ; is simulated. 0 000055BA 36F706[0000]0002 TEST word [ss:DOS34_FLAG],CTRL_BREAK_FLAG ;AN002; from RAWOUT 0 000055C1 7508 JNZ around_deadlock ;AN002; 0 000055C3 B003 MOV AL,3 ; Display "^C" 0 000055C5 E8[0000] invoke BUFOUT 0 000055C8 E8[0000] invoke CRLF 298 <1> around_deadlock: ;AN002; 0 000055CB 161F Context DS 0 000055CD 803E[0000]00 CMP BYTE PTR [CONSWAP],0 0 000055D2 7403 JZ NOSWAP 0 000055D4 E8[0000] invoke SWAPBACK 303 <1> NOSWAP: 0 000055D7 FA CLI ; Prepare to play with stack 0 000055D8 8E16[0000] MOV SS,[user_SS] ; User stack now restored 306 <1> ASSUME SS:NOTHING 0 000055DC 8B26[0000] MOV SP,[user_SP] 0 000055E0 E8[0000] invoke restore_world ; User registers now restored 309 <1> ASSUME DS:NOTHING 0 000055E3 53 push bx 0 000055E4 53 push bx 0 000055E5 BB[0000] mov bx, .next 313 <1> extern transfer_doscode_to_dosdata 0 000055E8 E9[0000] jmp transfer_doscode_to_dosdata 315 <1> === Switch to base=001140h -> "DOSDATACODE" 316 <1> section DOSDATACODE ; in DOSDATA 317 <1> .next: 0 0000127F 83C406 add sp, 6 ; discard retn & retf addresses 319 <1> 0 00001282 2EC606[0000]00 MOV BYTE PTR [cs:INDOS],0 ; Go to known state 0 00001288 2EC606[0000]00 MOV BYTE PTR [cs:ERRORMODE],0 0 0000128E 2E8926[0000] MOV [cs:ConC_spsave],SP ; save his SP 0 00001293 F8 CLC 0 00001294 CD23 INT int_ctrl_c ; Execute user Ctrl-C handler 325 <1> ; 326 <1> ; The user has returned to us. The circumstances we allow are: 327 <1> ; 328 <1> ; IRET We retry the operation by redispatching the system call 329 <1> ; CLC/RETF POP the stack and retry 330 <1> ; ... Exit the current process with ^C exit 331 <1> ; 332 <1> ; User's may RETURN to us and leave interrupts on. Turn 'em off just to be 333 <1> ; sure 334 <1> ; 0 00001296 FA CLI 336 <1> user_IN_AX equ User_In_AX ; NASM port label 0 00001297 2EA3[0000] MOV [cs:user_IN_AX],ax ; save the AX 0 0000129B 9C PUSHF ; and the flags (maybe new call) 0 0000129C 58 POP AX 340 <1> ; 341 <1> ; See if the input stack is identical to the output stack 342 <1> ; 0 0000129D 2E3B26[0000] CMP SP,[cs:ConC_spsave] 0 000012A2 7506 JNZ ctrlc_try_new ; current SP not the same as saved SP 345 <1> ; 346 <1> ; Repeat the operation by redispatching the system call. 347 <1> ; 348 <1> ctrlc_repeat: 0 000012A4 2EA1[0000] MOV AX,[cs:User_In_AX] 0 000012A8 EB11 jmp ctrlc_transfer_COMMAMD 351 <1> ; 352 <1> ; The current SP is NOT the same as the input SP. Presume that he RETF'd 353 <1> ; leaving some flags on the stack and examine the input 354 <1> ; 355 <1> ctrlc_try_new: 0 000012AA 83C402 ADD SP,2 ; pop those flags 357 <1> f_carry equ f_Carry ; NASM port equate 0 000012AD A90100 TEST AX,f_carry ; did he return with carry? 359 <1> Ctrlc_Repeat equ ctrlc_repeat ; NASM port label 0 000012B0 74F2 JZ Ctrlc_Repeat ; no carry set, just retry 361 <1> ; 362 <1> ; Well... time to abort the user. Signal a ^C exit and use the EXIT system 363 <1> ; call.. 364 <1> ; 365 <1> ctrlc_abort: 366 <1> EXIT equ Exit ; NASM port equate 0 000012B2 B8004C MOV AX,(EXIT << 8) + 0 0 000012B5 2EC606[0000]FF MOV byte [cs:DidCTRLC],-1 369 <1> ; give up by faking $EXIT 370 <1> 371 <1> extern dosdata_to_doscode 372 <1> 373 <1> ctrlc_transfer_COMMAMD: 0 000012BB 50 push ax 0 000012BC 2EFF36[0000] push word [cs:dosdata_to_doscode] 0 000012C1 B8[6201] mov ax, .next 0 000012C4 50 push ax 0 000012C5 CB retf 379 <1> === Switch to base=008400h -> "DOSCODECODE" 380 <1> section DOSCODECODE 381 <1> 382 <1> .next: 0 000055EB 58 pop ax 0 000055EC E9[0000] transfer COMMAND 385 <1> 386 <1> EndProc CNTCHAND 387 <1> 388 <1> === Switch to base=008400h -> "DOSCODECODE" 389 <1> section DOSCODECODE 390 <1> 391 <1> extern doscode_getdosdata 392 <1> 393 <1> relocated i00 0 000055EF 50 push ax 0 000055F0 E8[0000] call doscode_getdosdata 0 000055F3 50 push ax 0 000055F4 B8[4700] mov ax, DIVOV 0 000055F7 50 push ax 0 000055F8 CB retf 400 <1> 401 <1> === Switch to base=001140h -> "DOSDATACODE" 402 <1> section DOSDATACODE ; in DOSDATA 403 <1> 404 <1> Break 405 <1> 406 <1> ; Default handler for division overflow trap 407 <1> procedure DIVOV,NEAR 407 ****************** <1> warning: proc DIVOV... [-w+user] 408 <1> ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING 0 000012C6 2E8E06[0000] mov es, [cs:dosdata_to_doscode] 0 000012CB BE[0000] MOV SI,OFFSET DIVMES 0 000012CE 268B1E[0000] MOV BX,[es:DivMesLen] 0 000012D3 8CC8 MOV AX,CS 0 000012D5 8ED0 MOV SS,AX 414 <1> AUXSTACK equ AUXStack ; NASM port label 0 000012D7 BC[0000] MOV SP,OFFSET AUXSTACK wrt DOSGROUP ; Enough stack for interrupts 0 000012DA E80200 CALL OutMes 0 000012DD EBD3 JMP ctrlc_abort ; Use Ctrl-C abort on divide overflow 418 <1> EndProc DIVOV 419 <1> 420 <1> ; 421 <1> ; OutMes: perform message output 422 <1> ; Inputs: SS:SI points to message 423 <1> ; BX has message length 424 <1> ; Outputs: message to BCON 425 <1> ; 426 <1> procedure OutMes,NEAR 426 ****************** <1> warning: proc OutMes... [-w+user] 427 <1> 0 000012DF 161F Context DS ; get DS addressability 429 <1> 430 <1> DskStCom equ DSKSTCOM ; NASM port label 431 <1> DevWrt equ DEVWRT ; NASM port equate 0 000012E1 C606[0000]08 MOV BYTE PTR [DskStCom],DevWrt 433 <1> DskStCall equ DSKSTCALL ; NASM port label 434 <1> DRdWrHL equ DRDWRHL ; NASM port equate 0 000012E6 C606[0000]16 MOV BYTE PTR [DskStCall],DRdWrHL 436 <1> DskSTST equ DSKSTST ; NASM port label 0 000012EB C706[0000]0000 MOV word [DskSTST],0 438 <1> DskStCnt equ DSKSTCNT ; NASM port label 0 000012F1 891E[0000] MOV [DskStCnt],BX 0 000012F5 BB[0000] MOV BX,OFFSET DskStCall wrt DOSGROUP 441 <1> DskChRet equ DSKCHRET ; NASM port label 0 000012F8 8936[0100] MOV WORD PTR [DskChRet+1],SI ; transfer address (need an EQU) 0 000012FC 8C06[0300] MOV WORD PTR [DskChRet+3], es 0 00001300 C536[0000] LDS SI,[BCON] 445 <1> ASSUME DS:NOTHING 0 00001304 0E push cs ; allow far return 0 00001305 E81400 call int0_transfer_deviocall2 0 00001308 36C706[0100][0000] MOV WORD PTR [ss:DskChRet+1], OFFSET DevIOBuf wrt DOSGROUP 0 0000130F 368C16[0300] MOV WORD PTR [ss:DskChRet+3], ss 0 00001314 36C706[0000]0100 MOV word [ss:DskStCnt],1 0 0000131B C3 return 452 <1> EndProc OutMes 453 <1> 454 <1> 455 <1> int0_transfer_deviocall2: 0 0000131C 06 push es 0 0000131D B8[7001] mov ax, .next 0 00001320 50 push ax 0 00001321 1607 Context ES ; get ES addressability 0 00001323 CB retf ; branch into DOSCODE 461 <1> === Switch to base=008400h -> "DOSCODECODE" 462 <1> section DOSCODECODE 463 <1> 464 <1> .next: 0 000055F9 E8[0000] invoke DEVIOCALL2 ; call routine 0 000055FC CB retf ; return back to code in DOSDATA 467 <1> 468 <1> 469 <1> Break 470 <1> 471 <1> procedure CHARHARD,NEAR 471 ****************** <1> warning: proc CHARHARD... [-w+user] 472 <1> ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP 473 <1> 474 <1> ; Character device error handler 475 <1> ; Same function as HARDERR_DOS 476 <1> 477 <1> allowed_FAIL equ Allowed_FAIL ; NASM port equate 478 <1> allowed_IGNORE equ Allowed_IGNORE ; NASM port equate 479 <1> allowed_RETRY equ Allowed_RETRY ; NASM port equate 0 000055FD 80CC38 OR AH,allowed_FAIL + allowed_IGNORE + allowed_RETRY 481 <1> Allowed equ ALLOWED ; NASM port label 0 00005600 368826[0000] MOV [ss:Allowed],AH 483 <1> EXITHOLD equ ExitHold ; NASM port label 0 00005605 368C06[0200] MOV WORD PTR [ss:EXITHOLD+2],ES 0 0000560A 36892E[0000] MOV WORD PTR [ss:EXITHOLD],BP 0 0000560F 56 PUSH SI 0 00005610 81E7FF00 AND DI,STECODE 0 00005614 8CDD MOV BP,DS ; Device pointer is BP:SI 0 00005616 E86400 CALL FATALC 0 00005619 5E POP SI 0 0000561A C3 return 492 <1> EndProc CHARHARD 493 <1> 494 <1> ; Hard disk error handler. Entry conditions: 495 <1> ; DS:BX = Original disk transfer address 496 <1> ; DX = Original logical sector number 497 <1> ; CX = Number of sectors to go (first one gave the error) 498 <1> ; AX = Hardware error code 499 <1> ; DI = Original sector transfer count 500 <1> ; ES:BP = Base of drive parameters 501 <1> ; [READOP] = 0 for read, 1 for write 502 <1> ; [ALLOWED] Set with allowed responses to this error (other bits MUST BE 0) 503 <1> ; Output: 504 <1> ; [FAILERR] will be set if user responded FAIL 505 <1> 506 <1> procedure HardErr_DOS,NEAR 506 ****************** <1> warning: proc HardErr_DOS... [-w+user] 507 <1> ASSUME DS:NOTHING,ES:NOTHING 508 <1> 0 0000561B 97 XCHG AX,DI ; Error code in DI, count in AX 0 0000561C 81E7FF00 AND DI,STECODE ; And off status bits 0 00005620 83FF00 CMP DI,error_I24_write_protect ; Write Protect Error? 0 00005623 750A JNZ NOSETWRPERR 0 00005625 50 PUSH AX 0 00005626 268A4600 MOV AL,[ES:BP + dpb_drive] 515 <1> WPERR equ WPErr ; NASM port label 0 0000562A 36A2[0000] MOV BYTE PTR [ss:WPERR],AL ; Flag drive with WP error 0 0000562E 58 POP AX 518 <1> NOSETWRPERR: 0 0000562F 29C8 SUB AX,CX ; Number of sectors successfully transferred 0 00005631 01C2 ADD DX,AX ; First sector number to retry 0 00005633 52 PUSH DX 0 00005634 26F76602 MUL word [ES:BP + dpb_sector_size] ; Number of bytes transferred 0 00005638 5A POP DX 0 00005639 01C3 ADD BX,AX ; First address for retry 0 0000563B 30E4 XOR AH,AH ; Flag disk section in error 0 0000563D 263B5606 CMP DX,[ES:BP + dpb_first_FAT] ; In reserved area? 0 00005641 721A JB ERRINT 0 00005643 FEC4 INC AH ; Flag for FAT 0 00005645 263B5611 CMP DX,[ES:BP + dpb_dir_sector] ; In FAT? 0 00005649 7308 JAE TESTDIR ; No 0 0000564B 26C7461FFFFF MOV word [ES:BP + dpb_free_cnt],-1 ; Err in FAT must force recomp of freespace 0 00005651 EB0A JMP SHORT ERRINT 533 <1> 534 <1> TESTDIR: 0 00005653 FEC4 INC AH 0 00005655 263B560B CMP DX,[ES:BP + dpb_first_sector] ; In directory? 0 00005659 7202 JB ERRINT 0 0000565B FEC4 INC AH ; Must be in data area 539 <1> ERRINT: 0 0000565D D0E4 SHL AH,1 ; Make room for read/write bit 541 <1> READOP equ ReadOp ; NASM port label 0 0000565F 360A26[0000] OR AH,BYTE PTR [ss:READOP] ; Set bit 0 543 <1> ; If we have a write protect error when writing on a critical area on disk, 544 <1> ; do not allow a retry as this may write out garbage on any subsequent disk. 545 <1> ;test ah,1 546 <1> ;jz Not_Crit 547 <1> ;cmp ah,5 548 <1> ;ja Not_Crit 549 <1> ;and [ALLOWED],NOT Allowed_RETRY 550 <1> Not_Crit: 0 00005664 360A26[0000] OR AH,[ss:ALLOWED] ; Set the allowed_ bits 552 <1> entry FATAL 0 00005669 268A4600 MOV AL,[ES:BP + dpb_drive] ; Get drive number 554 <1> entry FATAL1 0 0000566D 368C06[0200] MOV WORD PTR [ss:EXITHOLD+2],ES 0 00005672 36892E[0000] MOV WORD PTR [ss:EXITHOLD],BP ; The only things we preserve 0 00005677 26C47613 LES SI,[ES:BP + dpb_driver_addr] 0 0000567B 8CC5 MOV BP,ES ; BP:SI points to the device involved 559 <1> ; 560 <1> ; DI has the INT-24-style extended error. We now map the error code for this 561 <1> ; into the normalized get extended error set by using the ErrMap24 table as an 562 <1> ; translate table. Note that we translate ONLY the device returned codes and 563 <1> ; leave all others beyond the look up table alone. 564 <1> ; 565 <1> FATALC: 0 0000567D E88C01 call SET_I24_EXTENDED_ERROR 0 00005680 83FF0C CMP DI,error_I24_gen_failure 0 00005683 7603 JBE GOT_RIGHT_CODE ; Error codes above gen_failure get 0 00005685 BF0C00 MOV DI,error_I24_gen_failure ; mapped to gen_failure. Real codes 570 <1> ; Only come via GetExtendedError 571 <1> 572 <1> entry NET_I24_ENTRY 573 <1> ; Entry point used by REDIRector on Network I 24 errors. 574 <1> ; 575 <1> ; ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP 576 <1> ; 577 <1> ; ALL I 24 regs set up. ALL Extended error info SET. ALLOWED Set. 578 <1> ; EXITHOLD set for restore of ES:BP. 579 <1> 580 <1> GOT_RIGHT_CODE: 0 00005688 36803E[0000]00 CMP BYTE PTR [ss:ERRORMODE],0 ; No INT 24s if already INT 24 0 0000568E 7405 JZ NoSetFail 0 00005690 B003 MOV AL,3 584 <1> FailRet equ FAILRET ; NASM port label 0 00005692 EB68 JMP FailRet 0 00005694 90 nop ; identicalise 587 <1> NoSetFail: 0 00005695 368926[0000] MOV [ss:CONTSTK],SP 0 0000569A 1607 Context ES 590 <1> fmt TypINT24,LevLog,<"INT 24: AX = $x DI = $x\n">, 591 <1> ; 592 <1> ; Wango!!! We may need to free some user state info... In particular, we 593 <1> ; may have locked down a JFN for a user and he may NEVER return to us. Thus, 594 <1> ; we need to free it here and then reallocate it when we come back. 595 <1> ; 0 0000569C 36833E[0000]FF CMP word [ss:SFN],-1 0 000056A2 740C JZ NoFree 0 000056A4 1E56 SaveReg 0 000056A6 36C536[0000] LDS SI,[ss:pJFN] 0 000056AB C604FF MOV BYTE PTR [SI],0FFH 0 000056AE 5E1F RestoreReg 602 <1> NoFree: 0 000056B0 FA CLI ; Prepare to play with stack 0 000056B1 36FE06[0000] INC BYTE PTR [ss:ERRORMODE] ; Flag INT 24 in progress 0 000056B6 36FE0E[0000] DEC BYTE PTR [ss:INDOS] ; INT 24 handler might not return 606 <1> ;; Extneded Open hooks 0 000056BB 36F706[0000]2000 TEST word [ss:DOS34_FLAG],Force_I24_Fail ;AN000;IFS. form IFS Call Back ;AN000; 0 000056C2 7508 JNZ faili24 ;AN000;IFS. ;AN000; 609 <1> EXT_OPEN_I24_OFF equ ext_open_I24_off ; NASM port equate 0 000056C4 36F606[0000]02 TEST byte [ss:EXTOPEN_ON],EXT_OPEN_I24_OFF ;AN000;IFS.I24 error disabled ;AN000; 0 000056CA 7405 JZ i24yes ;AN000;IFS.no ;AN000; 612 <1> faili24: ;AN000; 0 000056CC B003 MOV AL,3 ;AN000;IFS.fake fail ;AN000; 0 000056CE EB1B JMP passi24 ;AN000;IFS.exit ;AN000; 0 000056D0 90 nop ; identicalise 616 <1> i24yes: ;AN000; 617 <1> 618 <1> ;; Extended Open hooks 0 000056D1 368E16[0000] MOV SS,[ss:user_SS] 620 <1> ASSUME SS:NOTHING 0 000056D6 268B26[0000] MOV SP,[ES:user_SP] ; User stack pointer restored 0 000056DB CD24 INT int_fatal_abort ; Fatal error interrupt vector, must preserve ES 0 000056DD 268926[0000] MOV [ES:user_SP],SP ; restore our stack 0 000056E2 268C16[0000] MOV [ES:user_SS],SS 0 000056E7 8CC5 MOV BP,ES 0 000056E9 8ED5 MOV SS,BP 627 <1> ASSUME SS:DOSGROUP 628 <1> passi24: ;AN000; 0 000056EB 368B26[0000] MOV SP,[ss:CONTSTK] 0 000056F0 36FE06[0000] INC BYTE PTR [ss:INDOS] ; Back in the DOS 0 000056F5 36C606[0000]00 MOV BYTE PTR [ss:ERRORMODE],0 ; Back from INT 24 0 000056FB FB STI 633 <1> ;; MOV [ACT_PAGE],-1 ;LB. invalidate DOS active page ;AN000; 634 <1> ;; invoke SAVE_MAP ;LB. save user's EMS map ;AN000; 635 <1> fmt TypINT24,LevLog,<"INT 24: User reply = $x\n">, 636 <1> FAILRET: 0 000056FC 36C42E[0000] LES BP,[ss:EXITHOLD] 638 <1> ASSUME ES:NOTHING 639 <1> ; 640 <1> ; Triage the user's reply. 641 <1> ; 0 00005701 3C01 CMP AL,1 0 00005703 723E JB CheckIgnore ; 0 => ignore 0 00005705 7446 JZ CheckRetry ; 1 => retry 0 00005707 3C03 CMP AL,3 ; 3 => fail 0 00005709 754C JNZ DoAbort ; 2, invalid => abort 647 <1> ; 648 <1> ; The reply was fail. See if we are allowed to fail. 649 <1> ; 0 0000570B 36F606[0000]08 TEST byte [ss:ALLOWED],allowed_FAIL ; Can we? 0 00005711 7444 JZ DoAbort ; No, do abort 652 <1> DoFail: 0 00005713 B003 MOV AL,3 ; just in case... 0 00005715 36F606[0000]02 TEST byte [ss:EXTOPEN_ON],EXT_OPEN_I24_OFF ;AN000;EO. I24 error disabled 655 <1> cleanup equ CleanUp ; NASM port label 0 0000571B 7505 JNZ cleanup ;AN000;EO. no 0 0000571D 36FE06[0000] INC byte [ss:FAILERR] ; Tell everybody 658 <1> CleanUp: 659 <1> WpErr equ WPErr ; NASM port label 0 00005722 36C606[0000]FF MOV byte [ss:WpErr],-1 0 00005728 36833E[0000]FF CMP word [ss:SFN],-1 0 0000572E 7501C3 retz 0 00005731 1E5650 SaveReg 0 00005734 36A1[0000] MOV AX,[ss:SFN] 0 00005738 36C536[0000] LDS SI,[ss:pJFN] 0 0000573D 8804 MOV [SI],AL 0 0000573F 585E1F RestoreReg 0 00005742 C3 return 669 <1> ; 670 <1> ; The reply was IGNORE. See if we are allowed to ignore. 671 <1> ; 672 <1> CheckIgnore: 0 00005743 36F606[0000]20 TEST byte [ss:ALLOWED],allowed_IGNORE ; Can we? 0 00005749 74C8 JZ DoFail ; No, do fail 0 0000574B EBD5 JMP CleanUp 676 <1> ; 677 <1> ; The reply was RETRY. See if we are allowed to retry. 678 <1> ; 679 <1> CheckRetry: 0 0000574D 36F606[0000]10 TEST byte [ss:ALLOWED],allowed_RETRY ; Can we? 0 00005753 74BE JZ DoFail ; No, do fail 0 00005755 EBCB JMP CleanUp 683 <1> ; 684 <1> ; The reply was ABORT. 685 <1> ; 686 <1> DoAbort: 0 00005757 161F Context DS 0 00005759 803E[0000]00 CMP BYTE PTR [CONSWAP],0 0 0000575E 7403 JZ NOSWAP2 0 00005760 E8[0000] invoke SWAPBACK 691 <1> NOSWAP2: 692 <1> ; 693 <1> ; See if we are to truly abort. If we are in the process of aborting, turn 694 <1> ; this abort into a fail. 695 <1> ; 0 00005763 F606[0000]FF TEST byte [fAborting],-1 0 00005768 75A9 JNZ DoFail 698 <1> ; 699 <1> ; Set return code 700 <1> ; 701 <1> exit_Type equ Exit_type ; NASM port label 702 <1> Exit_hard_error equ Exit_Hard_Error ; NASM port equate 0 0000576A C606[0000]02 MOV BYTE PTR [exit_Type],Exit_hard_error 0 0000576F 30C0 XOR AL,AL 705 <1> ; 706 <1> ; we are truly aborting the process. Go restore information from the PDB as 707 <1> ; necessary. 708 <1> ; 0 00005771 E9[0000] Transfer exit_inner 710 <1> ; 711 <1> ; reset_environment checks the DS value against the CurrentPDB. If they are 712 <1> ; different, then an old-style return is performed. If they are the same, 713 <1> ; then we release jfns and restore to parent. We still use the PDB at DS:0 as 714 <1> ; the source of the terminate addresses. 715 <1> ; 716 <1> ; Some subtlety: We are about to issue a bunch of calls that *may* generate 717 <1> ; INT 24s. We *cannot* allow the user to restart the abort process; we may 718 <1> ; end up aborting the wrong process or turn a terminate/stay/resident into a 719 <1> ; normal abort and leave interrupt handlers around. What we do is to set a 720 <1> ; flag that will indicate that if any abort code is seen, we just continue the 721 <1> ; operation. In essence, we dis-allow the abort response. 722 <1> ; 723 <1> ; output: none. 724 <1> ; 725 <1> entry reset_environment 726 <1> ASSUME DS:NOTHING,ES:NOTHING 727 <1> 0 00005774 E8[0000] invoke Reset_Version ;AN007;MS. reset version number 0 00005777 1E PUSH DS ; save PDB of process 730 <1> 731 <1> ; 732 <1> ; There are no critical sections in force. Although we may enter here with 733 <1> ; critical sections locked down, they are no longer relevant. We may safely 734 <1> ; free all allocated resources. 735 <1> ; 0 00005778 B482 MOV AH,82h 0 0000577A CD2A INT int_IBM 738 <1> 0 0000577C 36C606[0000]FF MOV byte [ss:fAborting],-1 ; signal abort in progress 740 <1> 741 <1> multNet equ MultNET ; NASM port equate 0 00005782 B82211CD2F CallInstall NetResetEnvironment, multNet, 34 ;DOS 4.00 doesn't need it 743 <1> ; Allow REDIR to clear some stuff 744 <1> ; On process exit. 745 <1> int_Terminate equ int_terminate ; NASM port equate 0 00005787 B022 MOV AL,int_Terminate 0 00005789 E8[0000] invoke D_Get_interrupt_vector ; and who to go to 748 <1> 0 0000578C 59 POP CX ; get ThisPDB 0 0000578D 0653 SaveReg ; save return address 751 <1> 0 0000578F 368B1E[0000] MOV BX,[ss:CurrentPDB] ; get currentPDB 0 00005794 8EDB MOV DS,BX 0 00005796 A11600 MOV AX,[PDB_Parent_PID] ; get parentPDB 755 <1> 756 <1> ; 757 <1> ; AX = parentPDB, BX = CurrentPDB, CX = ThisPDB 758 <1> ; Only free handles if AX <> BX and BX = CX and [exit_code].upper is not 759 <1> ; Exit_keep_process 760 <1> ; 0 00005799 39D8 CMP AX,BX 0 0000579B 741E JZ reset_return ; parentPDB = CurrentPDB 0 0000579D 39CB CMP BX,CX 0 0000579F 751A JNZ reset_return ; CurrentPDB <> ThisPDB 0 000057A1 50 PUSH AX ; save parent 766 <1> exit_type equ Exit_type ; NASM port label 767 <1> Exit_keep_process equ Exit_Keep_process ; NASM port equate 0 000057A2 36803E[0000]03 CMP BYTE PTR [ss:exit_type],Exit_keep_process 0 000057A8 740C JZ reset_to_parent ; keeping this process 770 <1> ; 771 <1> ; We are truly removing a process. Free all allocation blocks belonging to 772 <1> ; this PDB 773 <1> ; 0 000057AA E8[0000] EnterCrit critMem 0 000057AD E8[0000] invoke arena_free_process 0 000057B0 E8[0000] LeaveCrit critMem 777 <1> ; 778 <1> ; Kill off remainder of this process. Close file handles and signal to 779 <1> ; relevant network folks that this process is dead. Remember that CurrentPDB 780 <1> ; is STILL the current process! 781 <1> ; 0 000057B3 E8[0000] invoke DOS_ABORT 783 <1> 784 <1> reset_to_parent: 0 000057B6 368F06[0000] POP word [ss:CurrentPDB] ; set up process as parent 786 <1> 787 <1> reset_return: ; come here for normal return 0 000057BB 16 PUSH ss 0 000057BC 1F POP DS 790 <1> ASSUME DS:DOSGROUP 0 000057BD B0FF MOV AL,-1 792 <1> ; 793 <1> ; make sure that everything is clean In this case ignore any errors, we cannot 794 <1> ; "FAIL" the abort, the program being aborted is dead. 795 <1> ; 0 000057BF E8[0000] EnterCrit critDisk 0 000057C2 E8[0000] invoke FLUSHBUF 0 000057C5 E8[0000] LeaveCrit critDisk 799 <1> ; 800 <1> ; Decrement open ref. count if we had done a virtual open earlier. 801 <1> ; 0 000057C8 E8[0000] invoke CHECK_VIRT_OPEN 803 <1> %ifndef BUF2 804 <1> %IF BUFFERFLAG 805 <1> RESTORE_USER_MAP equ restore_user_map ; NASM port label 806 <1> invoke RESTORE_USER_MAP ;AN000;LB. restore user's EMS map 807 <1> %ENDIF 808 <1> %endif 0 000057CB FA CLI 0 000057CC C606[0000]00 MOV BYTE PTR [INDOS],0 ; Go to known state 0 000057D1 C606[0000]FF MOV BYTE PTR [WPERR],-1 ; Forget about WP error 0 000057D6 C606[0000]00 MOV byte [fAborting],0 ; let aborts occur 813 <1> 814 <1> %if 1 0 000057DB 8E06[0000] mov es, [CurrentPDB] ; => PSP 0 000057DF 26C43E2E00 les di, [es:PDB_User_stack] ; -> user stack we'll restore 0 000057E4 83C712 add di, user_IP ; -> ip, cs, fl on stack 0 000057E7 58 pop ax 0 000057E8 AB stosw ; user_IP = ri22o (PRA) 0 000057E9 A3[0000] mov word [ExitHold], ax ; set compat variable 0 000057EC 58 pop ax 0 000057ED AB stosw ; user_CS = ri22s (PRA) 0 000057EE A3[0200] mov word [ExitHold + 2], ax ; set compat variable 0 000057F1 B802F2 MOV AX,0F202h ; STI, NC 0 000057F4 AB stosw ; user_F = flags 826 <1> 0 000057F5 268B45E8 mov ax, [es:di - (user_F + 2) + user_AX] 828 <1> ; get user ax 829 <1> User_SP equ user_SP ; NASM port label 0 000057F9 A3[0000] mov [User_SP], ax ; set compat variable 831 <1> 0 000057FC 8E1E[0000] MOV DS,[CurrentPDB] 833 <1> ASSUME DS:NOTHING 834 <1> PDB_user_stack equ PDB_User_stack ; NASM port equate 0 00005800 8E163000 MOV SS,WORD PTR [PDB_user_stack+2] 0 00005804 8B262E00 MOV SP,WORD PTR [PDB_user_stack] 837 <1> ; restore stack for PRA entry 838 <1> ASSUME SS:NOTHING 0 00005808 E8[0000] invoke restore_world ; pop our stack frame 840 <1> ASSUME ES:NOTHING 841 <1> 0 0000580B CF iret ; iret to PRA 843 <1> %else 844 <1> POP WORD [ExitHold] 845 <1> POP WORD [ExitHold+2] 846 <1> 847 <1> ; 848 <1> ; Snake into multitasking... Get stack from CurrentPDB person 849 <1> ; 850 <1> MOV DS,[CurrentPDB] 851 <1> ASSUME DS:NOTHING 852 <1> PDB_user_stack equ PDB_User_stack ; NASM port equate 853 <1> MOV SS,WORD PTR [PDB_user_stack+2] 854 <1> MOV SP,WORD PTR [PDB_user_stack] 855 <1> 856 <1> ASSUME SS:NOTHING 857 <1> invoke restore_world 858 <1> ASSUME ES:NOTHING 859 <1> 860 <1> push bx 861 <1> push bx 862 <1> mov bx, .next 863 <1> jmp transfer_doscode_to_dosdata 864 <1> === Switch to base=001140h -> "DOSDATACODE" 865 <1> section DOSDATACODE ; in DOSDATA 866 <1> .next: 867 <1> add sp, 6 ; discard retn & retf addresses 868 <1> 869 <1> User_SP equ user_SP ; NASM port label 870 <1> MOV [cs:User_SP],AX 871 <1> POP AX ; suck off CS:IP of interrupt... 872 <1> POP AX 873 <1> POP AX 874 <1> MOV AX,0F202h ; STI 875 <1> PUSH AX 876 <1> PUSH WORD PTR [cs:EXITHOLD+2] 877 <1> PUSH WORD PTR [cs:EXITHOLD] 878 <1> MOV AX,[cs:User_SP] 879 <1> IRET ; Long return back to user terminate address 880 <1> %endif 881 <1> 882 <1> 883 <1> EndProc HardErr_DOS 883 ****************** <1> warning: ***** Possible stack size error in HardErr_DOS ***** [-w+user] 884 <1> 885 <1> === Switch to base=008400h -> "DOSCODECODE" 886 <1> section DOSCODECODE 887 <1> 888 <1> ; 889 <1> ; This routine handles extended error codes. 890 <1> ; Input : DI = error code from device 891 <1> ; Output: All EXTERR fields are set 892 <1> ; 893 <1> Procedure SET_I24_EXTENDED_ERROR,NEAR 893 ****************** <1> warning: proc SET_I24_EXTENDED_ERROR... [-w+user] 0 0000580C 50 PUSH AX 895 <1> DOSGroup equ DOSGROUP ; NASM port equate 0 0000580D B8[0000] MOV AX,OFFSET ErrMap24End 0 00005810 2D[0000] SUB AX,OFFSET ErrMap24 898 <1> ; 899 <1> ; AX is the index of the first unavailable error. Do not translate if 900 <1> ; greater or equal to AX. 901 <1> ; 0 00005813 39C7 CMP DI,AX 0 00005815 89F8 MOV AX,DI 0 00005817 7307 JAE NoTrans 0 00005819 2E8A85[0000] MOV AL,[cs:ErrMap24 + DI] 0 0000581E 30E4 XOR AH,AH 907 <1> NoTrans: 0 00005820 36A3[0000] MOV [ss:EXTERR],AX 0 00005824 58 POP AX 910 <1> ; 911 <1> ; Now Extended error is set correctly. Translate it to get correct error 912 <1> ; locus class and recommended action. 913 <1> ; 0 00005825 56 PUSH SI 0 00005826 BE[0000] MOV SI,OFFSET ERR_TABLE_24 0 00005829 E8[0000] invoke CAL_LK ; Set other extended error fields 0 0000582C 5E POP SI 0 0000582D C3 ret 919 <1> EndProc SET_I24_EXTENDED_ERROR 920 <1> 921 <1> END 922 <1> 923 <1> 19 ;=== Pop trace listing source 20 === Trace listing source: ../DOS/fat.lst 1 ; SCCSID = @(#)fat.asm 1.3 85/08/15 2 ; SCCSID = @(#)fat.asm 1.3 85/08/15 3 ;TITLE FAT - FAT maintenance routines 4 ;NAME FAT 5 ; Low level local device routines for performing disk change sequence, 6 ; setting cluster validity, and manipulating the FAT 7 ; 8 ; IsEof 9 ; UNPACK 10 ; PACK 11 ; MAPCLUSTER 12 ; FATREAD_SFT 13 ; FATREAD_CDS 14 ; FAT_operation 15 ; 16 ; Revision history: 17 ; 18 ; AN000 version Jan. 1988 19 ; A001 PTM -- disk changed for look ahead buffers 20 ; 21 22 ; 23 ; get the appropriate segment definitions 24 ; 25 [list -] === Switch to base=008400h -> "DOSCODECODE" 29 section DOSCODECODE 30 [list -] 30 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 30 ****************** warning: out: BPB.INC... [-w+user] 30 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 30 ****************** warning: out: DEVSYM.INC... [-w+user] 37 38 FastDiv equ TRUE 39 40 i_need CURBUF,DWORD 41 i_need CLUSSPLIT,BYTE 42 i_need CLUSSAVE,WORD 43 i_need CLUSSEC,DWORD ;F.C. >32mb ;AN000; 44 i_need THISDRV,BYTE 45 i_need THISDPB,DWORD 46 i_need DEVCALL,BYTE 47 i_need CALLMED,BYTE 48 i_need CALLRBYT,BYTE 49 i_need BUFFHEAD,DWORD 50 i_need CALLXAD,DWORD 51 i_need CALLBPB,DWORD 52 i_need CDSADDR,DWORD 53 i_need CDSCOUNT,BYTE 54 i_need EXTERR,WORD 55 i_need EXTERRPT,DWORD 56 i_need CALLVIDM,DWORD 57 i_need ReadOp,BYTE 58 i_need FAILERR,BYTE 59 i_need ALLOWED,BYTE 60 i_need VOLCHNG_FLAG,BYTE 61 i_need HIGH_SECTOR,WORD 62 %ifdef BUF2 63 i_need BUF2_Dirty_Count,WORD 64 %else 65 i_need BUF_HASH_COUNT,WORD 66 i_need BUF_HASH_PTR,DWORD 67 i_need FIRST_BUFF_ADDR,WORD 68 i_need SC_CACHE_COUNT,WORD ;AN001; 69 %endif 70 i_need CURSC_DRIVE,BYTE ;AN001; 71 72 73 Break 74 75 ; 76 ; IsEOF - check the fat value in BX for eof. 77 ; 78 ; Inputs: ES:BP point to DPB 79 ; BX has fat value 80 ; Outputs: JAE eof 81 ; Registers modified: none 82 Procedure IsEof,NEAR 82 ****************** warning: proc IsEof... [-w+user] 83 ASSUME SS:DOSGROUP,CS:DOSGROUP,DS:NOTHING,ES:NOTHING 84 Assert ISDPB,,"IsEOF" 0 0000582E 26817E0DF60F CMP word [ES:BP + dpb_max_cluster],4096-10 ; is this 16 bit fat? 0 00005834 730B JAE EOF16 ; yes, check for eof there 87 ;J.K. 8/27/86 88 ;Modified to accept 0FF0h as an eof. This is to handle the diskfull case 89 ;of any media that has "F0"(Other) as a MediaByte. 90 ;Hopely, this does not create any side effect for those who may use any value 91 ;other than "FF8-FFF" as an Eof for their own file. 0 00005836 81FBF00F cmp bx,0FF0h 0 0000583A 7404 je IsEOF_other 0 0000583C 81FBF80F CMP BX,0FF8h ; do the 12 bit compare 95 IsEOF_other: 0 00005840 C3 return 97 EOF16: 0 00005841 83FBF8 CMP BX,0FFF8h ; 16 bit compare 0 00005844 C3 return 100 EndProc IsEof 101 102 Break 103 104 ; Inputs: 105 ; BX = Cluster number (may be full 16-bit quantity) 106 ; ES:BP = Base of drive parameters 107 ; Outputs: 108 ; DI = Contents of FAT for given cluster (may be full 16-bit quantity) 109 ; Zero set means DI=0 (free cluster) 110 ; Carry set means error (currently user FAILed to I 24) 111 ; SI Destroyed, No other registers affected. Fatal error if cluster too big. 112 113 procedure UNPACK,NEAR 113 ****************** warning: proc UNPACK... [-w+user] 114 DOSAssume CS,,"UnPack" 115 ASSUME ES:NOTHING 116 117 Assert ISDPB,,"Unpack" 0 00005845 263B5E0D CMP BX,[ES:BP + dpb_max_cluster] 0 00005849 7726 JA HURTFAT 0 0000584B E8D300 CALL MAPCLUSTER 121 ASSUME DS:NOTHING 0 0000584E 721E jc DoContext 0 00005850 8B3D MOV DI,[DI] 0 00005852 750E JNZ High12 ; MZ if high 12 bits, go get 'em 0 00005854 268B760D MOV SI,[ES:BP + dpb_max_cluster] ; MZ is this 16-bit fat? 0 00005858 81FEF60F CMP SI,4096-10 0 0000585C 720C JB Unpack12 ; MZ No, go 'AND' off bits 0 0000585E 85FF test DI,DI ; MZ set zero condition code, clears carry 0 00005860 EB0C JMP SHORT DoContext ; MZ go do context 130 131 High12: 0 00005862 D1EF SHR DI,1 0 00005864 D1EF SHR DI,1 0 00005866 D1EF SHR DI,1 0 00005868 D1EF SHR DI,1 136 Unpack12: 0 0000586A 81E7FF0F AND DI,0FFFH ; Clears carry 138 DoContext: 0 0000586E 16 PUSH SS 0 0000586F 1F POP DS 0 00005870 C3 return 142 143 HURTFAT: 0 00005871 26C7461FFFFF MOV word [ES:BP + dpb_free_cnt],-1 ; Err in FAT must force recomp of freespace 0 00005877 50 PUSH AX 146 allowed_fail equ Allowed_FAIL ; NASM port equate 0 00005878 B488 MOV AH,allowed_fail + 80h 148 Allowed equ ALLOWED ; NASM port label 0 0000587A 36C606[0000]08 MOV byte [ss:Allowed],allowed_fail 150 ; 151 ; Signal Bad FAT to INT int_fatal_abort handler. We have an invalid cluster. 152 ; 0 00005880 BFFF0F MOV DI,0FFFH ; In case INT int_fatal_abort returns (it shouldn't) 0 00005883 E8[0000] invoke FATAL 0 00005886 3C03 CMP AL,3 0 00005888 F8 CLC 0 00005889 7501 JNZ OKU_RET ; Try to ignore bad FAT 0 0000588B F9 STC ; User said FAIL 159 OKU_RET: 0 0000588C 58 POP AX 0 0000588D C3 return 162 EndProc UNPACK 163 164 Break 165 166 ; Inputs: 167 ; BX = Cluster number 168 ; DX = Data 169 ; ES:BP = Pointer to drive DPB 170 ; Outputs: 171 ; The data is stored in the FAT at the given cluster. 172 ; SI,DX,DI all destroyed 173 ; Carry set means error (currently user FAILed to I 24) 174 ; No other registers affected 175 176 procedure PACK,NEAR 176 ****************** warning: proc PACK... [-w+user] 177 DOSAssume CS,,"Pack" 178 ASSUME ES:NOTHING 179 180 Assert ISDPB,,"Pack" 0 0000588E E89000 CALL MAPCLUSTER 182 ASSUME DS:NOTHING 0 00005891 72DB JC DoContext 0 00005893 8B35 MOV SI,[DI] 185 Aligned equ ALIGNED ; NASM port label 0 00005895 740B JZ Aligned ; byte (not nibble) aligned 0 00005897 51 PUSH CX ; move data to upper 12 bits 0 00005898 B104 MOV CL,4 0 0000589A D3E2 SHL DX,CL 0 0000589C 59 POP CX 0 0000589D 83E60F AND SI,0FH ; leave in original low 4 bits 0 000058A0 EB14 JMP SHORT PACKIN 193 ALIGNED: 0 000058A2 26817E0DF60F CMP word [ES:BP + dpb_max_cluster],4096-10 ; MZ 16 bit fats? 0 000058A8 730A JAE Pack16 ; MZ yes, go clobber original data 0 000058AA 81E600F0 AND SI,0F000H ; MZ leave in upper 4 bits of original 0 000058AE 81E2FF0F AND DX,0FFFh ; MZ store only 12 bits 198 PackIn equ PACKIN ; NASM port label 0 000058B2 EB02 JMP SHORT PackIn ; MZ go store 200 Pack16: 0 000058B4 31F6 XOR SI,SI ; MZ no original data 202 PACKIN: 0 000058B6 09D6 OR SI,DX 0 000058B8 8935 MOV [DI],SI 0 000058BA 36C536[0000] LDS SI,[ss:CURBUF] 0 000058BF F6440540 TEST byte [SI + buf_flags],buf_dirty ;LB. if already dirty ;AN000; 0 000058C3 7507 JNZ yesdirty ;LB. don't increment dirty count ;AN000; 0 000058C5 E8[0000] invoke INC_DIRTY_COUNT ;LB. ;AN000; 0 000058C8 804C0540 OR byte [SI + buf_flags],buf_dirty ;LB. ;AN000; 210 yesdirty: ;LB. ;AN000; 0 000058CC 36803E[0000]00 CMP BYTE PTR [ss:CLUSSPLIT],0 0 000058D2 161F Context DS 0 000058D4 74B7 retz ; Carry clear 0 000058D6 50 PUSH AX 0 000058D7 53 PUSH BX 0 000058D8 51 PUSH CX 0 000058D9 A1[0000] MOV AX,[CLUSSAVE] 0 000058DC 8E1E[0200] MOV DS,WORD PTR [CURBUF+2] 219 ASSUME DS:NOTHING 0 000058E0 83C610 ADD SI,BUFINSIZ 0 000058E3 8824 MOV [SI],AH 0 000058E5 161F Context DS 0 000058E7 50 PUSH AX 0 000058E8 8B16[0200] MOV DX,WORD PTR [CLUSSEC+2] ;F.C. >32mb ;AN000; 0 000058EC 8916[0000] MOV WORD PTR [HIGH_SECTOR],DX ;F.C. >32mb ;AN000; 226 0 000058F0 8B16[0000] MOV DX,WORD PTR [CLUSSEC] 0 000058F4 BE0100 MOV SI,1 0 000058F7 30C0 XOR AL,AL 0 000058F9 E8[0000] invoke GETBUFFRB 0 000058FC 58 POP AX 0 000058FD 721C JC POPP_RET 0 000058FF C53E[0000] LDS DI,[CURBUF] 234 ASSUME DS:NOTHING 0 00005903 F6450540 TEST byte [DI + buf_flags],buf_dirty ;LB. if already dirty ;AN000; 0 00005907 7507 JNZ yesdirty2 ;LB. don't increment dirty count ;AN000; 0 00005909 E8[0000] invoke INC_DIRTY_COUNT ;LB. ;AN000; 0 0000590C 804D0540 OR byte [DI + buf_flags],buf_dirty 239 yesdirty2: 0 00005910 83C710 ADD DI,BUFINSIZ 0 00005913 4F DEC DI 0 00005914 26037E02 ADD DI,[ES:BP + dpb_sector_size] 0 00005918 8805 MOV [DI],AL 0 0000591A F8 CLC 245 POPP_RET: 0 0000591B 16 PUSH SS 0 0000591C 1F POP DS 0 0000591D 59 POP CX 0 0000591E 5B POP BX 0 0000591F 58 POP AX 0 00005920 C3 return 252 253 EndProc PACK 254 255 Break 256 257 ; Inputs: 258 ; ES:BP Points to DPB 259 ; BX Is cluster number 260 ; Function: 261 ; Get a pointer to the cluster 262 ; Outputs: 263 ; DS:DI Points to contents of FAT for given cluster 264 ; DS:SI Points to start of buffer 265 ; Zero Not set if cluster data is in high 12 bits of word 266 ; Zero set if cluster data is in low 12 or 16 bits 267 ; Carry set if failed. 268 ; SI is destroyed. 269 270 procedure MAPCLUSTER,NEAR 270 ****************** warning: proc MAPCLUSTER... [-w+user] 271 DOSAssume CS,,"MapCluster" 272 ASSUME ES:NOTHING 273 274 Assert ISDPB,,"MapCluster" 0 00005921 C606[0000]00 MOV BYTE PTR [CLUSSPLIT],0 0 00005926 50535152 SaveReg 0 0000592A 89D8 MOV AX,BX ; AX = BX 0 0000592C B9F60F MOV CX,4096-10 0 0000592F 26394E0D CMP [ES:BP + dpb_max_cluster],CX ; MZ 16 bit fat? 0 00005933 7302 JAE Map16 ; MZ yes, do 16 bit algorithm 0 00005935 D1E8 SHR AX,1 ; AX = BX/2 282 Map16: ; MZ skip prev => AX=2*BX 0 00005937 31FF XOR DI,DI ; >32mb fat ;AN000; 0 00005939 01D8 ADD AX,BX ; AX = 1.5*fat = byte offset in fat 0 0000593B 83D700 ADC DI,0 ; >32mb fat ;AN000; 286 DoConvert: 0 0000593E 268B4E02 MOV CX,[ES:BP + dpb_sector_size] 288 %IF FastDiv 289 ; 290 ; Gross hack: 99% of all disks have 512 bytes per sector. We test for this 291 ; case and apply a really fast algorithm to get the desired results 292 ; 293 ; Divide method takes 158 (XOR and DIV) 294 ; Fast method takes 20 295 ; 296 ; This saves a bunch. 297 ; 0 00005942 81F90002 CMP CX,512 ; 4 Is this 512 byte sector? 0 00005946 7403 JZ Nodiv ;F.C. >32mb ;AN000; 0 00005948 E98B00 JMP DoDiv ; 4/16 No, go do divide 301 Nodiv: ;F.C. >32mb ;AN000; 0 0000594B 89C2 MOV DX,AX ; 2 get set for remainder 0 0000594D 81E2FF01 AND DX,512-1 ; 4 Form remainder 0 00005951 88E0 MOV AL,AH ; 2 0 00005953 D0E8 SHR AL,1 ; 2 0 00005955 98 CBW ; 2 Fast divide by 512 0 00005956 09FF OR DI,DI ;>32mb >64k ? ;AN000; 0 00005958 7403 JZ g64k ;>32mb no ;AN000; 0 0000595A 0D8000 OR AX,80H ;>32mb ;AN000; 310 g64k: 311 %ELSE 312 XOR DX,DX ; 3 313 DIV CX ; 155 AX is FAT sector # DX is sector index 314 %ENDIF 315 DivDone: 0 0000595D 26034606 ADD AX,[ES:BP + dpb_first_FAT] 0 00005961 49 DEC CX ; CX is sector size - 1 0 00005962 505251 SaveReg 0 00005965 89C2 MOV DX,AX 0 00005967 C706[0000]0000 MOV word [HIGH_SECTOR],0 ;F.C. >32mb low sector # 0 0000596D 30C0 XOR AL,AL 0 0000596F BE0100 MOV SI,1 0 00005972 E8[0000] invoke GETBUFFRB 0 00005975 59585A RestoreReg ; CX is sec siz-1, AX is offset in sec 0 00005978 7257 JC MAP_POP 0 0000597A C536[0000] LDS SI,[CURBUF] 327 ASSUME DS:NOTHING 328 BufInSiz equ BUFINSIZ ; NASM port equate 0 0000597E 8D7C10 LEA DI,[SI + BufInSiz] 0 00005981 01C7 ADD DI,AX 0 00005983 39C8 CMP AX,CX 0 00005985 7537 JNZ MAPRET 0 00005987 8A05 MOV AL,[DI] 0 00005989 161F Context DS 0 0000598B FE06[0000] INC BYTE PTR [CLUSSPLIT] 0 0000598F A2[0000] MOV BYTE PTR [CLUSSAVE],AL 0 00005992 8916[0000] MOV WORD PTR [CLUSSEC],DX 0 00005996 C706[0200]0000 MOV WORD PTR [CLUSSEC+2],0 ;F.C. >32mb ;AN000; 0 0000599C 42 INC DX 0 0000599D C706[0000]0000 MOV word [HIGH_SECTOR],0 ;F.C. >32mb FAT sector <32mb ;AN000; 0 000059A3 30C0 XOR AL,AL 0 000059A5 BE0100 MOV SI,1 0 000059A8 E8[0000] invoke GETBUFFRB 0 000059AB 7224 JC MAP_POP 0 000059AD C536[0000] LDS SI,[CURBUF] 346 ASSUME DS:NOTHING 0 000059B1 8D7C10 LEA DI,[SI + BufInSiz] 0 000059B4 8A05 MOV AL,[DI] 0 000059B6 161F Context DS 0 000059B8 A2[0100] MOV BYTE PTR [CLUSSAVE+1],AL 0 000059BB BF[0000] MOV DI,OFFSET CLUSSAVE wrt DOSGROUP 352 MAPRET: 0 000059BE 5A595B RestoreReg 0 000059C1 31C0 XOR AX,AX ; MZ allow shift to clear carry 0 000059C3 26817E0DF60F CMP word [ES:BP + dpb_max_cluster],4096-10 ; MZ is this 16-bit fat? 0 000059C9 7302 JAE MapSet ; MZ no, set flags 0 000059CB 89D8 MOV AX,BX 358 MapSet: 0 000059CD A801 TEST AL,1 ; set zero flag if not on boundary 0 000059CF 58 RestoreReg 0 000059D0 C3 return 362 363 MAP_POP: 0 000059D1 5A595B58 RestoreReg 0 000059D5 C3 return 366 %IF FastDiv 367 DoDiv: 0 000059D6 31D2 XOR DX,DX ; 3 0 000059D8 F7F1 DIV CX ; 155 AX is FAT sector # DX is sector index 0 000059DA EB81 JMP DivDone ;15 total=35 371 %ENDIF 372 373 EndProc MAPCLUSTER 373 ****************** warning: ***** Possible stack size error in MAPCLUSTER ***** [-w+user] 374 375 Break 376 377 ; Inputs: 378 ; ES:DI points to an SFT for the drive of intrest (local only, 379 ; giving a NET SFT will produce system crashing results). 380 ; DS DOSGROUP 381 ; Function: 382 ; Can be used by an SFT routine (like CLOSE) to invalidate buffers 383 ; if disk changed. 384 ; In other respects, same as FATREAD_CDS. 385 ; (note ES:DI destroyed!) 386 ; Outputs: 387 ; Carry set if error (currently user FAILed to I 24) 388 ; NOTE: This routine may cause FATREAD_CDS to "miss" a disk change 389 ; as far as invalidating curdir_ID is concerned. 390 ; Since getting a true disk changed on this call is a screw up 391 ; anyway, that's the way it goes. 392 393 procedure FATREAD_SFT,NEAR 393 ****************** warning: proc FATREAD_SFT... [-w+user] 394 DOSAssume CS,,"FATRead_SFT" 395 ASSUME ES:NOTHING 396 0 000059DC 26C46D07 LES BP,[ES:DI + sf_devptr] 398 Assert ISDPB,,"FatReadSFT" 0 000059E0 268A4600 MOV AL,[ES:BP + dpb_drive] 0 000059E4 A2[0000] MOV [THISDRV],AL 0 000059E7 E8[0000] invoke GOTDPB ;Set THISDPB 0 000059EA E87900 CALL FAT_GOT_DPB 0 000059ED C3 return 404 EndProc FATREAD_SFT 405 406 ; Inputs: 407 ; DS:DOSGROUP 408 ; ES:DI points to an CDS for the drive of intrest (local only, 409 ; giving a NET or NUL CDS will produce system crashing results). 410 ; Function: 411 ; If disk may have been changed, media is determined and buffers are 412 ; flagged invalid. If not, no action is taken. 413 ; Outputs: 414 ; ES:BP = Drive parameter block 415 ; [THISDPB] = ES:BP 416 ; [THISDRV] set 417 ; Carry set if error (currently user FAILed to I 24) 418 ; DS preserved , all other registers destroyed 419 420 procedure FATREAD_CDS,NEAR 420 ****************** warning: proc FATREAD_CDS... [-w+user] 421 DOSAssume CS,,"FATRead_CDS" 422 ASSUME ES:NOTHING 423 0 000059EE 06 PUSH ES 0 000059EF 57 PUSH DI 0 000059F0 26C46D45 LES BP,[ES:DI + curdir_devptr] 427 Assert ISDPB,,"FatReadCDS" 0 000059F4 268A4600 MOV AL,[ES:BP + dpb_drive] 0 000059F8 A2[0000] MOV [THISDRV],AL 0 000059FB E8[0000] invoke GOTDPB ;Set THISDPB 0 000059FE E86500 CALL FAT_GOT_DPB 0 00005A01 5F POP DI ;Get back CDS pointer 0 00005A02 07 POP ES 0 00005A03 72E8 retc 0 00005A05 7538 JNZ NO_CHANGE ;Media NOT changed 436 ; Media changed. We now need to find all CDS structures which use this 437 ; DPB and invalidate their ID pointers. 438 MED_CHANGE: 0 00005A07 31C0 XOR AX,AX 0 00005A09 48 DEC AX ;AX = -1 0 00005A0A 1E PUSH DS 0 00005A0B 8A0E[0000] MOV CL,[CDSCOUNT] 0 00005A0F 30ED XOR CH,CH ; CX is number of structures 0 00005A11 26C57545 LDS SI,[ES:DI + curdir_devptr] ; Find all CDS with this devptr 445 ASSUME DS:NOTHING 0 00005A15 36C43E[0000] LES DI,[ss:CDSADDR] ; Start here 447 CHECK_CDS: 0 00005A1A 26F745430080 TEST word [ES:DI + curdir_flags],curdir_isnet 0 00005A20 7517 JNZ NEXTCDS ; Leave NET guys alone!! 0 00005A22 06 PUSH ES 0 00005A23 57 PUSH DI 0 00005A24 26C47D45 LES DI,[ES:DI + curdir_devptr] 0 00005A28 E8[0000] invoke POINTCOMP 0 00005A2B 5F POP DI 0 00005A2C 07 POP ES 0 00005A2D 750A JNZ NEXTCDS ; CDS not for this drive 0 00005A2F 26854549 TEST [ES:DI + curdir_ID],AX 0 00005A33 7404 JZ NEXTCDS ; If root, leave root 0 00005A35 26894549 MOV [ES:DI + curdir_ID],AX ; else invalid 460 NEXTCDS: 0 00005A39 83C758 ADD DI,curdir_list_struc_size ; Point to next CDS 0 00005A3C E2DC LOOP CHECK_CDS 0 00005A3E 1F POP DS 464 DOSAssume CS,,"FAT/NextCDS" 465 NO_CHANGE: 0 00005A3F C42E[0000] LES BP,[THISDPB] 0 00005A43 F8 CLC 0 00005A44 C3 return 469 EndProc FATREAD_CDS 470 471 Break 472 473 procedure FAT_operation,NEAR 473 ****************** warning: proc FAT_operation... [-w+user] 474 FATERR: 475 DOSAssume CS,,"FATERR" 0 00005A45 26C7461FFFFF MOV word [ES:BP + dpb_free_cnt],-1 ; Err in FAT must force recomp of freespace 0 00005A4B 81E7FF00 AND DI,STECODE ; Put error code in DI 478 allowed_FAIL equ Allowed_FAIL ; NASM port equate 479 allowed_RETRY equ Allowed_RETRY ; NASM port equate 0 00005A4F C606[0000]18 MOV byte [ALLOWED],allowed_FAIL + allowed_RETRY 0 00005A54 B41A MOV AH,2 + allowed_FAIL + allowed_RETRY ; While trying to read FAT 0 00005A56 A0[0000] MOV AL,BYTE PTR [THISDRV] ; Tell which drive 0 00005A59 E8[0000] invoke FATAL1 0 00005A5C C42E[0000] LES BP,[THISDPB] 0 00005A60 3C03 CMP AL,3 0 00005A62 7502 JNZ FAT_GOT_DPB ; User said retry 0 00005A64 F9 STC ; User said FAIL 0 00005A65 C3 return 489 490 FAT_GOT_DPB: 0 00005A66 161F Context DS 0 00005A68 B00F MOV AL,DMEDHL 0 00005A6A 268A6601 MOV AH,[ES:BP + dpb_UNIT] 0 00005A6E A3[0000] MOV WORD PTR [DEVCALL],AX 0 00005A71 C606[0200]01 MOV BYTE PTR [DEVCALL + REQFUNC],DEVMDCH 0 00005A76 C706[0300]0000 MOV word [DEVCALL + REQSTAT],0 0 00005A7C 268A4617 MOV AL,[ES:BP + dpb_media] 0 00005A80 A2[0000] MOV BYTE PTR [CALLMED],AL 0 00005A83 06 PUSH ES 0 00005A84 1E PUSH DS 0 00005A85 BB[0000] MOV BX,OFFSET DEVCALL wrt DOSGROUP 0 00005A88 26C57613 LDS SI,[ES:BP + dpb_driver_addr] ; DS:SI Points to device header 503 ASSUME DS:NOTHING 0 00005A8C 07 POP ES ; ES:BX Points to call header 0 00005A8D E8[0000] invoke DEVIOCALL2 0 00005A90 161F Context DS 0 00005A92 07 POP ES ; Restore ES:BP 0 00005A93 8B3E[0300] MOV DI,[DEVCALL + REQSTAT] 0 00005A97 F7C70080 TEST DI,STERR 0 00005A9B 75A8 JNZ FATERR 0 00005A9D 30E4 XOR AH,AH 0 00005A9F 26866618 XCHG AH,[ES:BP + dpb_first_access] ; Reset dpb_first_access 0 00005AA3 A0[0000] MOV AL,BYTE PTR [THISDRV] ; Use physical unit number 514 ; See if we had changed volume id by creating one on the diskette 0 00005AA6 3806[0000] cmp [VOLCHNG_FLAG],AL 0 00005AAA 7508 jnz CHECK_BYT 0 00005AAC C606[0000]FF mov byte [VOLCHNG_FLAG],-1 0 00005AB1 E99700 jmp GOGETBPB ; Need to get device driver to read in 519 ; new volume label. 520 CHECK_BYT: 0 00005AB4 0A26[0000] OR AH,BYTE PTR [CALLRBYT] 0 00005AB8 7903 JNS CHECK_ZR ; ns = 0 or 1 0 00005ABA EB66 JMP NEWDSK 0 00005ABC 90 nop ; identicalise 525 526 CHECK_ZR: 0 00005ABD 743D JZ CHKBUFFDIRT ; jump if I don't know 0 00005ABF F8 CLC 0 00005AC0 C3 return ; If Media not changed (NZ) 530 531 DISK_CHNG_ERR: 532 ASSUME DS:NOTHING 0 00005AC1 06 PUSH ES 0 00005AC2 55 PUSH BP 0 00005AC3 26C46E13 LES BP,[ES:BP + dpb_driver_addr] ; Get device pointer 0 00005AC7 26F746040008 TEST word [ES:BP + SDEVATT],DEVOPCL ; Did it set vol id? 0 00005ACD 5D POP BP 0 00005ACE 07 POP ES 0 00005ACF 7426 JZ FAIL_OPJ2 ; Nope, FAIL 0 00005AD1 1E PUSH DS ; Save buffer pointer for ignore 0 00005AD2 57 PUSH DI 0 00005AD3 161F Context DS 0 00005AD5 C606[0000]18 MOV byte [ALLOWED],allowed_FAIL + allowed_RETRY 0 00005ADA 06 PUSH ES 0 00005ADB C43E[0000] LES DI,[CALLVIDM] ; Get volume ID pointer 0 00005ADF 8C06[0200] MOV WORD PTR [EXTERRPT+2],ES 0 00005AE3 07 POP ES 0 00005AE4 893E[0000] MOV WORD PTR [EXTERRPT],DI 0 00005AE8 B80F00 MOV AX,error_I24_wrong_disk 550 READOP equ ReadOp ; NASM port label 0 00005AEB C606[0000]01 MOV byte [READOP],1 ; Write 0 00005AF0 E8[0000] invoke HARDERR_DOS 0 00005AF3 5F POP DI ; Get back buffer for ignore 0 00005AF4 1F POP DS 555 ASSUME DS:NOTHING 0 00005AF5 3C03 CMP AL,3 557 FAIL_OPJ2: 0 00005AF7 741E JZ FAIL_OP 0 00005AF9 E96AFF JMP FAT_GOT_DPB ; Retry 560 561 CHKBUFFDIRT: 562 DOSAssume CS,,"FAT/ChkBuffDirt" 563 %ifdef BUF2 0 00005AFC C53E[0000] LDS DI,[BUFFHEAD] 565 ASSUME DS:NOTHING 0 00005B00 36833E[0000]00 CMP word [ss:BUF2_Dirty_Count], 0 ;LB. if not dirty ;AN000; 0 00005B06 741A je NEWDSK 568 %else 569 XOR DX,DX ;LB. ;AN000; 570 LDS DI,[ss:BUF_HASH_PTR] ;LB. scan from 1st entry ;AN000; 571 MOV CX,[ss:BUF_HASH_COUNT] ;LB. get Hash entry count ;AN000; 572 573 scan_dirty: 574 Dirty_Count equ DIRTY_COUNT ; NASM port equate 575 CMP byte [DI + Dirty_Count],0 ;LB. if not dirty ;AN000; 576 JZ GETNEXT ;LB. get next hash entry ;AN000; 577 PUSH DS ;LB. save hash entry addr ;AN000; 578 PUSH DI ;LB. ;AN000; 579 invoke Map_Entry ;LB. ;AN000; 580 %endif 581 NBUFFER: ; Look for dirty buffers 0 00005B08 3A4504 CMP AL,[DI + buf_ID] 0 00005B0B 750E JNZ LFNXT ; Not for this unit 0 00005B0D F6450540 TEST byte [DI + buf_flags],buf_dirty 0 00005B11 7408 JZ LFNXT 586 %ifndef BUF2 587 POP DI ;LB. restore regs ;AN000; 588 POP DS ;LB. ;AN000; 589 %endif 0 00005B13 161F Context DS 0 00005B15 F8 CLC 0 00005B16 C3 return ; There is a dirty buffer, assume Media OK (NZ) 593 594 FAIL_OP: 0 00005B17 161F Context DS 0 00005B19 F9 STC 0 00005B1A C3 return 598 599 ASSUME DS:NOTHING 600 LFNXT: 601 %ifdef BUF2 0 00005B1B C53D lds di, [di + NEXTBUF] 0 00005B1D 83FFFF cmp di, -1 604 %else 605 mov DI,[DI + buf_next] ;; 1/19/88 606 CMP DI,[ss:FIRST_BUFF_ADDR] ;; 1/19/88 607 %endif 0 00005B20 75E6 JNZ NBUFFER 609 %ifndef BUF2 610 POP DI ;LB. restore regs ;AN000; 611 POP DS ;LB. ;AN000; 612 GETNEXT: 613 ADD DI,BUFFER_HASH_ENTRY_struc_size ;LB. next entry ;AN000; 614 LOOP scan_dirty ;LB. scan next entry ;AN000; 615 %endif 616 ; If no dirty buffers, assume Media changed 617 NEWDSK: 0 00005B22 26C7461FFFFF MOV word [ES:BP + dpb_free_cnt],-1 ; Media changed, must re-compute 619 ; NOTE: It is TECHNICALLY more correct 620 ASSUME DS:NOTHING 621 %ifdef BUF2 0 00005B28 36C53E[0000] lds di, [ss:BUFFHEAD] 623 %else 624 XOR DX,DX ;LB. ;AN000; 625 MOV [ss:HIGH_SECTOR],DX ;LB. scan from 1st entry ;AN000; 626 MOV CX,[ss:BUF_HASH_COUNT] ;LB. get Hash entry count ;AN000; 627 628 NxtHash: 629 invoke GETCURHEAD ;LB. get Hash entry buffer header ;AN000; 630 ; to do this AFTER the check for 631 %endif 632 ASSUME DS:NOTHING 633 NXBUFFER: 0 00005B2D 3A4504 CMP AL,[DI + buf_ID] ; For this drive? 0 00005B30 7404 JZ OLDDRV2 ;LB. yes ;AN000; 636 %ifdef BUF2 0 00005B32 C53D lds di, [di + NEXTBUF] 638 %else 639 mov DI,[DI + buf_next] ;LB. get next buffer 1/19/88 ;AN000; 640 %endif 0 00005B34 EB10 JMP SHORT SKPBUFF ;LB. ;AN000; 642 OLDDRV2: 0 00005B36 F6450540 TEST byte [DI + buf_flags],buf_dirty 644 OldDrv equ OLDDRV ; NASM port label 0 00005B3A 7402 JZ OldDrv 646 Disk_Chng_Err equ DISK_CHNG_ERR ; NASM port label 0 00005B3C EB83 JMP Disk_Chng_Err ; Disk changed but dirty buffers 648 OLDDRV: 649 %ifdef BUF2 0 00005B3E C74504FF00 MOV WORD PTR [DI + BUFDRV], 00FFH 651 %else 652 MOV WORD PTR [DI + buf_ID], 00FFH ; Free up buffer 653 %endif 0 00005B43 E8[0000] invoke SCANPLACE 655 SKPBUFF: 656 %ifdef BUF2 0 00005B46 83FFFF cmp di, -1 658 %else 659 CMP DI,[ss:FIRST_BUFF_ADDR] ;LB. end of chain 1/19/88 ;AN000; 660 %endif 0 00005B49 75E2 JNZ NXBUFFER ;LB. no ;AN000; 662 %ifndef BUF2 663 INC DX ;LB. ;AN000; 664 LOOP NxtHash ;LB. ;AN000; 665 CMP word [ss:SC_CACHE_COUNT],0 ;LB. look ahead buffers ? ;AN001; 666 JZ GOGETBPB ;LB. no ;AN001; 667 CMP AL,[ss:CURSC_DRIVE] ;LB. same as changed drive ;AN001; 668 JNZ GOGETBPB ;LB. no ;AN001; 669 MOV byte [ss:CURSC_DRIVE],-1 ;LB. invalidate look ahead buffers ;AN000; 670 %endif 671 GOGETBPB: 0 00005B4B 26C57E13 LDS DI,[ES:BP + dpb_driver_addr] 0 00005B4F F745040020 TEST word [DI + SDEVATT],ISFATBYDEV 0 00005B54 7510 JNZ GETFREEBUF 0 00005B56 161F context DS 0 00005B58 BB0200 MOV BX,2 0 00005B5B E8E7FC CALL UNPACK ; Read the first FAT sector into CURBUF 678 FAIL_OPJ: 0 00005B5E 72B7 JC FAIL_OP 0 00005B60 C53E[0000] LDS DI,[CURBUF] 681 ASSUME DS:NOTHING 0 00005B64 EB15 JMP SHORT GOTGETBUF 683 684 GETFREEBUF: 685 ASSUME DS:NOTHING 0 00005B66 06 PUSH ES ; Get a free buffer for BIOS to use 0 00005B67 55 PUSH BP 0 00005B68 31D2 XOR DX,DX ;LB. fake to get 1st ;AN000; 0 00005B6A 368916[0000] MOV [ss:HIGH_SECTOR],DX ;LB. buffer addr ;AN000; 690 %ifdef BUF2 0 00005B6F 36C53E[0000] lds di, [ss:BUFFHEAD] 692 %else 693 invoke GETCURHEAD ;LB. ;AN000; 694 %endif 695 0 00005B74 E8[0000] invoke BUFWRITE 0 00005B77 5D POP BP 0 00005B78 07 POP ES 0 00005B79 72E3 JC FAIL_OPJ 700 GOTGETBUF: 0 00005B7B 83C710 ADD DI,BUFINSIZ 0 00005B7E 368C1E[0200] MOV WORD PTR [ss:CALLXAD+2],DS 0 00005B83 161F Context DS 0 00005B85 893E[0000] MOV WORD PTR [CALLXAD],DI 0 00005B89 B016 MOV AL,DBPBHL 0 00005B8B 268A6601 MOV AH,BYTE PTR [ES:BP + dpb_UNIT] 0 00005B8F A3[0000] MOV WORD PTR [DEVCALL],AX 0 00005B92 C606[0200]02 MOV BYTE PTR [DEVCALL + REQFUNC],DEVBPB 0 00005B97 C706[0300]0000 MOV word [DEVCALL + REQSTAT],0 0 00005B9D 268A4617 MOV AL,BYTE PTR [ES:BP + dpb_media] 0 00005BA1 A2[0000] MOV [CALLMED],AL 0 00005BA4 06 PUSH ES 0 00005BA5 1E PUSH DS 0 00005BA6 26FF7615 PUSH WORD PTR [ES:BP + dpb_driver_addr+2] 0 00005BAA 26FF7613 PUSH WORD PTR [ES:BP + dpb_driver_addr] 0 00005BAE BB[0000] MOV BX,OFFSET DEVCALL wrt DOSGROUP 0 00005BB1 5E POP SI 0 00005BB2 1F POP DS ; DS:SI Points to device header 719 ASSUME DS:NOTHING 0 00005BB3 07 POP ES ; ES:BX Points to call header 0 00005BB4 E8[0000] invoke DEVIOCALL2 0 00005BB7 07 POP ES ; Restore ES:BP 0 00005BB8 161F Context DS 0 00005BBA 8B3E[0300] MOV DI,[DEVCALL + REQSTAT] 0 00005BBE F7C70080 TEST DI,STERR 0 00005BC2 751F JNZ FATERRJ 0 00005BC4 268A4617 MOV AL,BYTE PTR [ES:BP + dpb_media] 0 00005BC8 C536[0000] LDS SI,[CALLBPB] 729 ASSUME DS:NOTHING 730 DPB_next_free equ dpb_next_free ; NASM port equate 0 00005BCC 26C7461D0000 MOV word [ES:BP + DPB_next_free],0 ; recycle scanning pointer 0 00005BD2 E8[0000] invoke D_SETDPB 0 00005BD5 36C53E[0000] LDS DI,[ss:CALLXAD] ; Get back buffer pointer 734 %ifdef BUF2 0 00005BDA 804DF502 or byte [di - BUFINSIZ + buf_flags], buf_isFAT 736 %else 737 MOV AL,BYTE PTR [ES:BP + dpb_FAT_count] 738 MOV [DI + buf_wrtcnt-BUFINSIZ],AL ;>32mb ;AN000; 739 MOV AX,[ES:BP + dpb_FAT_size] ;>32mb ;AC000; 740 MOV [DI + buf_wrtcntinc-BUFINSIZ],AX ;>32mb Correct buffer info ;AC000; 741 %endif 742 0 00005BDE 161F Context DS 0 00005BE0 30C0 XOR AL,AL ;Media changed (Z), Carry clear 0 00005BE2 C3 return 746 0 00005BE3 E95FFE FATERRJ: JMP FATERR 748 749 EndProc FAT_operation 750 751 END === Trace listing source: ../DOS/buf.lst 1 ; SCCSID = @(#)buf.asm 1.1 85/04/09 2 ;TITLE BUF - MSDOS buffer management 3 ;NAME BUF 4 ; Low level routines for buffer cache management 5 ; 6 ; GETCURHEAD 7 ; SET_MAP_PAGE 8 ; SAVE_MAP 9 ; RESTORE_MAP 10 ; SETVISIT 11 ; ScanPlace 12 ; PLACEBUF 13 ; PLACEHEAD 14 ; PointComp 15 ; GETBUFFR 16 ; GETBUFFRB 17 ; FlushBuf 18 ; BufWrite 19 ; SKIPVISIT 20 ; SET_RQ_SC_PARMS 21 ; 22 ; Revision history: 23 ; 24 ; AN000 version 4.00 Jan. 1988 25 ; A004 PTM 3765 -- Disk reset failed 26 27 ; NEW PROCS FOR BUFFERS FIX: 28 29 ; SAVE_USER_MAP 30 ; RESTORE_USER_MAP 31 ; DETECT_COLLISION 32 ; SETUP_EMS_BUFFERS 33 ; 34 35 36 ; 37 ; get the appropriate segment definitions 38 ; 39 [list -] === Switch to base=008400h -> "DOSCODECODE" 43 section DOSCODECODE 44 [list -] 44 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 44 ****************** warning: out: BPB.INC... [-w+user] 44 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 44 ****************** warning: out: DEVSYM.INC... [-w+user] 44 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 52 53 %ifdef BUF2 54 %define FROMBUFNAS 55 %include "buf2.nas" 1 <1> %ifdef FROMBUFNAS 2 <1> [list -] 6 <1> %else 7 <1> ; 8 <1> ; buffer management for MSDOS 9 <1> ; 10 <1> 11 <1> %include "dosseg.nas" 12 <1> === Switch to base=008400h -> "DOSCODECODE" 13 <1> section DOSCODECODE 14 <1> 15 <1> [list -] 16 <1> ;.xcref 17 <1> %define BUF2 1 18 <1> %include "dossym.mac" 19 <1> %include "devsym.mac" 20 <1> %include "dosmac.mac" 21 <1> ;.cref 22 <1> [list +] 23 <1> %endif 24 <1> 25 <1> i_need BuffHead,DWORD 26 <1> i_need BuffFree,DWORD 27 <1> i_need PreRead,WORD 28 <1> i_need LastBuffer,DWORD 29 <1> i_need CurBuf,DWORD 30 <1> i_need WPErr,BYTE 31 <1> i_need ALLOWED,BYTE 32 <1> i_need FAILERR,BYTE 33 <1> i_need HIGH_SECTOR,WORD ; DOS 4.00 >32mb ;AN000; 34 <1> i_need DOS34_FLAG,WORD ; DOS 4.00 common flag ;AN000; 35 <1> i_need BUF2_Dirty_Count,WORD 36 <1> 37 <1> 38 <1> BUFFHEAD equ BuffHead ; NASM port label 39 <1> 40 <1> ;SUBTTL SCANPLACE, PLACEBUF -- PUT A BUFFER BACK IN THE POOL 41 <1> ;PAGE 42 <1> procedure ScanPlace,near 42 ****************** <1> warning: proc ScanPlace... [-w+user] 43 <1> ASSUME DS:NOTHING,ES:NOTHING 44 <1> 45 <1> ; Inputs: 46 <1> ; Same as PLACEBUF 47 <1> ; Function: 48 <1> ; Save scan location and call PLACEBUF 49 <1> ; Outputs: 50 <1> ; DS:DI Points to saved scan location 51 <1> ; SI destroyed, other registers unchanged 52 <1> 0 00005BE6 06 PUSH ES 0 00005BE7 C435 LES SI,[DI + NEXTBUF] ; Save scan location 0 00005BE9 E80800 CALL PLACEBUF 0 00005BEC 06 PUSH ES 0 00005BED 1F POP DS ; Restore scan location 0 00005BEE 89F7 MOV DI,SI 0 00005BF0 07 POP ES 0 00005BF1 C3 return 61 <1> ScanPlace ENDP 62 <1> 0 00005BF2 EB57 NRETJ: JMP SHORT NRET 64 <1> 65 <1> procedure PLACEBUF,NEAR 65 ****************** <1> warning: proc PLACEBUF... [-w+user] 66 <1> ASSUME DS:NOTHING,ES:NOTHING 67 <1> 68 <1> ; Input: 69 <1> ; DS:DI points to buffer 70 <1> ; Function: 71 <1> ; Remove buffer from queue and re-insert it in proper place. 72 <1> ; If buffer doesn't go at end, and isn't free, decrement 73 <1> ; priorities. 74 <1> ; NO registers altered 75 <1> ; 76 <1> ; DS:SI -- Curbuf, current buffer in list 77 <1> ; ES:DI -- Buf, buffer passed as argument 78 <1> ; BP:CX -- Pointsave, saved Buf.nextbuf 79 <1> ; DX:BX -- Lastbuf, previous buffer in list 80 <1> ; AL -- Inserted, Buf has been inserted 81 <1> ; AH -- Removed, Buf has been removed 82 <1> 83 <1> %IF IBM 84 <1> %IFN IBM 85 <1> invoke save_world 86 <1> XOR AX,AX ; Inserted = Removed = FALSE 87 <1> LES CX,[DI + NEXTBUF] 88 <1> MOV BP,ES ; Pointsave = Buf.nextbuf 89 <1> MOV SI,DS 90 <1> MOV ES,SI ; Buf is ES:DI 91 <1> LDS SI,[ss:BUFFHEAD] ; Curbuf = HEAD 92 <1> CALL POINTCOMP ; Buf == HEAD? 93 <1> JNZ TNEWHEAD 94 <1> CMP CX,-1 ; Buf is LAST? 95 <1> JZ NRETJ ; Only one buffer, nothing to do 96 <1> MOV WORD PTR [ss:BUFFHEAD],CX 97 <1> MOV WORD PTR [ss:BUFFHEAD+2],BP ; HEAD = Pointsave 98 <1> INC AH ; Removed = TRUE 99 <1> MOV DS,BP 100 <1> MOV SI,CX ; Curbuf = HEAD 101 <1> TNEWHEAD: 102 <1> MOV BL,[ES:DI + BUFPRI] 103 <1> CMP BL,[SI + BUFPRI] 104 <1> JGE BUFLOOP 105 <1> NEWHEAD: ; If Buf.pri < HEAD.pri 106 <1> MOV WORD PTR [ES:DI + NEXTBUF],SI 107 <1> MOV WORD PTR [ES:DI + NEXTBUF+2],DS ; Buf.nextbuf = HEAD 108 <1> MOV WORD PTR [ss:BUFFHEAD],DI 109 <1> MOV WORD PTR [ss:BUFFHEAD+2],ES ; HEAD = Buf 110 <1> INC AL ; Inserted = TRUE 111 <1> OR AH,AH 112 <1> JNZ NRET ; If Removed == TRUE 113 <1> BUFLOOP: 114 <1> PUSH DS 115 <1> PUSH SI 116 <1> LDS SI,[SI + NEXTBUF] 117 <1> CALL POINTCOMP 118 <1> POP SI 119 <1> POP DS 120 <1> JNZ TESTINS 121 <1> MOV WORD PTR [SI + NEXTBUF],CX ; If Curbuf.nextbuf == buf 122 <1> MOV WORD PTR [SI + NEXTBUF+2],BP ; Curbuf.nextbuf = Pointsave 123 <1> INC AH ; Removed = TRUE 124 <1> OR AL,AL 125 <1> JNZ SHUFFLE ; If Inserted == TRUE 126 <1> TESTINS: 127 <1> OR AL,AL 128 <1> JNZ LOOKBUF 129 <1> PUSH CX ; If NOT Inserted 130 <1> MOV CL,[ES:DI + BUFPRI] 131 <1> CMP CL,[SI + BUFPRI] 132 <1> POP CX 133 <1> JGE LOOKBUF 134 <1> PUSH DS ; If Buf.pri < Curbuf.pri 135 <1> MOV DS,DX 136 <1> MOV WORD PTR [BX + NEXTBUF],DI 137 <1> MOV WORD PTR [BX + NEXTBUF+2],ES ; Lastbuf.nextbuf = Buf 138 <1> POP DS 139 <1> MOV WORD PTR [ES:DI + NEXTBUF],SI 140 <1> MOV WORD PTR [ES:DI + NEXTBUF+2],DS ; Buf.nextbuf = Curbuf 141 <1> INC AL ; Inserted = TRUE 142 <1> OR AH,AH 143 <1> JNZ SHUFFLE ; If Removed == TRUE 144 <1> LOOKBUF: 145 <1> MOV BX,SI 146 <1> MOV DX,DS ; Lastbuf = Curbuf 147 <1> CMP WORD PTR [SI + NEXTBUF],-1 148 <1> JZ ISLAST 149 <1> LDS SI,[SI + NEXTBUF] ; Curbuf = Curbuf.nextbuf 150 <1> JMP SHORT BUFLOOP 151 <1> ISLAST: ; If Curbuf is LAST 152 <1> MOV WORD PTR [SI + NEXTBUF],DI 153 <1> MOV WORD PTR [SI + NEXTBUF+2],ES ; Curbuf.nextbuf = Buf 154 <1> MOV WORD PTR [ES:DI + NEXTBUF],-1 155 <1> MOV WORD PTR [ES:DI + NEXTBUF+2],-1 ; Buf is LAST 156 <1> NRET: 157 <1> invoke restore_world 158 <1> return 159 <1> 160 <1> SHUFFLE: 161 <1> LDS DI,[ss:BUFFHEAD] 162 <1> DECLOOP: 163 <1> CMP byte [DI + BUFPRI],FREEPRI 164 <1> JZ NODEC 165 <1> DEC byte [DI + BUFPRI] 166 <1> NODEC: 167 <1> LDS DI,[DI + NEXTBUF] 168 <1> CMP DI,-1 169 <1> JNZ DECLOOP 170 <1> JMP SHORT NRET 171 <1> %ENDIF 172 <1> %ENDIF 173 <1> 0 00005BF4 E8[0000] invoke save_world 0 00005BF7 C40D LES CX,[DI + NEXTBUF] 0 00005BF9 83F9FF CMP CX,-1 ; Buf is LAST? 0 00005BFC 744D JZ NRET ; Buffer already last 0 00005BFE 8CC5 MOV BP,ES ; Pointsave = Buf.nextbuf 0 00005C00 1E PUSH DS 0 00005C01 07 POP ES ; Buf is ES:DI 0 00005C02 36C536[0000] LDS SI,[ss:BUFFHEAD] ; Curbuf = HEAD 182 <1> POINTCOMP equ PointComp ; NASM port label 0 00005C07 E87A00 CALL POINTCOMP ; Buf == HEAD? 0 00005C0A 750C JNZ BUFLOOP 0 00005C0C 36890E[0000] MOV WORD PTR [ss:BUFFHEAD],CX 0 00005C11 36892E[0200] MOV WORD PTR [ss:BUFFHEAD+2],BP ; HEAD = Pointsave 0 00005C16 EB14 JMP SHORT LOOKEND 188 <1> 189 <1> BUFLOOP: 0 00005C18 1E PUSH DS 0 00005C19 56 PUSH SI 0 00005C1A C534 LDS SI,[SI + NEXTBUF] 0 00005C1C E86500 CALL POINTCOMP 0 00005C1F 7404 JZ GOTTHEBUF 0 00005C21 58 POP AX 0 00005C22 58 POP AX 0 00005C23 EBF3 JMP SHORT BUFLOOP 198 <1> 199 <1> GOTTHEBUF: 0 00005C25 5E POP SI 0 00005C26 1F POP DS 0 00005C27 890C MOV WORD PTR [SI + NEXTBUF],CX ; If Curbuf.nextbuf == buf 0 00005C29 896C02 MOV WORD PTR [SI + NEXTBUF+2],BP ; Curbuf.nextbuf = Pointsave 204 <1> LOOKEND: 0 00005C2C 1E PUSH DS 0 00005C2D 56 PUSH SI 0 00005C2E C534 LDS SI,[SI + NEXTBUF] 0 00005C30 83FEFF CMP SI,-1 0 00005C33 7404 JZ GOTHEEND 0 00005C35 58 POP AX 0 00005C36 58 POP AX 0 00005C37 EBF3 JMP SHORT LOOKEND 213 <1> 214 <1> GOTHEEND: 0 00005C39 5E POP SI 0 00005C3A 1F POP DS 0 00005C3B 893C MOV WORD PTR [SI + NEXTBUF],DI 0 00005C3D 8C4402 MOV WORD PTR [SI + NEXTBUF+2],ES ; Curbuf.nextbuf = Buf 0 00005C40 26C705FFFF MOV WORD PTR [ES:DI + NEXTBUF],-1 0 00005C45 26C74502FFFF MOV WORD PTR [ES:DI + NEXTBUF+2],-1 ; Buf is LAST 221 <1> NRET: 0 00005C4B E8[0000] invoke restore_world 0 00005C4E C3 return 224 <1> 225 <1> PLACEBUF ENDP 226 <1> 227 <1> procedure PLACEHEAD,NEAR 227 ****************** <1> warning: proc PLACEHEAD... [-w+user] 228 <1> ASSUME DS:NOTHING,ES:NOTHING 229 <1> 230 <1> ; SAME AS PLACEBUF except places buffer at head 231 <1> 0 00005C4F E8[0000] invoke save_world 0 00005C52 1E PUSH DS 0 00005C53 07 POP ES 0 00005C54 36C536[0000] LDS SI,[ss:BUFFHEAD] 0 00005C59 36893E[0000] MOV WORD PTR [ss:BUFFHEAD],DI 0 00005C5E 368C06[0200] MOV WORD PTR [ss:BUFFHEAD+2],ES 0 00005C63 268935 MOV WORD PTR [ES:DI + NEXTBUF],SI 0 00005C66 268C5D02 MOV WORD PTR [ES:DI + NEXTBUF+2],DS 240 <1> LOOKEND2: 0 00005C6A 1E PUSH DS 0 00005C6B 56 PUSH SI 0 00005C6C C534 LDS SI,[SI + NEXTBUF] 0 00005C6E E81300 CALL POINTCOMP 0 00005C71 7404 JZ GOTHEEND2 0 00005C73 58 POP AX 0 00005C74 58 POP AX 0 00005C75 EBF3 JMP SHORT LOOKEND2 249 <1> 250 <1> GOTHEEND2: 0 00005C77 5E POP SI 0 00005C78 1F POP DS 0 00005C79 C704FFFF MOV WORD PTR [SI + NEXTBUF],-1 0 00005C7D C74402FFFF MOV WORD PTR [SI + NEXTBUF+2],-1 ; Buf is LAST 0 00005C82 EBC7 JMP SHORT NRET 256 <1> 257 <1> PLACEHEAD ENDP 258 <1> 259 <1> ;SUBTTL POINTCOMP -- 20 BIT POINTER COMPARE 260 <1> ;PAGE 261 <1> procedure PointComp,NEAR 261 ****************** <1> warning: proc PointComp... [-w+user] 262 <1> ASSUME DS:NOTHING,ES:NOTHING 263 <1> 264 <1> ; Compare DS:SI to ES:DI (or DS:DI to ES:SI) for equality 265 <1> ; DO NOT USE FOR < or > 266 <1> ; No Registers altered 267 <1> 0 00005C84 39FE CMP SI,DI 0 00005C86 75C6 retnz 0 00005C88 51 PUSH CX 0 00005C89 52 PUSH DX 0 00005C8A 8CD9 MOV CX,DS 0 00005C8C 8CC2 MOV DX,ES 0 00005C8E 39D1 CMP CX,DX 0 00005C90 5A POP DX 0 00005C91 59 POP CX 0 00005C92 C3 return 278 <1> PointComp ENDP 279 <1> 280 <1> ;SUBTTL GETBUFFR -- GET A SECTOR INTO A BUFFER 281 <1> ;PAGE 282 <1> procedure GETBUFFR,NEAR 282 ****************** <1> warning: proc GETBUFFR... [-w+user] 283 <1> ASSUME DS:DOSGROUP,ES:NOTHING 284 <1> 285 <1> ; Input: 286 <1> ; AH = Priority buffer is to have 287 <1> ; AL = 0 means sector must be pre-read 288 <1> ; ELSE no pre-read 289 <1> ; DX = Desired physical sector number 290 <1> ; ES:BP = Pointer to drive parameters 291 <1> ; Function: 292 <1> ; Get the specified sector into one of the I/O buffers 293 <1> ; And shuffle the queue 294 <1> ; Output: 295 <1> ; [CURBUF] Points to the Buffer for the sector 296 <1> ; CY iff error (user selected FAIL on int 24h) 297 <1> ; DX,ES:BP unchanged, all other registers destroyed 298 <1> 0 00005C93 31F6 XOR SI,SI 300 <1> entry GETBUFFRB 301 <1> PREREAD equ PreRead ; NASM port label 0 00005C95 A3[0000] MOV [PREREAD],AX 0 00005C98 268A4600 MOV AL,[ES:BP + dpb_drive] 0 00005C9C 830E[0000]FF or word [BuffFree], -1 305 <1> LASTBUFFER equ LastBuffer ; NASM port label 0 00005CA1 C53E[0000] LDS DI,[LASTBUFFER] 307 <1> ASSUME DS:NOTHING 0 00005CA5 368B0E[0000] MOV CX,[ss:HIGH_SECTOR] ; F.C. >32mb ;AN000; 0 00005CAA 83FFFF CMP DI,-1 ; Recency pointer valid? 0 00005CAD 7412 JZ SKBUF ; No 0 00005CAF 3B5508 CMP DX,WORD PTR [DI + BUFSECNO] 0 00005CB2 750D JNZ SKBUF ; Wrong sector 0 00005CB4 3B4D0A CMP CX,WORD PTR [DI + BUFSECNO+2] ; F.C. >32mb ;AN000; 0 00005CB7 7508 JNZ SKBUF ; F.C. >32mb ;AN000; 0 00005CB9 3A4504 CMP AL,[DI + BUFDRV] 0 00005CBC 7503E99200 jz JUSTBUF ; Just asked for same buffer 317 <1> ; Wrong Drive 318 <1> SKBUF: 0 00005CC1 36C53E[0000] LDS DI,[ss:BUFFHEAD] 320 <1> NXTBFF: 0 00005CC6 807D04FF cmp byte [di + BUFDRV], 0FFh 0 00005CCA 750A jne .notfree 0 00005CCC 36893E[0000] mov word [ss:BuffFree], di 0 00005CD1 368C1E[0200] mov word [ss:BuffFree + 2], ds 325 <1> .notfree: 0 00005CD6 3B5508 CMP DX,WORD PTR [DI + BUFSECNO] ; F.C. >32mb ;AN000; 0 00005CD9 750A jne BUMP 0 00005CDB 3B4D0A CMP CX,WORD PTR [DI + BUFSECNO+2] ; F.C. >32mb ;AN000; 0 00005CDE 7505 jne BUMP ; F.C. >32mb ;AN000; 0 00005CE0 3A4504 CMP AL,[DI + BUFDRV] 0 00005CE3 746B je SETINF 332 <1> BUMP: 0 00005CE5 C53D LDS DI,[DI + NEXTBUF] 0 00005CE7 83FFFF CMP DI,-1 0 00005CEA 75DA JNZ NXTBFF 0 00005CEC 36C53E[0000] lds di, [ss:BuffFree] 0 00005CF1 83FFFF cmp di, -1 0 00005CF4 7505 jne .gotfree 0 00005CF6 36C53E[0000] LDS DI,[ss:BUFFHEAD] 340 <1> .gotfree: 0 00005CFB 36FF36[0000] PUSH word [ss:HIGH_SECTOR] ;F.C. >32mb ;AN000; 0 00005D00 56 PUSH SI 0 00005D01 52 PUSH DX 0 00005D02 55 PUSH BP 0 00005D03 06 PUSH ES 346 <1> BUFWRITE equ BufWrite ; NASM port label 0 00005D04 E8BF00 CALL BUFWRITE ; Write out the dirty buffer 0 00005D07 07 POP ES 0 00005D08 5D POP BP 0 00005D09 5A POP DX 0 00005D0A 5E POP SI 0 00005D0B 368F06[0000] POP word [ss:HIGH_SECTOR] ;F.C. >32mb ;AN000; 353 <1> RDSEC: ; Read in the new sector 0 00005D10 7255 JC GETBERR 0 00005D12 36F606[0000]FF TEST BYTE PTR [ss:PREREAD],-1 0 00005D18 751E JNZ SETBUF 357 <1> BufInSiz equ BUFINSIZ ; NASM port equate 0 00005D1A 8D5D10 LEA BX,[DI + BufInSiz] ; Point at buffer 0 00005D1D B90100 MOV CX,1 0 00005D20 56 PUSH SI 0 00005D21 57 PUSH DI 0 00005D22 52 PUSH DX 0 00005D23 85F6 test SI,SI 0 00005D25 7407 JZ NORMSEC 0 00005D27 E8[0000] invoke FATSECRD 0 00005D2A B402 MOV AH,buf_isFAT ; Set buf_flags 0 00005D2C EB05 JMP SHORT GOTTHESEC ; Buffer is marked free if read barfs 368 <1> NORMSEC: 0 00005D2E E8[0000] invoke DREAD ; Buffer is marked free if read barfs 0 00005D31 B400 MOV AH,0 ; Set buf_flags to no type, DO NOT XOR! 371 <1> GOTTHESEC: ; Carry set by either FATSECRD or DREAD 0 00005D33 5A POP DX 0 00005D34 5F POP DI 0 00005D35 5E POP SI 0 00005D36 722F jc GETBERR 376 <1> SETBUF: 0 00005D38 368B0E[0000] MOV CX,[ss:HIGH_SECTOR] ; F.C. >32mb ;AN000; 0 00005D3D 894D0A MOV WORD PTR [DI + BUFSECNO+2],CX ; F.C. >32mb ;AN000; 0 00005D40 895508 MOV WORD PTR [DI + BUFSECNO],DX ; F.C. >32mb ;AN000; 0 00005D43 896D0C MOV WORD PTR [DI + BUFDRVDP],BP 0 00005D46 8C450E MOV WORD PTR [DI + BUFDRVDP+2],ES 0 00005D49 268A4600 MOV AL,[ES:BP + dpb_drive] 0 00005D4D 894504 MOV WORD PTR [DI + BUFDRV],AX ; set buf_flags too 384 <1> SETINF: 0 00005D50 E8A1FE CALL PLACEBUF 386 <1> JUSTBUF: 387 <1> CURBUF equ CurBuf ; NASM port label 0 00005D53 368C1E[0200] MOV WORD PTR [ss:CURBUF+2],DS 0 00005D58 368C1E[0200] MOV WORD PTR [ss:LASTBUFFER+2],DS 0 00005D5D 16 PUSH SS 0 00005D5E 1F POP DS 392 <1> ASSUME DS:DOSGROUP 0 00005D5F 893E[0000] MOV WORD PTR [CURBUF],DI 0 00005D63 893E[0000] MOV WORD PTR [LASTBUFFER],DI 395 <1> GETBERR: 0 00005D67 16 PUSH SS 0 00005D68 1F POP DS 398 <1> ASSUME DS:DOSGROUP 0 00005D69 C3 return 400 <1> GETBUFFR ENDP 401 <1> 402 <1> 403 <1> ;SUBTTL FLUSHBUF -- WRITE OUT DIRTY BUFFERS 404 <1> ;PAGE 405 <1> procedure FlushBuf,NEAR 405 ****************** <1> warning: proc FlushBuf... [-w+user] 406 <1> ASSUME DS:DOSGROUP,ES:NOTHING 407 <1> 408 <1> ; Input: 409 <1> ; DS = DOSGROUP 410 <1> ; AL = Physical unit number 411 <1> ; = -1 for all units 412 <1> ; Function: 413 <1> ; Write out all dirty buffers for unit, and flag them as clean 414 <1> ; DS Preserved, all others destroyed (ES too) 415 <1> 0 00005D6A C53E[0000] LDS DI,[BUFFHEAD] 417 <1> ASSUME DS:NOTHING 0 00005D6E B4FF MOV AH,-1 419 <1> NXTBUFF: 0 00005D70 E82C00 CALL CHECKFLUSH ; Ignore Carry return from CHECKFLUSH. 421 <1> ; FAILERR is set if user FAILed. 0 00005D73 50 PUSH AX 0 00005D74 8A4504 MOV AL,[DI + BUFDRV] 424 <1> WPERR equ WPErr ; NASM port label 0 00005D77 363A06[0000] CMP AL,BYTE PTR [ss:WPERR] 426 <1> ZAP equ Zap ; NASM port label 0 00005D7C 7409 JZ ZAP 0 00005D7E 36F706[0000]0400 TEST word [ss:DOS34_FLAG],FROM_DISK_RESET ;MS. from disk reset ? 0 00005D85 7405 jz NOZAP 430 <1> Zap: 0 00005D87 C74504FF00 MOV WORD PTR [DI + BUFDRV], 00FFh 432 <1> ; (clears buf_flags as well) 433 <1> ; Invalidate buffer, it is inconsistent 434 <1> NOZAP: 0 00005D8C 58 POP AX 0 00005D8D C53D LDS DI,[DI + NEXTBUF] 0 00005D8F 83FFFF CMP DI,-1 0 00005D92 75DC JNZ NXTBUFF 0 00005D94 16 PUSH SS 0 00005D95 1F POP DS 0 00005D96 803E[0000]00 CMP byte [FAILERR],0 0 00005D9B 7401 je .good ; if no int 24h fail --> (NC) 0 00005D9D F9 STC ; Return error if user FAILed (CY) 444 <1> .good: 0 00005D9E C3 return 446 <1> FlushBuf ENDP 447 <1> 448 <1> 449 <1> procedure CHECKFLUSH,NEAR 449 ****************** <1> warning: proc CHECKFLUSH... [-w+user] 450 <1> ASSUME DS:NOTHING,ES:NOTHING 451 <1> ; Carry set if problem (currently user FAILed to I 24) 452 <1> 453 <1> Assert ISBUF,,"CheckFlush" 0 00005D9F 386504 CMP [DI + BUFDRV],AH 0 00005DA2 74FA retz ; Skip free buffers, carry clear 0 00005DA4 38C4 CMP AH,AL 0 00005DA6 7406 JZ DOBUFFER ; Do all dirty buffers 0 00005DA8 3A4504 CMP AL,[DI + BUFDRV] 0 00005DAB F8 CLC 0 00005DAC 75F0 retnz ; Buffer not for this unit or SFT 461 <1> DOBUFFER: 0 00005DAE F6450540 TEST byte [DI + buf_flags],buf_dirty 0 00005DB2 74EA retz ; Buffer not dirty, carry clear by TEST 0 00005DB4 50 PUSH AX 0 00005DB5 FF7504 PUSH WORD PTR [DI + BUFDRV] ; (reads buf_flags as well) 0 00005DB8 E80B00 CALL BUFWRITE 0 00005DBB 58 POP AX 0 00005DBC 7206 JC LEAVE_BUF ; Leave buffer marked free (lost). 0 00005DBE 80E4BF and ah, ~ buf_dirty ; Buffer is clean 0 00005DC1 894504 MOV WORD PTR [DI + BUFDRV],AX 471 <1> ; (sets buf_flags as well) 472 <1> LEAVE_BUF: 0 00005DC4 58 POP AX ; Search info 0 00005DC5 C3 return 475 <1> EndProc CHECKFLUSH 476 <1> 477 <1> 478 <1> ;SUBTTL BUFWRITE -- WRITE OUT A BUFFER IF DIRTY 479 <1> ;PAGE 480 <1> procedure BufWrite,NEAR 480 ****************** <1> warning: proc BufWrite... [-w+user] 481 <1> ASSUME DS:NOTHING,ES:NOTHING 482 <1> 483 <1> ; Input: 484 <1> ; DS:DI Points to the buffer 485 <1> ; Function: 486 <1> ; Write out all the buffer if dirty. 487 <1> ; Output: 488 <1> ; Buffer marked free 489 <1> ; Carry set if error (currently user FAILed to I 24) 490 <1> ; DS:DI Preserved, ALL others destroyed (ES too) 491 <1> 0 00005DC6 B8FF00 MOV AX,00FFH 0 00005DC9 874504 XCHG AX,WORD PTR [DI + BUFDRV] ; Free, in case write barfs 494 <1> ; (sets buf_flags as well) 0 00005DCC 3CFF CMP AL,0FFH 0 00005DCE 74F5 retz ; Buffer is free. (NC) 0 00005DD0 F6C440 test ah, buf_dirty 0 00005DD3 74F0 retz ; Buffer is clean. (NC) 0 00005DD5 E86400 invoke DEC_DIRTY_COUNT ; LB. decrement dirty count 0 00005DD8 363A06[0000] CMP AL,BYTE PTR [ss:WPERR] 0 00005DDD 74E6 retz ; If in WP error zap buffer 0 00005DDF C46D0C LES BP,[DI + BUFDRVDP] 0 00005DE2 8D5D10 LEA BX,[DI + BufInSiz] ; Point at buffer 0 00005DE5 8B5508 MOV DX,WORD PTR [DI + BUFSECNO] ;F.C. >32mb ;AN000; 0 00005DE8 8B4D0A MOV CX,WORD PTR [DI + BUFSECNO+2] ;F.C. >32mb ;AN000; 0 00005DEB 36890E[0000] MOV [ss:HIGH_SECTOR],CX ;F.C. >32mb ;AN000; 507 <1> 0 00005DF0 B90100 mov cx, 1 ; Default to not a FAT sector 0 00005DF3 F6450502 test byte [di + buf_flags], buf_isFAT 0 00005DF7 7408 jz .notfat 0 00005DF9 268B460F mov ax, [es:bp + dpb_FAT_size] 0 00005DFD 268A4E08 mov cl, [es:bp + dpb_FAT_count] 513 <1> .notfat: 514 <1> 515 <1> allowed_RETRY equ Allowed_RETRY ; NASM port equate 516 <1> allowed_FAIL equ Allowed_FAIL ; NASM port equate 0 00005E01 36C606[0000]18 MOV byte [ss:ALLOWED],allowed_RETRY + allowed_FAIL 0 00005E07 F6450508 TEST byte [DI + buf_flags],buf_isDATA 0 00005E0B 7406 JZ NO_IGNORE 520 <1> allowed_IGNORE equ Allowed_IGNORE ; NASM port equate 0 00005E0D 36800E[0000]20 OR byte [ss:ALLOWED],allowed_IGNORE 522 <1> NO_IGNORE: 0 00005E13 57 PUSH DI ; Save buffer pointer 0 00005E14 31FF XOR DI,DI ; Indicate failure 525 <1> WRTAGAIN: 0 00005E16 575150 SaveReg 0 00005E19 B90100 MOV CX,1 0 00005E1C 53521E SaveReg 529 <1> 0 00005E1F E8[0000] invoke DWRITE ; Write out the dirty buffer 531 <1> 0 00005E22 1F5A5B RestoreReg 0 00005E25 58595F RestoreReg 0 00005E28 7201 JC NOSET 0 00005E2A 47 INC DI ; If at least ONE write succeedes, the operation 536 <1> NOSET: ; succeedes. 0 00005E2B 01C2 ADD DX,AX 0 00005E2D E2E7 LOOP WRTAGAIN 0 00005E2F 85FF test DI,DI ; Clears carry 0 00005E31 7501 JNZ BWROK ; At least one write worked --> (NC) 0 00005E33 F9 STC ; DI never got INCed, all writes failed. 542 <1> BWROK: 0 00005E34 5F POP DI 0 00005E35 C3 return 545 <1> BufWrite ENDP 546 <1> 547 <1> Break 548 <1> 549 <1> ; Input: 550 <1> ; none 551 <1> ; Function: 552 <1> ; increment dirty buffers count 553 <1> ; Output: 554 <1> ; dirty buffers count in the current hash entry is incremented 555 <1> ; 556 <1> ; All registers preserved 557 <1> 558 <1> procedure INC_DIRTY_COUNT,NEAR 558 ****************** <1> warning: proc INC_DIRTY_COUNT... [-w+user] 559 <1> ASSUME DS:NOTHING,ES:NOTHING 0 00005E36 36FF06[0000] INC word [ss:BUF2_Dirty_Count] ;LB. add 1 ;AN000; 0 00005E3B C3 return 562 <1> EndProc INC_DIRTY_COUNT ;LB. return ;AN000; 563 <1> 564 <1> Break 565 <1> 566 <1> ; Input: 567 <1> ; none 568 <1> ; Function: 569 <1> ; decrement dirty buffers count 570 <1> ; Output: 571 <1> ; dirty buffers count in the current hash entry is decremented 572 <1> ; 573 <1> ; All registers preserved 574 <1> 575 <1> procedure DEC_DIRTY_COUNT,NEAR 575 ****************** <1> warning: proc DEC_DIRTY_COUNT... [-w+user] 576 <1> ASSUME DS:NOTHING,ES:NOTHING 0 00005E3C 36833E[0000]00 CMP word [ss:BUF2_Dirty_Count],0 ;LB. in case if 0 ;AN000; 0 00005E42 7405 je nodec ;LB. do nothing ;AN000; 0 00005E44 36FF0E[0000] DEC word [ss:BUF2_Dirty_Count] ;LB. sub 1 ;AN000; 580 <1> nodec: 0 00005E49 C3 return 582 <1> EndProc DEC_DIRTY_COUNT ;LB. return ;AN000; 583 <1> 584 <1> END 56 %else 57 58 %iassign Installed TRUE 59 60 i_need BuffHead,DWORD 61 i_need PreRead,WORD 62 i_need LastBuffer,DWORD 63 i_need CurBuf,DWORD 64 i_need WPErr,BYTE 65 i_need ALLOWED,BYTE 66 i_need FAILERR,BYTE 67 i_need HIGH_SECTOR,WORD ; DOS 4.00 >32mb ;AN000; 68 i_need CurHashEntry,DWORD ; DOS 4.00 current Hash entry ;AN000; 69 i_need BUF_HASH_PTR,DWORD ; DOS 4.00 Hash table pointer ;AN000; 70 i_need BUF_HASH_COUNT,WORD ; DOS 4.00 Hash table entries ;AN000; 71 i_need SC_CACHE_PTR,DWORD ; DOS 4.00 seconadary cache table ;AN000; 72 i_need SC_CACHE_COUNT,WORD ; DOS 4.00 secondary cache entries ;AN000; 73 i_need BUF_EMS_MODE,BYTE ; DOS 4.00 EMS mode ;AN000; 74 i_need BUF_EMS_HANDLE,WORD ; DOS 4.00 buffer EMS handle ;AN000; 75 i_need SC_SECTOR_SIZE,WORD ; DOS 4.00 sector size ;AN000; 76 i_need SC_DRIVE,BYTE ; DOS 4.00 drive ;AN000; 77 i_need ACT_PAGE,WORD ; DOS 4.00 active logical EMS page ;AN000; 78 i_need DOS34_FLAG,WORD ; DOS 4.00 common flag ;AN000; 79 i_need BUF_EMS_SEG_CNT,WORD ; DOS 4.00 EMS seg count ;AN000; 80 i_need BUF_EMS_MAP_BUFF,BYTE ; DOS 4.00 EMS map buffer ;AN000; 81 i_need FIRST_BUFF_ADDR,WORD ; DOS 4.00 beginning of the chain ;AN000; 82 i_need BUF_EMS_PAGE_FRAME,WORD ; DOS 4.00 EMS page frame ;AN000; 83 84 %IF BUFFERFLAG 85 i_need BUF_EMS_PFRAME,WORD 86 i_need BUF_EMS_LAST_PAGE,WORD 87 i_need BUF_EMS_FIRST_PAGE,WORD 88 i_need BUF_EMS_SAFE_FLAG,byte 89 i_need BUF_EMS_NPA640,WORD 90 i_need NEXTADD,WORD 91 i_need DMAADD,DWORD 92 i_need BYTCNT1,WORD 93 i_am BUF_EMS_MAP_BUF,12,<0,0,0,0,0,0,0,0,0,0,0,0> 94 i_am CURADD,WORD 95 i_am low_ems_buf,512 96 extrn SAVE_USER_MAP:near 97 extrn RESTORE_USER_MAP:near 98 %ENDIF 99 100 101 Break 102 103 ; Inputs: 104 ; DX= sector number (LOW) 105 ; [HIGH_SECTOR]= sector number (HIGH) 106 ; Function: 107 ; Hash into a buffer group and activate the extended memory if 108 ; necessary 109 ; Outputs: 110 ; [CurHashEntry] = current Hash entry addr 111 ; DS:DI = 1st buffer addr of the current Hash entry 112 ; No other registers altered 113 114 procedure GETCURHEAD,NEAR 115 ASSUME DS:NOTHING,ES:NOTHING 116 117 PUSH DX ;LB. save regs ;AN000; 118 PUSH AX ;LB. ;AN000; 119 PUSH BX ;LB. ;AN000; 120 MOV AX,DX ;LB. ;AN000; 121 ; MOV DX,[HIGH_SECTOR] ;LB. HASH(sector#) and get entry # ;AN000; 122 XOR DX,DX ;LB. to avoid divide overflow ;AN000; 123 DIV word [ss:BUF_HASH_COUNT] ;LB. get remainder ;AN000; 124 ADD DX,DX ;LB. 8 bytes per entry ;AN000; 125 ADD DX,DX ;LB. ;AN000; 126 ADD DX,DX ;LB. times 8 ;AN000; 127 128 LDS DI,[ss:BUF_HASH_PTR] ;LB. get Hash Table addr ;AN000; 129 ADD DI,DX ;LB position to entry ;AN000; 130 Map_Entry2: 131 MOV WORD PTR [ss:CurHashEntry+2],DS ;LB. update current Hash entry ptr ;AN000; 132 MOV WORD PTR [ss:CurHashEntry],DI ;LB. ;AN000; 133 LASTBUFFER equ LastBuffer ; NASM port label 134 MOV WORD PTR [ss:LASTBUFFER],-1 ;LB. invalidate last buffer ;AN000; 135 MOV BX,[DI + EMS_PAGE_NUM] ;LB. logical page ;AN000; 136 137 %IFN BUFFERFLAG 138 LDS DI,[DI + BUFFER_BUCKET] ;LB. ds:di is 1st buffer addr ;AN000; 139 MOV [ss:FIRST_BUFF_ADDR],DI ;LB. 1/19/88 save first buffer addr ;AN000; 140 CALL SET_MAP_PAGE ;LB. activate handle if EMS there ;AN000; 141 %ELSE 142 push ax 143 mov ax, [ss:NEXTADD] 144 mov [ss:CURADD], ax 145 pop ax 146 CALL SET_MAP_PAGE ;LB. activate handle if EMS there ;AN000; 147 LDS DI,[DI + BUFFER_BUCKET] ;LB. ds:di is 1st buffer addr ;AN000; 148 MOV [ss:FIRST_BUFF_ADDR],DI ;LB. 1/19/88 save first buffer addr ;AN000; 149 %ENDIF 150 151 ;AN000; 152 POP BX ;LB. ;AN000; 153 POP AX ;LB. ;AN000; 154 POP DX ;LB. ;AN000; 155 return ;LB. ;AN000; 156 EndProc GETCURHEAD ;AN000; 157 158 ;AN000; 159 Break ;AN000; 160 ; Inputs: ;AN000; 161 ; BX= logical page ;AN000; 162 ; Function: ;AN000; 163 ; Map handle and logical page to frame 0 page 0 ;AN000; 164 ; Outputs: ;AN000; 165 ; AH=0 success ;AN000; 166 ; No other registers altered ;AN000; 167 ;AN000; 168 Procedure SET_MAP_PAGE,NEAR ;AN000; 169 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 170 171 ; int 3 172 ;AN000; 173 CMP byte [ss:BUF_EMS_MODE],-1 ;LB. EMS support ;AN000; 174 JZ No_map ;LB. no ;AN000; 175 176 %IFN BUFFERFLAG 177 CMP [ss:ACT_PAGE],BX ;LB. already mapped ? ;AN000; 178 JZ No_map ;LB. yes ;AN000; 179 %ENDIF 180 MOV [ss:ACT_PAGE],BX ;LB. save active page mapped ;AN000; 181 182 %IF BUFFERFLAG 183 cmp byte [ss:BUF_EMS_SAFE_FLAG], 1 184 je no_coll 185 ; int 3 186 call detect_collision 187 no_coll: 188 %ENDIF 189 190 MOV DX,[ss:BUF_EMS_HANDLE] ;LB. ;AN000; 191 MOV AH,44H ;LB. activate current handle ;AN000; 192 MOV AL,BYTE PTR [ss:BUF_EMS_PAGE_FRAME] ;LB. page frame number ;AN000; 193 INT 67H ;LB. ;AN000; 194 No_map: ;AN000; 195 return ;AN000; 196 EndProc SET_MAP_PAGE ;AN000; 197 ;AN000; 198 199 %IF BUFFERFLAG 200 201 Break ;AN000; 202 ; Inputs: ;AN000; 203 ; none ;AN000; 204 ; Function: ;AN000; 205 ; save map ;AN000; 206 ; Outputs: ;AN000; 207 ; none ;AN000; 208 ; No other registers altered ;AN000; 209 ;AN000; 210 Procedure SAVE_MAP,NEAR ;AN000; 211 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 212 ;AN000; 213 CMP byte [ss:BUF_EMS_MODE],-1 ;LB. EMS support ;AN000; 214 JZ No_save ;LB. no ;AN000; 215 MOV word [ss:ACT_PAGE],-1 ;LB. invalidate active page ;AN000; 216 MOV WORD PTR [ss:LASTBUFFER],-1 ;LB. and last buffer pointer ;AN000; 217 PUSH AX ;LB. save regs ;AN000; 218 PUSH DS ;LB. save regs ;AN000; 219 PUSH ES ;LB. ;AN000; 220 PUSH SI ;LB. ;AN000; 221 PUSH DI ;LB. ;AN000; 222 MOV SI,OFFSET BUF_EMS_SEG_CNT wrt DOSGROUP ;LB. ;AN000; 223 MOV DI,OFFSET BUF_EMS_MAP_BUF wrt DOSGROUP ;LB. ;AN000; 224 225 PUSH ss 226 POP ES 227 PUSH ss ;LB. ;AN000; 228 POP DS ;LB. ds:si -> ems seg count ;AN000; 229 230 MOV AX,4F00H ;LB. save map ;AN000; 231 EnterCrit critDisk ;LB. enter critical section ;AN000; 232 INT 67H ;LB. ;AN000; 233 LeaveCrit critDisk ;LB. leave critical section ;AN000; 234 POP DI ;LB. ;AN000; 235 POP SI ;LB. restore regs ;AN000; 236 POP ES ;LB. ;AN000; 237 POP DS ;LB. ;AN000; 238 POP AX ;LB. restore ;AN000; 239 No_save: ;AN000; 240 return ;AN000; 241 EndProc SAVE_MAP ;AN000; 242 ;AN000; 243 244 Break ;AN000; 245 ; Inputs: ;AN000; 246 ; none ;AN000; 247 ; Function: ;AN000; 248 ; restore_map ;AN000; 249 ; Outputs: ;AN000; 250 ; none ;AN000; 251 ; No other registers altered ;AN000; 252 ;AN000; 253 Procedure RESTORE_MAP,NEAR ;AN000; 254 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 255 ;AN000; 256 CMP byte [ss:BUF_EMS_MODE],-1 ;LB. EMS support ;AN000; 257 JZ No_restore ;LB. no ;AN000; 258 PUSH AX ;LB. save regs ;AN000; 259 PUSH DS ;LB. save regs ;AN000; 260 PUSH SI ;LB. ;AN000; 261 MOV SI,OFFSET BUF_EMS_MAP_BUF wrt DOSGROUP ;LB. ;AN000; 262 263 PUSH ss 264 POP DS 265 MOV AX,4F01H ;LB. restore map ;AN000; 266 EnterCrit critDisk ;LB. enter critical section ;AN000; 267 INT 67H ;LB. ;AN000; 268 LeaveCrit critDisk ;LB. leave critical section ;AN000; 269 POP SI ;LB. restore regs ;AN000; 270 POP DS ;LB. ;AN000; 271 POP AX ;LB. ;AN000; 272 No_restore: ;AN000; 273 return ;AN000; 274 EndProc RESTORE_MAP ;AN000; 275 276 %ENDIF 277 ;AN000; 278 ;AN000; 279 280 Break 281 282 ; Inputs: 283 ; Same as PLACEBUF 284 ; Function: 285 ; Save scan location and call PLACEBUF 286 ; Outputs: 287 ; DS:DI Points to saved scan location 288 ; SI destroyed, other registers unchanged 289 290 procedure ScanPlace,near 291 ASSUME DS:NOTHING,ES:NOTHING 292 293 ;; PUSH ES 294 ;; LES SI,[DI.buf_link] ; Save scan location 295 MOV SI,[DI + buf_next] ; Save scan location 296 CALL PLACEBUF 297 ;; PUSH ES 298 ;; POP DS ; Restore scan location 299 MOV DI,SI 300 ;; POP ES 301 return 302 EndProc ScanPlace 303 304 ; Rewritten PLACEBUF (LKR), eliminates loops 305 ; 306 ; Input: 307 ; DS:DI points to buffer (DS->BUFFINFO array, DI=offset in array) 308 ; Function: 309 ; Remove buffer from queue and re-insert it in proper place. 310 ; NO registers altered 311 312 procedure PLACEBUF,NEAR 313 ASSUME DS:NOTHING,ES:NOTHING 314 315 ; invoke save_world 316 push AX ;Save only regs we modify ;AN000; 317 push BX ;AN000; 318 push SI ;AN000; 319 push ES ;AN000; 320 321 les SI,[ss:CurHashEntry] ;ES:SI -> Current Hash entry ;AN000; 322 mov BX,word ptr [ES:SI + BUFFER_BUCKET] ;BX = offset of head of list ;AN000; 323 324 cmp [DI + buf_next],BX ;Buf = last? ;AN000; 325 je nret ;Yes, special case ;AN000; 326 cmp DI,BX ;Buf = first? ;AN000; 327 je bufloop ;Yes, special case ;AN000; 328 mov SI,[DI + buf_prev] ;No, SI = prior Buf ;AN000; 329 mov AX,[DI + buf_next] ;Now delete Buf from list ;AN000; 330 mov [SI + buf_next],AX ;AN000; 331 push SI ;Save si ;AN000; 332 mov SI,[DI + buf_next] ;Update backward pointer ;AN000; 333 mov AX,[DI + buf_prev] ; ;AN000; 334 mov [SI + buf_prev],AX ; ;AN000; 335 pop si ;Restore si ;AN000; 336 lookend: ;(label is now a misnomer) ;AN000; 337 mov SI,[BX + buf_prev] ;SI-> last buffer ;AN000; 338 mov [SI + buf_next],DI ;Add Buf to end of list ;AN000; 339 mov [BX + buf_prev],DI ;AN000; 340 mov [DI + buf_prev],SI ;Update linkage in Buf too ;AN000; 341 mov [DI + buf_next],BX ;AN000; 342 nret: ;AN000; 343 ;AN000; 344 ; invoke restore_world ;AN000; 345 pop ES ;Restore regs we modified ;AN000; 346 pop SI ;AN000; 347 pop BX ;AN000; 348 pop AX ;AN000; 349 ;AN000; 350 cmp byte [DI + buf_ID],-1 ; Buffer FREE? ;AN000; 351 retnz ; No ;AN000; 352 invoke PLACEHEAD ; Buffer is free, belongs at hea;AN000; 353 return ;AN000; 354 bufloop: ;(label is now a misnomer) ;AN000; 355 mov BX,[DI + buf_next] ;Set new head position ;AN000; 356 mov word ptr [ES:SI + BUFFER_BUCKET],BX ;AN000; 357 jmp nret ;Continue with repositioning ;AN000; 358 359 EndProc PLACEBUF 360 361 ; SAME AS PLACEBUF except places buffer at head 362 ; NOTE:::::: ASSUMES THAT BUFFER IS CURRENTLY THE LAST 363 ; ONE IN THE LIST!!!!!!! 364 ; Rewritten PLACEBUF, takes buffer from end of list to head of list 365 366 procedure PLACEHEAD,NEAR ;AN000; 367 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 368 push ES ;AN000; 369 push SI ;AN000; 370 les SI,[ss:CurHashEntry] ;AN000; 371 mov word ptr [ES:SI + BUFFER_BUCKET],DI ;AN000; 372 pop SI ;AN000; 373 pop ES ;AN000; 374 return ;AN000; 375 EndProc PLACEHEAD ;AN000; 376 377 378 Break 379 380 ; Compare DS:SI to ES:DI (or DS:DI to ES:SI) for equality 381 ; DO NOT USE FOR < or > 382 ; No Registers altered 383 384 procedure PointComp,NEAR 385 ASSUME DS:NOTHING,ES:NOTHING 386 387 CMP SI,DI 388 retnz 389 PUSH CX 390 PUSH DX 391 MOV CX,DS 392 MOV DX,ES 393 CMP CX,DX 394 POP DX 395 POP CX 396 return 397 EndProc PointComp 398 399 Break 400 401 ; Input: 402 ; AL = 0 means sector must be pre-read 403 ; ELSE no pre-read 404 ; DX = Desired physical sector number (LOW) 405 ; [HIGH_SECTOR]= Desired physical sector number (HIGH) 406 ; ES:BP = Pointer to drive parameters 407 ; [ALLOWED] set in case of INT 24 408 ; Function: 409 ; Get the specified local sector into one of the I/O buffers 410 ; And shuffle the queue 411 ; Output: 412 ; [CURBUF] Points to the Buffer for the sector 413 ; THE BUFFER TYPE FIELD OF buf_flags = 0, caller must set it 414 ; Carry set if error (currently user FAILed to INT 24) 415 ; DS,DX,ES:BP unchanged, all other registers destroyed 416 417 procedure GETBUFFR,NEAR 418 DOSAssume CS,,"GetBuffr" 419 ASSUME ES:NOTHING 420 421 XOR SI,SI 422 423 entry GETBUFFRB 424 425 Assert ISDPB,,"GetBuffr" 426 PREREAD equ PreRead ; NASM port label 427 MOV [PREREAD],AX 428 MOV AL,[ES:BP + dpb_drive] 429 LDS DI,[LASTBUFFER] 430 ASSUME DS:NOTHING 431 MOV CX,[ss:HIGH_SECTOR] ; F.C. >32mb ;AN000; 432 CMP DI,-1 ; Recency pointer valid? 433 JZ SKBUF ; No 434 435 CMP DX,WORD PTR [DI + buf_sector] 436 JNZ SKBUF ; Wrong sector 437 CMP CX,WORD PTR [DI + buf_sector+2] ; F.C. >32mb ;AN000; 438 JNZ SKBUF ; F.C. >32mb ;AN000; 439 CMP AL,[DI + buf_ID] 440 JNZ SKBUF ; Wrong Drive 441 442 JMP JUSTBUF ; Just asked for same buffer 443 SKBUF: 444 CALL GETCURHEAD ;LB. get cuurent Hash entry ;AN000; 445 ; LDS DI,[BUFFHEAD] 446 NXTBFF: 447 CMP DX,WORD PTR [DI + buf_sector] ; F.C. >32mb ;AN000; 448 JNZ BUMP 449 CMP CX,WORD PTR [DI + buf_sector+2] ; F.C. >32mb ;AN000; 450 JNZ BUMP ; F.C. >32mb ;AN000; 451 CMP AL,[DI + buf_ID] 452 %ifn BUFFERFLAG 453 JZ SETINF 454 %else 455 bump equ BUMP ; NASM port label 456 jnz bump 457 setinf equ SETINF ; NASM port label 458 jmp setinf 459 %endif 460 BUMP: 461 mov DI,[DI + buf_next] ;;;;;;1/19/88 ;AN000; 462 cmp DI,[ss:FIRST_BUFF_ADDR] ;;;;;;1/19/88 ;AN000; 463 JNZ NXTBFF 464 ;;;; LDS DI,[CurHashEntry] ;LB. secondary cache's use ;AN000; 465 ;;;; LDS DI,[DI.BUFFER_BUCKET] ;LB. ;AN000; 466 ; LDS DI,[BUFFHEAD] 467 PUSH word [ss:HIGH_SECTOR] ;F.C. >32mb ;AN000; 468 PUSH SI 469 PUSH DX 470 PUSH BP 471 PUSH ES 472 BUFWRITE equ BufWrite ; NASM port label 473 CALL BUFWRITE ; Write out the dirty buffer 474 POP ES 475 POP BP 476 POP DX 477 POP SI 478 POP word [ss:HIGH_SECTOR] ;F.C. >32mb ;AN000; 479 %ifn BUFFERFLAG 480 JC GETBERR 481 %else 482 jnc skip_getberr 483 getberr equ GETBERR ; NASM port label 484 jmp getberr 485 skip_getberr: 486 %endif 487 CALL SET_RQ_SC_PARMS ;LB. set parms ;AN000; 488 XOR AH,AH ; initial flags 489 TEST BYTE PTR [ss:PREREAD],-1 ; Read in the new sector 490 JNZ SETBUF 491 BufInSiz equ BUFINSIZ ; NASM port equate 492 LEA BX,[DI + BufInSiz] ; Point at buffer 493 MOV CX,1 494 PUSH SI 495 PUSH DI 496 PUSH DX 497 ; Note: As far as I can tell, all disk reads into buffers go through this point. -mrw 10/88 498 %if BUFFERFLAG 499 ; int 3 500 buf_ems_mode equ BUF_EMS_MODE ; NASM port label 501 cmp byte [ss:buf_ems_mode], -1 502 jz normread 503 push bx 504 push ds ; save ds:bx --> ems_buffer 505 push ss 506 pop ds 507 dosgroup equ DOSGROUP ; NASM port equate 508 mov bx, offset low_ems_buf wrt dosgroup ; ds:bx --> low_ems_buffer 509 normread: 510 %endif 511 OR SI,SI 512 JZ NORMSEC 513 invoke FATSECRD 514 MOV AH,buf_isFAT ; Set buf_flags 515 JMP SHORT GOTTHESEC ; Buffer is marked free if read barfs 516 NORMSEC: 517 invoke DREAD ; Buffer is marked free if read barfs 518 MOV AH,0 ; Set buf_flags to no type, DO NOT XOR! 519 GOTTHESEC: ; Carry set by either FATSECRD or DREAD 520 %if BUFFERFLAG 521 pushf 522 jc skipreadtrans 523 cmp byte [ss:buf_ems_mode], -1 524 je skipreadtrans 525 526 popf 527 pop ds 528 pop bx ; restore ems_buffer pointer 529 pushf 530 531 push cx ; save regs to be used by rep mov 532 push ds 533 push es 534 535 mov di, bx 536 push ds 537 pop es ; es:di --> ems_buf 538 mov si, offset low_ems_buf wrt dosgroup 539 push ss 540 pop ds ; ds:si --> low_ems_buf 541 mov cx, 512/2 542 rep movsw 543 544 pop es ; restore regs. 545 pop ds 546 pop cx 547 skipreadtrans: 548 popf 549 %endif 550 POP DX 551 POP DI 552 POP SI 553 JC GETBERR 554 SETBUF: 555 MOV CX,[ss:HIGH_SECTOR] ; F.C. >32mb ;AN000; 556 MOV WORD PTR [DI + buf_sector+2],CX ; F.C. >32mb ;AN000; 557 MOV WORD PTR [DI + buf_sector],DX ; F.C. >32mb ;AN000; 558 MOV WORD PTR [DI + buf_DPB],BP 559 MOV WORD PTR [DI + buf_DPB+2],ES 560 MOV AL,[ES:BP + dpb_drive] 561 MOV WORD PTR [DI + buf_ID],AX ; Sets buf_flags too, to AH 562 SETINF: 563 MOV byte [DI + buf_wrtcnt],1 ; Default to not a FAT sector ;AC000; 564 XOR AX,AX ;>32mb ;AN000; 565 OR SI,SI 566 JZ SETSTUFFOK 567 MOV AL,[ES:BP + dpb_FAT_count] 568 MOV [DI + buf_wrtcnt],AL ;>32mb ;AN000; 569 MOV AX,[ES:BP + dpb_FAT_size] 570 SETSTUFFOK: 571 MOV [DI + buf_wrtcntinc],AX ;>32mb ;AC000; 572 CALL PLACEBUF 573 JUSTBUF: 574 CURBUF equ CurBuf ; NASM port label 575 MOV WORD PTR [ss:CURBUF+2],DS 576 MOV WORD PTR [ss:LASTBUFFER+2],DS 577 MOV WORD PTR [ss:CURBUF],DI 578 MOV WORD PTR [ss:LASTBUFFER],DI 579 CLC 580 GETBERR: 581 Context DS 582 return 583 EndProc GETBUFFR 584 585 Break 586 587 ; Input: 588 ; DS = DOSGROUP 589 ; AL = Physical unit number local buffers only 590 ; = -1 for all units and all remote buffers 591 ; Function: 592 ; Write out all dirty buffers for unit, and flag them as clean 593 ; Carry set if error (user FAILed to I 24) 594 ; Flush operation completed. 595 ; DS Preserved, all others destroyed (ES too) 596 597 procedure FlushBuf,NEAR 598 DOSAssume CS,,"FlushBuf" 599 ASSUME ES:NOTHING 600 601 MOV AH,-1 602 ; LDS DI,[BUFFHEAD] 603 ASSUME DS:NOTHING 604 605 LDS DI,[ss:BUF_HASH_PTR] ;LB. get Hash Table addr ;AN000; 606 MOV CX,[ss:BUF_HASH_COUNT] ;LB. get Hash entry count ;AN000; 607 XOR DX,DX ;LB. set initial index to 0 ;AN000; 608 609 NXTBUFF2: 610 PUSH CX ;LB. save Hash entry count ;AN000; 611 TEST word [ss:DOS34_FLAG],FROM_DISK_RESET ;MS. from disk reset ;AN004; 612 JNZ Zapzap ;MS. yes ;AN004; 613 Dirty_Count equ DIRTY_COUNT ; NASM port equate 614 CMP byte [DI + Dirty_Count],0 ;LB. dirty entry ? ;AN000; 615 JZ getnext ;LB. no ;AN000; 616 Zapzap: ;AN004; 617 PUSH DS ;LB. save regs ;AN000; 618 PUSH DI ;LB. ;AN000; 619 invoke Map_Entry ;LB. ds:di -> first buffer addr ;AN000; 620 NXTBUFF: 621 CALL CHECKFLUSH ; Ignore Carry return from CHECKFLUSH. 622 ; FAILERR is set if user FAILed. 623 PUSH AX 624 MOV AL,[DI + buf_ID] 625 WPERR equ WPErr ; NASM port label 626 CMP AL,BYTE PTR [ss:WPERR] 627 ZAP equ Zap ; NASM port label 628 JZ ZAP 629 TEST word [ss:DOS34_FLAG],FROM_DISK_RESET ;MS. from disk reset ;AN000; 630 JNZ Zap ;MS. yes ;AN000; 631 632 NOZAP: 633 POP AX 634 mov DI,[DI + buf_next] ;;;;1/19/88 ;AN000; 635 CMP DI,[ss:FIRST_BUFF_ADDR] ;;;;1/19/88 ;AN000; 636 JNZ NXTBUFF 637 638 POP DI ;LB. ;AN000; 639 POP DS ;LB. ;AN000; 640 getnext: 641 ADD DI,BUFFER_HASH_ENTRY_struc_size ;LB. position to next entry ;AN000; 642 POP CX ;LB. restore entry count ;AN000; 643 LOOP NXTBUFF2 ;LB. get next entry buffer ;AN000; 644 Context DS 645 CMP byte [FAILERR],0 646 FLSHBad equ FlshBad ; NASM port label 647 JNZ FLSHBad ; Carry clear if JMP 648 return 649 FlshBad: 650 STC ; Return error if user FAILed 651 return 652 Zap: 653 MOV WORD PTR [DI + buf_ID],00FFH ; Invalidate buffer, it is inconsistent 654 NoZap equ NOZAP ; NASM port label 655 JMP NoZap 656 657 EndProc FlushBuf 658 659 procedure CHECKFLUSH,NEAR 660 ASSUME DS:NOTHING,ES:NOTHING 661 ; Carry set if problem (currently user FAILed to I 24) 662 663 Assert ISBUF,,"CheckFlush" 664 CMP [DI + buf_ID],AH 665 retz ; Skip free buffers, carry clear 666 CMP AH,AL 667 JZ DOBUFFER ; Do all dirty buffers 668 CMP AL,[DI + buf_ID] 669 CLC 670 retnz ; Buffer not for this unit or SFT 671 DOBUFFER: 672 TEST byte [DI + buf_flags],buf_dirty 673 retz ; Buffer not dirty, carry clear by TEST 674 PUSH AX 675 PUSH WORD PTR [DI + buf_ID] 676 CALL BUFWRITE 677 POP AX 678 JC LEAVE_BUF ; Leave buffer marked free (lost). 679 AND AH,~ buf_dirty ; Buffer is clean, clears carry 680 MOV WORD PTR [DI + buf_ID],AX 681 LEAVE_BUF: 682 POP AX ; Search info 683 return 684 EndProc CHECKFLUSH 685 686 Break 687 688 ; Input: 689 ; DS:DI Points to the buffer 690 ; Function: 691 ; Write out all the buffer if dirty. 692 ; Output: 693 ; Buffer marked free 694 ; Carry set if error (currently user FAILed to I 24) 695 ; DS:DI Preserved, ALL others destroyed (ES too) 696 697 procedure BufWrite,NEAR 698 ASSUME DS:NOTHING,ES:NOTHING 699 700 Assert ISBUF,,"BufWrite" 701 MOV AX,00FFH 702 XCHG AX,WORD PTR [DI + buf_ID] ; Free, in case write barfs 703 CMP AL,0FFH 704 retz ; Buffer is free, carry clear. 705 TEST AH,buf_dirty 706 retz ; Buffer is clean, carry clear. 707 invoke DEC_DIRTY_COUNT ; LB. decrement dirty count 708 CMP AL,BYTE PTR [ss:WPERR] 709 retz ; If in WP error zap buffer 710 MOV [ss:SC_DRIVE],AL ;LB. set it for invalidation ;AN000; 711 LES BP,[DI + buf_DPB] 712 LEA BX,[DI + BufInSiz] ; Point at buffer 713 MOV DX,WORD PTR [DI + buf_sector] ;F.C. >32mb ;AN000; 714 MOV CX,WORD PTR [DI + buf_sector+2] ;F.C. >32mb ;AN000; 715 MOV [ss:HIGH_SECTOR],CX ;F.C. >32mb ;AN000; 716 MOV CL,[DI + buf_wrtcnt] ;>32mb ;AC000; 717 ; MOV AL,CH ; [DI.buf_wrtcntinc] 718 XOR CH,CH 719 MOV AX,[DI + buf_wrtcntinc] ;>32mb ;AC000; 720 allowed_RETRY equ Allowed_RETRY ; NASM port equate 721 allowed_FAIL equ Allowed_FAIL ; NASM port equate 722 MOV byte [ss:ALLOWED],allowed_RETRY + allowed_FAIL 723 TEST byte [DI + buf_flags],buf_isDATA 724 JZ NO_IGNORE 725 allowed_IGNORE equ Allowed_IGNORE ; NASM port equate 726 OR byte [ss:ALLOWED],allowed_IGNORE 727 NO_IGNORE: 728 PUSH DI ; Save buffer pointer 729 XOR DI,DI ; Indicate failure 730 WRTAGAIN: 731 SaveReg 732 MOV CX,1 733 SaveReg 734 ; Note: As far as I can tell, all disk reads into buffers go through this point. -mrw 10/88 735 736 %if BUFFERFLAG 737 ; int 3 738 cmp byte [ss:buf_ems_mode], -1 739 jz skipwritetrans 740 741 push es 742 push di 743 push si 744 push cx 745 746 mov si, bx ; ds:si --> ems_buffer 747 mov di, offset low_ems_buf wrt dosgroup 748 push ss 749 pop es ; es:di --> low_ems_buffer 750 mov cx, 512/2 751 rep movsw 752 753 pop cx 754 pop si 755 pop di 756 pop es 757 758 push ds 759 push bx 760 mov bx, offset low_ems_buf wrt dosgroup 761 push ss 762 pop ds ; ds:bx --> low_ems_buffer 763 skipwritetrans: 764 %endif 765 766 invoke DWRITE ; Write out the dirty buffer 767 768 %if BUFFERFLAG 769 pushf ; save carry flag from DWRITE 770 cmp byte [ss:buf_ems_mode], -1 771 jz normwrite 772 popf ; need to get at stack 773 pop bx ; ds:bx --> ems_buffer 774 pop ds 775 pushf ; put it back, so we can pop it 776 normwrite: 777 popf ; restore carry flag 778 %endif 779 780 RestoreReg 781 RestoreReg 782 JC NOSET 783 INC DI ; If at least ONE write succeedes, the operation 784 NOSET: ; succeedes. 785 ADD DX,AX 786 LOOP WRTAGAIN 787 OR DI,DI ; Clears carry 788 JNZ BWROK ; At least one write worked 789 STC ; DI never got INCed, all writes failed. 790 BWROK: 791 POP DI 792 return 793 EndProc BufWrite 794 795 Break 796 797 ; Input: 798 ; ES:BP = drive parameter block 799 ; Function: 800 ; Set requesting drive, and sector size 801 ; Output: 802 ; [SC_SECTOR_SIZE]= drive sector size 803 ; [SC_DRIVE]= drive # 804 ; 805 ; All registers preserved 806 807 procedure SET_RQ_SC_PARMS,NEAR 808 ASSUME DS:NOTHING,ES:NOTHING 809 810 CMP word [ss:SC_CACHE_COUNT],0 ;LB. do it only secondary cache exists ;AN000; 811 JZ nosec ;LB. ;AN000; 812 PUSH DX ;LB. save dx ;AN000; 813 MOV DX,[ES:BP + dpb_sector_size] ;LB. save sector size ;AN000; 814 MOV [ss:SC_SECTOR_SIZE],DX ;LB. ;AN000; 815 MOV DL,[ES:BP + dpb_drive] ;LB. save drive # ;AN000; 816 MOV [ss:SC_DRIVE],DL ;LB. ;AN000; 817 ;AN000; 818 POP DX ;LB. restore dx ;AN000; 819 820 nosec: 821 return 822 EndProc SET_RQ_SC_PARMS ;LB. return ;AN000; 823 824 Break 825 826 ; Input: 827 ; none 828 ; Function: 829 ; increment dirty buffers count 830 ; Output: 831 ; dirty buffers count in the current hash entry is incremented 832 ; 833 ; All registers preserved 834 835 procedure INC_DIRTY_COUNT,NEAR 836 ASSUME DS:NOTHING,ES:NOTHING 837 838 PUSH DS ;LB. save regs ;AN000; 839 PUSH SI ;LB. ;AN000; 840 LDS SI,[ss:CurHashEntry] ;LB. get current hash entry ;AN000; 841 INC byte [SI + Dirty_Count] ;LB. add 1 ;AN000; 842 POP SI ;LB. restore regs ;AN000; 843 POP DS ;LB. ;AN000; 844 return 845 EndProc INC_DIRTY_COUNT ;LB. return ;AN000; 846 847 Break 848 849 ; Input: 850 ; none 851 ; Function: 852 ; decrement dirty buffers count 853 ; Output: 854 ; dirty buffers count in the current hash entry is decremented 855 ; 856 ; All registers preserved 857 858 procedure DEC_DIRTY_COUNT,NEAR 859 ASSUME DS:NOTHING,ES:NOTHING 860 861 PUSH DS ;LB. save regs ;AN000; 862 PUSH SI ;LB. ;AN000; 863 LDS SI,[ss:CurHashEntry] ;LB. get current hash entry ;AN000; 864 CMP byte [SI + Dirty_Count],0 ;LB. in case if 0 ;AN000; 865 JZ nodec ;LB. do nothing ;AN000; 866 DEC byte [SI + Dirty_Count] ;LB. sub 1 ;AN000; 867 nodec: 868 POP SI ;LB. restore regs ;AN000; 869 POP DS ;LB. ;AN000; 870 return 871 EndProc DEC_DIRTY_COUNT ;LB. return ;AN000; 872 873 874 Break 875 876 ; Input: 877 ; DS:DI ponits to hash entry 878 ; Function: 879 ; map the buferrs of this entry 880 ; Output: 881 ; the buffers are mapped 882 ; 883 ; All registers preserved 884 885 procedure Map_Entry,NEAR 886 ASSUME DS:NOTHING,ES:NOTHING 887 888 PUSH DX ;LB. save regs ;AN000; 889 PUSH AX ;LB. ;AN000; 890 PUSH BX ;LB. ;AN000; 891 JMP Map_Entry2 ;LB. ;AN000; 892 EndProc Map_Entry ;LB. ;AN000; 893 894 895 %IF BUFFERFLAG 896 897 ;------------------------------------------------------------------------- 898 ; Procedure name : detect collision 899 ; Inputs : [DMAADD] - user Xaddr 900 ; [CURADD] - current offset 901 ; [BYTCNT1] - for partial sector read 902 ; SAFE_FLAG - cleared - indicating that the 903 ; current page is unsafe. 904 ; 905 ; Outputs : es - physical page segment to use 906 ; di - corresponding page number 907 ; SAFE_FLAG is set is a collision is detected 908 ; and the current page is switched form 909 ; LAST_PAGE to FIRST_PAGE. 910 ;--------------------------------------------------------------------------- 911 ; 912 913 Procedure detect_collision, near 914 ASSUME DS:NOTHING,ES:NOTHING 915 916 push ax 917 push bx 918 push cx 919 920 cmp byte [ss:BUF_EMS_MODE], -1 921 jz fin_detect_coll 922 923 mov ax, [ss:CURADD] ; current offset 924 925 cmp word [ss:BYTCNT1], 0 926 je no_partial_sector 927 add ax, [ss:BYTCNT1] 928 929 no_partial_sector: 930 mov cl, 4 931 shr ax, cl ; convert to paragraphs 932 mov bx, word ptr [ss:DMAADD+2] ; get original segment 933 add ax, bx ; get current segment 934 935 and ax, 0fc00h ; get ems page of current segment 936 cmp ax, [ss:BUF_EMS_LAST_PAGE] ; is the current segment = last segment 937 jne fin_detect_coll ; page is still safe 938 939 ; int 3 940 push ax 941 mov ax, word ptr [ss:DMAADD] 942 mov ax, [ss:NEXTADD] 943 mov ax, [ss:CURADD] 944 mov ax, [ss:BYTCNT1] 945 pop ax 946 947 restore_user_map equ RESTORE_USER_MAP ; NASM port label 948 call restore_user_map 949 mov word ptr [ss:LASTBUFFER], -1 950 mov ax, [ss:BUF_EMS_FIRST_PAGE] 951 mov [ss:BUF_EMS_PFRAME], ax 952 mov ax, [ss:BUF_EMS_FIRST_PAGE+2] 953 mov [ss:BUF_EMS_PAGE_FRAME], ax 954 mov byte [ss:BUF_EMS_SAFE_FLAG], 1 955 Setup_EMS_buffers equ Setup_EMS_Buffers ; NASM port label 956 call Setup_EMS_buffers 957 save_user_map equ SAVE_USER_MAP ; NASM port label 958 call save_user_map 959 960 fin_detect_coll: 961 pop cx 962 pop bx 963 pop ax 964 ret 965 966 EndProc detect_collision 967 968 Procedure Setup_EMS_Buffers,Near 969 ASSUME DS:NOTHING,ES:NOTHING ;AN000; 970 971 cmp byte [ss:BUF_EMS_MODE], -1 972 jz setup_ems_ret 973 974 push bx 975 push cx 976 push ax 977 push ds 978 push di 979 980 mov bx, [ss:BUF_HASH_COUNT] ; # of hash table entries 981 lds di, [ss:BUF_HASH_PTR] ; ds:di -> hash table 982 983 xor cx, cx 984 985 next_bucket: 986 mov ax, [ss:BUF_EMS_PFRAME] 987 mov word ptr [di + BUFFER_BUCKET+2], ax 988 add di, 8 ; next has entry. 989 inc cx 990 cmp cx, bx 991 jne next_bucket 992 993 pop di 994 pop ds 995 pop ax 996 pop cx 997 pop bx 998 999 setup_ems_ret: 1000 ret 1001 1002 EndProc Setup_EMS_Buffers 1003 1004 %ENDIF 1005 1006 END 1007 1008 %endif ; BUF2 === Trace listing source: ../DOS/proc.lst 1 ; SCCSID = @(#)proc.asm 1.1 85/04/10 2 ;TITLE IBMPROC - process maintenance 3 ;NAME IBMPROC 4 5 ; 6 ; Process related system calls and low level routines for DOS 2.X. 7 ; I/O specs are defined in DISPATCH. 8 ; 9 ; $WAIT 10 ; $EXEC 11 ; $Keep_process 12 ; Stay_resident 13 ; $EXIT 14 ; $ABORT 15 ; abort_inner 16 ; 17 ; Modification history: 18 ; 19 ; Created: ARR 30 March 1983 20 ; 21 22 [list -] === Switch to base=008400h -> "DOSCODECODE" 29 section DOSCODECODE 30 [list -] 30 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 30 ****************** warning: out: BPB.INC... [-w+user] 30 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 30 ****************** warning: out: DEVSYM.INC... [-w+user] 37 38 SAVEXIT EQU 10 39 40 i_need CurrentPDB,WORD 41 i_need CreatePDB,BYTE 42 i_need Exit_type,BYTE 43 i_need INDOS,BYTE 44 i_need DMAADD,DWORD 45 i_need DidCTRLC,BYTE 46 i_need exit_type,BYTE 47 i_need exit_code,WORD 48 i_need OpenBuf,128 49 I_need EXTERR_LOCUS,BYTE ; Extended Error Locus 50 51 ;SUBTTL $WAIT - return previous process error code 52 ;PAGE 53 ; 54 ; process control data 55 ; 56 i_need exit_code,WORD ; code of exit 57 58 ; 59 ; Assembler usage: 60 ; MOV AH, WaitProcess 61 ; INT int_command 62 ; AX has the exit code 63 procedure D_WAIT,NEAR 63 ****************** warning: proc D_WAIT... [-w+user] 64 ASSUME DS:NOTHING,ES:NOTHING 0 00005E4A 31C0 XOR AX,AX 0 00005E4C 368706[0000] XCHG AX,[ss:exit_code] 0 00005E51 E9[0000] transfer SYS_RET_OK 68 EndProc D_WAIT 69 70 ;=== Push trace listing source: exec.nas 71 %include "exec.nas" ; NASM included file 1 <1> ; SCCSID = @(#)exec.asm 1.3 85/08/13 2 <1> ; SCCSID = @(#)exec.asm 1.3 85/08/13 3 <1> ; AN000 version 4.0 jan. 1988 4 <1> ; A007 PTM 3957 - fake vesrion for IBMCACHE.COM 5 <1> ; A008 PTM 4070 - fake version for MS WINDOWS 6 <1> 7 <1> ;SUBTTL $exec - load/go a program 8 <1> ;PAGE 9 <1> ; 10 <1> ; Assembler usage: 11 <1> ; LDS DX, name 12 <1> ; LES BX, blk 13 <1> ; MOV AH, Exec 14 <1> ; MOV AL, func 15 <1> ; INT int_command 16 <1> ; 17 <1> ; AL Function 18 <1> ; -- -------- 19 <1> ; 0 Load and execute the program. 20 <1> ; 1 Load, create the program header but do not 21 <1> ; begin execution. 22 <1> ; 3 Load overlay. No header created. 23 <1> ; 24 <1> ; AL = 0 -> load/execute program 25 <1> ; 26 <1> ; +---------------------------+ 27 <1> ; | WORD segment address of | 28 <1> ; | environment. | 29 <1> ; +---------------------------+ 30 <1> ; | DWORD pointer to ASCIZ | 31 <1> ; | command line at 80h | 32 <1> ; +---------------------------+ 33 <1> ; | DWORD pointer to default | 34 <1> ; | FCB to be passed at 5Ch | 35 <1> ; +---------------------------+ 36 <1> ; | DWORD pointer to default | 37 <1> ; | FCB to be passed at 6Ch | 38 <1> ; +---------------------------+ 39 <1> ; 40 <1> ; AL = 1 -> load program 41 <1> ; 42 <1> ; +---------------------------+ 43 <1> ; | WORD segment address of | 44 <1> ; | environment. | 45 <1> ; +---------------------------+ 46 <1> ; | DWORD pointer to ASCIZ | 47 <1> ; | command line at 80h | 48 <1> ; +---------------------------+ 49 <1> ; | DWORD pointer to default | 50 <1> ; | FCB to be passed at 5Ch | 51 <1> ; +---------------------------+ 52 <1> ; | DWORD pointer to default | 53 <1> ; | FCB to be passed at 6Ch | 54 <1> ; +---------------------------+ 55 <1> ; | DWORD returned value of | 56 <1> ; | CS:IP | 57 <1> ; +---------------------------+ 58 <1> ; | DWORD returned value of | 59 <1> ; | SS:IP | 60 <1> ; +---------------------------+ 61 <1> ; 62 <1> ; AL = 3 -> load overlay 63 <1> ; 64 <1> ; +---------------------------+ 65 <1> ; | WORD segment address where| 66 <1> ; | file will be loaded. | 67 <1> ; +---------------------------+ 68 <1> ; | WORD relocation factor to | 69 <1> ; | be applied to the image. | 70 <1> ; +---------------------------+ 71 <1> ; 72 <1> ; Returns: 73 <1> ; AX = error_invalid_function 74 <1> ; = error_bad_format 75 <1> ; = error_bad_environment 76 <1> ; = error_not_enough_memory 77 <1> ; = error_file_not_found 78 <1> ; 79 <1> ; Revision history: 80 <1> ; 81 <1> ; A000 version 4.00 Jan. 1988 82 <1> ; 83 <1> %include "ea.mac" 1 <2> 2 <2> ;Get/Set Extended Attrbute Equates 3 <2> 4 <2> ;The following equates are for EA types 5 <2> 6 <2> EAISUNDEF equ 00H ; undefined 7 <2> EAISLOGICAL equ 01H ; logical (0 or 1), 1 byte 8 <2> EAISBINARY equ 02H ; binary integer 1, 2, or 4 bytes 9 <2> EAISASCII equ 03H ; ASCII , 0 to 128 bytes 10 <2> EAISDATE equ 04H ; DOS file date format, 2 bytes 11 <2> EAISTIME equ 05H ; DOS file time format, 2 bytes 12 <2> 13 <2> ;The following equates are for EA flags 14 <2> 15 <2> EASYSTEM equ 8000H ; system defined, bultin 16 <2> EAREADONLY equ 4000H ; read-only , cannot be changed 17 <2> EAHIDDEN equ 2000H ; hidden from ATTRIB 18 <2> EACREATEONLY equ 1000H ; settable only at create time 19 <2> 20 <2> ;The following equates are for EA failure reason code (set by DOS) 21 <2> 22 <2> EARCSUCCESS equ 00H ; success 23 <2> EARCNOTFOUND equ 01H ; name not found 24 <2> EARCNOSPACE equ 02H ; no space to hold name or value 25 <2> EARCNOTNOW equ 03H ; name can't be set on this function 26 <2> EARCNOTEVER equ 04H ; name can't be set 27 <2> EARCUNDEF equ 05H ; name known to IFS but not supported 28 <2> EARCDEFBAD equ 06H ; EA definition bad (type,length, etc) 29 <2> EARCACCESS equ 07H ; EA access denied 30 <2> EARCBADVAL equ 08H ; bad value 31 <2> EARCDEVERROR equ 09H ; device error 32 <2> EARCUNKNOWN equ 0FFFFH ; unknown cause 33 <2> 34 <2> 35 <2> ;The following equates are for EA file type 36 <2> 37 <2> EAEXISTING equ 00H ; existing file 38 <2> EARTL equ 02H ; right to left 39 <2> EAEXECUTABLE equ 03H ; executable program 40 <2> EAINSTALLABLE equ 04H ; installable executable program 41 <2> EAOVERLAY equ 05H ; program overlay 42 <2> EADEV_DRIVER equ 06H ; device driver 43 <2> EAIFS_DRIVER equ 07H ; ifs deriver 44 <2> 45 <2> 46 <2> 47 <2> 48 <2> By_Create equ 0000010B ; set by Extended Open (create) 49 <2> BY_XA equ 0000100B ; set by Get/Set XA by Handle 50 <2> 51 <2> ;Extended Attribute Structure 52 <2> 53 <2> EA STRUC ; extended attribute list 0 00005E4A ?? EA_TYPE DB ? ; type 0 00005E4B ???? EA_FLAGS DW ? ; flags 0 00005E4D ?? EA_RC DB ? ; reason code 0 00005E4E ?? EA_NAMELEN DB ? ; name length 0 00005E4F ???? EA_VALLEN DW ? ; value length 0 00005E51 ?? EA_NAME DB ? ; name 60 <2> EA ENDS 61 <2> 62 <2> 63 <2> ;Query Extended Attribute list 64 <2> 65 <2> QEA STRUC ; extended attribute list 0 00005E4A ?? QEA_TYPE DB ? ; type 0 00005E4B ???? QEA_FLAGS DW ? ; flags 0 00005E4D ?? QEA_NAMELEN DB ? ; name length 0 00005E4E ?? QEA_NAME DB ? ; name 70 <2> QEA ENDS 71 <2> 72 <2> 84 <1> %include "version.mac" 1 <2> ; Some modules really want TRUE to be 0FFH. Best to let them have their way. 2 <2> TRUE EQU 0FFFFh 3 <2> TRUEBYTE EQU 0FFh 4 <2> FALSE EQU 0 5 <2> 6 <2> ; 7 <2> ; Use the following switches to control cmacros.inc 8 <2> ; 9 <2> ?PLM equ 0 10 <2> ?WIN equ 0 11 <2> 12 <2> memS EQU 1 ; Small model 13 <2> ; 14 <2> ; Use the switches below to produce the standard Microsoft version or the IBM 15 <2> ; version of the operating system 16 <2> ; 17 <2> ; The below chart will indicate how to set the switches to build the various 18 <2> ; versions 19 <2> ; 20 <2> ; IBMVER IBMCOPYRIGHT 21 <2> ; -------------------------------------------------------- 22 <2> ; IBM Version | TRUE TRUE 23 <2> ; -------------------------------------------------------- 24 <2> ; MS Version | FALSE FALSE 25 <2> ; -------------------------------------------------------- 26 <2> ; Clone Version | TRUE FALSE 27 <2> ; 28 <2> IBMVER EQU TRUE 29 <2> IBMCOPYRIGHT EQU FALSE 30 <2> 31 <2> BUFFERFLAG EQU ~ IBMCOPYRIGHT 32 <2> 33 <2> %ifndef MSVER 34 <2> MSVER EQU ~ IBMVER 35 <2> %endif 36 <2> IBM EQU IBMVER 37 <2> ; 38 <2> ; 39 <2> %IF IBMVER 40 <2> %IF IBMCOPYRIGHT 41 <2> %warning out: ... IBM version build switch on ... 42 <2> %ELSE 43 <2> %warning out: ... CLONE version build switch on ... 43 ****************** <2> warning: out: ... CLONE version build switch on ... [-w+user] 44 <2> %ENDIF 45 <2> %ELSE 46 <2> %IFN IBMCOPYRIGHT 47 <2> %warning out: ... MS version build switch on ... 48 <2> %ELSE 49 <2> %warning out: !!!!!!!!! VERSION SWITCHES SET INCORECTLY !!!!!!!!! 50 <2> %warning out: !!!!!!!!! CHECK SETTINGS IN INC\VERSION.INC !!!!!!!!! 51 <2> %ENDIF 52 <2> %ENDIF 53 <2> ; 54 <2> ; 55 <2> ;*************************************************************************** 56 <2> ;* The following switches are for DBCS or SBCS support * 57 <2> ;* * 58 <2> ;* Set INTERNAT EQU TRUE FOR DBCS * 59 <2> ;* Set INTERNAT EQU FALSE FOR SBCS * 60 <2> ;* * 61 <2> ;*************************************************************************** 62 <2> ; 63 <2> IBMJAPVER EQU FALSE ;If TRUE set KANJI true also 64 <2> 65 <2> ; 66 <2> ; Switch INTERNAT for DBCS support 67 <2> ; 68 <2> INTERNAT EQU FALSE 69 <2> ; 70 <2> %IF INTERNAT 71 <2> %ifndef KANJI 72 <2> KANJI EQU TRUE 73 <2> %endif 74 <2> IBMJAPAN EQU TRUE 75 <2> %ELSE 76 <2> %ifndef KANJI 77 <2> KANJI EQU FALSE 78 <2> %endif 79 <2> IBMJAPAN EQU FALSE 80 <2> %ENDIF 81 <2> 82 <2> %ifndef altvect ; avoid jerking off vector.inc 83 <2> ALTVECT EQU FALSE ;Switch to build ALTVECT version 84 <2> %endif 85 <2> 86 <2> ; 87 <2> ; Country code switches 88 <2> ; The default contry code is assumed as USA. 89 <2> ; 90 <2> %IF INTERNAT 91 <2> KOREA EQU TRUE 92 <2> JAPAN EQU FALSE 93 <2> %ELSE 94 <2> KOREA EQU FALSE 95 <2> JAPAN EQU FALSE 96 <2> %ENDIF 97 <2> ; 98 <2> %IF INTERNAT 99 <2> %warning out: Internat(ECS) version build switch on 100 <2> %ENDIF 85 <1> %include "lmacros2.mac" 1 <2> [list -] 1 ****************** <2> warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi] 14 <2> [list -] 86 <1> %include "memsw.mac" 1 <2> %define LDOSMEM 1 87 <1> %include "entryseg.nas" 1 <2> === Switch to base=000000h -> "DOSENTRY" 2 <2> section DOSENTRY class=%[DOSENTRY] === Switch to base=000000h -> "DOSENTRY" 3 <2> section DOSENTRY 88 <1> 89 <1> I_Need Temp_Var2,WORD ;AN000;file type from $open 90 <1> I_Need Special_Entries,WORD ;AN007;address of special entries 91 <1> I_Need Special_Version,WORD ;AN007;special version number 92 <1> I_Need Fake_Count,BYTE ;AN008;fake version count 93 <1> I_need User_SS,WORD 94 <1> I_need User_SP,WORD 95 <1> I_need NSS,WORD 96 <1> I_need NSP,WORD 97 <1> extern restore_world 98 <1> 99 <1> %ifndef BUF2 100 <1> %IF BUFFERFLAG 101 <1> extrn restore_user_map:near 102 <1> %ENDIF 103 <1> %endif 104 <1> === Switch to base=001140h -> "DOSDATATABLE" 105 <1> section DOSDATATABLE ; in DOSDATA 106 <1> 107 <1> align 2, db ? 0 00001218 ???? exec_init_SP DW ? 0 0000121A ???? exec_init_SS DW ? 0 0000121C ???? exec_init_IP DW ? 0 0000121E ???? exec_init_CS DW ? 112 <1> 113 <1> exec_internal_buffer EQU OpenBuf 114 <1> 0 00001220 ???? exec_signature DW ? ; must contain 4D5A (yay zibo!) 0 00001222 ???? exec_len_mod_512 DW ? ; low 9 bits of length 0 00001224 ???? exec_pages DW ? ; number of 512b pages in file 0 00001226 ???? exec_rle_count DW ? ; count of reloc entries 0 00001228 ???? exec_par_dir DW ? ; number of paragraphs before image 0 0000122A ???? exec_min_BSS DW ? ; minimum number of para of BSS 0 0000122C ???? exec_max_BSS DW ? ; max number of para of BSS 0 0000122E ???? exec_SS DW ? ; stack of image 0 00001230 ???? exec_SP DW ? ; SP of image 0 00001232 ???? exec_chksum DW ? ; checksum of file (ignored) 0 00001234 ???? exec_IP DW ? ; IP of entry 0 00001236 ???? exec_CS DW ? ; CS of entry 0 00001238 ???? exec_rle_table DW ? ; byte offset of reloc table 128 <1> Exec_Signature equ exec_signature ; NASM port label 129 <1> Exec_header_len EQU $-Exec_Signature 130 <1> 131 <1> curdirLEN equ curdirLen ; NASM port equate 132 <1> exec_internal_buffer_size EQU (128+128+53+curdirLEN) 133 <1> %warning out: Please make sure that the following are contiguous and of the 133 ****************** <1> warning: out: Please make sure that the following are contiguous and of the [-w+user] 134 <1> %warning out: following sizes: 134 ****************** <1> warning: out: following sizes: [-w+user] 135 <1> %warning out: 135 ****************** <1> warning: out: [-w+user] 136 <1> %warning out: OpenBuf 128 136 ****************** <1> warning: out: OpenBuf 128 [-w+user] 137 <1> %warning out: RenBuf 128 137 ****************** <1> warning: out: RenBuf 128 [-w+user] 138 <1> %warning out: SearchBuf 53 138 ****************** <1> warning: out: SearchBuf 53 [-w+user] 139 <1> %warning out: DummyCDS CurDirLen 139 ****************** <1> warning: out: DummyCDS CurDirLen [-w+user] 140 <1> === Switch to base=008400h -> "DOSCODECODE" 141 <1> section DOSCODECODE ; TABLE ENDS 142 <1> 143 <1> ;.sall 144 <1> 145 <1> procedure D_Exec,NEAR 145 ****************** <1> warning: proc D_Exec... [-w+user] 0 00005E54 3C85 cmp al, 85h 0 00005E56 7404 je .state 0 00005E58 3C05 cmp al, 5 0 00005E5A 752C jne @F 150 <1> .state: 0 00005E5C E8[0000] call SYS_RET_OK ; NC in iret fl 152 <1> 153 <1> ; the following copied from disp.nas 0 00005E5F FA CLI 0 00005E60 16 push ss 0 00005E61 1F pop ds ; ds => DOSDATA, overwritten soon 0 00005E62 FE0E[0000] DEC byte [INDOS] 158 <1> user_SP equ User_SP ; NASM port label 159 <1> user_SS equ User_SS ; NASM port label 0 00005E66 8B2E[0000] MOV BP, [user_SP] ; -> user stack 0 00005E6A 8E16[0000] MOV SS, [user_SS] 0 00005E6E 89EC MOV SP, bp ; restore user stack 0 00005E70 884600 MOV BYTE PTR [BP + user_AX],AL 0 00005E73 A1[0000] MOV AX, [NSP] 0 00005E76 A3[0000] MOV [user_SP], AX 0 00005E79 A1[0000] MOV AX, [NSS] 0 00005E7C A3[0000] MOV [user_SS], AX 0 00005E7F E8[0000] CALL restore_world ; restore all registers 0 00005E82 31C0 xor ax, ax 0 00005E84 50 push ax 0 00005E85 E99A04 jmp do_a20_off_ax_on_stack 172 <1> 173 <1> @@: 174 <1> ASSUME DS:NOTHING, ES:NOTHING 175 <1> PUBLIC EXEC001S,EXEC001E 176 <1> EXEC001S: 177 <1> LocalVar exec_blk,DWORD 178 <1> LocalVar exec_func,BYTE 179 <1> LocalVar exec_load_high,BYTE 180 <1> LocalVar exec_fh,WORD 181 <1> LocalVar exec_rel_fac,WORD 182 <1> LocalVar exec_res_len_para,WORD 183 <1> LocalVar exec_environ,WORD 184 <1> LocalVar exec_size,WORD 185 <1> LocalVar exec_load_block,WORD 186 <1> LocalVar exec_dma,WORD 187 <1> LocalVar execNameLen,WORD 188 <1> LocalVar execName,DWORD 189 <1> EXEC001E: 0 00005E88 5589E583EC1A Enter 191 <1> ; 192 <1> ; validate function 193 <1> ; 194 <1> 0 00005E8E 8846FB MOV [exec_func],AL 196 <1> 0 00005E91 247F and al, 7Fh ; normalise from FreeDOS extension 0 00005E93 3C03 CMP AL,3 ; only 0, 1 or 3 are allowed 0 00005E95 760E Jbe exec_check_2 200 <1> 201 <1> exec_bad_fun: 0 00005E97 36C606[0000]01 MOV byte [ss:EXTERR_LOCUS],errLOC_Unk ; Extended Error Locus 0 00005E9D B001 mov al,error_invalid_function 204 <1> 205 <1> exec_ret_err: 0 00005E9F 89EC5D Leave 0 00005EA2 E9[0000] transfer SYS_RET_ERR 208 <1> 209 <1> exec_check_2: 0 00005EA5 3C02 CMP AL,2 0 00005EA7 74EE je exec_bad_fun 212 <1> 0 00005EA9 895EFC MOV [exec_blkL],BX ; stash args 0 00005EAC 8C46FE MOV [exec_blkH],ES 0 00005EAF C646FA00 MOV byte [exec_load_high],0 216 <1> ; 217 <1> ; set up length of exec name 218 <1> ; 0 00005EB3 8956E6 MOV [execNameL],DX 0 00005EB6 8C5EE8 MOV [execNameH],DS 0 00005EB9 89D6 MOV SI,DX ; move pointer to convenient place 0 00005EBB E8[0000] invoke DStrLen 0 00005EBE 894EEA MOV [ExecNameLen],CX ; save length 224 <1> 0 00005EC1 30C0 XOR AL,AL ; open for reading 0 00005EC3 55 PUSH BP 0 00005EC4 E8[0000] invoke D_OPEN ; is the file there? 0 00005EC7 5D POP BP 0 00005EC8 72D5 JC exec_ret_err 230 <1> ;File Type Checking 231 <1> ; CMP BYTE PTR [Temp_Var2],EAEXISTING ;AN000;;FT. old file ? 232 <1> ; JZ oldexf ;AN000;;FT. yes 233 <1> ; TEST BYTE PTR EXEC_FUNC,EXEC_FUNC_OVERLAY ;AN000;;FT. exec overlay? 234 <1> ; JNZ exovrly ;AN000;;FT. yes 235 <1> ; CMP BYTE PTR [Temp_Var2],EAEXECUTABLE ;AN000;;FT. only file type 236 <1> ; JZ oldexf ;AN000;;FT. 3 & 4 will pass 237 <1> ; CMP BYTE PTR [Temp_Var2],EAINSTALLABLE ;AN000;;FT. 238 <1> ; JZ oldexf ;AN000;;FT. 239 <1> ;exerr: ;AN000;;FT. 240 <1> ; MOV AL,error_access_denied ;AN000;;FT. error 241 <1> ; JMP exec_ret_err ;AN000;;FT. 242 <1> ;exovrly: ;AN000;;FT. 243 <1> ; CMP BYTE PTR [Temp_Var2],EAOVERLAY ;AN000;;FT. only 5,6,7 pass 244 <1> ; JZ oldexf ;AN000;;FT. 245 <1> ; CMP BYTE PTR [Temp_Var2],EADEV_DRIVER ;AN000;;FT. 246 <1> ; JZ oldexf ;AN000;;FT. 247 <1> ; CMP BYTE PTR [Temp_Var2],EAIFS_DRIVER ;AN000;;FT. 248 <1> ; JNZ exerr ;AN000;;FT. 249 <1> ; 250 <1> ;oldexf: ;AN000; 251 <1> ;File Type Checking 252 <1> 0 00005ECA 8946F8 MOV [exec_fh],AX 0 00005ECD 89C3 MOV BX,AX 0 00005ECF 30C0 XOR AL,AL 0 00005ED1 E8[0000] invoke D_IOCTL 0 00005ED4 7207 JC Exec_bombJ 0 00005ED6 F6C280 TEST DL,devid_ISDEV 0 00005ED9 740A JZ exec_check_environ 0 00005EDB B002 MOV AL,error_file_not_found 261 <1> Exec_bombJ: 262 <1> Exec_Bomb equ exec_bomb ; NASM port label 0 00005EDD E9D700 JMP Exec_Bomb 264 <1> 265 <1> BadEnv: 0 00005EE0 B00A MOV AL,error_bad_environment 0 00005EE2 E9D200 JMP exec_bomb 268 <1> 269 <1> exec_check_environ: 0 00005EE5 8366EE00 and word [exec_load_block],0 0 00005EE9 8366F200 and word [exec_environ],0 272 <1> 0 00005EED F646FB02 TEST BYTE [exec_func],exec_func_overlay ; overlays... no environment 0 00005EF1 7561 JNZ exec_read_header 0 00005EF3 C576FC LDS SI,[exec_blk] ; get block 0 00005EF6 8B04 MOV AX,[SI + Exec1_environ] ; address of environ 0 00005EF8 09C0 OR AX,AX 0 00005EFA 750F JNZ exec_scan_env 0 00005EFC 368E1E[0000] MOV DS,[ss:CurrentPDB] 0 00005F01 A12C00 MOV AX,[PDB_environ] 0 00005F04 8946F2 MOV [exec_environ],AX 0 00005F07 09C0 OR AX,AX 0 00005F09 7449 JZ exec_read_header 284 <1> 285 <1> exec_scan_env: 0 00005F0B 8EC0 MOV ES,AX 0 00005F0D 31FF XOR DI,DI 0 00005F0F B9FF7F MOV CX,07FFFh ; at most 32k of environment 0 00005F12 30C0 XOR AL,AL 290 <1> 291 <1> exec_get_environ_len: 0 00005F14 F2AE REPNZ SCASB ; find that nul byte 0 00005F16 75C8 JNZ BadEnv 0 00005F18 49 DEC CX ; Dec CX for the next nul byte test 0 00005F19 74C5 jz BadEnv ; gone beyond the end of the environment 0 00005F1B AE SCASB ; is there another nul byte? 0 00005F1C 75F6 JNZ exec_get_environ_len ; no, scan some more 0 00005F1E 57 PUSH DI 0 00005F1F 8D5D11 LEA BX,[DI+0Fh+2] 0 00005F22 035EEA ADD BX,[ExecNameLen] ; BX <- length of environment 301 <1> ; remember argv[0] length 302 <1> ; round up and remember argc 0 00005F25 B104 MOV CL,4 0 00005F27 D3EB SHR BX,CL ; number of paragraphs needed 0 00005F29 06 PUSH ES 306 <1> %ifdef LDOSMEM 0 00005F2A E8[0000] EnterCrit critMem 0 00005F2D E8AE00 call get_flags 0 00005F30 E8[0000] call AllocateMCBCompatible.flags_cx 0 00005F33 E8[0000] LeaveCrit critMem 311 <1> %else 312 <1> invoke D_ALLOC ; can we get the space? 313 <1> %endif 0 00005F36 1F POP DS 0 00005F37 59 POP CX 0 00005F38 7303 JNC exec_save_environ 0 00005F3A EB75 JMP exec_no_mem ; nope... cry and sob 0 00005F3C 90 nop ; identicalise 319 <1> 320 <1> exec_save_environ: 0 00005F3D 8EC0 MOV ES,AX 0 00005F3F 8946F2 MOV [exec_environ],AX ; save him for a rainy day 0 00005F42 31F6 XOR SI,SI 0 00005F44 89F7 MOV DI,SI 0 00005F46 F3A4 REP MOVSB ; copy the environment 0 00005F48 B80100 MOV AX,1 0 00005F4B AB STOSW 0 00005F4C C576E6 LDS SI,[execName] 0 00005F4F 8B4EEA MOV CX,[execNameLen] 0 00005F52 F3A4 REP MOVSB 331 <1> 332 <1> exec_read_header: 333 <1> ; 334 <1> ; We read in the program header into the above data area and determine 335 <1> ; where in this memory the image will be located. 336 <1> ; 0 00005F54 161F Context DS 338 <1> exec_header_len equ Exec_header_len ; NASM port equate 0 00005F56 B91A00 MOV CX,exec_header_len ; header size 0 00005F59 BA[0800] MOV DX,OFFSET exec_signature wrt DOSGROUP 0 00005F5C 06 PUSH ES 0 00005F5D 1E PUSH DS 0 00005F5E E8C703 CALL ExecRead 0 00005F61 1F POP DS 0 00005F62 07 POP ES 0 00005F63 7250 JC exec_bad_file 0 00005F65 85C0 test AX,AX 0 00005F67 744C JZ exec_bad_file 0 00005F69 83F81A CMP AX,exec_header_len ; did we read the right number? 0 00005F6C 7519 JNZ exec_com_filej ; yep... continue 0 00005F6E F706[1400]FFFF TEST word [exec_max_BSS],-1 ; indicate load high? 0 00005F74 7504 JNZ exec_check_sig 0 00005F76 C646FAFF MOV byte [exec_load_high],-1 354 <1> exec_check_sig: 0 00005F7A A1[0800] MOV AX,[exec_signature] 0 00005F7D 3D4D5A CMP AX,exe_valid_signature ; zibo arises! 0 00005F80 7408 JZ exec_save_start ; assume com file if no signature 0 00005F82 3D5A4D CMP AX,exe_valid_old_signature ; zibo arises! 0 00005F85 7403 JZ exec_save_start ; assume com file if no signature 360 <1> 361 <1> exec_com_filej: 0 00005F87 E9AB01 JMP exec_com_file 363 <1> 364 <1> ; 365 <1> ; We have the program header... determine memory requirements 366 <1> ; 367 <1> exec_save_start: 0 00005F8A A1[0C00] MOV AX,[exec_pages] ; get 512-byte pages 0 00005F8D B105 MOV CL,5 ; convert to paragraphs 0 00005F8F D3E0 SHL AX,CL 0 00005F91 2B06[1000] SUB AX,[exec_par_dir] ; AX = size in paragraphs 0 00005F95 8946F4 MOV [exec_res_len_para],AX 373 <1> 374 <1> ; 375 <1> ; Do we need to allocate memory? Yes if function is not load-overlay 376 <1> ; 0 00005F98 F646FB02 TEST BYTE [exec_func],exec_func_overlay 0 00005F9C 7451 JZ exec_allocate ; allocation of space 379 <1> ; 380 <1> ; get load address from block 381 <1> ; 0 00005F9E C47EFC LES DI,[exec_blk] 383 <1> exec3_load_addr equ Exec3_load_addr ; NASM port equate 0 00005FA1 268B05 MOV AX,[ES:DI + exec3_load_addr] 0 00005FA4 8946EC MOV [exec_dma],AX 386 <1> exec3_reloc_fac equ Exec3_reloc_fac ; NASM port equate 0 00005FA7 268B4502 MOV AX,[ES:DI + exec3_reloc_fac] 0 00005FAB 8946F6 MOV [exec_rel_fac],AX 0 00005FAE E9BB00 JMP exec_find_res 390 <1> 391 <1> exec_no_mem: 0 00005FB1 B008 MOV AL,error_not_enough_memory 0 00005FB3 EB02 JMP SHORT exec_bomb 394 <1> 395 <1> exec_bad_file: 0 00005FB5 B00B MOV AL,error_bad_format 397 <1> 398 <1> exec_bomb: 399 <1> ASSUME DS:NOTHING,ES:NOTHING 0 00005FB7 8B5EF8 MOV BX,[exec_fh] 0 00005FBA E87A03 CALL exec_dealloc 0 00005FBD E8[0000] LeaveCrit CritMem 0 00005FC0 5055 SaveReg 0 00005FC2 E8[0000] invoke D_CLOSE 0 00005FC5 5D58 RestoreReg 406 <1> Exec_Ret_Err equ exec_ret_err ; NASM port label 0 00005FC7 E9D5FE JMP Exec_Ret_Err 408 <1> 409 <1> %ifdef LDOSMEM 410 <1> extern GetMCBOwner, GetMCBFlags, AllocateLargestMCBRandom, GetRawMCBFlags 411 <1> extern AllocateMCBCompatible.flags_cx 412 <1> 413 <1> allocate_largest: 0 00005FCA E8[0000] EnterCrit critMem 0 00005FCD 51 push cx 0 00005FCE 52 push dx 0 00005FCF E8[0000] call GetMCBOwner ; dx = owner 0 00005FD2 E80900 call get_flags 0 00005FD5 E8[0000] call AllocateLargestMCBRandom ; call two-area allocation 0 00005FD8 5A pop dx 0 00005FD9 59 pop cx 0 00005FDA E8[0000] LeaveCrit critMem 0 00005FDD C3 retn 424 <1> 425 <1> get_flags: 0 00005FDE E8[0000] call GetMCBFlags ; cx = fixed flags 0 00005FE1 F646FB80 test byte [exec_func], 80h ; FreeDOS extension to use UMA ? 0 00005FE5 7407 jz .not_force_uma ; no, use current flags --> 0 00005FE7 E8[0000] call GetRawMCBFlags 0 00005FEA 81C98001 or cx, 180h ; 100h = ignore UMB link status, 431 <1> ; 80h = UMA then LMA, dual areas 432 <1> ; (80h overrides all lesser areas) 433 <1> .not_force_uma: 0 00005FEE C3 retn 435 <1> %endif 436 <1> 437 <1> exec_allocate: 438 <1> DOSAssume CS,,"EXEC/exec_allocate" 439 <1> %ifdef LDOSMEM 0 00005FEF 50 push ax 0 00005FF0 83C010 add ax, 10h 0 00005FF3 89C3 mov bx, ax 0 00005FF5 720C jc .max_ffff 0 00005FF7 F646FAFF TEST byte [exec_load_high],-1 ; if load high, use max 0 00005FFB 7506 JNZ .max_ffff ; use max 0 00005FFD 0306[1400] add ax, [exec_max_BSS] 0 00006001 7303 jnc @F 448 <1> .max_ffff: 0 00006003 B8FFFF mov ax, -1 450 <1> @@: 0 00006006 031E[1200] add bx, [exec_min_BSS] 0 0000600A 7303 jnc @F 0 0000600C BBFFFF mov bx, -1 454 <1> @@: 0 0000600F 1E push ds 0 00006010 E8B7FF call allocate_largest 0 00006013 1F pop ds 0 00006014 8946EE MOV [exec_load_block],AX 0 00006017 58 pop ax 0 00006018 7297 jc exec_no_mem 461 <1> %else 462 <1> PUSH AX 463 <1> MOV BX,0FFFFh ; see how much room in arena 464 <1> PUSH DS 465 <1> invoke D_ALLOC ; should have carry set and BX has max 466 <1> POP DS 467 <1> POP AX 468 <1> %endif 0 0000601A 83C010 ADD AX,10h ; room for header 0 0000601D 83FB11 CMP BX,11h ; enough room for a header 0 00006020 728F JB exec_no_mem 0 00006022 39D8 CMP AX,BX ; is there enough for bare image? 0 00006024 778B JA exec_no_mem 0 00006026 F646FAFF TEST byte [exec_load_high],-1 ; if load high, use max 0 0000602A 751E JNZ exec_BX_max ; use max 0 0000602C 0306[1200] ADD AX,[exec_min_BSS] ; go for min allocation 0 00006030 7303E97CFF JC exec_no_mem ; oops! carry 0 00006035 39D8 CMP AX,BX ; enough space? 0 00006037 7603E975FF JA exec_no_mem ; nope... 0 0000603C 2B06[1200] SUB AX,[exec_min_BSS] 0 00006040 0306[1400] ADD AX,[exec_max_BSS] ; go for the MAX 0 00006044 7204 JC exec_BX_max 0 00006046 39D8 CMP AX,BX 0 00006048 7602 JBE exec_got_block 485 <1> 486 <1> exec_BX_max: 0 0000604A 89D8 MOV AX,BX 488 <1> 489 <1> exec_got_block: 0 0000604C 89C3 MOV BX,AX 0 0000604E 895EF0 MOV [exec_size],BX 492 <1> %ifdef LDOSMEM 0 00006051 8B46EE MOV ax, [exec_load_block] 494 <1> %else 495 <1> PUSH DS 496 <1> invoke D_ALLOC ; get the space 497 <1> POP DS 498 <1> JC exec_no_mem 499 <1> MOV [exec_load_block],AX 500 <1> %endif 0 00006054 83C010 ADD AX,10h 0 00006057 F646FAFF TEST byte [exec_load_high],-1 0 0000605B 7409 JZ exec_use_ax ; use ax for load info 0 0000605D 0346F0 ADD AX,[exec_size] ; go to end 0 00006060 2B46F4 SUB AX,[exec_res_len_para] ; drop off header 0 00006063 83E810 SUB AX,10h ; drop off pdb 507 <1> exec_use_ax: 0 00006066 8946F6 MOV [exec_rel_fac],AX ; new segment 0 00006069 8946EC MOV [exec_dma],AX ; beginning of dma 510 <1> 511 <1> ; 512 <1> ; Determine the location in the file of the beginning of the resident 513 <1> ; 514 <1> exec_find_res: 0 0000606C 8B16[1000] MOV DX,[exec_par_dir] 0 00006070 52 PUSH DX 0 00006071 B104 MOV CL,4 0 00006073 D3E2 SHL DX,CL ; low word of location 0 00006075 58 POP AX 0 00006076 B10C MOV CL,12 0 00006078 D3E8 SHR AX,CL ; high word of location 0 0000607A 89C1 MOV CX,AX ; CX <- high 523 <1> 524 <1> ; 525 <1> ; Read in the resident image (first, seek to it) 526 <1> ; 0 0000607C 8B5EF8 MOV BX,[exec_fh] 0 0000607F 1E PUSH DS 0 00006080 30C0 XOR AL,AL 0 00006082 E8[0000] invoke D_LSEEK ; seek to resident 0 00006085 1F POP DS 0 00006086 7303 jnc exec_big_read 0 00006088 E92CFF jmp exec_bomb 534 <1> 535 <1> exec_big_read: ; Read resident into memory 0 0000608B 8B5EF4 MOV BX,[exec_res_len_para] 0 0000608E 81FB0010 CMP BX,1000h ; too many bytes to read? 0 00006092 7203 JB exec_read_ok 0 00006094 BBE00F MOV BX,0FE0h ; max in one chunk FE00 bytes 540 <1> 541 <1> exec_read_ok: 0 00006097 295EF4 SUB [exec_res_len_para],BX ; we read (soon) this many 0 0000609A 53 PUSH BX 0 0000609B B104 MOV CL,4 0 0000609D D3E3 SHL BX,CL ; get count in bytes from paras 0 0000609F 89D9 MOV CX,BX ; count in correct register 0 000060A1 1E PUSH DS 0 000060A2 8E5EEC MOV DS,[exec_dma] ; Set up read buffer 549 <1> ASSUME DS:NOTHING 0 000060A5 31D2 XOR DX,DX 0 000060A7 51 PUSH CX ; save our count 0 000060A8 E87D02 CALL ExecRead 0 000060AB 59 POP CX ; get old count to verify 0 000060AC 1F POP DS 555 <1> exec_bad_fileJ equ exec_bad_filej ; NASM port label 0 000060AD 7248 JC exec_bad_fileJ 557 <1> DOSAssume CS,,"EXEC/exec_read_ok" 0 000060AF 39C1 CMP CX,AX ; did we read enough? 0 000060B1 5B POP BX ; get paragraph count back 560 <1> execCheckEnd equ ExecCheckEnd ; NASM port label 0 000060B2 7408 JZ execCheckEnd ; and do reloc if no more to read 562 <1> ; 563 <1> ; The read did not match the request. If we are off by 512 bytes or more 564 <1> ; then the header lied and we have an error. 565 <1> ; 0 000060B4 29C1 SUB CX,AX 0 000060B6 81F90002 CMP CX,512 568 <1> Exec_Bad_fileJ equ exec_bad_filej ; NASM port label 0 000060BA 733B JAE Exec_Bad_fileJ 570 <1> ; 571 <1> ; We've read in CX bytes... bump DTA location 572 <1> ; 573 <1> ExecCheckEnd: 0 000060BC 015EEC ADD [exec_dma],BX ; bump dma address 0 000060BF F746F4FFFF TEST word [exec_res_len_para],-1 0 000060C4 75C5 JNZ exec_big_read 577 <1> ; 578 <1> ; The image has now been read in. We must perform relocation to 579 <1> ; the current location. 580 <1> ; 581 <1> exec_do_reloc: 0 000060C6 8B4EF6 MOV CX,[exec_rel_fac] 0 000060C9 A1[1600] MOV AX,[exec_SS] ; get initial SS 0 000060CC 01C8 ADD AX,CX ; and relocate him 0 000060CE A3[0200] MOV [exec_init_SS],AX 586 <1> 0 000060D1 A1[1800] MOV AX,[exec_SP] ; initial SP 0 000060D4 A3[0000] MOV [exec_init_SP],AX 589 <1> 0 000060D7 C406[1C00] LES AX,[exec_IP] 0 000060DB A3[0400] MOV [exec_init_IP],AX 0 000060DE 8CC0 MOV AX,ES 0 000060E0 01C8 ADD AX,CX ; relocated... 0 000060E2 A3[0600] MOV [exec_init_CS],AX 595 <1> 0 000060E5 31C9 XOR CX,CX 0 000060E7 8B16[2000] MOV DX,[exec_rle_table] 0 000060EB 8B5EF8 MOV BX,[exec_fh] 0 000060EE 1E PUSH DS 0 000060EF 31C0 XOR AX,AX 0 000060F1 E8[0000] invoke D_LSEEK 0 000060F4 1F POP DS 603 <1> 0 000060F5 7303 JNC exec_get_entries 605 <1> exec_bad_filej: 0 000060F7 E9BBFE JMP exec_bad_file 607 <1> 608 <1> exec_get_entries: 0 000060FA 8B16[0E00] MOV DX,[exec_rle_count] ; Number of entries left 610 <1> 611 <1> exec_read_reloc: 612 <1> ASSUME DS:NOTHING 0 000060FE 52 PUSH DX 0 000060FF BA[0000] MOV DX,OFFSET exec_internal_buffer wrt DOSGROUP 0 00006102 B98C01 MOV CX,((exec_internal_buffer_size)/4)*4 0 00006105 1E PUSH DS 0 00006106 E81F02 CALL ExecRead 0 00006109 07 POP ES 0 0000610A 5A POP DX 0 0000610B 72EA JC exec_bad_filej 0 0000610D B96300 MOV CX,(exec_internal_buffer_size)/4 0 00006110 BF[0000] MOV DI,OFFSET exec_internal_buffer wrt DOSGROUP ; Pointer to byte location in header 623 <1> ; 624 <1> ; Relocate a single address 625 <1> ; 0 00006113 8B76F6 MOV SI,[exec_rel_fac] 627 <1> 628 <1> exec_reloc_one: 0 00006116 85D2 test DX,DX ; Any more entries? 0 00006118 7415 JE exec_set_PDBJ 631 <1> 632 <1> exec_get_addr: 0 0000611A 26C51D LDS BX,[ES:DI] ; Get ra/sa of entry 0 0000611D 8CD8 MOV AX,DS ; Relocate address of item 0 0000611F 01F0 ADD AX,SI 0 00006121 8ED8 MOV DS,AX 0 00006123 0137 ADD [BX],SI 0 00006125 83C704 ADD DI,4 0 00006128 4A DEC DX 0 00006129 E2EB LOOP exec_reloc_one ; End of internal buffer? 641 <1> 642 <1> ; 643 <1> ; We've exhausted a single buffer's worth. Read in the next piece 644 <1> ; of the relocation table. 645 <1> ; 646 <1> 0 0000612B 06 PUSH ES 0 0000612C 1F POP DS 0 0000612D EBCF JMP exec_read_reloc 650 <1> 651 <1> exec_set_PDBJ: 0 0000612F E9A600 JMP exec_set_PDB 653 <1> 654 <1> exec_no_memj: 0 00006132 E97CFE JMP exec_no_mem 656 <1> 657 <1> ; 658 <1> ; we have a .COM file. First, determine if we are merely loading an overlay. 659 <1> ; 660 <1> exec_com_file: 0 00006135 F646FB02 TEST BYTE [exec_func],exec_func_overlay 0 00006139 740C JZ exec_alloc_com_file 0 0000613B C576FC LDS SI,[exec_blk] ; get arg block 0 0000613E AD LODSW ; get load address 0 0000613F 8946EC MOV [exec_dma],AX 0 00006142 B8FFFF MOV AX,0FFFFh 0 00006145 EB46 JMP SHORT exec_read_block ; read it all! 668 <1> 669 <1> ; We must allocate the max possible size block (ick!) and set up 670 <1> ; CS=DS=ES=SS=PDB pointer, IP=100, SP=max size of block. 671 <1> ; 672 <1> exec_alloc_com_file: 673 <1> %ifdef LDOSMEM 0 00006147 8B5EF8 mov bx, [exec_fh] 0 0000614A 31C9 xor cx, cx 0 0000614C 31D2 xor dx, dx 0 0000614E B80200 mov ax, 2 ; seek to EOF 0 00006151 E8[0000] invoke D_LSEEK ; get file size 0 00006154 85D2 test dx, dx ; >= 64 KiB ? 0 00006156 75DA jnz exec_no_memj ; yes, too much --> 0 00006158 3D00FF cmp ax, 0FF00h ; >= 0FF00h ? 0 0000615B 73D5 jae exec_no_memj ; too much --> 0 0000615D 83C00F add ax, 15 ; round up 0 00006160 B104 mov cl, 4 0 00006162 D3E8 shr ax, cl ; to paragraphs 0 00006164 83C010 add ax, 10h ; add in PSP size 0 00006167 93 xchg bx, ax ; bx = minimum size 0 00006168 B8FFFF mov ax, -1 ; maximum size = largest 0 0000616B E85CFE call allocate_largest 0 0000616E 72C2 jc exec_no_memj 0 00006170 895EF0 MOV [exec_size],BX ; save size of allocation block 692 <1> %else 693 <1> MOV BX,0FFFFh 694 <1> invoke D_ALLOC ; largest piece available as error 695 <1> OR BX,BX 696 <1> JZ exec_no_memj 697 <1> MOV [exec_size],BX ; save size of allocation block 698 <1> PUSH BX 699 <1> invoke D_ALLOC ; largest piece available as error 700 <1> POP BX ; get size of block... 701 <1> %endif 0 00006173 8946EE MOV [exec_load_block],AX 0 00006176 83C010 ADD AX,10h ; increment for header 0 00006179 8946EC MOV [exec_dma],AX 0 0000617C 31C0 XOR AX,AX ; presume 64K read... 0 0000617E 81FB0010 CMP BX,1000h ; 64k or more in block? 0 00006182 7306 JAE exec_read_com ; yes, read only 64k 0 00006184 89D8 MOV AX,BX ; convert size to bytes 0 00006186 B104 MOV CL,4 0 00006188 D3E0 SHL AX,CL 711 <1> exec_read_com: 0 0000618A 2D0001 SUB AX,100h ; remember size of psp 713 <1> exec_read_block: 0 0000618D 50 PUSH AX ; save number to read 0 0000618E 8B5EF8 MOV BX,[exec_fh] ; of com file 0 00006191 31C9 XOR CX,CX ; but seek to 0:0 0 00006193 89CA MOV DX,CX 0 00006195 31C0 XOR AX,AX ; seek relative to beginning 0 00006197 E8[0000] invoke D_LSEEK ; back to beginning of file 0 0000619A 59 POP CX ; number to read 0 0000619B 8E5EEC MOV DS,[exec_dma] 0 0000619E 31D2 XOR DX,DX 0 000061A0 51 PUSH CX 0 000061A1 E88401 CALL ExecRead 0 000061A4 5E POP SI ; get number of bytes to read 0 000061A5 7303 jnc OkRead 0 000061A7 E90BFE jmp exec_bad_file 728 <1> OkRead: 0 000061AA 39F0 CMP AX,SI ; did we read them all? 0 000061AC 7484 JZ exec_no_memj ; exactly the wrong number... no memory 0 000061AE F646FB02 TEST BYTE [exec_func],exec_func_overlay 0 000061B2 7524 JNZ exec_set_PDB ; no starto, chumo! 0 000061B4 8B46EC MOV AX,[exec_DMA] 0 000061B7 83E810 SUB AX,10h 0 000061BA 36A3[0600] MOV [ss:exec_init_CS],AX 0 000061BE 36C706[0400]0001 MOV word [ss:exec_init_IP],100h ; initial IP is 100 737 <1> ; 738 <1> ; SI is at most FF00h. Add FE to account for PSP - word of 0 on stack. 739 <1> ; 0 000061C5 81C6FE00 ADD SI,0FEh ; make room for stack 0 000061C9 368936[0000] MOV [ss:exec_init_SP],SI ; max value for read is also SP! 0 000061CE 36A3[0200] MOV [ss:exec_init_SS],AX 0 000061D2 8ED8 MOV DS,AX 0 000061D4 C7040000 MOV WORD PTR [SI],0 ; 0 for return 745 <1> 746 <1> exec_set_PDB: 0 000061D8 8B5EF8 MOV BX,[exec_fh] ; we are finished with the file. 0 000061DB E85901 CALL exec_dealloc 0 000061DE 55 PUSH BP 0 000061DF E8[0000] invoke D_CLOSE ; release the jfn 0 000061E2 5D POP BP 0 000061E3 E85D01 CALL exec_alloc 0 000061E6 F646FB02 TEST BYTE [exec_func],exec_func_overlay 0 000061EA 740C JZ exec_build_header 0 000061EC E88101 CALL Scan_Execname ;MS.;AN007; 0 000061EF E89501 CALL Scan_Special_Entries ;MS.;AN007; 0 000061F2 89EC5D Leave 0 000061F5 E9[0000] transfer SYS_RET_OK ; overlay load -> done 759 <1> 760 <1> exec_build_header: 0 000061F8 8B56EE MOV DX,[exec_load_block] 762 <1> ; 763 <1> ; assign the space to the process 764 <1> ; 765 <1> 0 000061FB BE0100 MOV SI,arena_owner ; pointer to owner field 767 <1> 0 000061FE 8B46F2 MOV AX,[exec_environ] ; get environ pointer 0 00006201 09C0 OR AX,AX 0 00006203 7405 JZ NO_OWNER ; no environment 0 00006205 48 DEC AX ; point to header 0 00006206 8ED8 MOV DS,AX 0 00006208 8914 MOV [SI],DX ; assign ownership 774 <1> NO_OWNER: 0 0000620A 8B46EE MOV AX,[exec_load_block] ; get load block pointer 0 0000620D 48 DEC AX 0 0000620E 8ED8 MOV DS,AX ; point to header 0 00006210 8914 MOV [SI],DX ; assign ownership 779 <1> 0 00006212 1E PUSH DS ;AN000;MS. make ES=DS 0 00006213 07 POP ES ;AN000;MS. 782 <1> ARENA_NAME equ arena_name ; NASM port equate 0 00006214 BF0800 MOV DI,ARENA_NAME ;AN000;MS. ES:DI points to destination 0 00006217 E85601 CALL Scan_Execname ;AN007;MS. parse execname 785 <1> ; ds:si->name, cx=name length 0 0000621A 51 PUSH CX ;AN007;;MS. save for fake version 0 0000621B 56 PUSH SI ;AN007;;MS. save for fake version 788 <1> 789 <1> movename: ;AN000; 0 0000621C AC LODSB ;AN000;;MS. get char 0 0000621D 3C2E CMP AL,'.' ;AN000;;MS. is '.' ,may be name.exe 0 0000621F 7403 JZ mem_done ;AN000;;MS. no, move to header 793 <1> ;AN000; 0 00006221 AA STOSB ;AN000;;MS. move char 0 00006222 E2F8 LOOP movename ;AN000;;MS. continue 796 <1> mem_done: ;AN000; 0 00006224 30C0 XOR AL,AL ;AN000;;MS. make ASCIIZ 798 <1> ARENA_struc_size equ arena_struc_size ; NASM port equate 0 00006226 83FF10 CMP DI,ARENA_struc_size ;AN000;MS. if not all filled 0 00006229 7301 JAE fill8 ;AN000;MS. 0 0000622B AA STOSB ;AN000;MS. 802 <1> fill8: ;AN000; 0 0000622C 5E POP SI ;AN007;MS. ds:si -> file name 0 0000622D 59 POP CX ;AN007;MS. 805 <1> 0 0000622E E85601 CALL Scan_Special_Entries ;AN007;MS. 807 <1> 0 00006231 52 PUSH DX 0 00006232 8B76F0 MOV SI,[exec_size] 0 00006235 01D6 ADD SI,DX 0 00006237 E8[0000] invoke D_Dup_PDB ; ES is now PDB 0 0000623A 5A POP DX 813 <1> 0 0000623B FF76F2 PUSH word [exec_environ] 0 0000623E 268F062C00 POP word [ES:PDB_environ] 816 <1> ; 817 <1> ; set up proper command line stuff 818 <1> ; 0 00006243 C576FC LDS SI,[exec_blk] ; get the block 0 00006246 1E PUSH DS ; save its location 0 00006247 56 PUSH SI 822 <1> exec0_5C_FCB equ Exec0_5C_FCB ; NASM port equate 0 00006248 C57406 LDS SI,[SI + exec0_5C_FCB] ; get the 5c fcb 824 <1> ; 825 <1> ; DS points to user space 5C FCB 826 <1> ; 0 0000624B B90C00 MOV CX,12 ; copy drive, name and ext 0 0000624E 51 PUSH CX 0 0000624F BF5C00 MOV DI,5Ch 0 00006252 8A1C MOV BL,[SI] 0 00006254 F3A4 REP MOVSB 832 <1> ; 833 <1> ; DI = 5Ch + 12 = 5Ch + 0Ch = 68h 834 <1> ; 0 00006256 31C0 XOR AX,AX ; zero extent, etc for CPM 0 00006258 AB STOSW 0 00006259 AB STOSW 838 <1> ; 839 <1> ; DI = 5Ch + 12 + 4 = 5Ch + 10h = 6Ch 840 <1> ; 0 0000625A 59 POP CX 0 0000625B 5E POP SI ; get block 0 0000625C 1F POP DS 0 0000625D 1E PUSH DS ; save (again) 0 0000625E 56 PUSH SI 846 <1> exec0_6C_FCB equ Exec0_6C_FCB ; NASM port equate 0 0000625F C5740A LDS SI,[SI + exec0_6C_FCB] ; get 6C FCB 848 <1> ; 849 <1> ; DS points to user space 6C FCB 850 <1> ; 0 00006262 8A3C MOV BH,[SI] ; do same as above 0 00006264 F3A4 REP MOVSB 0 00006266 AB STOSW 0 00006267 AB STOSW 0 00006268 5E POP SI ; get block (last time) 0 00006269 1F POP DS 857 <1> exec0_com_line equ Exec0_com_line ; NASM port equate 0 0000626A C57402 LDS SI,[SI + exec0_com_line] ; command line 859 <1> ; 860 <1> ; DS points to user space 80 command line 861 <1> ; 0 0000626D 80C980 OR CL,80h 0 00006270 89CF MOV DI,CX 0 00006272 F3A4 REP MOVSB ; Wham! 865 <1> ; 866 <1> ; Process BX into default AX (validity of drive specs on args). We no longer 867 <1> ; care about DS:SI. 868 <1> ; 0 00006274 FEC9 DEC CL ; get 0FFh in CL 0 00006276 88F8 MOV AL,BH 0 00006278 30FF XOR BH,BH 0 0000627A E8[0000] invoke GetVisDrv 0 0000627D 7302 JNC exec_BL 0 0000627F 88CF MOV BH,CL 875 <1> exec_BL: 0 00006281 88D8 MOV AL,BL 0 00006283 30DB XOR BL,BL 0 00006285 E8[0000] invoke GetVisDrv 879 <1> exec_Set_Return equ exec_set_return ; NASM port label 0 00006288 7302 JNC exec_Set_Return 0 0000628A 88CB MOV BL,CL 882 <1> exec_set_return: 0 0000628C E8[0000] invoke get_user_stack ; get his return address 0 0000628F FF7414 PUSH word [SI + user_CS] ; suck out the CS and IP 0 00006292 FF7412 PUSH word [SI + user_IP] 0 00006295 FF7414 PUSH word [SI + user_CS] ; suck out the CS and IP 0 00006298 FF7412 PUSH word [SI + user_IP] 0 0000629B 268F060A00 POP WORD PTR [ES:PDB_Exit] 0 000062A0 268F060C00 POP WORD PTR [ES:PDB_Exit+2] 0 000062A5 31C0 XOR AX,AX 0 000062A7 8ED8 MOV DS,AX 0 000062A9 8F068800 POP word [addr_int_terminate] ; save them where we can get them later 0 000062AD 8F068A00 POP word [addr_int_terminate+2] ; when the child exits. 0 000062B1 36C706[0000]8000 MOV WORD [ss:DMAADD],80h 0 000062B8 368E1E[0000] MOV DS,[ss:CurrentPDB] 0 000062BD 368C1E[0200] MOV WORD PTR [ss:DMAADD+2],DS 897 <1> 898 <1> extern ReleaseOwnersMCBs, backdoor_free_mcb_exec 0 000062C2 53 push bx 0 000062C3 E8[0000] EnterCrit critMem 0 000062C6 31DB xor bx, bx 0 000062C8 36871E[0000] xchg bx, [ss:backdoor_free_mcb_exec] ; get backdoor owner 0 000062CD E8[0000] call ReleaseOwnersMCBs ; exec success: free it 0 000062D0 E8[0000] LeaveCrit critMem 0 000062D3 5B pop bx 906 <1> 0 000062D4 F646FB01 TEST BYTE [exec_func],exec_func_no_execute 0 000062D8 7427 JZ exec_go 909 <1> 0 000062DA 36C536[0000] LDS SI,[ss:exec_init_SP] ; get stack 0 000062DF C47EFC LES DI,[exec_blk] ; and block for return 912 <1> exec1_SS equ Exec1_SS ; NASM port equate 0 000062E2 268C5D10 MOV [ES:DI + exec1_SS],DS ; return SS 914 <1> 0 000062E6 4E DEC SI ; 'push' default AX 0 000062E7 4E DEC SI 0 000062E8 891C MOV [SI],BX ; save default AX reg 918 <1> exec1_SP equ Exec1_SP ; NASM port equate 0 000062EA 2689750E MOV [ES:DI + exec1_SP],SI ; return 'SP' 920 <1> 0 000062EE 36C506[0400] LDS AX,[ss:exec_init_IP] 922 <1> exec1_CS equ Exec1_CS ; NASM port equate 0 000062F3 268C5D14 MOV [ES:DI + exec1_CS],DS ; initial entry stuff 924 <1> 925 <1> exec1_IP equ Exec1_IP ; NASM port equate 0 000062F7 26894512 MOV [ES:DI + exec1_IP],AX 0 000062FB 89EC5D Leave 0 000062FE E9[0000] transfer SYS_RET_OK 929 <1> 930 <1> exec_go: 0 00006301 36C536[0400] LDS SI,[ss:exec_init_IP] ; get entry point 0 00006306 36C43E[0000] LES DI,[ss:exec_init_SP] ; new stack 0 0000630B 8CC0 MOV AX,ES 934 <1> ; 935 <1> ; DS:SI points to entry point 936 <1> ; AX:DI points to initial stack 937 <1> ; DX has PDB pointer 938 <1> ; BX has initial AX value 939 <1> ; 0 0000630D FA CLI 0 0000630E 36C606[0000]00 MOV BYTE [ss:INDOS],0 942 <1> ASSUME SS:NOTHING 0 00006314 8ED0 MOV SS,AX ; set up user's stack 0 00006316 89FC MOV SP,DI ; and SP 0 00006318 FB STI 0 00006319 90 nop 0 0000631A 9C pushf ; iret frame 0 0000631B 1E PUSH DS ; fake long call to entry 0 0000631C 56 PUSH SI 0 0000631D 8EC2 MOV ES,DX ; set up proper seg registers 0 0000631F 8EDA MOV DS,DX 0 00006321 53 push bx ; = ax = bx on stack 953 <1> do_a20_off_ax_on_stack: 0 00006322 53 push bx ; for both registers 955 <1> %ifndef BUF2 956 <1> %IF BUFFERFLAG 957 <1> invoke restore_user_map 958 <1> %ENDIF 959 <1> %endif 960 <1> extern a20off_entry 961 <1> 0 00006323 EA[0000][0000] jmp DOSENTRY:a20off_entry ; must address XMS entry variable with cs 963 <1> 964 <1> EndProc D_Exec 965 <1> 966 <1> Procedure ExecRead,NEAR 966 ****************** <1> warning: proc ExecRead... [-w+user] 0 00006328 E80C00 CALL exec_dealloc 0 0000632B 8B5EF8 MOV bx,[exec_fh] 0 0000632E 55 PUSH BP 0 0000632F E8[0000] invoke D_READ 0 00006332 5D POP BP 0 00006333 E80D00 CALL exec_alloc 0 00006336 C3 return 974 <1> EndProc ExecRead 975 <1> 976 <1> procedure exec_dealloc,near 976 ****************** <1> warning: proc exec_dealloc... [-w+user] 977 <1> ASSUME DS:NOTHING,ES:NOTHING 0 00006337 53 PUSH BX 0 00006338 BB0000 MOV BX,arena_owner_system 0 0000633B E8[0000] EnterCrit CritMEM 0 0000633E E81000 CALL ChangeOwners 0 00006341 5B POP BX 0 00006342 C3 return 984 <1> EndProc exec_dealloc 985 <1> 986 <1> procedure exec_alloc,near 986 ****************** <1> warning: proc exec_alloc... [-w+user] 0 00006343 53 PUSH BX 0 00006344 368B1E[0000] MOV BX,[ss:CurrentPDB] 0 00006349 E80500 CALL ChangeOwners 0 0000634C E8[0000] LeaveCrit CritMEM 0 0000634F 5B POP BX 0 00006350 C3 return 993 <1> EndProc exec_alloc 994 <1> 995 <1> procedure ChangeOwners,NEAR 995 ****************** <1> warning: proc ChangeOwners... [-w+user] 0 00006351 9C pushf 0 00006352 50 PUSH AX 0 00006353 8B46F2 MOV AX,[exec_environ] 0 00006356 E80900 CALL ChangeOwner 0 00006359 8B46EE MOV AX,[exec_load_block] 0 0000635C E80300 Call ChangeOwner 0 0000635F 58 POP AX 0 00006360 9D popf 0 00006361 C3 return 1005 <1> EndProc ChangeOwners 1006 <1> 1007 <1> Procedure ChangeOwner,near 1007 ****************** <1> warning: proc ChangeOwner... [-w+user] 0 00006362 09C0 OR AX,AX ; is area allocated? 0 00006364 74FB retz ; no, do nothing 0 00006366 48 DEC AX 0 00006367 1E PUSH DS 0 00006368 8ED8 MOV DS,AX 0 0000636A 891E0100 MOV [arena_owner],BX 0 0000636E 1F POP DS 0 0000636F C3 return 1016 <1> EndProc ChangeOwner 1017 <1> 1018 <1> Procedure Scan_Execname,near ;AN000;MS. 1018 ****************** <1> warning: proc Scan_Execname... [-w+user] 1019 <1> 0 00006370 C576E6 LDS SI,[execName] ;AN000;MS. DS:SI points to name 1021 <1> save_begin: ;AN000; 0 00006373 89F1 MOV CX,SI ;AN000;MS. CX= starting addr 1023 <1> scan0: ;AN000; 0 00006375 AC LODSB ;AN000;MS. get char 0 00006376 3C3A CMP AL,':' ;AN000;;MS. is ':' , may be A:name 0 00006378 74F9 JZ save_begin ;AN000;;MS. yes, save si 0 0000637A 3C5C CMP AL,'\' ;AN000;;MS. is '\', may be A:\name 0 0000637C 74F5 JZ save_begin ;AN000;;MS. yes, save si 0 0000637E 3C00 CMP AL,0 ;AN000;;MS. is end of name 0 00006380 75F3 JNZ scan0 ;AN000;;MS. no, continue scanning 0 00006382 29CE SUB SI,CX ;AN000;;MS. get name's length 0 00006384 87F1 XCHG SI,CX ;AN000;;MS. cx= length, si= starting addr 1033 <1> 0 00006386 C3 return ;AN000;;MS. 1035 <1> EndProc Scan_Execname ;AN000;;MS. 1036 <1> 1037 <1> 1038 <1> Procedure Scan_Special_Entries,near ;AN000;MS. 1038 ****************** <1> warning: proc Scan_Special_Entries... [-w+user] 1039 <1> 0 00006387 49 DEC CX ;AN007;MS. cx= name length 0 00006388 368B3E[0000] MOV DI,[ss:Special_Entries] ;AN007;MS. es:di -> addr of special entries 0 0000638D E83D00 CALL Reset_Version ;AN008;MS. 0 00006390 16 PUSH ss ;AN007;MS. 0 00006391 07 POP ES ;AN007;MS. 1045 <1> Getentries: ;AN007;MS. 0 00006392 268A05 MOV AL,[ES:DI] ;AN007;MS. end of list 0 00006395 08C0 OR AL,AL ;AN007;MS. 0 00006397 7433 JZ end_list ;AN007;MS. yes 0 00006399 36893E[0000] MOV [ss:Temp_Var2],DI ;AN007;MS. save di 0 0000639E 38C8 CMP AL,CL ;AN007;MS. same length ? 0 000063A0 751C JNZ skipone ;AN007;MS. no 0 000063A2 47 INC DI ;AN007;MS. es:di -> special name 0 000063A3 51 PUSH CX ;AN007;MS. save length and name addr 0 000063A4 56 PUSH SI ;AN007;MS. 0 000063A5 F3A6 REPZ CMPSB ;AN007;MS. same name ? 0 000063A7 7513 JNZ not_matched ;AN007;MS. no 0 000063A9 268B05 MOV AX,[ES:DI] ;AN007;MS. get special version 0 000063AC 36A3[0000] MOV [ss:Special_Version],AX ;AN007;MS. save it 0 000063B0 268A4502 MOV AL,[ES:DI+2] ;AN008;MS. get fake count 0 000063B4 36A2[0000] MOV [ss:Fake_Count],AL ;AN007;MS. save it 0 000063B8 5E POP SI ;AN007;MS. 0 000063B9 59 POP CX ;AN007;MS. 0 000063BA EB10 JMP SHORT end_list ;AN007;MS. 1064 <1> not_matched: ;AN007;MS. 0 000063BC 5E POP SI ;AN007;MS. restore si,cx 0 000063BD 59 POP CX ;AN007;MS. 1067 <1> skipone: ;AN007;MS. 0 000063BE 368B3E[0000] MOV DI,[ss:Temp_Var2] ;AN007;MS. restore old di 0 000063C3 30E4 XOR AH,AH ;AN007;MS. position to next entry 0 000063C5 01C7 ADD DI,AX ;AN007;MS. 0 000063C7 83C704 ADD DI,4 ;AN007;MS. 0 000063CA EBC6 JMP Getentries ;AN007;MS. 1073 <1> 1074 <1> 1075 <1> end_list: ;AN007;MS. 0 000063CC C3 return 1077 <1> EndProc Scan_Special_Entries ;AN000;;MS. 1078 <1> 1079 <1> Procedure Reset_Version,near ;AN008;MS. 1079 ****************** <1> warning: proc Reset_Version... [-w+user] 1080 <1> 0 000063CD 36803E[0000]FF CMP byte [ss:Fake_Count],0FFH ;AN008;MS. 0 000063D3 7507 JNZ dont_reset ;AN008;MS. 0 000063D5 36C706[0000]0000 MOV word [ss:Special_Version],0 ;AN008;MS. reset to current version 1084 <1> dont_reset: 0 000063DC C3 return 1086 <1> EndProc Reset_Version,near ;AN008;;MS. 1087 <1> 1088 <1> 72 ;=== Pop trace listing source 73 74 ;SUBTTL Terminate and stay resident handler 75 ;PAGE 76 ; 77 ; Input: DX is an offset from CurrentPDB at which to 78 ; truncate the current block. 79 ; 80 ; output: The current block is truncated (expanded) to be [DX+15]/16 81 ; paragraphs long. An exit is simulated via resetting CurrentPDB 82 ; and restoring the vectors. 83 ; 84 procedure D_Keep_process,NEAR 84 ****************** warning: proc D_Keep_process... [-w+user] 85 ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP 86 0 000063DD 50 PUSH AX ; keep exit code around 88 Exit_keep_process equ Exit_Keep_process ; NASM port equate 0 000063DE 36C606[0000]03 MOV BYTE PTR [ss:Exit_type],Exit_keep_process 0 000063E4 368E06[0000] MOV ES,[ss:CurrentPDB] 0 000063E9 83FA06 CMP DX,6h ; keep enough space around for system 92 Keep_shrink equ keep_shrink ; NASM port label 0 000063EC 7303 JAE Keep_shrink ; info 0 000063EE BA0600 MOV DX,6h 95 keep_shrink: 0 000063F1 89D3 MOV BX,DX 0 000063F3 53 PUSH BX 0 000063F4 06 PUSH ES 0 000063F5 E8[0000] invoke D_SETBLOCK ; ignore return codes. 0 000063F8 1F POP DS 0 000063F9 5B POP BX 0 000063FA 7207 JC keep_done ; failed on modification 0 000063FC 8CD8 MOV AX,DS 0 000063FE 01D8 ADD AX,BX 0 00006400 A30200 MOV [PDB_block_len],AX 106 107 keep_done: 0 00006403 58 POP AX 109 exit_inner equ Exit_inner ; NASM port label 0 00006404 EB26 JMP SHORT exit_inner ; and let abort take care of the rest 111 112 EndProc D_Keep_process 113 114 relocated i27 115 procedure Stay_resident,NEAR 115 ****************** warning: proc Stay_resident... [-w+user] 116 ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING 117 Keep_process equ Keep_Process ; NASM port equate 0 00006406 B80031 MOV AX,(Keep_process << 8) + 0 ; Lower part is return code 0 00006409 83C20F ADD DX,15 0 0000640C D1DA RCR DX,1 0 0000640E B103 MOV CL,3 0 00006410 D3EA SHR DX,CL 123 0 00006412 E9[0000] transfer COMMAND 125 EndProc Stay_resident 126 127 ;SUBTTL $EXIT - return to parent process 128 ;PAGE 129 ; 130 ; Assembler usage: 131 ; MOV AL, code 132 ; MOV AH, Exit 133 ; INT int_command 134 ; Error return: 135 ; None. 136 ; 137 procedure D_EXIT,NEAR 137 ****************** warning: proc D_EXIT... [-w+user] 138 ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP 0 00006415 30E4 XOR AH,AH 0 00006417 368626[0000] XCHG AH,BYTE PTR [ss:DidCTRLC] 0 0000641C 08E4 OR AH,AH 142 exit_terminate equ Exit_terminate ; NASM port equate 0 0000641E 36C606[0000]00 MOV BYTE PTR [ss:Exit_type],exit_terminate 0 00006424 7406 JZ exit_inner 145 exit_ctrl_c equ Exit_Ctrl_C ; NASM port equate 0 00006426 36C606[0000]01 MOV BYTE PTR [ss:Exit_type],exit_ctrl_c 147 148 entry Exit_inner 149 0 0000642C E8[0000] invoke get_user_stack 0 0000642F 36FF36[0000] PUSH word [ss:CurrentPDB] 0 00006434 8F4414 POP word [SI + user_CS] 0 00006437 EB08 JMP SHORT abort_inner 154 EndProc D_EXIT 155 156 BREAK <$ABORT -- Terminate a process> 157 158 ; Inputs: 159 ; user_CS:00 must point to valid program header block 160 ; Function: 161 ; Restore terminate and Cntrl-C addresses, flush buffers and transfer to 162 ; the terminate address 163 ; Returns: 164 ; TO THE TERMINATE ADDRESS 165 166 procedure D_ABORT,NEAR 166 ****************** warning: proc D_ABORT... [-w+user] 167 ASSUME DS:NOTHING,ES:NOTHING 168 0 00006439 30C0 XOR AL,AL 170 exit_abort equ Exit_abort ; NASM port equate 0 0000643B 36C606[0000]00 MOV byte [ss:exit_type],exit_abort 172 173 ; 174 ; abort_inner must have AL set as the exit code! The exit type is retrieved 175 ; from exit_type. Also, the PDB at user_CS needs to be correct as the one 176 ; that is terminating. 177 ; 178 entry abort_inner 179 0 00006441 368A26[0000] MOV AH,[ss:exit_type] 0 00006446 36A3[0000] MOV [ss:exit_code],AX 0 0000644A E8[0000] invoke Get_user_stack 0 0000644D 8E5C14 MOV DS,[SI + user_CS] ; set up old interrupts 0 00006450 31C0 XOR AX,AX 0 00006452 8EC0 MOV ES,AX 0 00006454 BE0A00 MOV SI,SAVEXIT 0 00006457 BF8800 MOV DI,addr_int_terminate 0 0000645A A5 MOVSW 0 0000645B A5 MOVSW 0 0000645C A5 MOVSW 0 0000645D A5 MOVSW 0 0000645E A5 MOVSW 0 0000645F A5 MOVSW 0 00006460 E9[0000] transfer $reset_environment 195 EndProc D_ABORT 196 197 END === Trace listing source: ../DOS/alloc.lst 1 ; SCCSID = @(#)alloc.asm 1.1 85/04/09 2 ;TITLE ALLOC.ASM - memory arena manager 3 ;NAME Alloc 4 ; 5 ; Memory related system calls and low level routines for MSDOS 2.X. 6 ; I/O specs are defined in DISPATCH. 7 ; 8 ; $ALLOC 9 ; $SETBLOCK 10 ; $DEALLOC 11 ; $AllocOper 12 ; arena_free_process 13 ; arena_next 14 ; check_signature 15 ; Coalesce 16 ; 17 ; Modification history: 18 ; 19 ; Created: ARR 30 March 1983 20 ; 21 22 [list -] === Switch to base=008400h -> "DOSCODECODE" 29 section DOSCODECODE 30 [list -] 30 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 30 ****************** warning: out: BPB.INC... [-w+user] 30 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 30 ****************** warning: out: DEVSYM.INC... [-w+user] 30 ****************** warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi] 36 %include "memsw.mac" 1 <1> %define LDOSMEM 1 37 ;.cref 38 [list +] 39 40 ;.lall 41 42 ;SUBTTL memory allocation utility routines 43 ;PAGE 44 ; 45 ; arena data 46 ; 47 i_need arena_head,WORD ; seg address of start of arena 48 first_mcb equ arena_head 49 I_need first_umcb, word 50 i_need CurrentPDB,WORD ; current process data block addr 51 i_need FirstArena,WORD ; first free block found 52 i_need BestArena,WORD ; best free block found 53 i_need LastArena,WORD ; last free block found 54 i_need AllocMethod,BYTE ; how to alloc first(best)last 55 I_need alloc_strategy_ext, byte 56 I_need enable_uma, byte 57 I_need EXTERR_LOCUS,BYTE ; Extended Error Locus 58 59 %ifdef LDOSMEM 60 getpsp: 0 00006463 368B1E[0000] mov bx, word [ss:CurrentPDB] 0 00006468 C3 retn 63 64 %assign _UMA 1 65 %assign _ERRORFLAGS 0 66 67 %include "memory.asm" 1 <1> 2 <1> %if 0 3 <1> 4 <1> lDOS memory handling 5 <1> by E. C. Masloch, 2018--2025 6 <1> 7 <1> Usage of the works is permitted provided that this 8 <1> instrument is retained with the works, so that any entity 9 <1> that uses the works is notified of this instrument. 10 <1> 11 <1> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY. 12 <1> 13 <1> %endif 14 <1> 15 <1> %if 0 16 <1> 17 <1> Inside most functions, di is set to zero and used as index register to access 18 <1> MCB fields (this allows the assembler to use byte offsets resulting in smaller 19 <1> instructions). It's also used whenever a register with the value zero is handy, 20 <1> for example, when ClearMCB wants to free the MCB by setting the owner word to 21 <1> zero. 22 <1> 23 <1> Most functions access the current working MCB with ds. CollectNextFreeMCB 24 <1> accesses the secondary MCB (which is to be removed) with es. 25 <1> 26 <1> -- 27 <1> 28 <1> The separate CheckMCBs function has been removed. To check the MCB chain, call 29 <1> ReleaseOwnersMCBs with bx set to zero. The returned status indicates whether 30 <1> the MCB chain is invalid. (This also resets the mcbName field of all already 31 <1> free MCBs, but that shouldn't be an issue.) 32 <1> 33 <1> -- 34 <1> 35 <1> As you may note, the functions are mostly ordered from those performing simple 36 <1> or preparatory tasks to those more complex, calling the simpler ones. The last 37 <1> functions are ModifyMCBRandom (which takes an address and resizes that MCB as 38 <1> requested) and AllocateMCBRandom (which searches through the MCBs and decides 39 <1> which one to reserve depending on the requested allocation strategy). 40 <1> 41 <1> -- 42 <1> 43 <1> Note that the MS-DOS-compatible UMB link and memory allocation strategies 44 <1> for allocation behave as follows: 45 <1> 46 <1> UMB link? --> Off On 47 <1> v Strategy area 48 <1> 00h LMA only LMA then UMA, as one area 49 <1> 40h LMA only UMA only, as one area 50 <1> 80h LMA only UMA as one area, then LMA as one area 51 <1> 52 <1> In particular, "UMA then LMA" (80h) treats the two areas as distinct areas 53 <1> for the search; if a UMA block is found that satisfies the search, it is 54 <1> used, even if a better (best-fit) or later (last-fit) block would be found 55 <1> in the LMA. (For first-fit, there is no difference.) 56 <1> 57 <1> Our original implementation treated the "UMA then LMA" (80h) strategy area 58 <1> as one area for the search, which for best-fit and last-fit differs. 59 <1> 60 <1> -- 61 <1> 62 <1> The default now is to behave compatible to MS-DOS, that is, UMA then LMA 63 <1> is handled as two areas, while LMA then UMA is handled as one area. 64 <1> Setting the flag 2 in the high byte of the allocation strategy (stored 65 <1> in alloc_strategy_ext) handles both cases in the original lDOS meaning, 66 <1> that is, as one area. Setting the flag 4 instead handles both cases as 67 <1> two areas. Flag 2 takes precedence if both are set. (This is handled in 68 <1> AllocateMCBCompatible, which calls AllocateLargestMCBRandom for the two 69 <1> area cases.) 70 <1> 71 <1> -- 72 <1> 73 <1> When flag 1 of alloc_strategy_ext is set, the UMB link status (which 74 <1> here includes whether the last LMCB has an M or a Z) is ignored and 75 <1> the area flags of the allocation strategy are used exclusively. 76 <1> 77 <1> %endif 78 <1> 79 <1> %include "lmacros2.mac" 1 <2> [list -] 14 <2> [list -] 80 <1> %include "lstruct.mac" 1 <2> [list -] 13 <2> [list -] 81 <1> 82 <1> 83 <1> global GetMCBOwner, GetMCBFlags, GetRawMCBFlags, AllocateLargestMCBRandom 84 <1> global AllocateMCBCompatible.flags_cx 85 <1> 86 <1> 87 <1> ; INP: cx = user-requested flags 88 <1> ; OUT: cx = internally usable flags 89 <1> ; (only one bit of bits 4..7 set, low nibble contains 0..2, high byte always clear) 90 <1> ; word [ss:error_flags] updated 91 <1> ; CHG: - 92 <1> ; STK: 4 word 93 <1> ; 94 <1> ; The user-requested flags are parsed to these internally used: 95 <1> ; area: 10h LMA only 96 <1> ; 20h LMA then UMA 97 <1> ; 40h UMA only 98 <1> ; 80h UMA then LMA 99 <1> ; (for the non-UMA build, all area flags are ignored and cleared) 100 <1> ; mode: 00h First fit 101 <1> ; 01h Best fit 102 <1> ; 02h Last fit 103 <1> %ifn _UMA 104 <1> FixMCBFlags: 105 <1> test ch, ~(1 | 2 | 4) ; invalid flags set ? 106 <1> jz .validhigh 107 <1> and ch, (1 | 2 | 4) 108 <1> %if _ERRORFLAGS 109 <1> or byte [ss:error_flags], EF_InvalidAllocStrategy 110 <1> %endif 111 <1> .validhigh: 112 <1> ; The problem arises that MS-DOS 5+ always supports 113 <1> ; UMBs. Older versions allowed any value as strategy 114 <1> ; using anything above 2 as "Last fit" too. Instead 115 <1> ; of reproducing this behaviour, builds without UMA 116 <1> ; fake that they actually support UMA but that there 117 <1> ; was none installed. (After all, we use the DOS 5+ 118 <1> ; internal data layout.) Programs can check for this 119 <1> ; fake support by calling 21.5802 and 21.5803. If UMA 120 <1> ; is actually supported, 21.5802 always returns NC. If 121 <1> ; UMA is not supported, it returns CY (ax = 0001h). If 122 <1> ; UMA is supported, but not installed, 21.5803 still 123 <1> ; returns CY (ax = 0001h). 124 <1> and cl, 0Fh ; clear area flags (we don't check these either) 125 <1> cmp cl, 3 ; valid strategy ? 126 <1> jb .validstrategy ; yes --> 127 <1> xor cl, cl ; force first fit 128 <1> %if _ERRORFLAGS 129 <1> or byte [ss:error_flags], EF_InvalidAllocStrategy ; report invalid strategy 130 <1> %endif 131 <1> .validstrategy: 132 <1> retn 133 <1> %else 134 <1> FixMCBFlags: 0 00006469 F6C5F8 test ch, ~(1 | 2 | 4) ; invalid flags set ? 0 0000646C 7403 jz .validhigh 0 0000646E 80E507 and ch, (1 | 2 | 4) 138 <1> %if _ERRORFLAGS 139 <1> or byte [ss:error_flags], EF_InvalidAllocStrategy 140 <1> %endif 141 <1> .validhigh: 0 00006471 50 push ax 0 00006472 51 push cx 0 00006473 F6C1F0 test cl, ~0Fh ; test whether any flag set 0 00006476 7503 jnz .gotflag 0 00006478 80C920 or cl, 20h ; "LMA then UMA" (if UMA enabled) 147 <1> .gotflag: 0 0000647B B580 mov ch, 80h 0 0000647D F9 stc 0 0000647E E81A00 call .test 0 00006481 E81700 call .test 0 00006484 E81400 call .test ; (after this call, 10h is the only flag left. it is set) 153 <1> 0 00006487 30ED xor ch, ch ; insure high byte zero 0 00006489 51 push cx 0 0000648A 80E10F and cl, 0Fh ; clear flags 0 0000648D 80F903 cmp cl, 3 ; valid strategy ? 158 <1> ; (0 = first fit, 1 = best fit, 2 = last fit) 0 00006490 59 pop cx 0 00006491 7203 jb .validstrategy ; yes --> 0 00006493 80E1F0 and cl, ~0Fh ; force first fit 162 <1> %if _ERRORFLAGS 163 <1> or byte [ss:error_flags], EF_InvalidAllocStrategy ; invalid low nibble 164 <1> %endif 165 <1> .validstrategy: 0 00006496 58 pop ax ; restore ch from stack into ah 0 00006497 88E5 mov ch, ah ; restore ch 0 00006499 58 pop ax ; restore ax from stack 0 0000649A C3 retn 170 <1> 171 <1> .test: 0 0000649B 7307 jnc .return ; previous call got flag 0 0000649D 84E9 test cl, ch ; current flag set ? 0 0000649F 7504 jnz .match ; yes --> 0 000064A1 D0ED shr ch, 1 ; shift down 0 000064A3 F9 stc ; signal next calls to pass 177 <1> .return: 0 000064A4 C3 retn 179 <1> .match: 0 000064A5 30E9 xor cl, ch ; clear flag itself 0 000064A7 F6C1F0 test cl, ~0Fh ; any of the lower flags set ? 0 000064AA 7403 jz .valid ; nope --> 0 000064AC 80E10F and cl, 0Fh ; clear lower flags 184 <1> %if _ERRORFLAGS 185 <1> or byte [ss:error_flags], EF_MultipleAllocAreas ; flag the error 186 <1> %endif 187 <1> .valid: 0 000064AF 30E9 xor cl, ch ; (NC) set flag again 0 000064B1 C3 retn 190 <1> 191 <1> 192 <1> ; Compare ax to first UMCB 193 <1> ; 194 <1> ; INP: ax = MCB 195 <1> ; OUT: NZ if not first UMCB (or if there's no UMCB) 196 <1> ; ZR if first UMCB 197 <1> ; CHG: - 198 <1> ; STK: 1 word 199 <1> IsFirstUMCB?: 0 000064B2 36833E[0000]FE cmp word [ss:first_umcb], byte -2 0 000064B8 7705 ja .return ; (NZ if it jumps) --> 0 000064BA 363B06[0000] cmp ax, word [ss:first_umcb] 203 <1> .return: 0 000064BF C3 retn 205 <1> 206 <1> 207 <1> GetRawMCBFlags: 0 000064C0 368A2E[0000] mov ch, byte [ss:alloc_strategy_ext] 0 000064C5 368A0E[0000] mov cl, byte [ss:AllocMethod] ; cx = flags 0 000064CA C3 retn 211 <1> 212 <1> 213 <1> ; Get current MCB flags 214 <1> ; 215 <1> ; INP: - 216 <1> ; OUT: cx = internally usable flags 217 <1> ; (only one bit of bits 4..7 set, low nibble contains 0..2, high byte always clear) 218 <1> ; error_flags updated 219 <1> ; CHG: - 220 <1> ; STK: 3 word 221 <1> GetMCBFlags: 0 000064CB E8F2FF call GetRawMCBFlags 0 000064CE E898FF call FixMCBFlags ; detect multiple area flags 224 <1> %if _ERRORFLAGS 225 <1> test byte [ss:enable_uma], ~1 226 <1> jz .validlink 227 <1> or byte [ss:error_flags], EF_InvalidUMBLink ; invalid UMB link bits set 228 <1> .validlink: 229 <1> %endif 0 000064D1 F6C501 test ch, 1 ; use area flags and 231 <1> ; disregard UMB link ? 0 000064D4 7516 jnz .return ; yes --> 0 000064D6 36F606[0000]01 test byte [ss:enable_uma], 1 ; UMA enabled ? 0 000064DC 7408 jz .lmaonly ; no, force LMA only --> (no error flag) 0 000064DE 36833E[0000]FF cmp word [ss:first_umcb], byte -1 ; UMA available ? 0 000064E4 7506 jne .return 237 <1> %if _ERRORFLAGS 238 <1> or byte [ss:error_flags], EF_NoUMBsToLink ; UMB link enabled but none there 239 <1> %endif 240 <1> .lmaonly: ; change area to LMA only 0 000064E6 80E10F and cl, 0Fh 0 000064E9 80C910 or cl, 10h 243 <1> .return: 0 000064EC C3 retn 245 <1> %endif 246 <1> 247 <1> 248 <1> ; Set MCB flags for linear access 249 <1> ; ("LMA only" if no UMA available, else "LMA then UMA") 250 <1> ; 251 <1> ; INP: - 252 <1> ; OUT: ax = 0000h (to get first MCB on SNextMCB call) 253 <1> ; ss:sp-> flags (word 10h if no first UMCB, 20h else), 254 <1> ; loop detection counter (word initialised to 0), 255 <1> ; original si value 256 <1> ; ss:si-> flags (si = sp) 257 <1> ; NC, ZR 258 <1> ; CHG: - 259 <1> ; STK: 5 word 260 <1> SetLinearMCBFlags: 0 000064ED 55 push bp 0 000064EE 89E5 mov bp, sp 0 000064F0 B81000 mov ax, 10h ; if no UMCB, set to 10h ("LMA only") 264 <1> %if _UMA 0 000064F3 36833E[0000]FF cmp word [ss:first_umcb], -1 0 000064F9 7402 je .nonuma 0 000064FB B020 mov al, 20h ; else set to 20h ("LMA then UMA") 268 <1> .nonuma: 269 <1> %endif 0 000064FD 50 push ax ; flags word, at [bp - 2] 0 000064FE FF7602 push word [bp + 2] ; create return stack space, ip 0 00006501 FF7600 push word [bp] ; bp on stack 0 00006504 31C0 xor ax, ax 0 00006506 897602 mov word [bp + 2], si ; save si value on stack 0 00006509 894600 mov word [bp], ax ; loop detection counter 0 0000650C 8D76FE lea si, [bp - 2] ; ss:si-> flags 0 0000650F 5D pop bp ; bp = [bp - 6] 0 00006510 C3 retn ; ip = [bp - 4] 279 <1> 280 <1> 281 <1> ; Get current MCB owner 282 <1> ; 283 <1> ; INP: - 284 <1> ; OUT: dx = PSP address or owner override value 285 <1> ; CHG: - 286 <1> ; STK: 2 word 287 <1> GetMCBOwner: 0 00006511 87D3 xchg dx, bx 289 <1> %if 0 290 <1> mov bx, word [ss:current_driver] 291 <1> inc bx 292 <1> jz .usepsp ; was FFFFh, override inactive --> 293 <1> dec bx 294 <1> jnz .override ; was not 0000h, override active --> 295 <1> %endif 296 <1> .usepsp: 0 00006513 E84DFF call getpsp ; don't care which value returned 0 00006516 85DB test bx, bx 0 00006518 7501 jnz .return 0 0000651A 43 inc bx ; except, not zero ! 301 <1> .override: 302 <1> .return: 0 0000651B 87D3 xchg dx, bx 0 0000651D C3 retn 305 <1> 306 <1> 307 <1> ; Verify MCB 308 <1> ; 309 <1> ; INP: ax = MCB 310 <1> ; OUT: ds = MCB 311 <1> ; di = 0 312 <1> ; NZ, CY if invalid MCB, 313 <1> ; ax = error code 0007h (MCB chain corrupted) 314 <1> ; ZR, NC if valid MCB 315 <1> ; CHG: - 316 <1> ; STK: 1 word 317 <1> VerifyMCB: 0 0000651E 31FF xor di, di 0 00006520 8ED8 mov ds, ax ; set up working registers 0 00006522 40 inc ax 0 00006523 83F802 cmp ax, byte 2 ; passed value FFFFh or 0000h ? 0 00006526 720B jb .invalid ; (NZ, CY) yes --> 0 00006528 48 dec ax 0 00006529 803D4D cmp byte [di+mcbSignature], 'M' ; valid 'M' signature ? 0 0000652C 7409 je .return ; yes --> (ZR, NC) 0 0000652E 803D5A cmp byte [di+mcbSignature], 'Z' ; valid 'Z' signature ? 0 00006531 7404 je .return ; yes --> (ZR, NC) 328 <1> .invalid: 0 00006533 F9 stc 0 00006534 B80700 mov ax, errorMCBDestroyed ; (CY, NZ) else invalid 331 <1> .return: 0 00006537 C3 retn 333 <1> 334 <1> 335 <1> ; INP: ax = memory block's segment 336 <1> ; OUT: di = 0 337 <1> ; NC if valid MCB, 338 <1> ; ds = ax = MCB address 339 <1> ; CY if invalid MCB, 340 <1> ; ax = error code 0009h (Invalid MCB) 341 <1> ; CHG: ds 342 <1> ; STK: 2 word 343 <1> GetMCBFromBlock: 0 00006538 48 dec ax 345 <1> 346 <1> ; Besides checking the signature, we don't do anything here. 347 <1> ; We could walk the actual chain to insure that MCB is on it, 348 <1> ; but that would prohibit freeing or resizing blocks in the 349 <1> ; excluded UMA sub-chains. (As I verified once with my 350 <1> ; horrible DEBUG preloading device driver hack, the usage of 351 <1> ; independant sub-chains isn't prohibited by MS-DOS.) 352 <1> 353 <1> ; Verify MCB, different error code 354 <1> ; 355 <1> ; INP: ax = MCB 356 <1> ; OUT: ds = MCB 357 <1> ; di = 0 358 <1> ; NZ, CY if invalid MCB, 359 <1> ; ax = error code 0009h (Invalid MCB) 360 <1> ; ZR, NC if valid MCB 361 <1> ; CHG: - 362 <1> ; STK: 2 word 363 <1> VerifySingleMCB: 0 00006539 E8E2FF call VerifyMCB 0 0000653C 7303 jnc .return 0 0000653E B80900 mov ax, errorMCBInvalid 367 <1> .return: 0 00006541 C3 retn 369 <1> 370 <1> 371 <1> ; Clear MCB owner and name, or name only 372 <1> ; 373 <1> ; INP: ds = MCB 374 <1> ; di = 0 375 <1> ; OUT: - 376 <1> ; CHG: - (CF is preserved too) 377 <1> ; STK: 1 word 378 <1> ClearMCB: 0 00006542 897D01 mov word [di+mcbOwner], di ; free up block 380 <1> ClearMCBName: 0 00006545 897D08 mov word [di+mcbName+0], di 0 00006548 897D0A mov word [di+mcbName+2], di 0 0000654B 897D0C mov word [di+mcbName+4], di 0 0000654E 897D0E mov word [di+mcbName+6], di ; clear the name field 0 00006551 C3 retn 386 <1> 387 <1> 388 <1> ; Release MCB 389 <1> ; 390 <1> ; INP: ax = memory block's segment 391 <1> ; OUT: CY if invalid MCB, 392 <1> ; ax = error code 393 <1> ; NC if valid MCB, released, 394 <1> ; ax = MCB 395 <1> ; CHG: ax 396 <1> ; STK: 5 word 397 <1> ; 398 <1> ; DOS should not collect MCBs after freeing. This can 399 <1> ; break software which directly modifies MCBs because 400 <1> ; the software may think the MCB still exists there. 401 <1> ReleaseMCB: 0 00006552 1E push ds 0 00006553 57 push di 0 00006554 E8E1FF call GetMCBFromBlock ; get MCB from block address 0 00006557 7203 jc .error ; invalid address or signature --> 0 00006559 E8E6FF call ClearMCB ; free it 407 <1> .error: 0 0000655C 5F pop di 0 0000655D 1F pop ds 0 0000655E C3 retn 411 <1> 412 <1> 413 <1> ; Get next MCB, insuring the chain doesn't loop 414 <1> ; 415 <1> ; INP: word [ss:si] = area flags and allocation strategy 416 <1> ; word [ss:si + 2] = loop detection counter, init to 0 417 <1> ; ax = former MCB (0000h to get first) 418 <1> ; OUT: CY if MCB chain corrupted or loops, 419 <1> ; ax = error code 420 <1> ; NC if MCB chain intact, 421 <1> ; NZ if no next MCB, 422 <1> ; ax = error code (0008h) 423 <1> ; ZR if next MCB available, 424 <1> ; ax = next MCB 425 <1> ; di = 0 426 <1> ; CHG: - 427 <1> ; STK: 8 word 428 <1> ; doscode_insure_low_byte_not_0CCh 429 <1> SNextMCB: 0 0000655F 31FF xor di, di 0 00006561 36FF4C02 dec word [ss:si + 2] 0 00006565 7505 jnz @F 433 <1> ; This doesn't branch if ZR, meaning if the 1_0000h iterations 434 <1> ; have run out (if counter was 1 prior to the dec). 0 00006567 F9 stc 0 00006568 B8FE00 mov ax, errorMCBLoops 0 0000656B C3 retn 438 <1> 439 <1> @@: 440 <1> ; (fall through to NextMCB) 441 <1> 442 <1> 443 <1> ; Get next MCB 444 <1> ; 445 <1> ; INP: word [ss:si] = area flags and allocation strategy 446 <1> ; word [ss:si + 2] = loop detection counter 447 <1> ; ax = former MCB (0000h to get first) 448 <1> ; OUT: CY if MCB chain corrupted, 449 <1> ; ax = error code 450 <1> ; NC if MCB chain intact, 451 <1> ; NZ if no next MCB, 452 <1> ; ax = error code 0008h (Not enough memory) 453 <1> ; ZR if next MCB available, 454 <1> ; ax = next MCB 455 <1> ; di = 0 456 <1> ; CHG: - 457 <1> ; STK: 3 word 458 <1> ; 459 <1> ; An interesting effect of how this code handles the first UMCB 460 <1> ; is that it doesn't care whether the previous MCB contains an 461 <1> ; 'M' (normal MCB chain extended into UMA) or 'Z' (normal MCB 462 <1> ; chain limited to LMA). Also, the parsed area flags allow to 463 <1> ; ignore the actual requested UMB link: If it was zero, all 464 <1> ; area flags are cleared and forced to 10h (LMA only) instead. 465 <1> %ifn _UMA 466 <1> NextMCB: 467 <1> push ds 468 <1> test ax, ax ; request for first ? 469 <1> jz .first ; yes --> 470 <1> 471 <1> call VerifyMCB ; check input MCB first 472 <1> jc .return 473 <1> inc ax 474 <1> add ax, word [di+mcbSize] ; get address of next (if any) 475 <1> cmp byte [di+mcbSignature], 'M' ; current in-chain ? 476 <1> je .verify ; yes, verify it --> 477 <1> ; If this was NZ and didn't jump, then the mcbSignature 478 <1> ; contains the letter 'Z', which is above 'M'. Therefore, 479 <1> ; it is always true that it is NC at this point. 480 <1> mov ax, errorInsufficientMemory ; (NC, NZ) 481 <1> pop ds 482 <1> retn 483 <1> .first: 484 <1> mov ax, word [ss:first_mcb] 485 <1> .verify: 486 <1> call VerifyMCB ; NC, ZR if valid - CY if invalid 487 <1> .return: 488 <1> pop ds 489 <1> retn 490 <1> %else 491 <1> ; The UMA build has to evaluate the (parsed) area flags 492 <1> ; here to show the caller a continuous chain of MCBs. 493 <1> ; This requires special handling in two cases: If the 494 <1> ; caller's input was 0000h (to get the first MCB) or if 495 <1> ; it was the MCB before the first UMCB. Area flags of 496 <1> ; 80h and 40h want to start their search with the first 497 <1> ; UMCB instead. Flags 20h want to proceed at the first 498 <1> ; UMCB, all other flags want to stop there. The first 499 <1> ; UMCB's handling ignores whether the preceeding MCB 500 <1> ; contained 'M' or 'Z'. 501 <1> NextMCB: 0 0000656C 1E push ds 0 0000656D 85C0 test ax, ax ; request for first ? 0 0000656F 742E jz .first ; yes --> 505 <1> 0 00006571 E8AAFF call VerifyMCB ; check input MCB first 0 00006574 723F jc .return 0 00006576 40 inc ax 0 00006577 034503 add ax, word [di+mcbSize] ; get address of next (whether current is 'M' or 'Z') 510 <1> 0 0000657A E835FF call IsFirstUMCB? ; is the one behind this the first UMCB ? 0 0000657D 7508 jne .notfirstumcb ; nope, check if last --> 0 0000657F 36F604D0 test byte [ss:si], ~2Fh ; "LMA then UMA" ? 514 <1> ; x = D0h --> x & ~20h != 00h if area other than LMA-then-UMA, 515 <1> ; x = 20h --> x & ~20h = 00h if area is LMA-then-UMA 0 00006583 742D jz .verify ; yes, proceed here --> 517 <1> ; After test, it is always NC here. 0 00006585 EB13 jmp short .last ; (NC, NZ) else it's the last one (even if 'M') --> 519 <1> .notfirstumcb: 0 00006587 803D4D cmp byte [di+mcbSignature], 'M' ; current in-chain ? 0 0000658A 7426 je .verify ; no --> 0 0000658C 36833E[0000]FE cmp word [ss:first_umcb], byte -2 ; any UMA ? 0 00006592 7706 ja .last ; (NC, NZ) no, really last --> 0 00006594 36F60470 test byte [ss:si], ~8Fh ; "UMA then LMA" ? 525 <1> ; x = 70h --> x & ~80h != 00h if area other than UMA-then-LMA, 526 <1> ; x = 80h --> x & ~80h = 00h if area is UMA-then-LMA 0 00006598 7414 jz .firstlma ; yes, start to search LMA instead --> 528 <1> ; After test, it is always NC here. 529 <1> .last: 0 0000659A B80800 mov ax, errorInsufficientMemory ; (NC, NZ) 0 0000659D 1F pop ds 0 0000659E C3 retn 533 <1> .first: 0 0000659F 36F604C0 test byte [ss:si], (80h|40h) ; "UMA then LMA" or "UMA only" ? 0 000065A3 7409 jz .firstlma ; no, start with LMA --> 0 000065A5 36A1[0000] mov ax, word [ss:first_umcb] ; yes, start with UMA 0 000065A9 83F8FF cmp ax, -1 ; UMA valid ? 0 000065AC 7504 jne .verify ; yes --> 539 <1> .firstlma: 0 000065AE 36A1[0000] mov ax, word [ss:first_mcb] ; start with LMA 541 <1> .verify: 0 000065B2 E869FF call VerifyMCB ; NC, ZR if valid - CY if invalid 543 <1> .return: 0 000065B5 1F pop ds 0 000065B6 C3 retn 546 <1> %endif 547 <1> 548 <1> 549 <1> ; Release all memory of a specific owner 550 <1> ; 551 <1> ; INP: bx = MCB owner of which blocks are to be freed 552 <1> ; OUT: CY if MCB chain corrupted or loops, 553 <1> ; ax = error code 554 <1> ; NC if MCB chain valid 555 <1> ; CHG: ax 556 <1> ; STK: 13 word 557 <1> ReleaseOwnersMCBs: 0 000065B7 1E push ds 0 000065B8 57 push di 0 000065B9 E831FF call SetLinearMCBFlags ; set order for accessing all MCBs 561 <1> .loop: 0 000065BC E8A0FF call SNextMCB ; ax = MCB 0 000065BF 720E jc .return 0 000065C1 750C jne .return 0 000065C3 8ED8 mov ds, ax ; ds = MCB 0 000065C5 395D01 cmp word [di+mcbOwner], bx ; does block belong to owner ? 0 000065C8 75F2 jne .loop ; no --> 0 000065CA E875FF call ClearMCB ; free up block 0 000065CD EBED jmp short .loop 570 <1> .return: 0 000065CF 5E pop si ; discard flags word 0 000065D0 5E pop si ; discard loop counter word 0 000065D1 5E pop si 0 000065D2 5F pop di 0 000065D3 1F pop ds 0 000065D4 C3 retn 577 <1> 578 <1> 579 <1> ; Merge MCB with next one if possible 580 <1> ; 581 <1> ; INP: ds = ax = MCB 582 <1> ; word [ss:si] = 20h/10h (linear MCB flag setting) 583 <1> ; word [ss:si + 2] = loop detection counter 584 <1> ; OUT: CY if invalid MCB, 585 <1> ; ax = error code 586 <1> ; CY if no next MCB or next MCB is not free, 587 <1> ; ax = errorInsufficientMemory 588 <1> ; NC if valid next MCB was free, merged 589 <1> ; di = 0 590 <1> ; CHG: - 591 <1> ; STK: 10 word 592 <1> CollectNextFreeMCB: 0 000065D5 06 push es 0 000065D6 E886FF call SNextMCB 0 000065D9 721F jc .return 0 000065DB 751F jne .notenough ; at last block, can't expand --> 597 <1> %if _UMA 0 000065DD E8D2FE call IsFirstUMCB? ; next is first UMCB ? 0 000065E0 741A je .notenough ; yes, can't expand --> 600 <1> %endif 0 000065E2 8EC0 mov es, ax ; address of next block 0 000065E4 26397D01 cmp word [es:di+mcbOwner], di ; is next block free ? 0 000065E8 7512 jne .notenough ; no, can't expand --> 604 <1> 0 000065EA 268A05 mov al, byte [es:di+mcbSignature] ; get letter of next MCB 0 000065ED 8805 mov byte [di+mcbSignature], al ; adjust letter of MCB if next was 'Z' 0 000065EF 268B4503 mov ax, word [es:di+mcbSize] 0 000065F3 40 inc ax ; get size of next MCB (including the MCB) 0 000065F4 014503 add word [di+mcbSize], ax ; expand MCB 0 000065F7 8CD8 mov ax, ds 0 000065F9 F8 clc 612 <1> .return: 0 000065FA 07 pop es 0 000065FB C3 retn 615 <1> 616 <1> .notenough: 0 000065FC F9 stc 0 000065FD B80800 mov ax, errorInsufficientMemory 0 00006600 07 pop es 0 00006601 C3 retn 621 <1> 622 <1> 623 <1> ; Collect free MCBs 624 <1> ; 625 <1> ; INP: - 626 <1> ; OUT: CY if MCB chain corrupted or loops, 627 <1> ; ax = error code 628 <1> ; NC if valid 629 <1> ; CHG: ax 630 <1> ; STK: 15 word 631 <1> ; 632 <1> ; Scans all MCBs and merges free ones together. 633 <1> CollectFreeMCBs: 0 00006602 1E push ds 0 00006603 57 push di 0 00006604 E8E6FE call SetLinearMCBFlags ; set order for accessing all MCBs 637 <1> .loop: 0 00006607 E855FF call SNextMCB ; ax = next MCB 0 0000660A 7218 jc .return ; chain corrupted --> 0 0000660C 7516 jne .return ; no next --> 641 <1> .check: 0 0000660E 8ED8 mov ds, ax ; ds = MCB 0 00006610 397D01 cmp word [di+mcbOwner], di ; is block free ? 0 00006613 75F2 jne .loop ; no, try next --> 645 <1> .again: 0 00006615 E8BDFF call CollectNextFreeMCB ; merge next with this one, if free 0 00006618 73FB jnc .again ; merged, check if next also free --> 0 0000661A 83F808 cmp ax, errorInsufficientMemory ; was error "Not enough memory" ? 0 0000661D F9 stc 0 0000661E 7504 jne .return ; no, real error --> 0 00006620 8CD8 mov ax, ds 0 00006622 EBE3 jmp short .loop ; try next block --> (SNextMCB reports if current was last) 653 <1> .return: 0 00006624 5E pop si ; discard flags word 0 00006625 5E pop si ; discard loop counter word 0 00006626 5E pop si 0 00006627 5F pop di 0 00006628 1F pop ds 0 00006629 C3 retn 660 <1> 661 <1> 662 <1> ; Split one MCB into two smaller MCBs 663 <1> ; 664 <1> ; INP: ds = ax = MCB 665 <1> ; di = 0 666 <1> ; cx = requested size of existing MCB 667 <1> ; (the MCB *MUST* be larger currently) 668 <1> ; dx = requested owner of new MCB 669 <1> ; OUT: dx = created new MCB (at ax+cx+1) 670 <1> ; NC if valid input 671 <1> ; CY if MCB size is smaller than or equal to cx, 672 <1> ; ax = error code (errorMCBDestroyed) 673 <1> ; CHG: cx 674 <1> ; STK: 5 word 675 <1> ; 676 <1> ; Interestingly, this is the only code to create new MCBs. 677 <1> ; Functions not calling this code simply re-use existing MCBs. 678 <1> SplitMCB: 0 0000662A 50 push ax 0 0000662B 51 push cx ; save new size of MCB 0 0000662C 1E push ds 0 0000662D 41 inc cx ; include size of the MCB itself 0 0000662E 01C8 add ax, cx ; ax = where to create new MCB 0 00006630 50 push ax 0 00006631 8B4503 mov ax, word [di+mcbSize] ; current size of MCB 0 00006634 29C8 sub ax, cx ; size of new MCB 0 00006636 7220 jc .internal_error 688 <1> ; CY here means MCB's size currently <= INP:cx. 689 <1> ; ax = 0 is valid, it means an MCB with size 0 is created. 690 <1> ; (The modified MCB is then shortened by 1 paragraph.) 0 00006638 8A0D mov cl, byte [di+mcbSignature] 0 0000663A 1F pop ds ; ds = new MCB 0 0000663B E807FF call ClearMCBName ; clear name 0 0000663E 897D05 mov word [di+mcbReserved], di 0 00006641 897D06 mov word [di+mcbReserved + 1], di ; clear reserved bytes 0 00006644 880D mov byte [di+mcbSignature], cl ; move letter of MCB to new one 0 00006646 894503 mov word [di+mcbSize], ax 0 00006649 895501 mov word [di+mcbOwner], dx ; set size and owner 0 0000664C 8CDA mov dx, ds 0 0000664E 1F pop ds ; restore MCB's address 0 0000664F 8F4503 pop word [di+mcbSize] ; resize the existing MCB 0 00006652 C6054D mov byte [di+mcbSignature], 'M' ; link it to new one (if it was 'Z') 0 00006655 58 pop ax 0 00006656 F8 clc 0 00006657 C3 retn 706 <1> 707 <1> .internal_error: 0 00006658 58 pop ax 0 00006659 1F pop ds 0 0000665A 58 pop ax 0 0000665B 58 pop ax 0 0000665C 31D2 xor dx, dx 0 0000665E B80700 mov ax, errorMCBDestroyed 0 00006661 F9 stc 0 00006662 C3 retn 716 <1> 717 <1> 718 <1> ; Modify MCB size 719 <1> ; 720 <1> ; INP: ax = memory block's segment 721 <1> ; bx = requested number of paragraphs 722 <1> ; OUT: bx = new size of block 723 <1> ; CY if error, 724 <1> ; ax = error code 725 <1> ; NC if successful, 726 <1> ; ax = memory block's segment 727 <1> ; CHG: - 728 <1> ; STK: 21 word 729 <1> ; 730 <1> ; Contraction involves splitting the block into two smaller 731 <1> ; portions. Expansion requires that the block which follows 732 <1> ; is empty. If it is, it is combined with the first block 733 <1> ; to create a huge block, which can then be split. 734 <1> ; 735 <1> ; As MS-DOS does, we'll extend the block to the maximum 736 <1> ; possible size if there's not enough free memory behind it 737 <1> ; to fulfill the request. Also copying MS-DOS's behaviour 738 <1> ; we'll set the owner of the resized MCB if it was resized 739 <1> ; successfully (NC). This allows to allocate specific MCBs, 740 <1> ; although I don't recommend to do so. 741 <1> ModifyMCB: 0 00006663 52 push dx 0 00006664 E8AAFE call GetMCBOwner ; dx = owner 0 00006667 E80200 call ModifyMCBRandom 0 0000666A 5A pop dx 0 0000666B C3 retn 747 <1> 748 <1> ; Modify MCB size with random owner 749 <1> ; 750 <1> ; INP: ax = memory block's segment 751 <1> ; bx = requested number of paragraphs 752 <1> ; dx = new owner 753 <1> ; OUT: bx = new size of block 754 <1> ; CY if error, 755 <1> ; ax = error code 756 <1> ; NC if successful, 757 <1> ; ax = memory block's segment 758 <1> ; CHG: - 759 <1> ; STK: 19 word 760 <1> ModifyMCBRandom: 761 <1> lframe near 0 0000666C 5589E5 lenter 763 <1> lvar word, alloc 0 0000666F 53 push bx 765 <1> lvar word, owner 0 00006670 52 push dx 767 <1> 0 00006671 52 push dx 0 00006672 51 push cx 0 00006673 57 push di 0 00006674 1E push ds 0 00006675 89C2 mov dx, ax 0 00006677 E873FE call SetLinearMCBFlags ; set order for accessing all MCBs 0 0000667A 89D0 mov ax, dx ; (restore ax without push and pop) 0 0000667C 31DB xor bx, bx ; largest possible size of MCB, preset to zero 0 0000667E E8B7FE call GetMCBFromBlock ; get MCB from block address, ax = ds = MCB 777 <1> .compare_return_if_CY: 0 00006681 721F jc .return ; invalid MCB --> 779 <1> .compare: 0 00006683 8B5D03 mov bx, word [di+mcbSize] ; remember current size if request fails 0 00006686 8B4EFE mov cx, word [bp + ?alloc] ; cx = requested size 0 00006689 39D9 cmp cx, bx ; what action is required ? 0 0000668B 7207 jb .contract ; contraction --> 0 0000668D 740C je .success ; none, succeed --> 785 <1> .expand: 0 0000668F E843FF call CollectNextFreeMCB ; expansion, use next MCB if free 787 <1> ; jc .return ; not free, or MCB chain corrupted --> 0 00006692 EBED jmp short .compare_return_if_CY ; compare new size, expand again or contract --> 789 <1> .contract: 0 00006694 31D2 xor dx, dx 0 00006696 E891FF call SplitMCB ; free the unused high part of the MCB 0 00006699 EBE6 jmp short .compare_return_if_CY ; set ?size and return (MCB size now equals _alloc) 793 <1> .success: 0 0000669B 40 inc ax ; point past MCB to actual allocation 0 0000669C FF76FC push word [bp + ?owner] 0 0000669F 8F4501 pop word [di+mcbOwner] ; re-allocate MCB with requested owner 797 <1> 798 <1> ; Testing on MS-DOS 7.10 revealed that the owner is only 799 <1> ; set by 21.4A when the resizing was successful. A partial 800 <1> ; resize (that cannot be fulfilled entirely due to not 801 <1> ; enough free space) doesn't set the owner. 802 <1> .return: 0 000066A2 5E pop si ; discard flags word 0 000066A3 5E pop si ; discard loop counter word 0 000066A4 5E pop si 0 000066A5 1F pop ds 0 000066A6 5F pop di 0 000066A7 59 pop cx 0 000066A8 5A pop dx 0 000066A9 89EC5D lleave 0 000066AC C3 lret 812 <1> 813 <1> 814 <1> %ifn _UMA ; (Currently only used in non-UMA build.) 815 <1> ; Allocate MCB 816 <1> ; 817 <1> ; INP: bx = requested number of paragraphs 818 <1> ; OUT: CY if error, 819 <1> ; ax = error code 820 <1> ; bx = paragraph size of largest available block (zero if not error 0008h) 821 <1> ; NC if successful, 822 <1> ; ax = segment address of allocation 823 <1> ; bx = paragraph size of allocation 824 <1> ; CHG: - 825 <1> ; STK: 23 word 826 <1> AllocateMCB: 827 <1> push cx 828 <1> %ifn _UMA 829 <1> mov ch, byte [ss:alloc_strategy_exŧ] 830 <1> mov cl, byte [ss:AllocMethod] ; cx = flags 831 <1> %else 832 <1> call GetMCBFlags ; cx = fixed flags 833 <1> %endif 834 <1> db __TEST_IMM8 ; (skip push) 835 <1> .flags_cx: 836 <1> push cx 837 <1> push dx 838 <1> call GetMCBOwner ; dx = owner 839 <1> call AllocateMCBRandom 840 <1> pop dx 841 <1> pop cx 842 <1> retn 843 <1> %endif 844 <1> 845 <1> 846 <1> ; Allocate MCB with random owner and flags 847 <1> ; 848 <1> ; INP: bx = requested number of paragraphs 849 <1> ; cx = allocation strategy 850 <1> ; dx = owner 851 <1> ; OUT: CY if error, 852 <1> ; ax = error code 853 <1> ; bx = paragraph size of largest available block (zero unless error 0008h) 854 <1> ; NC if successful, 855 <1> ; ax = segment address of allocation 856 <1> ; bx = paragraph size of allocation 857 <1> ; CHG: - 858 <1> ; STK: 20 word 859 <1> AllocateMCBRandom: 0 000066AD E852FF call CollectFreeMCBs ; collect free blocks first 861 <1> ; CHG: ax 862 <1> ; We could jump here if CY was returned, indicating 863 <1> ; a corrupted MCB chain. However, if it is relevantly 864 <1> ; corrupted, this error will also occur later on. 865 <1> lframe near 866 <1> lvar word, loopcounter ; (immediately above ?flags) 867 <1> lvar word, flags 868 <1> lvar word, bestfit ; segment of best fit (if cx != FFFFh) 869 <1> lvar word, lastfit ; segment of last fit (if bx >= _alloc) 0 000066B0 5589E58D66F8 lenter 871 <1> lvar word, alloc 0 000066B6 53 push bx 873 <1> lvar word, owner 0 000066B7 52 push dx 875 <1> 0 000066B8 51 push cx 0 000066B9 52 push dx 0 000066BA 56 push si 0 000066BB 57 push di 0 000066BC 1E push ds 0 000066BD 8D76FC lea si, [bp + ?flags] ; ss:si-> flags 0 000066C0 E8A6FD call FixMCBFlags ; fix flags to internally used ones 883 <1> %if _UMA 0 000066C3 36833E[0000]FF cmp word [ss:first_umcb], byte -1 ; UMA available ? 0 000066C9 7506 jne .umavalid 886 <1> %endif 0 000066CB 80E10F and cl, 0Fh 0 000066CE 80C910 or cl, 10h ; force "LMA only" if no UMA available 889 <1> .umavalid: 0 000066D1 36890C mov word [ss:si], cx ; store fixed flags 0 000066D4 31C0 xor ax, ax ; 0000h to get first MCB 0 000066D6 36894402 mov word [ss:si + 2], ax ; initialise loop counter 0 000066DA 31DB xor bx, bx 894 <1> ; variable: size of largest block available 0 000066DC B9FFFF mov cx, 0FFFFh 896 <1> ; variable: best-fit excess size (excess size over requested) 897 <1> .loop: 0 000066DF E87DFE call SNextMCB 0 000066E2 727F jc .return ; chain corrupted --> 0 000066E4 7529 jne .end ; end of chain, look for best or last fit --> 0 000066E6 8ED8 mov ds, ax 0 000066E8 397D01 cmp word [di+mcbOwner], di ; free block ? 0 000066EB 75F2 jne .loop ; no, next --> 904 <1> 0 000066ED 8B5503 mov dx, word [di+mcbSize] ; get size 906 <1> 0 000066F0 39D3 cmp bx, dx ; larger than previous largest ? 0 000066F2 7302 jae .notlarger ; no --> 0 000066F4 89D3 mov bx, dx ; store as new largest 910 <1> .notlarger: 911 <1> 0 000066F6 2B56F6 sub dx, word [bp + ?alloc] ; large enough for request ? 0 000066F9 72E4 jb .loop ; no, next --> 0 000066FB 36F60403 test byte [ss:si], 03h ; strategy zero (first fit) ? 0 000066FF 742C jz .alloc ; yes, allocate block now --> 916 <1> 0 00006701 8946F8 mov word [bp + ?lastfit], ax ; unconditionally store as last fit 918 <1> 0 00006704 39D1 cmp cx, dx ; better than previous best ? 0 00006706 7605 jbe .notbetter ; no --> (important: prefer previous if same) 0 00006708 89D1 mov cx, dx 0 0000670A 8946FA mov word [bp + ?bestfit], ax ; store as new best 923 <1> .notbetter: 0 0000670D EBD0 jmp short .loop 925 <1> 926 <1> ; ax = error code 0008h (errorInsufficientMemory) here 927 <1> .end: 0 0000670F 36F60401 test byte [ss:si], 01h 0 00006713 7409 jz .notbestfit 0 00006715 41 inc cx 0 00006716 F9 stc 0 00006717 744A jz .return ; (CY) no fit (cx was still FFFFh) --> 0 00006719 8B46FA mov ax, word [bp + ?bestfit] 0 0000671C EB0F jmp short .alloc 935 <1> .notbestfit: 0 0000671E 36F60403 test byte [ss:si], 03h 0 00006722 F9 stc 0 00006723 743E jz .return ; (CY) first fit requested but none found --> 0 00006725 3B5EF6 cmp bx, word [bp + ?alloc] 0 00006728 7239 jb .return ; (CY) no block large enough found --> 0 0000672A 8B46F8 mov ax, word [bp + ?lastfit] 942 <1> .alloc: 0 0000672D 8ED8 mov ds, ax 0 0000672F 8B56F4 mov dx, word [bp + ?owner] 0 00006732 895501 mov word [di+mcbOwner], dx ; allocate it now 0 00006735 E80DFE call ClearMCBName ; clear the name 0 00006738 8B4D03 mov cx, word [di+mcbSize] ; get size of block 0 0000673B 2B4EF6 sub cx, word [bp + ?alloc] ; determine remaining block's size 0 0000673E 741F je .done ; (NC) no remaining block --> 0 00006740 36F60402 test byte [ss:si], 02h ; last fit ? 0 00006744 750C jnz .lastfit ; yes, use upper part --> 0 00006746 8B4EF6 mov cx, word [bp + ?alloc] ; size of lower part (allocation) 0 00006749 31D2 xor dx, dx ; free upper part 0 0000674B E8DCFE call SplitMCB 0 0000674E 7213 jc .return ; (else NC) 0 00006750 EB0D jmp short .done 957 <1> .lastfit: 0 00006752 49 dec cx 0 00006753 E8D4FE call SplitMCB ; (dx = owner upper part, cx = size lower part) 0 00006756 720B jc .return ; (else NC) 0 00006758 897D01 mov word [di+mcbOwner], di ; free lower part 0 0000675B 89D0 mov ax, dx 0 0000675D 8EDA mov ds, dx ; set ds = ax = allocation 964 <1> .done: ; (NC) 0 0000675F 40 inc ax ; point past MCB 0 00006760 8B5D03 mov bx, word [di+mcbSize] ; allocated size 967 <1> .return: 0 00006763 7308 jnc .noerror ; no error --> (actual allocation size) 0 00006765 83F808 cmp ax, errorInsufficientMemory ; "not enough memory" ? 0 00006768 7402 je .memerror ; bx set correctly --> (largest seen) 0 0000676A 31DB xor bx, bx ; else report none free as largest 972 <1> .memerror: 0 0000676C F9 stc ; set CY again 974 <1> .noerror: 0 0000676D 1F pop ds 0 0000676E 5F pop di 0 0000676F 5E pop si 0 00006770 5A pop dx 0 00006771 59 pop cx 0 00006772 89EC5D lleave 0 00006775 C3 lret 982 <1> 983 <1> 984 <1> ; Allocate largest MCB with random owner and flags 985 <1> ; 986 <1> ; INP: ax = requested maximal number of paragraphs (FFFFh for largest) 987 <1> ; bx = requested minimal number of paragraphs 988 <1> ; cx = allocation strategy 989 <1> ; dx = owner 990 <1> ; OUT: CY if error, 991 <1> ; ax = error code 992 <1> ; bx = paragraph size of largest available block (zero unless error 0008h) 993 <1> ; NC if successful, 994 <1> ; ax = segment address of allocation 995 <1> ; bx = paragraph size of allocation 996 <1> ; CHG: - 997 <1> ; STK: 29 word 998 <1> ; 999 <1> ; If the requested maximal size is smaller than the requested minimal size, 1000 <1> ; the minimal size is forced to the requested maximal size. 1001 <1> AllocateLargestMCBRandom: 1002 <1> .: 1003 <1> lframe near 0 00006776 5589E5 lenter 1005 <1> lvar word, min 0 00006779 53 push bx 1007 <1> 1008 <1> %if _UMA 0 0000677A 36833E[0000]FF cmp word [ss:first_umcb], byte -1 ; UMA available ? 0 00006780 740F je .single ; nope, all area flags turn to "LMA only" anyway --> 0 00006782 F6C180 test cl, 80h ; 80h "UMA then LMA" (top priority) ? 0 00006785 7523 jnz .dual ; yes, dual area --> 0 00006787 F6C140 test cl, 40h ; 40h "UMA only" (priority over 20h) ? 0 0000678A 7505 jnz .single ; yes, single area --> 0 0000678C F6C120 test cl, 20h ; 20h "LMA then UMA" (priority over 10h) 0 0000678F 7519 jnz .dual ; yes, dual area --> 1017 <1> .single: 1018 <1> %endif 0 00006791 89C3 mov bx, ax ; maximal size 0 00006793 E817FF call AllocateMCBRandom ; request with maximal size 0 00006796 730E jnc .return ; if it succeeded --> 0 00006798 83F808 cmp ax, errorInsufficientMemory ; "not enough memory" error ? 0 0000679B F9 stc 0 0000679C 7508 jne .return ; if not this error, invalid MCBs --> 0 0000679E 3B5EFE cmp bx, word [bp + ?min] ; reported largest is large enough for request ? 0 000067A1 7203 jb .return ; no, return the error as is --> (CY) 0 000067A3 E807FF call AllocateMCBRandom ; allocate the reported largest block, pass errors if any 1028 <1> .return: 1029 <1> %if _UMA 0 000067A6 89EC5D lleave code 1031 <1> %else 1032 <1> lleave 1033 <1> %endif 0 000067A9 C3 lret 1035 <1> 1036 <1> %if _UMA 1037 <1> ; Area flags involving two areas are split into two calls: 1038 <1> ; If the first area contains a block which is large enough, 1039 <1> ; it is preferred over a possibly larger block in the other 1040 <1> ; area and the other area won't be searched. The reported 1041 <1> ; largest block (if neither area contains one large enough) 1042 <1> ; is the larger one of these reported for both areas. 1043 <1> .dual: 1044 <1> lvar word, max 0 000067AA 50 push ax 1046 <1> lvar word, flags 0 000067AB 51 push cx 1048 <1> 0 000067AC 51 push cx 0 000067AD E8B9FC call FixMCBFlags ; check whether multiple flags are set 0 000067B0 80E10F and cl, 0Fh ; clear current flags 0 000067B3 80C940 or cl, 40h ; second try "UMA only" 0 000067B6 F646FA80 test byte [bp + ?flags], 80h ; requested "UMA then LMA" ? 0 000067BA 7406 jz .dual_lmafirst ; no, must be "LMA then UMA" --> 1055 <1> %if _ERRORFLAGS 1056 <1> test byte [bp + ?flags], 40h|20h|10h ; either set ? (multiple) 1057 <1> jz .dual_validflags_umafirst 1058 <1> or byte [ss:error_flags], EF_MultipleAllocAreas ; yes, flag 1059 <1> .dual_validflags_umafirst: 1060 <1> %endif 0 000067BC 80E10F and cl, 0Fh 0 000067BF 80C910 or cl, 10h ; second try "LMA only" 1063 <1> .dual_lmafirst: 0 000067C2 894EFA mov word [bp + ?flags], cx ; remember area for second try 0 000067C5 80F150 xor cl, 40h|10h ; set cx to the other one of the single areas 1066 <1> 0 000067C8 E8ABFF call . ; try to allocate in first area 0 000067CB 7321 jnc .dual_return ; (NC) success --> 0 000067CD 83F808 cmp ax, errorInsufficientMemory ; "not enough memory" error ? 0 000067D0 751B jne .dual_error ; no, invalid MCB --> 0 000067D2 8B4EFA mov cx, word [bp + ?flags] ; get other flags 0 000067D5 8B46FC mov ax, word [bp + ?max] ; restore maximal value 0 000067D8 875EFE xchg bx, word [bp + ?min] ; restore minimal value, save largest available 0 000067DB E898FF call . ; try to allocate in second area instead 0 000067DE 730E jnc .dual_return ; (NC) success --> 0 000067E0 83F808 cmp ax, errorInsufficientMemory ; "not enough memory" error ? 0 000067E3 7508 jne .dual_error ; no, invalid MCB --> 1078 <1> 0 000067E5 3B5EFE cmp bx, word [bp + ?min] ; second area contains larger free block ? 0 000067E8 7303 jae .dual_error ; yes --> 0 000067EA 8B5EFE mov bx, word [bp + ?min] ; return largest free block of first area instead 1082 <1> 1083 <1> .dual_error: 0 000067ED F9 stc 1085 <1> .dual_return: 0 000067EE 59 pop cx ; restore cx 0 000067EF 89EC5D lleave 0 000067F2 C3 lret 1089 <1> %endif 1090 <1> 1091 <1> 1092 <1> ; Allocate MCB, compatible to MS-DOS 1093 <1> ; 1094 <1> ; INP: bx = requested number of paragraphs 1095 <1> ; OUT: CY if error, 1096 <1> ; ax = error code 1097 <1> ; bx = paragraph size of largest available block (zero if not error 0008h) 1098 <1> ; NC if successful, 1099 <1> ; ax = segment address of allocation 1100 <1> ; bx = paragraph size of allocation 1101 <1> ; CHG: - 1102 <1> ; 1103 <1> ; Note: This function implements the MS-DOS-compatible 1104 <1> ; handling where UMA-then-LMA is treated as two areas. 1105 <1> %if _UMA 1106 <1> AllocateMCBCompatible: 0 000067F3 51 push cx 0 000067F4 E8D4FC call GetMCBFlags ; cx = fixed flags 0 000067F7 A8 db __TEST_IMM8 ; (skip push) 1110 <1> .flags_cx: 0 000067F8 51 push cx 0 000067F9 52 push dx 0 000067FA E814FD call GetMCBOwner ; dx = owner 0 000067FD F6C502 test ch, 2 ; use lDOS meaning ? (one area) 0 00006800 750A jnz .default ; yes --> 0 00006802 F6C504 test ch, 4 ; use two areas ? 0 00006805 750B jnz @F ; yes --> 0 00006807 F6C180 test cl, 80h ; is it UMA then LMA ? 0 0000680A 7506 jnz @F ; yes, use two areas--> 1120 <1> .default: 0 0000680C E89EFE call AllocateMCBRandom ; else, simply use default 1122 <1> .end: 0 0000680F 5A pop dx 0 00006810 59 pop cx 0 00006811 C3 retn 1126 <1> 1127 <1> @@: 0 00006812 89D8 mov ax, bx ; set up maximum size = size 0 00006814 E85FFF call AllocateLargestMCBRandom ; call two-area allocation 0 00006817 EBF6 jmp .end 1131 <1> %else 1132 <1> AllocateMCBCompatible: equ AllocateMCB 1133 <1> AllocateMCBCompatible.flags_cx: equ AllocateMCB.flags_cx 1134 <1> %endif 1135 <1> 1136 <1> 1137 <1> %if 0 1138 <1> ; INP: dx = segment of which to get size 1139 <1> ; OUT: NC if not overlapping, 1140 <1> ; bx = size of that segment until next MCB 1141 <1> ; CY if overlapping (dx points to an MCB, 1142 <1> ; or not inside any of the MCBs, 1143 <1> ; or inside a free MCB), 1144 <1> ; bx = 0 1145 <1> ; ax = error code 1146 <1> ; CHG: ax 1147 <1> GetSizeInMCB: 1148 <1> xor bx, bx 1149 <1> push cx 1150 <1> push ds 1151 <1> push di 1152 <1> call SetLinearMCBFlags ; set order for accessing all MCBs 1153 <1> .loop: 1154 <1> call SNextMCB ; ax = next MCB 1155 <1> jc .return ; chain corrupted --> 1156 <1> jne .error ; no next --> 1157 <1> .check: 1158 <1> mov ds, ax ; ds = MCB 1159 <1> cmp dx, ax 1160 <1> jbe .error 1161 <1> mov cx, ax 1162 <1> add cx, word [di+mcbSize] 1163 <1> inc cx ; => next MCB 1164 <1> cmp dx, cx ; is it equal-to-or-above the next MCB? 1165 <1> jae .loop ; yes, next --> 1166 <1> cmp word [di+mcbOwner], di ; is this block free ? 1167 <1> je .error ; yes --> 1168 <1> sub cx, dx ; (next MCB) - (block address) 1169 <1> mov bx, cx ; size 1170 <1> clc 1171 <1> jmp .return 1172 <1> 1173 <1> .error: 1174 <1> xor bx, bx 1175 <1> mov ax, errorMCBInvalid 1176 <1> stc 1177 <1> .return: 1178 <1> pop si ; discard flags word 1179 <1> pop si ; discard loop counter word 1180 <1> pop si 1181 <1> pop di 1182 <1> pop ds 1183 <1> pop cx 1184 <1> retn 1185 <1> %endif 68 69 global ReleaseOwnersMCBs 70 global arena_free_process 71 arena_free_process equ ReleaseOwnersMCBs 72 73 74 procedure D_ALLOC,NEAR 74 ****************** warning: proc D_ALLOC... [-w+user] 0 00006819 E8[0000] EnterCrit critMem 0 0000681C E8D4FF call AllocateMCBCompatible 77 return_CF_bx_crit: 0 0000681F 7315 jnc return_CF_crit 0 00006821 83F808 cmp ax, errorInsufficientMemory 0 00006824 751B jne return_CY_crit 0 00006826 E8[0000] invoke get_user_stack 0 00006829 895C02 mov [si + user_BX], bx 0 0000682C EB13 jmp return_CY_crit 84 EndProc D_ALLOC 85 86 87 procedure D_DEALLOC,NEAR 87 ****************** warning: proc D_DEALLOC... [-w+user] 0 0000682E E8[0000] EnterCrit critMem 0 00006831 8CC0 mov ax, es 0 00006833 E81CFD call ReleaseMCB 91 return_CF_crit: 0 00006836 E8[0000] LeaveCrit critMem 93 return_CF: 0 00006839 7203 jc .err 0 0000683B E9[0000] transfer SYS_RET_OK 96 .err: 0 0000683E E9[0000] transfer SYS_RET_ERR 98 EndProc D_DEALLOC 99 100 return_CY_crit: 0 00006841 F9 stc 0 00006842 EBF2 jmp return_CF_crit 103 104 105 procedure D_SETBLOCK,NEAR 105 ****************** warning: proc D_SETBLOCK... [-w+user] 0 00006844 E8[0000] EnterCrit critMem 0 00006847 8CC0 mov ax, es 0 00006849 E817FE call ModifyMCB 0 0000684C EBD1 jmp return_CF_bx_crit 110 EndProc D_SETBLOCK 111 112 113 %else 114 ; 115 ; arena_free_process 116 ; input: BX - PID of process 117 ; output: free all blocks allocated to that PID 118 ; 119 procedure arena_free_process,NEAR 120 ASSUME DS:NOTHING,ES:NOTHING 121 MOV DI,arena_signature 122 MOV AX,[ss:arena_head] 123 Check_Signature equ check_signature ; NASM port label 124 CALL Check_Signature ; ES <- AX, check for valid block 125 126 arena_free_process_loop: 127 retc 128 PUSH ES 129 POP DS 130 CMP [arena_owner],BX ; is block owned by pid? 131 JNZ arena_free_next ; no, skip to next 132 MOV [arena_owner],DI ; yes... free him 133 134 arena_free_next: 135 CMP BYTE PTR [DI],arena_signature_end 136 ; end of road, Jack? 137 retz ; never come back no more 138 CALL arena_next ; next item in ES/AX carry set if trash 139 JMP arena_free_process_loop 140 141 EndProc arena_free_process 142 143 ; 144 ; arena_next 145 ; input: DS - pointer to block head 146 ; output: AX,ES - pointers to next head 147 ; carry set if trashed arena 148 ; 149 procedure arena_next,NEAR 150 ASSUME DS:NOTHING,ES:NOTHING 151 MOV AX,DS ; AX <- current block 152 ADD AX,[arena_size] ; AX <- AX + current block length 153 INC AX ; remember that header! 154 ; 155 ; fall into check_signature and return 156 ; 157 ; CALL check_signature ; ES <- AX, carry set if error 158 ; RET 159 EndProc arena_next 160 161 ; 162 ; check_signature 163 ; input: AX - address of block header 164 ; output: ES=AX, carry set if signature is bad 165 ; 166 procedure check_signature,NEAR 167 ASSUME DS:NOTHING,ES:NOTHING 168 MOV ES,AX ; ES <- AX 169 CMP BYTE PTR [ES:DI],arena_signature_normal 170 ; IF next signature = not_end THEN 171 retz ; GOTO ok 172 CMP BYTE PTR [ES:DI],arena_signature_end 173 ; IF next signature = end then 174 retz ; GOTO ok 175 STC ; set error 176 return 177 178 EndProc Check_signature 179 180 ; 181 ; Coalesce - combine free blocks ahead with current block 182 ; input: DS - pointer to head of free block 183 ; output: updated head of block, AX is next block 184 ; carry set -> trashed arena 185 ; 186 procedure Coalesce,NEAR 187 ASSUME DS:NOTHING,ES:NOTHING 188 CMP BYTE PTR [DI],arena_signature_end 189 ; IF current signature = END THEN 190 retz ; GOTO ok 191 CALL arena_next ; ES, AX <- next block, Carry set if error 192 retc ; IF no error THEN GOTO check 193 194 coalesce_check: 195 CMP [ES:arena_owner],DI 196 retnz ; IF next block isnt free THEN return 197 MOV CX,[ES:arena_size] ; CX <- next block size 198 INC CX ; CX <- CX + 1 (for header size) 199 ADD [arena_size],CX ; current size <- current size + CX 200 MOV CL,[ES:DI] ; move up signature 201 MOV [DI],CL 202 coalesce equ Coalesce ; NASM port label 203 JMP coalesce ; try again 204 EndProc Coalesce 205 206 ;SUBTTL $Alloc - allocate space in memory 207 ;PAGE 208 ; 209 ; Assembler usage: 210 ; MOV BX,size 211 ; MOV AH,Alloc 212 ; INT 21h 213 ; AX:0 is pointer to allocated memory 214 ; BX is max size if not enough memory 215 ; 216 ; Description: 217 ; Alloc returns a pointer to a free block of 218 ; memory that has the requested size in paragraphs. 219 ; 220 ; Error return: 221 ; AX = error_not_enough_memory 222 ; = error_arena_trashed 223 ; 224 procedure D_ALLOC,NEAR 225 ASSUME DS:NOTHING,ES:NOTHING 226 227 EnterCrit critMem 228 XOR AX,AX 229 MOV DI,AX 230 231 MOV [ss:FirstArena],AX ; init the options 232 MOV [ss:BestArena],AX 233 MOV [ss:LastArena],AX 234 235 PUSH AX ; alloc_max <- 0 236 MOV AX,[ss:arena_head] ; AX <- beginning of arena 237 Check_signature equ check_signature ; NASM port label 238 CALL Check_signature ; ES <- AX, carry set if error 239 JC alloc_err ; IF error THEN GOTO err 240 241 alloc_scan: 242 PUSH ES 243 POP DS ; DS <- ES 244 CMP [arena_owner],DI 245 JZ alloc_free ; IF current block is free THEN examine 246 247 alloc_next: 248 CMP BYTE PTR [DI],arena_signature_end 249 ; IF current block is last THEN 250 JZ alloc_end ; GOTO end 251 CALL arena_next ; AX, ES <- next block, Carry set if error 252 JNC alloc_scan ; IF no error THEN GOTO scan 253 254 alloc_err: 255 POP AX 256 257 alloc_trashed: 258 LeaveCrit critMem 259 error error_arena_trashed 260 261 alloc_end: 262 CMP word [ss:FirstArena],0 263 JNZ alloc_do_split 264 265 alloc_fail: 266 invoke get_user_stack 267 POP BX 268 MOV [SI + user_BX],BX 269 LeaveCrit critMem 270 error error_not_enough_memory 271 272 alloc_free: 273 CALL coalesce ; add following free block to current 274 JC alloc_err ; IF error THEN GOTO err 275 MOV CX,[arena_size] 276 277 POP DX ; check for max found size 278 CMP CX,DX 279 JNA alloc_test 280 MOV DX,CX 281 282 alloc_test: 283 PUSH DX 284 CMP BX,CX ; IF BX > size of current block THEN 285 JA alloc_next ; GOTO next 286 287 CMP word [ss:FirstArena],0 288 JNZ alloc_best 289 MOV [ss:FirstArena],DS ; save first one found 290 alloc_best: 291 CMP word [ss:BestArena],0 292 JZ alloc_make_best ; initial best 293 PUSH ES 294 MOV ES,[ss:BestArena] 295 CMP [ES:arena_size],CX ; is size of best larger than found? 296 POP ES 297 JBE alloc_last 298 alloc_make_best: 299 MOV [ss:BestArena],DS ; assign best 300 alloc_last: 301 MOV [ss:LastArena],DS ; assign last 302 JMP alloc_next 303 304 ; 305 ; split the block high 306 ; 307 alloc_do_split_high: 308 MOV DS,[ss:LastArena] 309 MOV CX,[arena_size] 310 SUB CX,BX 311 MOV DX,DS 312 JE alloc_set_owner ; sizes are equal, no split 313 ADD DX,CX ; point to next block 314 MOV ES,DX ; no decrement! 315 DEC CX 316 XCHG BX,CX ; bx has size of lower block 317 JMP alloc_set_sizes ; cx has upper (requested) size 318 nop ; identicalise 319 320 ; 321 ; we have scanned memory and have found all appropriate blocks 322 ; check for the type of allocation desired; first and best are identical 323 ; last must be split high 324 ; 325 alloc_do_split: 326 CMP BYTE PTR [ss:AllocMethod], 1 327 JA alloc_do_split_high 328 MOV DS,[ss:FirstArena] 329 JB alloc_get_size 330 MOV DS,[ss:BestArena] 331 alloc_get_size: 332 MOV CX,[arena_size] 333 SUB CX,BX ; get room left over 334 MOV AX,DS 335 MOV DX,AX ; save for owner setting 336 JE alloc_set_owner ; IF BX = size THEN (don't split) 337 ADD AX,BX 338 INC AX ; remember the header 339 MOV ES,AX ; ES <- DS + BX (new header location) 340 DEC CX ; CX <- size of split block 341 alloc_set_sizes: 342 MOV [arena_size],BX ; current size <- BX 343 MOV [ES:arena_size],CX ; split size <- CX 344 MOV BL,arena_signature_normal 345 XCHG BL,[DI] ; current signature <- 4D 346 MOV [ES:DI],BL ; new block sig <- old block sig 347 MOV [ES:arena_owner],DI 348 349 alloc_set_owner: 350 MOV DS,DX 351 MOV AX,[ss:CurrentPDB] 352 MOV [arena_owner],AX 353 MOV AX,DS 354 INC AX 355 POP BX 356 LeaveCrit critMem 357 transfer SYS_RET_OK 358 359 EndProc D_alloc 360 361 ;SUBTTL $SETBLOCK - change size of an allocated block (if possible) 362 ;PAGE 363 ; 364 ; Assembler usage: 365 ; MOV ES,block 366 ; MOV BX,newsize 367 ; MOV AH,setblock 368 ; INT 21h 369 ; if setblock fails for growing, BX will have the maximum 370 ; size possible 371 ; Error return: 372 ; AX = error_invalid_block 373 ; = error_arena_trashed 374 ; = error_not_enough_memory 375 ; = error_invalid_function 376 ; 377 procedure D_SETBLOCK,NEAR 378 ASSUME DS:NOTHING,ES:NOTHING 379 EnterCrit critMem 380 MOV DI,arena_signature 381 MOV AX,ES 382 DEC AX 383 CALL check_signature 384 JNC setblock_grab 385 386 setblock_bad: 387 JMP alloc_trashed 388 389 setblock_grab: 390 MOV DS,AX 391 CALL coalesce 392 JC setblock_bad 393 MOV CX,[arena_size] 394 PUSH CX 395 CMP BX,CX 396 JBE alloc_get_size 397 JMP alloc_fail 398 EndProc D_setblock 399 400 ;SUBTTL $DEALLOC - free previously allocated piece of memory 401 ;PAGE 402 ; 403 ; Assembler usage: 404 ; MOV ES,block 405 ; MOV AH,dealloc 406 ; INT 21h 407 ; 408 ; Error return: 409 ; AX = error_invalid_block 410 ; = error_arena_trashed 411 ; 412 procedure D_DEALLOC,NEAR 413 ASSUME DS:NOTHING,ES:NOTHING 414 EnterCrit critMem 415 MOV DI,arena_signature 416 MOV AX,ES 417 DEC AX 418 CALL check_signature 419 JC dealloc_err 420 MOV [ES:arena_owner],DI 421 LeaveCrit critMem 422 transfer SYS_RET_OK 423 424 dealloc_err: 425 LeaveCrit critMem 426 error error_invalid_block 427 EndProc D_DEALLOC 428 %endif 429 430 ;SUBTTL $AllocOper - get/set allocation mechanism 431 ;PAGE 432 ; 433 ; Assembler usage: 434 ; MOV AH,AllocOper 435 ; MOV BX,method 436 ; MOV AL,func 437 ; INT 21h 438 ; 439 ; Error return: 440 ; AX = error_invalid_function 441 ; 442 procedure D_AllocOper,NEAR 442 ****************** warning: proc D_AllocOper... [-w+user] 443 ASSUME DS:NOTHING,ES:NOTHING 444 %ifdef LDOSMEM 0 0000684E 3C03 cmp al, 3 0 00006850 7767 ja alloc_oper_invalid 0 00006852 740E je set_umb_link 448 %endif 0 00006854 3C01 CMP AL,1 0 00006856 726B JB AllocOperGet 0 00006858 7476 JZ AllocOperSet 452 %ifdef LDOSMEM 453 get_umb_link: 0 0000685A 31C0 xor ax, ax 0 0000685C 36A0[0000] mov al, byte [ss:enable_uma] ; get allow/disallow flag 0 00006860 EBD9 transfer SYS_RET_OK 457 458 set_umb_link: 0 00006862 368B16[0000] mov dx, word [ss:first_umcb] ; any UMA ? 0 00006867 83FAFF cmp dx, -1 0 0000686A 7507 jne .got 462 463 .none: 0 0000686C F6C301 test bl, 1 ; (NC) 0 0000686F 7548 jnz alloc_oper_invalid 0 00006871 EB41 jmp alloc_oper_CF 467 468 .got: 0 00006873 E8[0000] EnterCrit critMem 0 00006876 50 push ax 0 00006877 E873FC call SetLinearMCBFlags ; ax = 0 = get first MCB 472 .next: 0 0000687A 89C2 mov dx, ax ; remember MCB in case it is the target 0 0000687C E8E0FC call SNextMCB ; get next MCB 0 0000687F 722D jc .end 0 00006881 7527 jnz .error ; end ? UMCB not found --> 0 00006883 363B06[0000] cmp ax, word [ss:first_umcb] ; this the first UMCB ? 0 00006888 75F0 jne .next ; no, loop --> 479 0 0000688A 85D2 test dx, dx ; no previous ? 0 0000688C 741C jz .error ; if so, error --> 0 0000688E 8EC2 mov es, dx ; => MCB that points to first UMCB 0 00006890 F6C301 test bl, 1 ; (NC) 0 00006893 7408 jz .set_Z ; 0, set to 'Z' --> 485 .set_M: 0 00006895 26C60600004D mov byte [es:mcbSignature], "M" ; nonzero, set to 'M' 0 0000689B EB06 jmp @F 488 .set_Z: 0 0000689D 26C60600005A mov byte [es:mcbSignature], "Z" 490 @@: 491 %if _ERRORFLAGS 492 test bh, bh 493 jz @F 494 or byte [ss:error_flags], EF_InvalidUMBLink ; invalid UMB link bits set 495 @@: 496 %endif 0 000068A3 36881E[0000] mov byte [ss:enable_uma], bl ; store UMB link 0 000068A8 EB04 jmp .end 499 500 .error: 0 000068AA B80700 mov ax, errorMCBDestroyed 0 000068AD F9 stc 503 .end: 0 000068AE 5E pop si ; discard flags word 0 000068AF 5E pop si ; discard loop counter word 0 000068B0 5E pop si 0 000068B1 E8[0000] LeaveCrit critMem 508 alloc_oper_CF: 0 000068B4 7317 jnc alloc_oper_ok_ax 0 000068B6 5E pop si 0 000068B7 EB85 transfer SYS_RET_ERR 512 %endif 513 514 alloc_oper_invalid: 515 errLoc_mem equ errLOC_Mem ; NASM port equate 0 000068B9 36C606[0000]05 MOV byte [ss:EXTERR_LOCUS],errLoc_mem ; Extended Error Locus 0 000068BF B001EBF4 error error_invalid_function 518 AllocOperGet: 0 000068C3 36A0[0000] MOV AL,BYTE PTR [ss:AllocMethod] 520 %ifdef LDOSMEM 0 000068C7 368A26[0000] mov ah, [ss:alloc_strategy_ext] 522 523 alloc_oper_ok: 0 000068CC A8 db __TEST_IMM8 ; (skip pop) 525 alloc_oper_ok_ax: 0 000068CD 58 pop ax 527 %else 528 mov ah, 0 529 %endif 0 000068CE EB90 transfer SYS_RET_OK 531 AllocOperSet: 0 000068D0 36881E[0000] MOV [ss:AllocMethod],BL 0 000068D5 36883E[0000] mov [ss:alloc_strategy_ext], bh 0 000068DA EBF2 transfer SYS_RET_OK 535 EndProc D_AllocOper 536 537 END === Trace listing source: ../DOS/srvcall.lst 1 ; SCCSID = @(#)srvcall.asm 1.4 85/08/02 2 ;TITLE SRVCALL - Server DOS call 3 ;NAME SRVCALL 4 ; 5 ; Server DOS call functions 6 ; 7 ; 8 ; $ServerCall 9 ; 10 ; Modification history: 11 ; 12 ; Created: ARR 08 August 1983 13 ; 14 15 [list -] === Switch to base=008400h -> "DOSCODECODE" 22 section DOSCODECODE 23 [list -] 23 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 23 ****************** warning: out: BPB.INC... [-w+user] 23 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 23 ****************** warning: out: DEVSYM.INC... [-w+user] 30 31 %ifndef Installed 32 %iassign Installed 0 33 %endif 34 35 %include "dpl.nas" 1 <1> ; SCCSID = @(#)dpl.asm 1.1 85/04/10 2 <1> ; SCCSID = @(#)dpl.asm 1.1 85/04/10 3 <1> DPL STRUC 0 000068DC ???? DPL_AX DW ? ; AX register 0 000068DE ???? DPL_BX DW ? ; BX register 0 000068E0 ???? DPL_CX DW ? ; CX register 0 000068E2 ???? DPL_DX DW ? ; DX register 0 000068E4 ???? DPL_SI DW ? ; SI register 0 000068E6 ???? DPL_DI DW ? ; DI register 0 000068E8 ???? DPL_DS DW ? ; DS register 0 000068EA ???? DPL_ES DW ? ; ES register 0 000068EC ???? DPL_reserved DW ? ; Reserved 0 000068EE ???? DPL_UID DW ? ; User (Machine) ID (0 = local macine) 0 000068F0 ???? DPL_PID DW ? ; Process ID (0 = local user PID) 15 <1> DPL ENDS 36 37 %iassign Installed TRUE 38 39 i_need USER_ID,WORD 40 i_need PROC_ID,WORD 41 i_need SaveBX,WORD 42 i_need SaveDS,WORD 43 i_need SWAP_START,BYTE 44 i_need SWAP_ALWAYS,BYTE 45 i_need SWAP_END,BYTE 46 I_Need ThisSFT,DWORD 47 I_need fSharing,BYTE 48 i_need OpenBuf,128 49 I_Need ExtErr,WORD 50 I_Need ExtErr_Action,BYTE 51 I_Need ExtErrPt,DWORD 52 I_Need EXTERR_LOCUS,BYTE ; Extended Error Locus 53 i_need JShare,DWORD 54 i_need SWAP_AREA_TABLE,BYTE 55 i_need SWAP_ALWAYS_AREA,DWORD 56 i_need SWAP_ALWAYS_AREA_LEN,WORD 57 i_need SWAP_AREA_LEN,WORD 58 59 BREAK 60 === Switch to base=008400h -> "DOSCODETABLE" 61 section DOSCODETABLE 62 Public SRVC001S,SRVC001E 63 SRVC001S label byte 64 65 align 2, db 0 66 DOSGroup equ DOSGROUP ; NASM port equate 67 Server_Disp equ SERVER_DISP ; NASM port label 0 00000580 [0500] ServerTab DW Server_Disp 0 00000582 [4800] SERVERLEAVE DW ServerReturn 0 00000584 00 db 0 0 00000585 0B SERVER_DISP DB (SERVER_DISP_END-SERVER_DISP-1)/2 0 00000586 [AD00] DW OFFSET SRV_CALL ; 0 0 00000588 [4900] DW OFFSET COMMIT_ALL ; 1 0 0000058A [7C00] DW OFFSET CLOSE_NAME ; 2 0 0000058C [8700] DW OFFSET CLOSE_UID ; 3 0 0000058E [8E00] DW OFFSET CLOSE_UID_PID ; 4 0 00000590 [9500] DW OFFSET GET_LIST ; 5 0 00000592 [EE00] DW OFFSET GET_DOS_DATA ; 6 0 00000594 [0F01] DW OFFSET SPOOL_OPER ; 7 0 00000596 [0F01] DW OFFSET SPOOL_OPER ; 8 0 00000598 [0F01] DW OFFSET SPOOL_OPER ; 9 82 D_setExtendedError equ D_SetExtendedError ; NASM port label 0 0000059A [1D01] DW OFFSET D_setExtendedError ; 10 84 SERVER_DISP_END LABEL BYTE 85 86 SRVC001E label byte 87 === Switch to base=008400h -> "DOSCODECODE" 88 section DOSCODECODE 89 90 ; Inputs: 91 ; DS:DX -> DPL (except calls 7,8,9) 92 ; Function: 93 ; AL=0 Server DOS call 94 ; AL=1 Commit All files 95 ; AL=2 Close file by name (SHARING LOADED ONLY) DS:DX in DPL -> name 96 ; AL=3 Close all files for DPL_UID 97 ; AL=4 Close all files for DPL_UID/PID_PID 98 ; AL=5 Get open file list entry 99 ; IN: BX File Index 100 ; CX User Index 101 ; OUT:ES:DI -> Name 102 ; BX = UID 103 ; CX = # locked blocks held by this UID 104 ; AL=6 Get DOS data area 105 ; OUT: DS:SI -> Start 106 ; CX size in bytes of swap if indos 107 ; DX size in bytes of swap always 108 ; AL=7 Get truncate flag 109 ; AL=8 Set truncate flag 110 ; AL=9 Close all spool files 111 ; AL=10 SetExtendedError 112 ; AL=11 DOS4.00 Get DOS data area 113 ; DS:SI -> swap table 114 115 procedure D_ServerCall,NEAR 115 ****************** warning: proc D_ServerCall... [-w+user] 116 ASSUME DS:NOTHING,ES:NOTHING 0 000068DC 3C07 CMP AL,7 0 000068DE 7219 JB SET_STUFF 0 000068E0 3C09 CMP AL,9 0 000068E2 7627 JBE NO_SET_ID ; No DPL on calls 7,8,9 0 000068E4 3C0B CMP AL,11 ;IFS. ;AN000; 0 000068E6 7511 JNZ SET_STUFF ;IFS. ;AN000; 0 000068E8 BF[0000] MOV DI,OFFSET SWAP_AREA_TABLE wrt DOSGROUP ;IFS. ;AN000; 0 000068EB 16 PUSH SS ;IFS. ;AN000; 0 000068EC 07 POP ES ;IFS. ;AN000; 0 000068ED E8[0000] invoke GET_USER_STACK ;IFS. ;AN000; 0 000068F0 8C440E MOV [SI + user_DS],ES ;IFS. ds:si -> swap tab ;AN000; 0 000068F3 897C08 MOV [SI + user_SI],DI ;IFS. ;AN000; 0 000068F6 E9[0000] transfer SYS_RET_OK ;IFS. ;AN000; 130 SET_STUFF: 0 000068F9 89D6 MOV SI,DX ; Point to DPL with DS:SI 0 000068FB 8B5C12 MOV BX,[SI + DPL_UID] 0 000068FE 36891E[0000] MOV [ss:USER_ID],BX ; Set UID 0 00006903 8B5C14 MOV BX,[SI + DPL_PID] 0 00006906 36891E[0000] MOV [ss:PROC_ID],BX ; Set process ID 136 NO_SET_ID: 0 0000690B 2EFF36[0200] PUSH word [cs:SERVERLEAVE] ; push return address 0 00006910 2EFF36[0000] PUSH word [cs:ServerTab] ; push table address 0 00006915 50 PUSH AX 0 00006916 E8[0000] Invoke TableDispatch 141 errLoc_Unk equ errLOC_Unk ; NASM port equate 0 00006919 36C606[0000]01 MOV byte [ss:EXTERR_LOCUS],errLoc_Unk ; Extended Error Locus 0 0000691F B001E9[0000] error error_invalid_function 144 ServerReturn: 0 00006924 C3 return 146 147 ; Commit - iterate through the open file list and make sure that the 148 ; directory entries are correctly updated. 149 150 COMMIT_ALL: 151 ASSUME DS:NOTHING,ES:NOTHING 0 00006925 31DB XOR BX,BX ; for (i=0; ThisSFT=getSFT(i); i++) 0 00006927 161F Context DS 0 00006929 E8[0000] EnterCrit critSFT ; Gonna scan SFT cache, lock it down 155 CommitLoop: 0 0000692C 53 SaveReg 0 0000692D E8[0000] Invoke SFFromSFN 0 00006930 7220 JC CommitDone 159 sf_Ref_Count equ sf_ref_count ; NASM port equate 0 00006932 26833D00 CMP word [ES:DI + sf_Ref_Count],0 ; if (ThisSFT->refcount != 0) 0 00006936 7416 JZ CommitNext 0 00006938 26833DFF CMP word [ES:DI + sf_Ref_Count],sf_busy ; BUSY SFTs have god knows what 0 0000693C 7410 JZ CommitNext ; in them. 164 ; TEST [ES:DI].sf_flags,sf_isnet 0 0000693E E8[0000] invoke Test_IFS_Remote ;IFS. ;AN000; 0 00006941 750B JNZ CommitNext ; Skip Network SFTs so the SERVER 167 ; doesn't deadlock 0 00006943 893E[0000] MOV WORD PTR [ThisSFT],DI 0 00006947 8C06[0200] MOV WORD PTR [ThisSFT+2],ES 0 0000694B E8[0000] Invoke DOS_Commit ; DOSCommit (); 171 CommitNext: 0 0000694E 5B RestoreReg 0 0000694F 43 INC BX 0 00006950 EBDA JMP CommitLoop 175 CommitDone: 0 00006952 E8[0000] LeaveCrit critSFT 0 00006955 5B RestoreReg 0 00006956 EB9E transfer Sys_Ret_OK 179 180 CLOSE_NAME: 181 ASSUME DS:NOTHING,ES:NOTHING 182 183 %if installed 0 00006958 36FF1E[1400] Call far [ss:JShare + 5 * 4] 185 %else 186 Call MFTcloN 187 %endif 188 CheckReturns: 0 0000695D 7202 JC func_err 0 0000695F EBF5 transfer SYS_RET_OK 191 func_err: 0 00006961 EBBE transfer SYS_RET_ERR 193 194 CLOSE_UID: 195 ASSUME DS:NOTHING,ES:NOTHING 196 197 %if installed 0 00006963 36FF1E[0C00] Call far [ss:JShare + 3 * 4] 199 %else 200 Call MFTclU 201 %endif 0 00006968 EBF3 JMP CheckReturns 203 204 CLOSE_UID_PID: 205 ASSUME DS:NOTHING,ES:NOTHING 206 207 %if installed 0 0000696A 36FF1E[1000] Call far [ss:JShare + 4 * 4] 209 %else 210 Call MFTCloseP 211 %endif 0 0000696F EBEC JMP CheckReturns 213 214 GET_LIST: 215 ASSUME DS:NOTHING,ES:NOTHING 216 %if installed 0 00006971 36FF1E[2400] Call far [ss:JShare + 9 * 4] 218 %else 219 Call MFT_get 220 %endif 0 00006976 72E9 JC func_err 0 00006978 E8[0000] invoke get_user_stack 0 0000697B 895C02 MOV [SI + user_BX],BX 0 0000697E 897C0A MOV [SI + user_DI],DI 0 00006981 8C4410 MOV [SI + user_ES],ES 226 SetCXOK: 0 00006984 894C04 MOV [SI + user_CX],CX 0 00006987 EBD6 transfer SYS_RET_OK 229 230 SRV_CALL: 231 ASSUME DS:NOTHING,ES:NOTHING 0 00006989 58 POP AX ; get rid of call to $srvcall 0 0000698A 1E56 SaveReg 0 0000698C E8[0000] invoke GET_USER_STACK 0 0000698F 5F07 RestoreReg 236 ; 237 ; DS:SI point to stack 238 ; ES:DI point to DPL 239 ; 0 00006991 E8[0000] invoke XCHGP 241 ; 242 ; DS:SI point to DPL 243 ; ES:DI point to stack 244 ; 245 ; We now copy the registers from DPL to save stack 246 ; 0 00006994 56 SaveReg 0 00006995 B90600 MOV CX,6 0 00006998 F3A5 REP MOVSW ; Put in AX,BX,CX,DX,SI,DI 0 0000699A 47 INC DI 0 0000699B 47 INC DI ; Skip user_BP 0 0000699C A5 MOVSW ; DS 0 0000699D A5 MOVSW ; ES 0 0000699E 5E RestoreReg ; DS:SI -> DPL 0 0000699F 8B04 MOV AX,[SI + DPL_AX] 0 000069A1 8B5C02 MOV BX,[SI + DPL_BX] 0 000069A4 8B4C04 MOV CX,[SI + DPL_CX] 0 000069A7 8B5406 MOV DX,[SI + DPL_DX] 0 000069AA 8B7C0A MOV DI,[SI + DPL_DI] 0 000069AD 8E440E MOV ES,[SI + DPL_ES] 0 000069B0 FF7408 PUSH word [SI + DPL_SI] 0 000069B3 8E5C0C MOV DS,[SI + DPL_DS] 0 000069B6 5E POP SI 0 000069B7 368C1E[0000] MOV [ss:SaveDS],DS 0 000069BC 36891E[0000] MOV [ss:SaveBX],BX 0 000069C1 36C606[0000]FF MOV byte [ss:fSharing],-1 ; set no redirect flag 0 000069C7 E9[0000] transfer REDISP 268 269 GET_DOS_DATA: 270 ASSUME DS:NOTHING,ES:NOTHING 0 000069CA 36C43E[0000] LES DI,[ss:SWAP_ALWAYS_AREA] ;IFS. get beginning addr of swap ;AC000; 0 000069CF 368B16[0000] MOV DX,[ss:SWAP_ALWAYS_AREA_LEN] ;IFS. get swap always area len ;AC000; 0 000069D4 81E2FF7F AND DX,7FFFH ;IFS. clear high bit ;AC000; 0 000069D8 368B0E[0000] MOV CX,[ss:SWAP_AREA_LEN] ;IFS. get swap len ;AC000; 0 000069DD E8[0000] invoke GET_USER_STACK 0 000069E0 8C440E MOV [SI + user_DS],ES ; set user regs 0 000069E3 897C08 MOV [SI + user_SI],DI ; 0 000069E6 895406 MOV [SI + user_DX],DX ; 0 000069E9 EB99 JMP SetCXOK ; ;AN000; 280 281 SPOOL_OPER: 282 ASSUME DS:NOTHING,ES:NOTHING 283 multNet equ MultNET ; NASM port equate 0 000069EB 50B82511CD2F5B CallInstall NETSpoolOper,multNet,37,AX,BX 0 000069F2 7202 JC func_err2 0 000069F4 EB91 transfer SYS_RET_OK 287 func_err2: 0 000069F6 E9[0000] transfer SYS_RET_ERR 289 290 Break <$SetExtendedError - set extended error for later retrieval> 291 292 ; 293 ; $SetExtendedError takes extended error information and loads it up for the 294 ; next extended error call. This is used by interrupt-level proccessors to 295 ; mask their actions. 296 ; 297 ; Inputs: DS:SI points to DPL which contains all registers 298 ; Outputs: none 299 ; 300 301 D_SetExtendedError: 302 ASSUME DS:NOTHING,ES:NOTHING 303 dpl_AX equ DPL_AX ; NASM port equate 0 000069F9 8B04 MOV AX,[SI + dpl_AX] 305 EXTERR equ ExtErr ; NASM port label 0 000069FB 36A3[0000] MOV [ss:EXTERR],AX 307 dpL_di equ DPL_DI ; NASM port equate 0 000069FF 8B440A MOV AX,[SI + dpL_di] 0 00006A02 36A3[0000] MOV WORD PTR [ss:ExtErrPt],AX 310 dpL_ES equ DPL_ES ; NASM port equate 0 00006A06 8B440E MOV AX,[SI + dpL_ES] 0 00006A09 36A3[0200] MOV WORD PTR [ss:ExtErrPt+2],AX 313 dpL_BX equ DPL_BX ; NASM port equate 0 00006A0D 8B4402 MOV AX,[SI + dpL_BX] 315 EXTERR_ACTION equ ExtErr_Action ; NASM port label 0 00006A10 36A3[0000] MOV WORD PTR [ss:EXTERR_ACTION],AX 317 dpL_CX equ DPL_CX ; NASM port equate 0 00006A14 8B4404 MOV AX,[SI + dpL_CX] 0 00006A17 368826[0000] MOV [ss:EXTERR_LOCUS],AH 0 00006A1C C3 return 321 EndProc D_ServerCall 321 ****************** warning: ***** Possible stack size error in D_ServerCall ***** [-w+user] 322 323 END === Trace listing source: ../DOS/util.lst 1 ; SCCSID = @(#)util.asm 1.1 85/04/10 2 ;TITLE UTIL - Handle utilities 3 ;NAME UTIL 4 ; 5 ; Handle related utilities for MSDOS 2.X. 6 ; 7 ; pJFNFromHandle written 8 ; SFFromHandle written 9 ; SFFromSFN written 10 ; JFNFree written 11 ; SFNFree written 12 ; 13 ; Modification history: 14 ; 15 ; Created: MZ 1 April 1983 16 ; 17 18 [list -] === Switch to base=008400h -> "DOSCODECODE" 25 section DOSCODECODE 26 [list -] 26 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 26 ****************** warning: out: BPB.INC... [-w+user] 26 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 26 ****************** warning: out: DEVSYM.INC... [-w+user] 33 ;.sall 34 35 I_need CurrentPDB,WORD ; current process data block location 36 I_need SFT_Addr,DWORD ; pointer to beginning of table 37 I_Need PROC_ID,WORD ; current process ID 38 I_Need USER_ID,WORD ; current user ID 39 %if debug 40 I_need BugLev,WORD 41 I_need BugTyp,WORD 42 %include "bugtyp.nas" 43 %endif 44 45 BREAK 46 47 ; 48 ; pJFNFromHandle - Given a handle, return the pointer to the JFN location 49 ; in the user's data space 50 ; Inputs: BX - Handle 51 ; Outputs: Carry Set 52 ; AX has error code 53 ; Carry reset 54 ; ES:DI point to the handle spot 55 ; Registers modified: 56 ; If no error, ES:DI, else AX,ES 57 procedure pJFNFromHandle,NEAR 57 ****************** warning: proc pJFNFromHandle... [-w+user] 58 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING 0 00006A1D 368E06[0000] MOV ES,[ss:CurrentPDB] ; get user process data block 0 00006A22 263B1E3200 CMP BX,[ES:PDB_JFN_Length] ; is handle greater than allocated 0 00006A27 7204 JB JFNAdd ; no, get offset 62 fmt TypAccess,LevSFN,<"$p: Illegal JFN %x\n">, 0 00006A29 B006 MOV AL,error_invalid_handle ; appropriate error 64 ReturnCarry: 0 00006A2B F9 STC ; signal error 0 00006A2C C3 return ; go back 0 00006A2D 26C43E3400 JFNAdd: LES DI,[ES:PDB_JFN_Pointer] ; get pointer to beginning of table 0 00006A32 01DF ADD DI,BX ; add in offset 69 ReturnNoCarry: 0 00006A34 F8 CLC ; no holes 0 00006A35 C3 return ; bye! 72 EndProc pJFNFromHandle 73 74 BREAK 75 76 ; 77 ; SFFromHandle - Given a handle, get JFN and then index into SF table 78 ; 79 ; Input: BX has handle 80 ; Output: Carry Set 81 ; AX has error code 82 ; Carry Reset 83 ; ES:DI has pointer to SF entry 84 ; Registers modified: If error, AX,ES, else ES:DI 85 procedure SFFromHandle,NEAR 85 ****************** warning: proc SFFromHandle... [-w+user] 86 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING 0 00006A36 E8E4FF CALL pJFNFromHandle ; get jfn pointer 0 00006A39 72FA retc ; return if error 0 00006A3B 26803DFF CMP BYTE PTR [ES:DI],-1 ; unused handle 0 00006A3F 7504 JNZ GetSF ; nope, suck out SF 91 fmt TypAccess,LevSFN,<"$p: Illegal SFN $x:$x\n">, 0 00006A41 B006 MOV AL,error_invalid_handle ; appropriate error 0 00006A43 EBE6 jump ReturnCarry ; signal it 94 GetSF: 0 00006A45 53 SaveReg ; save handle 0 00006A46 268A1D MOV BL,BYTE PTR [ES:DI] ; get SFN 0 00006A49 30FF XOR BH,BH ; ignore upper half 0 00006A4B E80200 CALL SFFromSFN ; get real sf spot 0 00006A4E 5B RestoreReg ; restore 0 00006A4F C3 return ; say goodbye 101 EndProc SFFromHandle 102 103 BREAK 104 105 ; 106 ; SFFromSFN - index into SF tables for SFN. 107 ; 108 ; Input: BX has SF index 109 ; Output: ES:DI points to SF entry 110 ; Registers modified: ES:DI, BX only 111 procedure SFFromSFN,NEAR 111 ****************** warning: proc SFFromSFN... [-w+user] 112 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING 0 00006A50 36C43E[0000] LES DI,[ss:SFT_Addr] ; get pointer to beginning of table 114 ScanLoop: 0 00006A55 263B5D04 CMP BX,[ES:DI + SFCount] ; is handle in this table? 0 00006A59 720F JB GetOffset ; yes, go grab it 0 00006A5B 262B5D04 SUB BX,[ES:DI + SFCount] 0 00006A5F 26C43D LES DI,[ES:DI + SFLink] ; get next table segment 0 00006A62 83FFFF CMP DI,-1 ; end of tables? 0 00006A65 75EE JNZ ScanLoop ; no, try again 0 00006A67 F9 STC ; error... 0 00006A68 EB0D JMP SHORT Restore ; go restore 123 GetOffset: 0 00006A6A 50 SaveReg ; save AX 125 SF_Entry_struc_size equ sf_entry_struc_size ; NASM port equate 0 00006A6B B83B00 MOV AX,SF_Entry_struc_size ; put it in a nice place 0 00006A6E F6E3 MUL BL ; times size 0 00006A70 01C7 ADD DI,AX ; offset by size 0 00006A72 58 RestoreReg ; get world back 0 00006A73 83C706 ADD DI,SFTable ; offset into structure 0 00006A76 F8 CLC ; no holes 132 Restore: 0 00006A77 C3 return ; bye! 134 EndProc SFFromSFN 135 136 BREAK 137 138 ; 139 ; JFNFree - scan through the JFN table and return a pointer to a free slot 140 ; 141 ; Input: None. 142 ; Output: Carry Set 143 ; AX has error code, BX,ES,DI garbage 144 ; Carry Reset 145 ; BX has new handle, ES:DI is pointer to JFN slot 146 ; Registers modified: As above only. 147 procedure JFNFree,NEAR 147 ****************** warning: proc JFNFree... [-w+user] 148 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 0 00006A78 31DB XOR BX,BX ; try starting low 150 JFNScan: 0 00006A7A E8A0FF CALL pJFNFromHandle ; get the appropriate handle 0 00006A7D 7209 JC JFNNone ; no more handles 0 00006A7F 26803DFF CMP BYTE PTR [ES:DI],-1 ; free? 0 00006A83 7405 JZ JFNFound ; yes, carry is clear 0 00006A85 43 INC BX ; no, next handle 0 00006A86 EBF2 JMP JFNScan ; and try again 157 JFNNone: 0 00006A88 B004 MOV AL,error_too_many_open_files 159 JFNFound: 0 00006A8A C3 return ; bye 161 EndProc JFNFree 162 163 BREAK 164 165 ; 166 ; SFNFree - scan through the sf table looking for free entries 167 ; Inputs: none 168 ; Outputs: Carry Set - AX has error code, BX destroyed 169 ; Carry Clear - BX has SFN 170 ; ES:DI - pointer to SFT 171 ; SFT_ref_count is set to 1 172 ; Registers modified: none 173 174 Procedure SFNFree,NEAR 174 ****************** warning: proc SFNFree... [-w+user] 175 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 0 00006A8B 31DB XOR BX,BX ; start at beginning 177 SFNFreeLoop: 0 00006A8D 53 SaveReg ; Next call zaps BX 0 00006A8E E8BFFF CALL SFFromSFN ; get the potential handle 0 00006A91 5B RestoreReg 0 00006A92 7305 JNC SFNCheck ; no carry, check to see if its free 0 00006A94 B004 MOV AL,error_too_many_open_files ; appropriate error 0 00006A96 EB42 JMP SFNDone 0 00006A98 90 nop ; identicalise 185 SFNCheck: 186 sf_Ref_Count equ sf_ref_count ; NASM port equate 0 00006A99 26833D00 CMP word [ES:DI + sf_Ref_Count],0 ; free? 188 %IFN DEBUG 0 00006A9D 7421 JZ SFNGot ; yep, got return him 190 %ELSE 191 JNZ NoGot 192 JMP SFNGot 193 NoGot: 194 %ENDIF 0 00006A9F 26833DFF CMP word [ES:DI + sf_ref_count],sf_busy 0 00006AA3 7518 JNZ SFNNext ; not marked busy... 197 fmt TypAccess,LevSFN,<"$p: SFT $x:$x($x)is busy, owner $x:$x\n">, 0 00006AA5 53 SaveReg 199 User_ID equ USER_ID ; NASM port label 0 00006AA6 368B1E[0000] MOV BX,[ss:User_ID] 0 00006AAB 26395D2F CMP [ES:DI + sf_UID],BX 0 00006AAF 750B JNZ SFNNextP 203 Proc_ID equ PROC_ID ; NASM port label 0 00006AB1 368B1E[0000] MOV BX,[ss:Proc_ID] 0 00006AB6 26395D31 CMP [ES:DI + sf_PID],BX 0 00006ABA 7405 JZ SFNGotP 207 SFNNextP: 208 fmt TypAccess,LevSFN,<"$p: SFT unusable\n"> 0 00006ABC 5B RestoreReg 210 SFNNext: 0 00006ABD 43 INC BX ; no, try next sf number 0 00006ABE EBCD JMP SFNFreeLoop ; and go until it fails 213 SFNGot: 0 00006AC0 53 SaveReg 215 SFNGotP: 0 00006AC1 F8 CLC ; no error 217 fmt TypAccess,LevSFN,<"$p: SFT $x:$x($x) marked busy\n">, 0 00006AC2 26C705FFFF MOV word [ES:DI + sf_ref_count],sf_busy ; make sure that this is allocated 0 00006AC7 368B1E[0000] MOV BX,[ss:User_ID] 0 00006ACC 26895D2F MOV [ES:DI + sf_UID],BX 0 00006AD0 368B1E[0000] MOV BX,[ss:Proc_ID] 0 00006AD5 26895D31 MOV [ES:DI + sf_PID],BX 0 00006AD9 5B RestoreReg 224 SFNDone: 0 00006ADA C3 return ; bye 226 EndProc SFNFree 227 228 END === Trace listing source: ../DOS/handle.lst 1 ; SCCSID = @(#)handle.asm 1.1 85/04/10 2 ;TITLE HANDLE - Handle-related system calls 3 ;NAME HANDLE 4 ; 5 ; Handle related system calls for MSDOS 2.X. Only top-level system calls 6 ; are present. I/O specs are defined in DISPATCH. The system calls are: 7 ; 8 ; $Close written 9 ; $Commit written DOS 3.3 F.C. 6/4/86 10 ; $ExtHandle written DOS 3.3 F.C. 6/4/86 11 ; $Read written 12 ; Align_Buffer DOS 4.00 13 ; $Write written 14 ; $LSeek written 15 ; $FileTimes written 16 ; $Dup written 17 ; $Dup2 written 18 ; 19 ; Revision history: 20 ; 21 ; Created: MZ 28 March 1983 22 ; MZ 15 Dec 1982 Jeff Harbers and Multiplan hard disk copy 23 ; rely on certain values in AX when $CLOSE 24 ; succeeds even though we document it as 25 ; always trashing AX. 26 ; 27 ; A000 version 4.00 Jan. 1988 28 ; 29 30 [list -] === Switch to base=008400h -> "DOSCODECODE" 37 section DOSCODECODE 38 [list -] 38 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 38 ****************** warning: out: BPB.INC... [-w+user] 38 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 38 ****************** warning: out: DEVSYM.INC... [-w+user] 38 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 47 ;.sall 48 49 EXTRN DOS_Read:NEAR, DOS_Write:NEAR 50 51 %ifndef BUF2 52 %IF BUFFERFLAG 53 extrn save_user_map:near 54 extrn restore_user_map:near 55 extrn Setup_EMS_Buffers:near 56 %ENDIF 57 %endif 58 59 I_need ThisSFT,DWORD ; pointer to SFT entry 60 I_need DMAAdd,DWORD ; old-style DMA address 61 I_Need EXTERR_LOCUS,byte ; Extended Error Locus 62 I_need FailErr,BYTE ; failed error flag 63 I_need User_ID,WORD ; current effective user_id 64 i_need JShare,DWORD ; jump table 65 I_need CurrentPDB,WORD ; current process data block 66 I_need EXTOPEN_ON,BYTE ;AN000;FT. flag for extended open 67 ; I_need XA_device,BYTE ;AN000; XA device 68 I_need XA_type,BYTE ;AN000; extended open subfunction 69 ; I_need XA_handle,WORD ;AN000; handle 70 I_need THISCDS,DWORD ;AN000; 71 I_need DUMMYCDS,128 ;AN000; 72 I_need SAVE_ES,WORD ;AN000; saved ES 73 I_need SAVE_DI,WORD ;AN000; saved DI 74 I_need SAVE_DS,WORD ;AN000; saved DS 75 I_need SAVE_SI,WORD ;AN000; saved SI 76 I_need SAVE_CX,WORD ;AN000; saved CX 77 78 %ifndef BUF2 79 %IF BUFFERFLAG 80 I_need BUF_EMS_MODE,BYTE 81 I_need BUF_EMS_LAST_PAGE,DWORD 82 I_need BUF_EMS_FIRST_PAGE,DWORD 83 I_need BUF_EMS_SAFE_FLAG,BYTE 84 I_need BUF_EMS_NPA640,WORD 85 I_need BUF_EMS_PAGE_FRAME,WORD 86 I_need BUF_EMS_PFRAME,WORD 87 I_need LASTBUFFER,DWORD 88 %ENDIF 89 %endif 90 91 ; I_need XA_ES,WORD ;AN000; extended find 92 ; I_need XA_BP,WORD ;AN000; extended find 93 ; I_need XA_from,BYTE ;AN000; for filetimes 94 %if debug 95 I_need BugLev,WORD 96 I_need BugTyp,WORD 97 %include "bugtyp.nas" 98 %endif 99 100 BREAK <$Close - return a handle to the system> 101 102 ; 103 ; Assembler usage: 104 ; MOV BX, handle 105 ; MOV AH, Close 106 ; INT int_command 107 ; 108 ; Error return: 109 ; AX = error_invalid_handle 110 ; 111 ; No registers returned 112 113 Procedure D_Close,NEAR 113 ****************** warning: proc D_Close... [-w+user] 114 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 115 fmt TypSysCall,LevLog,<"$p Close\n"> 116 fmt TypSysCall,LevArgs,<"$p Handle = $x\n">, 117 ; 118 ; Grab the SFT pointer from the JFN. 119 ; 0 00006ADB E8D202 call CheckOwner ; get system file entry 0 00006ADE 722B JC CloseError ; error return 122 fmt TypAccess,LevSFN,<"$p Close SFT $x:$x\n">, 0 00006AE0 161F context DS ; For DOS_CLOSE 0 00006AE2 893E[0000] MOV WORD PTR [ThisSFT],DI ; save offset of pointer 0 00006AE6 8C06[0200] MOV WORD PTR [ThisSFT+2],ES ; save segment value 126 ; 127 ; DS:SI point to JFN table entry. 128 ; ES:DI point to SFT 129 ; 130 ; We now examine the user's JFN entry; If the file was a 70-mode file (network 131 ; FCB, we examine the ref count on the SFT; if it was 1, we free the JFN. 132 ; If the file was not a net FCB, we free the JFN too. 133 ; 0 00006AEA 26833D01 CMP word [ES:DI + sf_ref_count],1 ; will the SFT become free? 0 00006AEE 740A JZ FreeJFN ; yes, free JFN anyway. 0 00006AF0 268A4502 MOV AL,BYTE PTR [ES:DI + sf_mode] 0 00006AF4 24F0 AND AL,sharing_mask 138 sharing_net_fcb equ sharing_net_FCB ; NASM port equate 0 00006AF6 3C70 CMP AL,sharing_net_fcb 0 00006AF8 7407 JZ PostFree ; 70-mode and big ref count => free it 141 ; 142 ; The JFN must be freed. Get the pointer to it and replace the contents with 143 ; -1. 144 ; 145 FreeJFN: 0 00006AFA E8[0000] Invoke pJFNFromHandle ; d = pJFN (handle); 147 fmt TypAccess,LevSFN,<"$p Close jfn pointer $x:$x\n">, 0 00006AFD 26C605FF MOV BYTE PTR [ES:DI],0FFh ; release the JFN 149 PostFree: 150 ; 151 ; ThisSFT is correctly set, we have DS = DOSGROUP. Looks OK for a DOS_CLOSE! 152 ; 0 00006B01 E8[0000] invoke DOS_Close 154 ; 155 ; DOS_Close may return an error. If we see such an error, we report it but 156 ; the JFN stays closed because DOS_Close always frees the SFT! 157 ; 0 00006B04 7205 JC CloseError 159 fmt TypSysCall,LevLog,<"$p: Close ok\n"> 160 close equ Close ; NASM port equate 0 00006B06 B43E MOV AH,close ; MZ Bogus multiplan fix 0 00006B08 E9[0000] transfer Sys_Ret_OK 163 CloseError: 164 ASSUME DS:NOTHING 165 fmt TypSysCall,LevLog,<"$p: Close error $x\n">, 0 00006B0B E9[0000] transfer Sys_Ret_Err 167 EndProc D_Close 168 169 BREAK <$Commit - commit the file> 170 171 ; 172 ; Assembler usage: 173 ; MOV BX, handle 174 ; MOV AH, Commit 175 ; INT int_command 176 ; 177 ; Error return: 178 ; AX = error_invalid_handle 179 ; 180 ; No registers returned 181 182 Procedure D_Commit,NEAR 182 ****************** warning: proc D_Commit... [-w+user] 183 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 184 ; 185 ; Grab the SFT pointer from the JFN. 186 ; 0 00006B0E E89F02 call CheckOwner ; get system file entry 0 00006B11 7213 JC Commiterror ; error return 0 00006B13 161F context DS ; For DOS_COMMIT 0 00006B15 893E[0000] MOV WORD PTR [ThisSFT],DI ; save offset of pointer 0 00006B19 8C06[0200] MOV WORD PTR [ThisSFT+2],ES ; save segment value 192 ; 193 ; ES:DI point to SFT 194 ; 195 ; 196 ; ThisSFT is correctly set, we have DS = DOSGROUP. Looks OK for a DOS_COMMIT 197 ; 0 00006B1D E8[0000] invoke DOS_COMMIT 199 ; 200 ; 0 00006B20 7204 JC Commiterror 0 00006B22 B468 MOV AH,Commit ; 0 00006B24 EBE2 transfer Sys_Ret_OK 204 Commiterror: 205 ASSUME DS:NOTHING 0 00006B26 EBE3 transfer Sys_Ret_Err 207 EndProc D_Commit 208 209 210 BREAK <$ExtHandle - extend handle count> 211 212 ; 213 ; Assembler usage: 214 ; MOV BX, Number of Opens Allowed (MAX=65534;66535 is 215 ; MOV AX, 6700H reserved to mark SFT 216 ; INT int_command busy ) 217 ; 218 ; Error return: 219 ; AX = error_not_enough_memory 220 ; or error_too_many_open_files 221 ; No registers returned 222 223 Procedure D_ExtHandle,NEAR 223 ****************** warning: proc D_ExtHandle... [-w+user] 224 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 225 ; 226 ; 227 ; 0 00006B28 31ED XOR BP,BP ; 0: enlarge 1: shrink 2:psp 0 00006B2A 83FB14 CMP BX,FilPerProc ; < 20 0 00006B2D 7303 JAE getpdb ; no 0 00006B2F BB1400 MOV BX,FilPerProc ; bx = 20 232 233 getpdb: 0 00006B32 368E06[0000] MOV ES,[ss:CurrentPDB] ; get user process data block 0 00006B37 268B0E3200 MOV CX,[ES:PDB_JFN_Length] ; get number of handle allowed 0 00006B3C 39CB CMP BX,CX ; the requested == current 0 00006B3E 7452 JE ok_done ; yes and exit 0 00006B40 7723 JA larger ; go allocate new table 239 0 00006B42 BD0100 MOV BP,1 ; shrink 0 00006B45 268E1E3600 MOV DS,WORD PTR [ES:PDB_JFN_Pointer+2] ; 0 00006B4A 89DE MOV SI,BX ; 0 00006B4C 29D9 SUB CX,BX ; get difference 244 chck_handles: 0 00006B4E 803CFF CMP BYTE PTR [SI],-1 ; scan through handles to ensure close 0 00006B51 7541 JNZ too_many_files ; status 0 00006B53 46 INC SI 0 00006B54 E2F8 LOOP chck_handles 0 00006B56 83FB14 CMP BX,FilPerProc ; = 20 0 00006B59 770A JA larger ; no 251 0 00006B5B BD0200 MOV BP,2 ; psp 0 00006B5E BF1800 MOV DI,PDB_JFN_Table ; es:di -> jfn table in psp 0 00006B61 53 PUSH BX 0 00006B62 EB1E JMP movhandl 0 00006B64 90 nop ; identicalise 257 258 larger: 0 00006B65 83FBFF CMP BX,-1 ; 65535 is not allowed 0 00006B68 747F JZ invalid_func 0 00006B6A F8 CLC 0 00006B6B 53 PUSH BX ; save requested number 0 00006B6C 83C30F ADD BX,0FH ; adjust to paragraph boundary 0 00006B6F B104 MOV CL,4 0 00006B71 D3DB RCR BX,CL ; DOS 4.00 fix ;AC000; 0 00006B73 81E3FF1F AND BX,1FFFH ; clear most 3 bits 267 0 00006B77 55 PUSH BP 0 00006B78 E8[0000] invoke D_ALLOC ; allocate memory 0 00006B7B 5D POP BP 0 00006B7C 7266 JC no_memory ; not enough meory 272 0 00006B7E 8EC0 MOV ES,AX ; es:di points to new table memory 0 00006B80 31FF XOR DI,DI 275 movhandl: 0 00006B82 368E1E[0000] MOV DS,[ss:CurrentPDB] ; get user PDB address 277 0 00006B87 F7C50300 TEST BP,3 ; enlarge ? 0 00006B8B 740B JZ enlarge ; yes 0 00006B8D 59 POP CX ; cx = the amount you shrink 0 00006B8E 51 PUSH CX 0 00006B8F EB0B JMP copy_hand 0 00006B91 90 nop ; identicalise 284 ok_done: 0 00006B92 EB90 transfer Sys_Ret_OK 286 too_many_files: 0 00006B94 B004 MOV AL,error_too_many_open_files 0 00006B96 EB8E transfer Sys_Ret_Err 289 enlarge: 0 00006B98 8B0E3200 MOV CX,[PDB_JFN_Length] ; get number of old handles 291 copy_hand: 0 00006B9C 89CA MOV DX,CX 0 00006B9E C5363400 LDS SI,[PDB_JFN_Pointer] ; get old table pointer 294 ASSUME DS:NOTHING 0 00006BA2 F3A4 REP MOVSB ; copy infomation to new table 296 0 00006BA4 59 POP CX ; get new number of handles 0 00006BA5 51 PUSH CX ; save it again 0 00006BA6 29D1 SUB CX,DX ; get the difference 0 00006BA8 B0FF MOV AL,-1 ; set availability to handles 0 00006BAA F3AA REP STOSB 302 0 00006BAC 368E1E[0000] MOV DS,[ss:CurrentPDB] ; get user process data block 0 00006BB1 833E340000 CMP WORD PTR [PDB_JFN_Pointer],0 ; check if original table pointer 0 00006BB6 750D JNZ update_info ; yes, go update PDB entries 0 00006BB8 55 PUSH BP 0 00006BB9 1E PUSH DS ; save old table segment 0 00006BBA 06 PUSH ES ; save new table segment 0 00006BBB 8E063600 MOV ES,WORD PTR [PDB_JFN_Pointer+2] ; get old table segment 0 00006BBF E8[0000] invoke D_DEALLOC ; deallocate old table meomory 0 00006BC2 07 POP ES ; restore new table segment 0 00006BC3 1F POP DS ; restore old table segment 0 00006BC4 5D POP BP 314 315 update_info: 0 00006BC5 F7C50200 TEST BP,2 ; psp? 0 00006BC9 7409 JZ non_psp ; no 0 00006BCB C70634001800 MOV WORD PTR [PDB_JFN_Pointer],PDB_JFN_Table ; restore 0 00006BD1 EB07 JMP final 0 00006BD3 90 nop ; identicalise 321 non_psp: 0 00006BD4 C70634000000 MOV WORD PTR [PDB_JFN_Pointer],0 ; new table pointer offset always 0 323 final: 0 00006BDA 8C063600 MOV WORD PTR [PDB_JFN_Pointer+2],ES ; update table pointer segment 0 00006BDE 8F063200 POP word [PDB_JFN_Length] ; restore new number of handles 0 00006BE2 EBAE transfer Sys_Ret_Ok 327 no_memory: 0 00006BE4 5B POP BX ; clean stack 0 00006BE5 B008 MOV AL,error_not_enough_memory 0 00006BE7 EBAD transfer Sys_Ret_Err 331 invalid_func: 0 00006BE9 B001 MOV AL,error_invalid_function 0 00006BEB EBFA transfer Sys_Ret_Err 334 EndProc D_ExtHandle 335 336 BREAK <$READ - Read from a file handle> 337 ; 338 ; Assembler usage: 339 ; LDS DX, buf 340 ; MOV CX, count 341 ; MOV BX, handle 342 ; MOV AH, Read 343 ; INT int_command 344 ; AX has number of bytes read 345 ; Errors: 346 ; AX = read_invalid_handle 347 ; = read_access_denied 348 ; 349 ; Returns in register AX 350 351 procedure D_READ,NEAR 351 ****************** warning: proc D_READ... [-w+user] 352 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 353 fmt TypSysCall,LevLog,<"Read\n"> 354 fmt TypSysCall,LevArgs,<" Handle $x Cnt $x Buf $x:$x\n">, 0 00006BED BE[0000] MOV SI,OFFSET DOS_Read 356 ReadDo: 0 00006BF0 E8[0000] invoke pJFNFromHandle 0 00006BF3 7208 JC ReadError 0 00006BF5 268A05 MOV AL,[ES:DI] 0 00006BF8 E8B501 call CheckOwner ; get the handle 0 00006BFB 7302 JNC ReadSetup ; no errors do the operation 362 ReadError: 363 fmt TypSysCall,LevLog,<"Read/Write error $x\n">, 0 00006BFD EBEC transfer SYS_RET_ERR ; go to error traps 365 ReadSetup: 0 00006BFF 36893E[0000] MOV WORD PTR [ss:ThisSFT],DI ; save offset of pointer 0 00006C04 368C06[0200] MOV WORD PTR [ss:ThisSFT+2],ES ; save segment value 368 ;; Extended Open 369 INT_24_ERROR equ int_24_error ; NASM port equate 0 00006C09 26F745020020 TEST word [ES:DI + sf_mode],INT_24_ERROR ;AN000;;EO. need i24 0 00006C0F 7406 JZ needi24 ;AN000;;EO. yes 372 EXT_OPEN_I24_OFF equ ext_open_I24_off ; NASM port equate 0 00006C11 36800E[0000]02 OR byte [ss:EXTOPEN_ON],EXT_OPEN_I24_OFF ;AN000;;EO. set it off 374 needi24: ;AN000; 375 376 ;; Extended Open 0 00006C17 36FF36[0000]36FF36 SaveReg <, > 0 00006C1F [0200] 378 ;;;;; BAD SPOT FOR 286!!! SEGMENT ARITHMETIC!!! 0 00006C21 E81500 CALL Align_Buffer ;AN000;MS. align user's buffer 380 ;;;;; END BAD SPOT FOR 286!!! SEGMENT ARITHMETIC!!! 381 382 %ifndef BUF2 383 %IF BUFFERFLAG 384 ; int 3 385 ; cmp [BUF_EMS_MODE], -1 386 ; jz dos_call 387 ; call choose_buf_page 388 ; jc ReadError 389 ; call save_user_map 390 ;dos_call: 391 %ENDIF 392 %endif 393 0 00006C24 161F context DS ; go for DOS addressability 0 00006C26 FFD6 CALL SI ; indirect call to operation 0 00006C28 8F06[0200]8F06 RestoreReg <, > 0 00006C2E [0000] 397 398 %ifndef BUF2 399 %IF BUFFERFLAG 400 pushf 401 push ax 402 push bx 403 404 cmp byte [ss:BUF_EMS_MODE], -1 405 jz dos_call_done 406 call restore_user_map 407 mov ax, word ptr [ss:BUF_EMS_LAST_PAGE] 408 cmp [ss:BUF_EMS_PFRAME], ax 409 je dos_call_done 410 mov word ptr [ss:LASTBUFFER], -1 411 mov [ss:BUF_EMS_PFRAME], ax 412 mov ax, word ptr [ss:BUF_EMS_LAST_PAGE+2] 413 mov [ss:BUF_EMS_PAGE_FRAME], ax 414 mov byte [ss:BUF_EMS_SAFE_FLAG], 1 415 call Setup_EMS_Buffers 416 417 dos_call_done: 418 pop bx 419 pop ax 420 popf 421 %ENDIF 422 %endif 423 424 %IFN BUFFERFLAG 425 JC ReadError ; if error, say bye bye 426 %ELSE 0 00006C30 EB01 jmp tmp_rerr 0 00006C32 90 nop ; identicalise 429 tmp_rerr: 0 00006C33 72C8 jc ReadError 431 %ENDIF 432 0 00006C35 89C8 MOV AX,CX ; get correct return in correct reg 434 fmt TypSysCall,LevLog,<"Read/Write cnt done $x\n">, 0 00006C37 EBA9 transfer sys_ret_ok ; successful return 436 EndProc D_READ 437 438 ; 439 ; Input: DS:DX points to user's buffer addr 440 ; Function: rearrange segment and offset for READ/WRITE buffer 441 ; Output: [DMAADD] set 442 ; 443 ; 444 445 procedure Align_Buffer,NEAR ;AN000; 445 ****************** warning: proc Align_Buffer... [-w+user] 446 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; 0 00006C39 51 push cx 0 00006C3A B104 mov cl, 4 0 00006C3C 8CD8 mov ax, ds 0 00006C3E 89D3 mov bx, dx 451 ; cmp bx, 15 452 ; jbe .end 0 00006C40 83E20F and dx, 15 ; mask off full paragraphs 0 00006C43 D3EB shr bx, cl ; how much can at most be added to ds 0 00006C45 01D8 add ax, bx ; => candidate segment, 456 ; CY if > 0FFFFh (must be in HMA) 0 00006C47 7308 jnc .simple 458 ; ffff:20 ds:dx (want ffff:20) -> 2 ax -> 2+ffff = 1000_1 459 ; fffe:20 ds:dx (want ffff:10) -> 2 ax -> 2+fffe = 1000_0 460 ; fffe:30 ds:dx (want ffff:20) -> 3 ax -> 3+fffe = 1000_1 461 ; fffe:40 ds:dx (want ffff:30) -> 4 ax -> 4+fffe = 1000_2 462 ; fffe:80 ds:dx (want ffff:70) -> 8 ax -> 8+fffe = 1000_6 463 ; fffe:0 ds:dx (want fffe:0) -> 0 ax -> 0+fffe = fff_e jnc 464 ; fff0:0 ds:dx (want fff0:0) -> 0 ax -> 0+fff0 = fff_0 jnc 465 ; fff0:80 ds:dx (want fff8:0) -> 8 ax -> 8+fff0 = fff_8 jnc 466 ; fff0:180 ds:dx (want ffff:90) -> 18 ax -> 18+fff0 = 1000_8 0 00006C49 40 inc ax ; adjust, gives offset high 12 bits 0 00006C4A D3E0 shl ax, cl ; shift the 12 bits up 0 00006C4C 09C2 or dx, ax ; get final offset 0 00006C4E B8FFFF mov ax, -1 ; final segment is always 0FFFFh if in HMA 471 .simple: 0 00006C51 8ED8 mov ds, ax 473 .end: 0 00006C53 59 pop cx 0 00006C54 368916[0000] MOV WORD PTR [ss:DMAAdd],DX ; use user DX as offset 0 00006C59 368C1E[0200] MOV WORD PTR [ss:DMAAdd+2],DS ; use user DS as segment for DMA 0 00006C5E C3 return ;AN000; 478 EndProc Align_Buffer ;AN000; 479 480 BREAK <$WRITE - write to a file handle> 481 482 ; 483 ; Assembler usage: 484 ; LDS DX, buf 485 ; MOV CX, count 486 ; MOV BX, handle 487 ; MOV AH, Write 488 ; INT int_command 489 ; AX has number of bytes written 490 ; Errors: 491 ; AX = write_invalid_handle 492 ; = write_access_denied 493 ; 494 ; Returns in register AX 495 496 procedure D_WRITE,NEAR 496 ****************** warning: proc D_WRITE... [-w+user] 497 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 498 fmt TypSysCall,LevLog,<"Write\n"> 499 fmt TypSysCall,LevArgs,<" Handle $x Cnt $x Buf $x:$x\n">, 0 00006C5F BE[0000] MOV SI,OFFSET DOS_Write 0 00006C62 EB8C JMP ReadDo 502 EndProc D_Write 503 504 BREAK <$LSEEK - move r/w pointer> 505 506 ; 507 ; Assembler usage: 508 ; MOV DX, offsetlow 509 ; MOV CX, offsethigh 510 ; MOV BX, handle 511 ; MOV AL, method 512 ; MOV AH, LSeek 513 ; INT int_command 514 ; DX:AX has the new location of the pointer 515 ; Error returns: 516 ; AX = error_invalid_handle 517 ; = error_invalid_function 518 ; Returns in registers DX:AX 519 520 procedure D_LSEEK,NEAR 520 ****************** warning: proc D_LSEEK... [-w+user] 521 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 0 00006C64 E84901 call CheckOwner ; get system file entry 523 LSeekError: 524 525 %IF BUFFERFLAG 526 TMP_RERR equ tmp_rerr ; NASM port label 0 00006C67 72CA JC TMP_RERR 528 %ELSE 529 JC ReadError ; error return 530 %ENDIF 0 00006C69 3C02 CMP AL,2 ; is the seek value correct? 0 00006C6B 760A JBE LSeekDisp ; yes, go dispatch 533 errLoc_Unk equ errLOC_Unk ; NASM port equate 0 00006C6D 36C606[0000]01 MOV byte [ss:EXTERR_LOCUS],errLoc_Unk ; Extended Error Locus 0 00006C73 B001EB86 error error_invalid_function ; invalid method 536 LSeekDisp: 0 00006C77 3C01 CMP AL,1 ; best way to dispatch; check middle 0 00006C79 720A JB LSeekStore ; just store CX:DX 0 00006C7B 771B JA LSeekEOF ; seek from end of file 540 SF_Position equ sf_position ; NASM port equate 0 00006C7D 26035515 ADD DX,WORD PTR [ES:DI + SF_Position] 0 00006C81 26134D17 ADC CX,WORD PTR [ES:DI + SF_Position+2] 543 LSeekStore: 0 00006C85 89C8 MOV AX,CX ; AX:DX 0 00006C87 92 XCHG AX,DX ; DX:AX is the correct value 546 LSeekSetpos: 0 00006C88 26894515 MOV WORD PTR [ES:DI + SF_Position],AX 0 00006C8C 26895517 MOV WORD PTR [ES:DI + SF_Position+2],DX 0 00006C90 E8[0000] invoke Get_user_stack 550 User_DX equ user_DX ; NASM port equate 0 00006C93 895406 MOV [SI + User_DX],DX ; return DX:AX 0 00006C96 EB9F transfer SYS_RET_OK ; successful return 553 554 LSeekEOF: 0 00006C98 26F745050080 TEST word [ES:DI + sf_flags],sf_isnet 0 00006C9E 750A JNZ Check_LSeek_Mode ; Is Net 557 LOCAL_LSeek: 558 SF_Size equ sf_size ; NASM port equate 0 00006CA0 26035511 ADD DX,WORD PTR [ES:DI + SF_Size] 0 00006CA4 26134D13 ADC CX,WORD PTR [ES:DI + SF_Size+2] 0 00006CA8 EBDB JMP LSeekStore ; go and set the position 562 563 Check_LSeek_Mode: 0 00006CAA 26F745020080 TEST word [ES:DI + sf_mode],sf_isfcb 0 00006CB0 75EE JNZ LOCAL_LSeek ; FCB treated like local file 0 00006CB2 268B4502 MOV AX,[ES:DI + sf_mode] 0 00006CB6 25F000 AND AX,sharing_mask 0 00006CB9 83F840 CMP AX,sharing_deny_none 0 00006CBC 7405 JZ NET_LSEEK ; LSEEK exported in this mode 0 00006CBE 83F830 CMP AX,sharing_deny_read 0 00006CC1 75DD JNZ LOCAL_LSeek ; Treated like local Lseek 572 NET_LSEEK: 573 ; JMP LOCAL_LSeek 574 ; REMOVE ABOVE INSTRUCTION TO ENABLE DCR 142 575 Net_Lseek equ NET_LSEEK ; NASM port label 576 multNet equ MultNET ; NASM port equate 0 00006CC3 B82111CD2F CallInstall Net_Lseek,multNet,33 578 LSeekSetPos equ LSeekSetpos ; NASM port label 0 00006CC8 73BE JNC LSeekSetPos 0 00006CCA EBA9 transfer SYS_RET_ERR 581 582 EndProc D_LSeek 583 584 BREAK 585 586 ; 587 ; Assembler usage: 588 ; MOV AH, FileTimes (57H) 589 ; MOV AL, func 590 ; MOV BX, handle 591 ; ; if AL = 1 then then next two are mandatory 592 ; MOV CX, time 593 ; MOV DX, date 594 ; INT 21h 595 ; ; if AL = 0 then CX/DX has the last write time/date 596 ; ; for the handle. 597 ; 598 ; AL=02 get extended attributes 599 ; BX=handle 600 ; CX=size of buffer (0, return max size ) 601 ; DS:SI query list (si=-1, selects all EA) 602 ; ES:DI buffer to hold EA list 603 ; 604 ; AL=03 get EA name list 605 ; BX=handle 606 ; CX=size of buffer (0, return max size ) 607 ; ES:DI buffer to hold name list 608 ; 609 ; AL=04 set extended attributes 610 ; BX=handle 611 ; ES:DI buffer of EA list 612 ; 613 ; 614 ; 615 ; 616 ; Error returns: 617 ; AX = error_invalid_function 618 ; = error_invalid_handle 619 ; 620 621 procedure D_File_Times,NEAR 621 ****************** warning: proc D_File_Times... [-w+user] 622 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 0 00006CCC 3C02 CMP AL,2 ; correct subfunction? 0 00006CCE 7303 JAE gsetxa 0 00006CD0 EB6D JMP filetimes_ok ; Yes, continue 0 00006CD2 90 nop ; identicalise 627 ;;;; DOS 4.00 ;AN000; 628 gsetxa: ;AN000; 0 00006CD3 E8[0000] EnterCrit critSFT ;AN000;;FT. enter critical section 0 00006CD6 3C04 CMP AL,4 ;AN000;;FT. =4 0 00006CD8 7603 JBE gshandle ;AN000;;FT. 2,3,4 do get/set by handle 632 funcerr: ;AN000; 0 00006CDA EB59 JMP inval_func ;AN000;;FT. invalid function 0 00006CDC 90 nop ; identicalise 635 ;AN000; 636 gshandle: ;AN000; 0 00006CDD 368C06[0000] MOV [ss:SAVE_ES],ES ;AN000;;FT. save regs 0 00006CE2 36893E[0000] MOV [ss:SAVE_DI],DI ;AN000;;FT. 0 00006CE7 368C1E[0000] MOV [ss:SAVE_DS],DS ;AN000;;FT. save regs 0 00006CEC 368936[0000] MOV [ss:SAVE_SI],SI ;AN000;;FT. 0 00006CF1 36890E[0000] MOV [ss:SAVE_CX],CX ;AN000;;FT. 642 XA_TYPE equ XA_type ; NASM port label 0 00006CF6 36A2[0000] MOV [ss:XA_TYPE],AL ;AN000;;FT. 644 ;AN000; 645 ; MOV [XA_handle],BX ;AN000; ;FT. save handle 0 00006CFA E8B300 CALL CheckOwner ;AN000; ;FT. get sf pointer 0 00006CFD 7306 JNC getsetit ;AN000; ;FT. good handle 0 00006CFF E8[0000] LeaveCrit critSFT ;AN000; ;FT. leave critical section 0 00006D02 E962FF JMP LSeekError ;AN000; ;FT. turkey handle 650 ;AN000; 651 getsetit: ;AN000; 0 00006D05 36893E[0000] MOV WORD PTR [ss:ThisSFT],DI ;AN000; ;FT. set ThisSFT 0 00006D0A 368C06[0200] MOV WORD PTR [ss:ThisSFT+2],ES ;AN000; ;FT. set ThisSFT 654 ; TEST [ES:DI.sf_mode],INT_24_ERROR ;AN000;;FT. mask INT 24 655 ; JZ nomask ;AN000;;FT. no 656 ; OR [EXTOPEN_ON],EXT_OPEN_I24_OFF ;AN000;;FT. set bit for I24 handler 657 nomask: ;AN000; 0 00006D0F 26F745050080 TEST word [ES:DI + sf_flags],sf_isnet ;AN000;;FT. remote handle 0 00006D15 7412 JZ localhandle ;AN000;;FT. no 0 00006D17 E8[0000] LeaveCrit critSFT ;AN000;;FT. doesn't support Network 661 0 00006D1A 368A1E[0000] MOV BL,[ss:XA_TYPE] ;AN000;;FT. 663 IFSsearch: ;AN000; 664 multNET equ MultNET ; NASM port equate 0 00006D1F B82D11 MOV AX,(multNET << 8) | 45 ;AN000;;FT. Get/Set XA support 0 00006D22 CD2F INT 2FH ;AN000; 0 00006D24 720D JC getseterror ;AN000;;FT. error 0 00006D26 E9[0000] transfer SYS_RET_OK ;AN000;;FT. 669 localhandle: ;AN000; 670 ; TEST [ES:DI.sf_flags],devid_device ;AN000;;FT. device 671 ; JZ getsetfile8 ;AN000;;FT. no 672 ; MOV [XA_device],1 ;AN000;;FT. indicating device 673 ; JMP SHORT doXA ;AN000;;FT. do XA 674 getsetfile8: ;AN000; 675 ; MOV [XA_device],0 ;AN000;;FT. indicating File 676 ; LES BP,[ES:DI.sf_devptr] ;AN000;;FT. ES:BP -> DPB 677 678 doXA: ;AN000; 679 ; MOV [XA_from],By_XA ;AN000;;FT. from get/set XA 680 ; PUSH [SAVE_ES] ;AN000;;FT. save XA list 681 ; PUSH [SAVE_DI] ;AN000;;FT. save XA list 682 0 00006D29 E8[0000] invoke GetSet_XA ;AN000;;FT. issue Get/Set XA 684 ; POP SI ;AN000;;FT. DS:SI -> XA list 685 ; POP DS ;AN000; 0 00006D2C 7202 JC getexit ;AN000;;FT. error 687 ; CMP [XA_device],0 ;AN000;;FT. device ? 688 ; JNZ ftok ;AN000;;FT. yes, exit 689 ; MOV AX,4 ;AN000;;FT. function 4 for ShSU 690 ; CMP [XA_type],4 ;AN000;;FT. set XA 691 ; JNZ ftok ;AN000;;FT. no 692 ; 693 ; 694 ; LES DI,[ThisSFT] ;AN000;;FT. es:di -> sft 695 ; CMP WORD PTR [SI],0 ;AN000;;FT. null list ? 696 ; JNZ do_share ;AN000;;FT. no 0 00006D2E EB4D JMP SHORT ftok ;AN000;;FT. return 698 getexit: ;AN000;;FT. 0 00006D30 E8[0000] LeaveCrit critSFT ;AN000;;FT. leave critical section 700 701 702 getseterror: ;AN000; 0 00006D33 EB95 transfer SYS_RET_ERR ;AN000;;FT. mark file as dirty 704 inval_func: 705 706 ;;;;; DOS 4.00 0 00006D35 36C606[0000]01 MOV byte [ss:EXTERR_LOCUS],errLoc_Unk ; Extended Error Locus 0 00006D3B B001EBF4 error error_invalid_function ; give bad return 709 filetimes_ok: 0 00006D3F E86E00 call CheckOwner ; get sf pointer 0 00006D42 7303 JNC gsdt 0 00006D44 E920FF JMP LSeekError ; turkey handle 713 gsdt: 0 00006D47 08C0 OR AL,AL ; is it Get? 0 00006D49 7515 JNZ filetimes_set ; no, go set the time 0 00006D4B FA CLI 717 sf_Time equ sf_time ; NASM port equate 0 00006D4C 268B4D0D MOV CX,[ES:DI + sf_Time] ; suck out time 719 sf_Date equ sf_date ; NASM port equate 0 00006D50 268B550F MOV DX,[ES:DI + sf_Date] ; and date 0 00006D54 FB STI 0 00006D55 E8[0000] invoke Get_user_stack ; obtain place to return it 0 00006D58 894C04 MOV [SI + user_CX],CX ; and stash in time 0 00006D5B 895406 MOV [SI + user_DX],DX ; and stask in date 725 ext_done: 0 00006D5E EBC6 transfer SYS_RET_OK ; and say goodnight 727 filetimes_set: 0 00006D60 E8[0000] EnterCrit critSFT 0 00006D63 26894D0D MOV [ES:DI + sf_Time],CX ; drop in new time 0 00006D67 2689550F MOV [ES:DI + sf_Date],DX ; and date 0 00006D6B 31C0 XOR AX,AX 732 do_share: 733 %if installed 0 00006D6D 36FF1E[3800] Call far [ss:JShare + 14 * 4] 735 %else 736 Call ShSU 737 %endif 738 datetimeflg: 739 sf_Flags equ sf_flags ; NASM port equate 0 00006D72 26836505BF AND word [ES:DI + sf_Flags],~ devid_file_clean 0 00006D77 26814D050040 OR word [ES:DI + sf_Flags],sf_close_nodate 742 ftok: 0 00006D7D E8[0000] LeaveCrit critSFT 0 00006D80 EBDC transfer SYS_RET_OK ; mark file as dirty and return 745 EndProc D_File_Times 746 747 BREAK <$DUP - duplicate a jfn> 748 ; 749 ; Assembler usage: 750 ; MOV BX, fh 751 ; MOV AH, Dup 752 ; INT int_command 753 ; AX has the returned handle 754 ; Errors: 755 ; AX = dup_invalid_handle 756 ; = dup_too_many_open_files 757 Procedure D_DUP,NEAR 757 ****************** warning: proc D_DUP... [-w+user] 758 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 0 00006D82 89D8 MOV AX,BX ; save away old handle in AX 0 00006D84 E8[0000] invoke JFNFree ; free handle? into ES:DI, new in BX 761 DupErrorCheck: 0 00006D87 7217 JC DupErr ; nope, bye 0 00006D89 0657 SaveReg ; save away SFT 0 00006D8B 5E1F RestoreReg ; into convenient place DS:SI 0 00006D8D 93 XCHG AX,BX ; get back old handle 0 00006D8E E81F00 call CheckOwner ; get sft in ES:DI 0 00006D91 720D JC DupErr ; errors go home 0 00006D93 E8[0000] invoke DOS_Dup_Direct 0 00006D96 E8[0000] invoke pJFNFromHandle ; get pointer 0 00006D99 268A1D MOV BL,[ES:DI] ; get SFT number 0 00006D9C 881C MOV [SI],BL ; stuff in new SFT 0 00006D9E EBE0 transfer SYS_RET_OK ; and go home 0 00006DA0 EB9B DupErr: transfer SYS_RET_ERR 774 775 EndProc D_Dup 776 777 BREAK <$DUP2 - force a dup on a particular jfn> 778 ; 779 ; Assembler usage: 780 ; MOV BX, fh 781 ; MOV CX, newfh 782 ; MOV AH, Dup2 783 ; INT int_command 784 ; Error returns: 785 ; AX = error_invalid_handle 786 ; 787 Procedure D_Dup2,NEAR 787 ****************** warning: proc D_Dup2... [-w+user] 788 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 0 00006DA2 5351 SaveReg ; save source 0 00006DA4 89CB MOV BX,CX ; get one to close 0 00006DA6 E832FD invoke D_Close ; close destination handle 0 00006DA9 5B58 RestoreReg ; old in AX, new in BX 0 00006DAB E8[0000] invoke pJFNFromHandle ; get pointer 0 00006DAE EBD7 JMP DupErrorCheck ; check error and do dup 795 EndProc D_Dup2 796 797 Break 798 799 ; 800 ; CheckOwner - Due to the ability of the server to close file handles for a 801 ; process without the process knowing it (delete/rename of open files, for 802 ; example), it is possible for the redirector to issue a call to a handle 803 ; that it soes not rightfully own. We check here to make sure that the 804 ; issuing process is the owner of the SFT. At the same time, we do a 805 ; SFFromHandle to really make sure that the SFT is good. 806 ; 807 ; Inputs: BX has the handle 808 ; User_ID is the current user 809 ; Output: Carry Clear => ES:DI points to SFT 810 ; Carry Set => AX has error code 811 ; Registers modified: none 812 ; 813 814 Procedure CheckOwner,NEAR 814 ****************** warning: proc CheckOwner... [-w+user] 815 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 0 00006DB0 E8[0000] invoke SFFromHandle 0 00006DB3 7301C3 retc 0 00006DB6 50 push ax 819 user_id equ User_ID ; NASM port label 0 00006DB7 36A1[0000] mov ax,[ss:user_id] 0 00006DBB 263B452F cmp ax,[es:di + sf_UID] 0 00006DBF 58 pop ax 0 00006DC0 74F3 retz 0 00006DC2 B006 mov al,error_invalid_handle 0 00006DC4 F9 stc 0 00006DC5 C3 return 827 EndProc CheckOwner 828 829 ;------------------------------------------------------------------------- 830 ; Function name : choose_buf_page 831 ; Inputs : DMAADD = Xaddr 832 ; cx = # of bytes to transfer 833 ; Outputs : if NC 834 ; 835 ; SAFE_FLAG - 0 ==> page is safe. no need to 836 ; detect collision between 837 ; user & system buffer. 838 ; SAFE_FLAG - 1 ==> page is unsafe. Must check 839 ; for collision 840 ; 841 ; CY - error 842 ; 843 ; 844 ; High Level Alogrithm: 845 ; 846 ; 1. If Xaddr. is above the first physical page above 640K 847 ; 2. choose that page 848 ; 3. set safe flag 849 ; 4. else 850 ; 5. choose highest page above 640K 851 ; 6. If 6 or more pages above 640k 852 ; 7. Set safe flag 853 ; 8. else 854 ; 9. if Xaddr. + # of bytes to transfer does not spill into the 855 ; chosen page 856 ; 10. set safe flag 857 ; 11.else 858 ; 12. clear safe flag 859 ; 13.endif 860 ; 14.endif 861 ; 15.endif 862 ; 863 ;---------------------------------------------------------------------------- 864 ;Procedure choose_buf_page,near 865 ; 866 ; assume cs:dosgroup, ds:nothing, es:nothing, ss:dosgroup 867 ; 868 ; push cx 869 ; push bx 870 ; push dx 871 ; push si 872 ; push ds 873 ; push ax 874 ; 875 ; mov ax, word ptr [DMAADD+2] 876 ; and ax, 0fc00h ; page segment of transfer segment 877 ; 878 ; cmp ax, word ptr [BUF_EMS_FIRST_PAGE] 879 ; ja pick_first 880 ; 881 ; cmp [BUF_EMS_NPA640], 6 882 ; jae safe_pick_last 883 ; 884 ; add cx, word ptr [DMAADD] ; get final offset 885 ; mov bx, cx 886 ; 887 ; mov cl, 4 888 ; shr bx, cl ; get # of paragraphs 889 ; mov ax, word ptr [DMAADD+2] ; get initial segment 890 ; add ax, bx ; get final segment 891 ; 892 ; and ax, 0fc00h 893 ; cmp ax, word ptr [BUF_EMS_LAST_PAGE] 894 ; jne safe_pick_last 895 ; 896 ; mov [BUF_EMS_SAFE_FLAG], 0 897 ; jmp fin_choose_page 898 ; 899 ;safe_pick_last: 900 ; mov [BUF_EMS_SAFE_FLAG], 1 901 ; jmp fin_choose_page 902 ; 903 ;;pick_last: 904 ;; mov ax, word ptr [BUF_EMS_LAST_PAGE] 905 ;; mov [BUF_EMS_PFRAME], ax 906 ;; mov ax, word ptr [BUF_EMS_LAST_PAGE+2] 907 ;; mov [BUF_EMS_PAGE_FRAME], ax 908 ;; xor ax, ax 909 ;; jmp fin_choose_page 910 ; 911 ;pick_first: 912 ; mov ax, word ptr [BUF_EMS_FIRST_PAGE] 913 ; cmp [BUF_EMS_PFRAME], ax 914 ; je fin_choose_page 915 ; mov word ptr [LASTBUFFER], -1 916 ; mov [BUF_EMS_PFRAME], ax 917 ; mov ax, word ptr [BUF_EMS_FIRST_PAGE+2] 918 ; mov [BUF_EMS_PAGE_FRAME], ax 919 ; mov [BUF_EMS_SAFE_FLAG], 1 920 ; call Setup_EMS_Buffers 921 ; jmp fin_choose_page 922 ; 923 ;err_choose_page: 924 ; stc 925 ; 926 ;fin_choose_page: 927 ; clc 928 ; 929 ; pop ax 930 ; pop ds 931 ; pop si 932 ; pop dx 933 ; pop bx 934 ; pop cx 935 ; return 936 ; 937 ;EndProc choose_buf_page 938 ; 939 940 END 941 942 === Trace listing source: ../DOS/macro.lst 1 ; SCCSID = @(#)macro.asm 1.2 85/07/11 2 ;TITLE MACRO - Pathname and macro related internal routines 3 ;NAME MACRO 4 ; 5 ; $AssignOper written 6 ; FIND_DPB written 7 ; InitCDS written 8 ; $UserOper written 9 ; GetVisDrv written 10 ; GetThisDrv written 11 ; GetCDSFromDrv written 12 ; 13 ; Revision history: 14 ; 15 ; Created: MZ 4 April 1983 16 ; MZ 18 April 1983 Make TransFCB handle extended FCBs 17 ; AR 2 June 1983 Define/Delete macro for NET redir. 18 ; MZ 3 Nov 83 Fix InitCDS to reset length to 2 19 ; MZ 4 Nov 83 Fix NetAssign to use STRLEN only 20 ; MZ 18 Nov 83 Rewrite string processing for subtree 21 ; aliasing. 22 ; 23 ; MSDOS performs several types of name translation. First, we maintain for 24 ; each valid drive letter the text of the current directory on that drive. 25 ; For invalid drive letters, there is no current directory so we pretend to 26 ; be at the root. A current directory is either the raw local directory 27 ; (consisting of drive:\path) or a local network directory (consisting of 28 ; \\machine\path. There is a limit on the point to which a .. is allowed. 29 ; 30 ; Given a path, MSDOS will transform this into a real from-the-root path 31 ; without . or .. entries. Any component that is > 8.3 is truncated to 32 ; this and all * are expanded into ?'s. 33 ; 34 ; The second part of name translation involves subtree aliasing. A list of 35 ; subtree pairs is maintained by the external utility SUBST. The results of 36 ; the previous 'canonicalization' are then examined to see if any of the 37 ; subtree pairs is a prefix of the user path. If so, then this prefix is 38 ; replaced with the other subtree in the pair. 39 ; 40 ; A third part involves mapping this "real" path into a "physical" path. A 41 ; list of drive/subtree pairs are maintained by the external utility JOIN. 42 ; The output of the previous translation is examined to see if any of the 43 ; subtrees in this list are a prefix of the string. If so, then the prefix 44 ; is replaced by the appropriate drive letter. In this manner, we can 45 ; 'mount' one device under another. 46 ; 47 ; The final form of name translation involves the mapping of a user's 48 ; logical drive number into the internal physical drive. This is 49 ; accomplished by converting the drive number into letter:CON, performing 50 ; the above translation and then converting the character back into a drive 51 ; number. 52 ; 53 ; curdir_list STRUC 54 ; curdir_text DB DIRSTRLEN DUP (?) ; text of assignment and curdir 55 ; curdir_flags DW ? ; various flags 56 ; curdir_devptr DD ? ; local pointer to DPB or net device 57 ; curdir_ID DW ? ; cluster of current dir (net ID) 58 ; DW ? 59 ; curdir_end DW ? ; end of assignment 60 ; curdir_list ENDS 61 ; curdir_netID EQU DWORD PTR curdir_ID 62 ; ;Flag word masks 63 ; curdir_isnet EQU 1000000000000000B 64 ; curdir_inuse EQU 0100000000000000B 65 ; 66 ; There are two main entry points: TransPath and TransFCB. TransPath will 67 ; take a path and form the real text of the pathname with all . and .. 68 ; removed. TransFCB will translate an FCB into a path and then invoke 69 ; TransPath. 70 ; 71 ; Implementation note: CURDIR_End field points to the point in the text 72 ; string where the user may back up to via .. It is the location of a 73 ; separator character. For the root, it points at the leading /. For net 74 ; assignments it points at the end (nul) of the initial assignment: 75 ; A:/ \\foo\bar \\foo\bar\blech\bozo 76 ; ^ ^ ^ 77 ; A: -> d: /path/ path/ text 78 ; 79 ; A000 version 4.00 Jan. 1988 80 81 [list -] === Switch to base=008400h -> "DOSCODECODE" 88 section DOSCODECODE 89 [list -] 89 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 89 ****************** warning: out: BPB.INC... [-w+user] 89 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 89 ****************** warning: out: DEVSYM.INC... [-w+user] 96 ;.sall 97 98 %iassign Installed TRUE 99 100 I_need ThisCDS,DWORD ; pointer to CDS used 101 I_need CDSAddr,DWORD ; pointer to CDS table 102 I_need CDSCount,BYTE ; number of CDS entries 103 I_need CurDrv,BYTE ; current macro assignment (old 104 ; current drive) 105 I_need NUMIO,BYTE ; Number of physical drives 106 I_need fSharing,BYTE ; TRUE => no redirection allowed 107 I_need DummyCDS,80h ; buffer for dummy cds 108 I_need DIFFNAM,BYTE ; flag for MyName being set 109 I_need MYNAME,16 ; machine name 110 I_need MYNUM,WORD ; machine number 111 I_need DPBHEAD,DWORD ; beginning of DPB chain 112 I_need EXTERR_LOCUS,BYTE ; Extended Error Locus 113 I_need DrvErr,BYTE ; drive error 114 115 BREAK <$AssignOper -- Set up a Macro> 116 117 ; Inputs: 118 ; AL = 00 get assign mode (ReturnMode) 119 ; AL = 01 set assign mode (SetMode) 120 ; AL = 02 get attach list entry (GetAsgList) 121 ; AL = 03 Define Macro (attch start) 122 ; BL = Macro type 123 ; = 0 alias 124 ; = 1 file/device 125 ; = 2 drive 126 ; = 3 Char device -> network 127 ; = 4 File device -> network 128 ; DS:SI -> ASCIZ source name 129 ; ES:DI -> ASCIZ destination name 130 ; AL = 04 Cancel Macro 131 ; DS:SI -> ASCIZ source name 132 ; AL = 05 Modified get attach list entry 133 ; AL = 06 Get ifsfunc item 134 ; AL = 07 set in_use of a drive's CDS 135 ; DL = drive number, 0=default 0=A,, 136 ; AL = 08 reset in_use of a drive's CDS 137 ; DL = drive number, 0=A, 1=B,,, 138 ; Function: 139 ; Do macro stuff 140 ; Returns: 141 ; Std Xenix style error return 142 143 procedure D_AssignOper,NEAR 143 ****************** warning: proc D_AssignOper... [-w+user] 144 ASSUME DS:NOTHING,ES:NOTHING 145 0 00006DC6 3C07 CMP AL,7 ; set in_use ? ;AN000; 0 00006DC8 7526 JNZ chk08 ; no ;AN000; 148 srinuse: ;AN000; 0 00006DCA 50 PUSH AX ; save al ;AN000; 0 00006DCB 88D0 MOV AL,DL ; AL= drive id ;AN000; 0 00006DCD E86F01 CALL GetCDSFromDrv ; ds:si -> cds ;AN000; 0 00006DD0 58 POP AX ; ;AN000; 0 00006DD1 7218 JC baddrv ; bad drive ;AN000; 0 00006DD3 837C4500 CMP WORD PTR [SI + curdir_devptr],0 ; dpb ptr =0 ? ;AN000; 0 00006DD7 7412 JZ baddrv ; no ;AN000; 0 00006DD9 3C07 CMP AL,7 ; set ? ;AN000; 0 00006DDB 7507 JNZ resetdrv ; no ;AN000; 0 00006DDD 814C430040 OR word [SI + curdir_flags],curdir_inuse ; set in_use ;AN000; 0 00006DE2 EB19 JMP SHORT okdone ; ;AN000; 160 resetdrv: ;AN000; 0 00006DE4 816443FFBF AND word [SI + curdir_flags],~ curdir_inuse ; reset in_use ;AN000; 0 00006DE9 EB12 JMP SHORT okdone ; ;AN000; 163 baddrv: ;AN000; 0 00006DEB B80F00 MOV AX,error_invalid_drive ; error ;AN000; 0 00006DEE EB10 JMP SHORT ASS_ERR ; ;AN000; 166 chk08: ;AN000; 0 00006DF0 3C08 CMP AL,8 ; reset inuse ? ;AN000; 0 00006DF2 74D6 JZ srinuse ; yes ;AN000; 169 170 %IFN INSTALLED 171 transfer NET_ASSOPER 172 %ELSE 0 00006DF4 50 PUSH AX 174 multnet equ MultNET ; NASM port equate 0 00006DF5 B81E11 MOV AX,(multnet << 8) | 30 0 00006DF8 CD2F INT 2FH 0 00006DFA 5B POP BX ; Don't zap error code in AX 0 00006DFB 7203 JC ASS_ERR 179 okdone: 0 00006DFD E9[0000] transfer SYS_RET_OK 181 182 ASS_ERR: 0 00006E00 E9[0000] transfer SYS_RET_ERR 184 %ENDIF 185 186 EndProc D_AssignOper 187 188 Break 189 190 ; Inputs: AL has drive number A = 0 191 ; Outputs: Carry Set 192 ; No DPB for this drive number 193 ; Carry Clear 194 ; DS:SI points to DPB for drive 195 ; registers modified: DS,SI 196 Procedure FIND_DPB,NEAR 196 ****************** warning: proc FIND_DPB... [-w+user] 197 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 00006E03 36C536[0000] LDS SI,[ss:DPBHEAD] 199 DPB_LOOP: 0 00006E08 83FEFF CMP SI,-1 0 00006E0B 740A JZ NO_DPB 0 00006E0D 3A04 CMP AL,[SI + dpb_drive] 0 00006E0F 7501C3 retz ; Carry clear 0 00006E12 C57419 LDS SI,[SI + dpb_next_dpb] 0 00006E15 EBF1 JMP DPB_LOOP 206 207 NO_DPB: 0 00006E17 F9 STC 0 00006E18 C3 return 210 EndProc FIND_DPB 211 212 Break 213 214 ; Inputs: ThisCDS points to CDS 215 ; AL has uppercase drive letter 216 ; Outputs: ThisCDS is now empty 217 ; ES:DI point to CDS 218 ; Carry set if no DPB associated with drive 219 ; registers modified: AH,ES,DI 220 Procedure InitCDS,NEAR 220 ****************** warning: proc InitCDS... [-w+user] 221 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 00006E19 B43A MOV AH,':' 0 00006E1B 50 PUSH AX 0 00006E1C 2C40 SUB AL,"A"-1 ; A = 1 0 00006E1E 363806[0000] CMP [ss:NUMIO],AL 0 00006E23 58 POP AX 227 THISCDS equ ThisCDS ; NASM port label 0 00006E24 36C43E[0000] LES DI,[ss:THISCDS] 0 00006E29 26C745430000 MOV word [ES:DI + curdir_flags],0 ; "free" CDS 0 00006E2F 7239 JB RET_OK ; Drive does not map a physical drive 0 00006E31 268905 MOV WORD PTR [ES:DI + curdir_text],AX 0 00006E34 50 PUSH AX 0 00006E35 B85C00 MOV AX,"\" 0 00006E38 26894502 MOV WORD PTR [ES:DI + curdir_text+2],AX ; NUL terminate 0 00006E3C 58 POP AX 0 00006E3D 26814D430040 OR word [ES:DI + curdir_flags],curdir_inuse 237 curdir_END equ curdir_end ; NASM port equate 0 00006E43 26C7454F0200 MOV word [ES:DI + curdir_END],2 ; MZ 3 Nov 83 0 00006E49 26C745490000 MOV word [ES:DI + curdir_ID],0 0 00006E4F 26C7454B0000 MOV word [ES:DI + curdir_ID+2],0 0 00006E55 50 PUSH AX 0 00006E56 1E PUSH DS 0 00006E57 56 PUSH SI 0 00006E58 2C41 SUB AL,"A" ; A = 0 0 00006E5A E8A6FF invoke FIND_DPB 0 00006E5D 7208 JC PRET ; OOOOPPPPPSSSS!!!! 0 00006E5F 26897545 MOV WORD PTR [ES:DI + curdir_devptr],SI 0 00006E63 268C5D47 MOV WORD PTR [ES:DI + curdir_devptr+2],DS 249 PRET: 0 00006E67 5E POP SI 0 00006E68 1F POP DS 0 00006E69 58 POP AX 0 00006E6A C3 RET_OK: return 254 EndProc InitCDS 255 256 Break <$UserOper - get/set current user ID (for net)> 257 258 ; 259 ; $UserOper - retrieve or initiate a user id string. MSDOS will only 260 ; maintain this string and do no verifications. 261 ; 262 ; Inputs: AL has function type (0-get 1-set 2-printer-set 3-printer-get 263 ; 4-printer-set-flags,5-printer-get-flags) 264 ; DS:DX is user string pointer (calls 1,2) 265 ; ES:DI is user buffer (call 3) 266 ; BX is assign index (calls 2,3,4,5) 267 ; CX is user number (call 1) 268 ; DX is flag word (call 4) 269 ; Outputs: If AL = 0 then the current user string is written to DS:DX 270 ; and user CX is set to the user number 271 ; If AL = 3 then CX bytes have been put at input ES:DI 272 ; If AL = 5 then DX is flag word 273 274 Procedure D_UserOper,NEAR 274 ****************** warning: proc D_UserOper... [-w+user] 275 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 00006E6B 50 PUSH AX 0 00006E6C 2C01 SUB AL,1 ; quick dispatch on 0,1 0 00006E6E 58 POP AX 0 00006E6F 7211 JB UserGet ; return to user the string 0 00006E71 742E JZ UserSet ; set the current user 0 00006E73 3C05 CMP AL,5 ; test for 2,3,4 or 5 0 00006E75 763D JBE UserPrint ; yep 283 errLoc_Unk equ errLOC_Unk ; NASM port equate 0 00006E77 36C606[0000]01 MOV byte [ss:EXTERR_LOCUS],errLoc_Unk ; Extended Error Locus 285 error_Invalid_Function equ error_invalid_function ; NASM port equate 0 00006E7D B001E9[0000] error error_Invalid_Function ; not 0,1,2,3 287 288 UserGet: 289 ; Transfer MYNAME to DS:DX 290 ; Set Return CX to MYNUM 0 00006E82 1E PUSH DS ; switch registers 0 00006E83 07 POP ES 0 00006E84 89D7 MOV DI,DX ; destination 0 00006E86 368B0E[0000] MOV CX,[ss:MYNUM] ; Get number 0 00006E8B E8[0000] invoke get_user_stack 296 User_CX equ user_CX ; NASM port equate 0 00006E8E 894C04 MOV [SI + User_CX],CX ; Set number return 0 00006E91 161F Context DS ; point to DOSGroup 299 ASSUME DS:DOSGROUP 300 DOSGroup equ DOSGROUP ; NASM port equate 301 MyName equ MYNAME ; NASM port label 0 00006E93 BE[0000] MOV SI,OFFSET MyName wrt DOSGroup ; point source to user string 303 UserMove: 304 ASSUME DS:NOTHING 0 00006E96 B90F00 MOV CX,15 0 00006E99 F3A4 REP MOVSB ; blam. 0 00006E9B 31C0 XOR AX,AX ; 16th byte is 0 0 00006E9D AA STOSB 309 UserBye: 0 00006E9E E9[0000] transfer sys_ret_ok ; no errors here 311 312 UserSet: 313 ASSUME DS:NOTHING 314 ; Transfer DS:DX to MYNAME 315 ; CX to MYNUM 0 00006EA1 36890E[0000] MOV [ss:MYNUM],CX 0 00006EA6 89D6 MOV SI,DX ; user space has source 0 00006EA8 1607 Context ES 0 00006EAA BF[0000] MOV DI,OFFSET MyName wrt DOSGroup ; point dest to user string 320 DiffNam equ DIFFNAM ; NASM port label 0 00006EAD 36FE06[0000] INC byte [ss:DiffNam] ; signal change 0 00006EB2 EBE2 JMP UserMove 323 324 UserPrint: 325 ASSUME ES:NOTHING 326 %IFN Installed 327 transfer PRINTER_GETSET_STRING 328 %ELSE 0 00006EB4 50 PUSH AX 330 multNET equ MultNET ; NASM port equate 0 00006EB5 B81F11 MOV AX,(multNET << 8) | 31 0 00006EB8 CD2F INT 2FH 0 00006EBA 5A POP DX ; Clean stack 0 00006EBB 7302 JNC OKPA 0 00006EBD EBC0 transfer SYS_RET_ERR 336 337 OKPA: 0 00006EBF EBDD transfer SYS_RET_OK 339 %ENDIF 340 341 EndProc D_UserOper 342 343 Break 344 345 ; 346 ; GetVisDrv - correctly map non-spliced inuse drives 347 ; 348 ; Inputs: AL has drive identifier (0=default) 349 ; Outputs: Carry Set - invalid drive/macro 350 ; Carry Clear - AL has physical drive (0=A) 351 ; ThisCDS points to CDS 352 ; Registers modified: AL 353 354 Procedure GetVisDrv,NEAR 354 ****************** warning: proc GetVisDrv... [-w+user] 355 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 00006EC1 E81A00 CALL GetThisDrv ; get inuse drive 0 00006EC4 72A4 retc 0 00006EC6 1E56 SaveReg 0 00006EC8 36C536[0000] LDS SI,[ss:ThisCDS] 0 00006ECD F744430020 TEST word [SI + curdir_flags],curdir_splice 0 00006ED2 5E1F RestoreReg 0 00006ED4 7494 retz ; if not spliced, return OK 0 00006ED6 36C606[0000]0F MOV byte [ss:DrvErr],error_invalid_drive ;IFS. ;AN000; 0 00006EDC F9 STC ; signal error 0 00006EDD C3 return 366 EndProc GetVisDrv 367 368 Break 369 370 ; 371 ; GetThisDrv - look through a set of macros and return the current drive and 372 ; macro pointer 373 ; 374 ; Inputs: AL has drive identifier (1=A, 0=default) 375 ; Outputs: 376 ; Carry Set - invalid drive/macro 377 ; Carry Clear - AL has physical drive (0=A) 378 ; ThisCDS points to macro 379 ; Registers modified: AL 380 381 Procedure GetThisDrv,NEAR 381 ****************** warning: proc GetThisDrv... [-w+user] 382 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 00006EDE 08C0 OR AL,AL ; are we using default drive? 0 00006EE0 7506 JNZ GetMap ; no, go get the CDS pointers 0 00006EE2 36A0[0000] MOV AL,[ss:CurDrv] ; get the current drive 0 00006EE6 FEC0 INC AL ; Counteract next instruction 387 GetMap: 0 00006EE8 FEC8 DEC AL ; 0 = A 0 00006EEA 1E56 SaveReg ; save world 0 00006EEC 36C606[0000]02 mov byte [ss:EXTERR_LOCUS],errLOC_Disk 0 00006EF2 36F606[0000]FF TEST byte [ss:fSharing],-1 ; Logical or Physical? 0 00006EF8 7421 JZ Not_SRVC ; Logical 0 00006EFA 500657 SaveReg 0 00006EFD 36C706[0000][0000] MOV WORD [ss:ThisCDS],OFFSET DummyCDS wrt DOSGroup 0 00006F04 368C16[0200] MOV WORD PTR [ss:ThisCDS+2], ss ; ThisCDS = &DummyCDS; 0 00006F09 0441 ADD AL,'A' 0 00006F0B E80BFF CALL InitCDS ; InitCDS(c); 0 00006F0E 26F745430040 TEST word [ES:DI + curdir_flags],curdir_inuse ; Clears carry 0 00006F14 5F0758 RestoreReg 0 00006F17 740E JZ GetBerr ; Not a physical drive. 0 00006F19 EB21 JMP SHORT GetBye ; carry clear 402 403 Not_SRVC: 0 00006F1B E82100 invoke GetCDSFromDrv 0 00006F1E 720F JC GetBerr2 ; Unassigned CDS -> return error already set 0 00006F20 F744430040 TEST word [SI + curdir_flags],curdir_inuse ; Clears Carry 0 00006F25 7515 JNZ GetBye ; carry clear 408 GetBerr: 0 00006F27 B01A MOV AL,error_not_DOS_disk ;AN000;IFS. Formatted IFS drive 0 00006F29 837C4500 CMP WORD PTR [SI + curdir_devptr],0 ;AN000;IFS. dpb ptr =0 ? 0 00006F2D 7502 JNZ notfat ;AN000;IFS. no 412 GetBerr2: 0 00006F2F B00F MOV AL,error_invalid_drive ;AN000;;IFS. invalid FAT drive 414 notfat: ;AN000; 0 00006F31 36A2[0000] MOV [ss:DrvErr],AL ;AN000;;IFS. save this for IOCTL 416 errLOC_UNK equ errLOC_Unk ; NASM port equate 0 00006F35 36C606[0000]01 mov byte [ss:EXTERR_LOCUS],errLOC_UNK 0 00006F3B F9 STC 0 00006F3C 5E1F GetBye: RestoreReg ; restore world 0 00006F3E C3 return 421 EndProc GetThisDrv 422 423 Break 424 425 ; 426 ; GetCDSFromDrv - given a physical drive number, convert it to a CDS 427 ; pointer, returning an error if the drive number is greater than the 428 ; number of CDS's 429 ; 430 ; Inputs: AL is physical unit # A=0... 431 ; Outputs: Carry Set if Bad Drive 432 ; Carry Clear 433 ; DS:SI -> CDS 434 ; [THISCDS] = DS:SI 435 ; Registers modified: DS,SI 436 437 Procedure GetCDSFromDrv,NEAR 437 ****************** warning: proc GetCDSFromDrv... [-w+user] 438 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 00006F3F 363A06[0000] CMP AL,[ss:CDSCount] ; is this a valid designator 0 00006F44 7202 JB GetCDS ; yes, go get the macro 0 00006F46 F9 STC ; signal error 0 00006F47 C3 return ; bye 443 GetCDS: 0 00006F48 5350 SaveReg 0 00006F4A 36C536[0000] LDS SI,[ss:CDSAddr] ; get pointer to table 446 CurDir_list_struc_size equ curdir_list_struc_size ; NASM port equate 0 00006F4F B358 MOV BL,CurDir_list_struc_size ; size in convenient spot 0 00006F51 F6E3 MUL BL ; get net offset 0 00006F53 01C6 ADD SI,AX ; convert to true pointer 0 00006F55 368936[0000] MOV WORD PTR [ss:ThisCDS],SI ; store convenient offset 0 00006F5A 368C1E[0200] MOV WORD PTR [ss:ThisCDS+2],DS ; store convenient segment 0 00006F5F 585B RestoreReg 0 00006F61 F8 CLC ; no error 0 00006F62 C3 return ; bye! 455 EndProc GetCDSFromDrv 456 457 END === Trace listing source: ../DOS/macro2.lst 1 ; SCCSID = @(#)macro2.asm 1.2 85/07/23 2 ;TITLE MACRO2 - Pathname and macro related internal routines 3 ;NAME MACRO2 4 ; 5 ; TransFCB written 6 ; TransPath written 7 ; TransPathSet written 8 ; TransPathNoSet Written 9 ; Canonicalize written 10 ; PathSep written 11 ; SkipBack written 12 ; CopyComponent written 13 ; Splice written 14 ; $NameTrans written 15 ; DriveFromText 16 ; TextFromDrive 17 ; PathPref 18 ; ScanPathChar 19 ; 20 ; Revision history: 21 ; 22 ; Created: MZ 4 April 1983 23 ; MZ 18 April 1983 Make TransFCB handle extended FCBs 24 ; AR 2 June 1983 Define/Delete macro for NET redir. 25 ; MZ 3 Nov 83 Fix InitCDS to reset length to 2 26 ; MZ 4 Nov 83 Fix NetAssign to use STRLEN only 27 ; MZ 18 Nov 83 Rewrite string processing for subtree 28 ; aliasing. 29 ; BAS 3 Jan 85 ScanPathChar to search for path separator 30 ; in null terminated string. 31 ; 32 ; MSDOS performs several types of name translation. First, we maintain for 33 ; each valid drive letter the text of the current directory on that drive. 34 ; For invalid drive letters, there is no current directory so we pretend to 35 ; be at the root. A current directory is either the raw local directory 36 ; (consisting of drive:\path) or a local network directory (consisting of 37 ; \\machine\path. There is a limit on the point to which a .. is allowed. 38 ; 39 ; Given a path, MSDOS will transform this into a real from-the-root path 40 ; without . or .. entries. Any component that is > 8.3 is truncated to 41 ; this and all * are expanded into ?'s. 42 ; 43 ; The second part of name translation involves subtree aliasing. A list of 44 ; subtree pairs is maintained by the external utility SUBST. The results of 45 ; the previous 'canonicalization' are then examined to see if any of the 46 ; subtree pairs is a prefix of the user path. If so, then this prefix is 47 ; replaced with the other subtree in the pair. 48 ; 49 ; A third part involves mapping this "real" path into a "physical" path. A 50 ; list of drive/subtree pairs are maintained by the external utility JOIN. 51 ; The output of the previous translation is examined to see if any of the 52 ; subtrees in this list are a prefix of the string. If so, then the prefix 53 ; is replaced by the appropriate drive letter. In this manner, we can 54 ; 'mount' one device under another. 55 ; 56 ; The final form of name translation involves the mapping of a user's 57 ; logical drive number into the internal physical drive. This is 58 ; accomplished by converting the drive number into letter:CON, performing 59 ; the above translation and then converting the character back into a drive 60 ; number. 61 ; 62 ; curdir_list STRUC 63 ; curdir_text DB DIRSTRLEN DUP (?) ; text of assignment and curdir 64 ; curdir_flags DW ? ; various flags 65 ; curdir_devptr DD ? ; local pointer to DPB or net device 66 ; curdir_ID DW ? ; cluster of current dir (net ID) 67 ; DW ? 68 ; curdir_end DW ? ; end of assignment 69 ; curdir_list ENDS 70 ; curdir_netID EQU DWORD PTR curdir_ID 71 ; ;Flag word masks 72 ; curdir_isnet EQU 1000000000000000B 73 ; curdir_inuse EQU 0100000000000000B 74 ; 75 ; 76 ; There are two main entry points: TransPath and TransFCB. TransPath will 77 ; take a path and form the real text of the pathname with all . and .. 78 ; removed. TransFCB will translate an FCB into a path and then invoke 79 ; TransPath. 80 ; 81 ; Implementation note: CURDIR_End field points to the point in the text 82 ; string where the user may back up to via .. It is the location of a 83 ; separator character. For the root, it points at the leading /. For net 84 ; assignments it points at the end (nul) of the initial assignment: 85 ; A:/ \\foo\bar \\foo\bar\blech\bozo 86 ; ^ ^ ^ 87 ; A: -> d: /path/ path/ text 88 ; 89 ; A000 version 4.00 Jan. 1988 90 91 [list -] === Switch to base=008400h -> "DOSCODECODE" 98 section DOSCODECODE 99 [list -] 99 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 99 ****************** warning: out: BPB.INC... [-w+user] 99 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 99 ****************** warning: out: DEVSYM.INC... [-w+user] 106 ;.sall 107 108 %iassign Installed TRUE 109 110 I_need Splices,BYTE ; TRUE => splices are being done. 111 I_need WFP_Start,WORD ; pointer to beginning of expansion 112 I_need Curr_Dir_End,WORD ; offset to end of current dir 113 I_need ThisCDS,DWORD ; pointer to CDS used 114 I_need ThisDPB,DWORD ; pointer to DPB used 115 I_need NAME1,11 ; Parse output of NameTrans 116 I_need OpenBuf,128 ; ususal destination of strings 117 I_need ExtFCB,BYTE ; flag for extended FCBs 118 I_need Sattrib,BYTE ; attribute of search 119 I_need fSplice,BYTE ; TRUE => do splice after canonicalize 120 I_need fSharing,BYTE ; TRUE => no redirection allowed 121 I_Need NoSetDir,BYTE ; TRUE => syscall is interested in 122 ; entry, not contents. We splice only 123 ; inexact matches 124 I_Need cMeta,BYTE ; count of meta chars in path 125 I_Need Temp_Var,WORD ;AN000; variable for temporary use 3/31/KK 126 I_Need DOS34_FLAG,WORD ;AN000; variable for dos34 127 I_Need NO_FILTER_PATH,DWORD ;AN000; pointer to orignal path === Switch to base=008400h -> "DOSCODETABLE" 128 section DOSCODETABLE 129 EXTRN CharType:BYTE === Switch to base=008400h -> "DOSCODECODE" 130 section DOSCODECODE 131 132 BREAK 133 134 ; 135 ; TransFCB - Copy an FCB from DS:DX into a reserved area doing all of the 136 ; gritty substitution. 137 ; 138 ; Inputs: DS:DX - pointer to FCB 139 ; ES:DI - point to destination 140 ; Outputs: Carry Set - invalid path in final map 141 ; Carry Clear - FCB has been mapped into ES:DI 142 ; Sattrib is set from possibly extended FCB 143 ; ExtFCB set if extended FCB found 144 ; Registers modified: most 145 146 Procedure TransFCB,NEAR 146 ****************** warning: proc TransFCB... [-w+user] 147 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 148 PUBLIC MACRO001S,MACRO001E 149 MACRO001S: 150 LocalVar FCBTmp,15 151 MACRO001E: 0 00006F63 5589E583EC0F Enter 0 00006F69 1607 Context ES ; get DOSGroup addressability 0 00006F6B 0657 SaveReg ; save away final destination 0 00006F6D 8D7EF1 LEA DI,[FCBTmp] ; point to FCB temp area 0 00006F70 368326[0000]00 and word [ss:ExtFCB], 0 ; clear ExtFCB and Sattrib 157 ; MOV byte [ss:ExtFCB],0 ; no extended FCB found 158 ; MOV byte [ss:Sattrib],0 ; default search attributes 0 00006F76 E8[0000] invoke GetExtended ; get FCB, extended or not 0 00006F79 740C JZ GetDrive ; not an extended FCB, get drive 0 00006F7B 8A44FF MOV AL,[SI-1] ; get attributes 162 SAttrib equ Sattrib ; NASM port label 0 00006F7E 36A2[0000] MOV [ss:SAttrib],AL ; store search attributes 0 00006F82 36FE0E[0000] dec byte [ss:ExtFCB] ; = 255, signal extended FCB 165 GetDrive: 0 00006F87 AC LODSB ; get drive byte 0 00006F88 E8[0000] invoke GetThisDrv 0 00006F8B 722C jc BadPack 0 00006F8D E87D03 CALL TextFromDrive ; convert 0-based drive to text 170 ; 171 ; Scan the source to see if there are any illegal chars 172 ; 173 DOSGroup equ DOSGROUP ; NASM port equate 0 00006F90 BB[0000] MOV BX,OFFSET CharType 175 %IF DBCS ;AN000; 176 ;----------------------------- Start of DBCS 2/13/KK 177 SaveReg ;AN000;; back over name, ext 178 MOV CX,8 ;AN000;; 8 chars in main part of name 179 FCBScan:LODSB ;AN000;; get a byte 180 invoke testkanj ;AN000; 181 jz notkanj2 ;AN000; 182 DEC CX ;AN000; 183 JCXZ VolidChck ;AN000;; Kanji half char screw up 184 LODSB ;AN000;; second kanji byte 185 Nextch equ NextCh ; NASM port label 186 jmp short Nextch ;AN000; 187 VolidChck: ;AN000; 188 TEST byte [ss:SAttrib],attr_volume_id ;AN000;; volume id ? 189 Badpack equ BadPack ; NASM port label 190 JZ Badpack ;AN000;; no, error 191 OR word [ss:DOS34_FLAG],DBCS_VOLID ;AN000;; no, error 192 DEC CX ;AN000;; cx=-1 193 INC SI ;AN000;; next char 194 JMP SHORT FCBScango ;AN000; 195 notkanj2: ;AN000; 196 cs xlatb ;AN000;;get bits 197 TEST AL,fFCB ;AN000; 198 JZ BadPack ;AN000; 199 NextCh: ;AN000; 200 LOOP FCBScan ;AN000; 201 FCBScango: ;AN000; 202 ADD CX,3 ;AN000;; Three chars in extension 203 FCBScanE: ;AN000; 204 LODSB ;AN000; 205 invoke testkanj ;AN000; 206 jz notkanj3 ;AN000; 207 DEC CX ;AN000; 208 JCXZ BadPack ;AN000;; Kanji half char problem 209 LODSB ;AN000;; second kanji byte 210 jmp short NextChE ;AN000; 211 notkanj3: ;AN000; 212 cs xlatb ;AN000;; get bits 213 TEST AL,fFCB ;AN000; 214 JZ BadPack ;AN000; 215 NextChE: ;AN000; 216 LOOP FCBScanE ;AN000; 217 ;----------------------------- End of DBCS 2/13/KK 218 %ELSE 219 0 00006F93 B90B00 MOV CX,11 0 00006F96 56 SaveReg ; back over name, ext 0 00006F97 AC FCBScan:LODSB ; get a byte 0 00006F98 2ED7 cs xlatb ; get bits 0 00006F9A A808 TEST AL,fFCB 0 00006F9C 741B JZ BadPack 0 00006F9E E2F7 NextCh: LOOP FCBScan 227 %ENDIF 0 00006FA0 5E RestoreReg 0 00006FA1 89FB MOV BX,DI 0 00006FA3 E8[0000] invoke PackName ; crunch the path 0 00006FA6 5F07 RestoreReg ; get original destination 0 00006FA8 161F Context DS ; get DS addressability 0 00006FAA 8D76F1 LEA SI,[FCBTmp] ; point at new pathname 0 00006FAD 803F00 CMP BYTE PTR [BX],0 0 00006FB0 7407 JZ BadPack 0 00006FB2 55 SaveReg 0 00006FB3 E80D00 CALL TransPathSet ; convert the path 0 00006FB6 5D RestoreReg 0 00006FB7 7303 JNC FCBRet ; bye with transPath error code 240 BadPack: 0 00006FB9 F9 STC 0 00006FBA B003 MOV AL,error_path_not_found 0 00006FBC 89EC5D FCBRet: Leave 0 00006FBF C3 return 245 EndProc TransFCB,NoCheck 246 247 BREAK 248 249 ; 250 ; TransPath - copy a path from DS:SI to ES:DI, performing component string 251 ; substitution, insertion of current directory and fixing . and .. 252 ; entries. Perform splicing. Allow input string to match splice 253 ; exactly. 254 ; 255 ; TransPathSet - Same as above except No splicing is performed if input path 256 ; matches splice. 257 ; 258 ; TransPathNoSet - No splicing/local using is performed at all. 259 ; 260 ; The following anomalous behaviour is required: 261 ; 262 ; Drive letters on devices are ignored. (set up DummyCDS) 263 ; Paths on devices are ignored. (truncate to 0-length) 264 ; Raw net I/O sets ThisCDS => NULL. 265 ; fSharing => dummyCDS and no subst/splice. Only canonicalize. 266 ; 267 ; Other behaviour: 268 ; 269 ; ThisCDS set up. 270 ; FatRead done on local CDS. 271 ; ValidateCDS done on local CDS. 272 ; 273 ; Brief flowchart: 274 ; 275 ; if fSharing then 276 ; set up DummyCDS (ThisCDS) 277 ; canonicalize (sets cMeta) 278 ; splice 279 ; fatRead 280 ; return 281 ; if \\ or d:\\ lead then 282 ; set up null CDS (ThisCDS) 283 ; canonicalize (sets cMeta) 284 ; return 285 ; if device then 286 ; set up dummyCDS (ThisCDS) 287 ; canonicalize (sets cMeta) 288 ; return 289 ; if file then 290 ; getCDS (sets (ThisCDS) from name) 291 ; validateCDS (may reset current dir) 292 ; Copy current dir 293 ; canonicalize (set cMeta) 294 ; splice 295 ; generate correct CDS (ThisCDS) 296 ; if local then 297 ; fatread 298 ; return 299 ; 300 ; Inputs: DS:SI - point to ASCIZ string path 301 ; DI - point to buffer in DOSGroup 302 ; Outputs: Carry Set - invalid path specification: too many .., bad 303 ; syntax, etc. or user FAILed to I 24. 304 ; WFP_Start - points to beginning of buffer 305 ; Curr_Dir_End - points to end of current dir in path 306 ; DS - DOSGroup 307 ; Registers modified: most 308 309 Procedure TransPath,NEAR 309 ****************** warning: proc TransPath... [-w+user] 310 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 00006FC0 30C0 XOR AL,AL 0 00006FC2 A9 db 0A9h ; test ax, imm16 - skip mov al, -1 313 Entry TransPathSet 0 00006FC3 B0FF MOV AL,-1 315 SetSplice: 0 00006FC5 36A2[0000] MOV [ss:NoSetDir],AL ; NoSetDir = !fExact; 0 00006FC9 B0FF MOV AL,-1 318 Entry TransPathNoSet 0 00006FCB 368936[0000] MOV WORD PTR [ss:NO_FILTER_PATH],SI ;AN000;;IFS. save old path for IFS 0 00006FD0 368C1E[0200] MOV WORD PTR [ss:NO_FILTER_PATH+2],DS ;AN000;;IFS. 321 0 00006FD5 36A2[0000] MOV [ss:fSplice],AL ; fSplice = TRUE; 0 00006FD9 36C606[0000]FF MOV byte [ss:cMeta],-1 0 00006FDF 36893E[0000] MOV [ss:WFP_Start],DI 0 00006FE4 36C706[0000]FFFF MOV word [ss:Curr_Dir_End],-1 ; crack from start 0 00006FEB 1607 Context ES 0 00006FED 8DAD8600 LEA BP,[DI+TEMPLEN] ; end of buffer 328 ; 329 ; if this is through the server dos call, fsharing is set. We set up a 330 ; dummy cds and let the operation go. 331 ; 0 00006FF1 36F606[0000]FF TEST byte [ss:fSharing],-1 ; if no sharing 333 CheckUNC equ CheckUnc ; NASM port label 0 00006FF7 7435 JZ CheckUNC ; skip to UNC check 335 ; 336 ; ES:DI point to buffer 337 ; 0 00006FF9 E8FA02 CALL DriveFromText ; get drive and advance DS:SI 0 00006FFC E8[0000] invoke GetThisDrv ; Set ThisCDS and convert to 0-based 0 00006FFF 722A jc NoPath 0 00007001 E80903 CALL TextFromDrive ; drop in new 0 00007004 8D5D01 LEA BX,[DI+1] ; backup limit 0 00007007 E83601 CALL Canonicalize ; copy and canonicalize 0 0000700A 72B3 retc ; errors 345 ; 346 ; Perform splices for net guys. 347 ; 0 0000700C 161F Context DS 349 wfp_Start equ WFP_Start ; NASM port label 0 0000700E 8B36[0000] MOV SI,[wfp_Start] ; point to name 0 00007012 F606[0000]FF TEST byte [fSplice],-1 0 00007017 7403 JZ NoServerSplice 0 00007019 E83502 CALL Splice 354 NoServerSplice: 0 0000701C 161F Context DS ; for FATREAD 0 0000701E C43E[0000] LES DI,[ThisCDS] ; for fatread 0 00007022 E8[0000] EnterCrit critDisk 0 00007025 E8[0000] Invoke FatRead_CDS 0 00007028 E8[0000] LeaveCrit critDisk 360 NoPath: 0 0000702B B003 MOV AL,error_path_not_found ; Set up for possible bad path error 0 0000702D C3 return ; any errors are in Carry flag 363 ASSUME DS:NOTHING 364 ; 365 ; Let the network decide if the name is for a spooled device. It will map 366 ; the name if so. 367 ; 368 CheckUnc: 0 0000702E 36C706[0000]FFFF MOV WORD [ss:ThisCDS],-1 ; NULL thisCDS 370 multNet equ MultNET ; NASM port equate 0 00007035 B82311CD2F CallInstall NetSpoolCheck,multNet,35 0 0000703A 7329 JNC UNCDone 373 ; 374 ; At this point the name is either a UNC-style name (prefixed with two leading 375 ; \\s) or is a local file/device. Remember that if a net-spooled device was 376 ; input, then the name has been changed to the remote spooler by the above net 377 ; call. Also, there may be a drive in front of the \\. 378 ; 379 NO_CHECK: 0 0000703C E8B702 CALL DriveFromText ; eat drive letter 0 0000703F 50 PUSH AX ; save it 0 00007040 8B04 MOV AX,WORD PTR [SI] ; get first two bytes of path 0 00007042 E8[0000] Invoke PathChrCmp ; convert to normal form 0 00007045 86E0 XCHG AH,AL ; swap for second byte 0 00007047 E8[0000] Invoke PathChrCmp ; convert to normal form 0 0000704A 751F JNZ CheckDevice ; not a path char 0 0000704C 38C4 CMP AH,AL ; are they same? 0 0000704E 751B JNZ CheckDevice ; nope 389 ; 390 ; We have a UNC request. We must copy the string up to the beginning of the 391 ; local machine root path 392 ; 393 0 00007050 58 POP AX 0 00007051 A5 MOVSW ; get the lead \\. 0 00007052 AC UNCCpy: LODSB ; get a byte 397 %IF DBCS ;AN000; 398 ;----------------------------- Start of DBCS 2/23/KK 399 invoke testkanj ;AN000; 400 jz notkanj1 ;AN000; 401 STOSB ;AN000; 402 LODSB ;AN000; 403 OR AL,AL ;AN000; 404 JZ UNCTerm ;AN000;; Ignore half kanji error for now 405 STOSB ;AN000; 406 jmp UNCCpy ;AN000; 407 notkanj1: ;AN000; 408 ;----------------------------- End of DBCS 2/23/KK 409 %ENDIF ;AN000; 0 00007053 E8[0000] invoke UCase ;AN000;; convert the char 0 00007056 08C0 OR AL,AL 0 00007058 740E JZ UNCTerm ; end of string. All done. 0 0000705A E8[0000] Invoke PathChrCmp ; is it a path char? 0 0000705D 89FB MOV BX,DI ; backup position 0 0000705F AA STOSB 0 00007060 75F0 JNZ UNCCpy ; no, go copy 0 00007062 E8DB00 CALL Canonicalize ; wham (and set cMeta) 418 UNCDone: 0 00007065 161F Context DS 420 %IF DBCS 421 ;----------------------------- Start of DBCS 2/23/KK 422 retc ;AN000; Return if error from Canonicalize 423 424 ; Although Cononicalize has done lots of good things for us it may also have 425 ; done e5 to 05 conversion on the fisrt char following a path sep char which is 426 ; not wanted on a UNC request as this should be left for the remote station. 427 ; The simplest thing to do is check for such conversions and convert them back 428 ; again. 429 ; This check loop is also called from the DoFile section of TransPath if the 430 ; file is a remote file. Entry point when called is TP_check05 with the 431 ; inputs/outputs as follows; 432 ; Inputs : ES:DI = Buffer to check for re-conversion 433 ; Outputs: None 434 ; Used : DI,AX 435 436 437 WFP_start equ WFP_Start ; NASM port label 438 MOV DI,[WFP_start] ;AN000;; ES:DI points to converted string 439 TP_check05: ;AN000; 440 MOV AL,BYTE PTR [ES:DI] ;AN000;; Get character from path 441 OR AL,AL ;AN000;; End of null terminated path? 442 JZ TP_end05 ;AN000;; Finished, CF =0 from OR (ret success) 443 invoke testkanj ;AN000;; Kanji lead character? 444 JZ TP_notK ;AN000;; Check for path seperator if not 445 INC DI ;AN000;; Bypass Kanji second byte 446 JMP TP_nxt05 ;AN000;; Go to check next character 447 TP_notK: ;AN000; 448 invoke PathChrCmp ;AN000;; Is it a path seperator char? 449 JNZ TP_nxt05 ;AN000;; Check next character if not 450 CMP BYTE PTR [ES:DI+1],05 ;AN000;; 05 following path sep char? 451 JNZ TP_nxt05 ;AN000;; Check next character if not 452 MOV BYTE PTR [ES:DI+1],0E5h ;AN000;; Convert 05 back to E5 453 TP_nxt05: ;AN000; 454 INC DI ;AN000;; Point to next char in path 455 JMP TP_check05 ;AN000;; Test all chars in path 456 TP_end05: 457 ;----------------------------- End of DBCS 2/23/KK 458 %ENDIF ;AN000; 0 00007067 C3 return ; return error code 460 461 ASSUME DS:NOTHING 462 UNCTerm: 0 00007068 AA STOSB ;AN000; 0 00007069 EBFA JMP UNCDone ;AN000; 465 466 CheckDevice: 467 ; 468 ; Check DS:SI for device. First eat any path stuff 469 ; 0 0000706B 58 POP AX ; retrieve drive info 0 0000706C 803C00 CMP BYTE PTR [SI],0 ; check for null file 0 0000706F 7504 JNZ CheckPath 0 00007071 B002 MOV AL,error_file_not_found ; bad file error 0 00007073 F9 STC ; signal error on null input 0 00007074 C3 RETURN ; bye! 476 CheckPath: 0 00007075 5055 SaveReg ; save drive number 0 00007077 E8[0000] Invoke CheckThisDevice ; snoop for device 0 0000707A 5D58 RestoreReg ; get drive letter back 0 0000707C 731C JNC DoFile ; yes we have a file. 481 ; 482 ; We have a device. AX has drive letter. At this point we may fake a CDS ala 483 ; sharing DOS call. We know by getting here that we are NOT in a sharing DOS 484 ; call. 485 ; 0 0000707E 36C606[0000]FF MOV byte [ss:fSharing],-1 ; simulate sharing dos call 0 00007084 E8[0000] invoke GetThisDrv ; set ThisCDS and init DUMMYCDS 0 00007087 36C606[0000]00 MOV byte [ss:fSharing],0 ; 489 ; 490 ; Now that we have noted that we have a device, we put it into a form that 491 ; getpath can understand. Normally getpath requires d:\ to begin the input 492 ; string. We relax this to state that if the d:\ is present then the path 493 ; may be a file. If D:/ (note the forward slash) is present then we have 494 ; a device. 495 ; 0 0000708D E87D02 CALL TextFromDrive 0 00007090 B02F MOV AL,'/' ; path sep. 0 00007092 AA STOSB 0 00007093 E8[0000] invoke StrCpy ; move remainder of string 0 00007096 F8 CLC ; everything OK. 0 00007097 161F Context DS ; remainder of OK stuff 0 00007099 C3 return 503 ; 504 ; We have a file. Get the raw CDS. 505 ; 506 DoFile: 507 ASSUME DS:NOTHING 0 0000709A E8[0000] invoke GetVisDrv ; get proper CDS 0 0000709D B003 MOV AL,error_path_not_found ; Set up for possible bad file error 0 0000709F 72F8 retc ; CARRY set -> bogus drive/spliced 511 ; 512 ; ThisCDS has correct CDS. DS:SI advanced to point to beginning of path/file. 513 ; Make sure that CDS has valid directory; ValidateCDS requires a temp buffer 514 ; Use the one that we are going to use (ES:DI). 515 ; 0 000070A1 1E560657 SaveReg ; save all string pointers. 0 000070A5 E8[0000] invoke ValidateCDS ; poke CDS amd make everything OK 0 000070A8 5F075E1F RestoreReg ; get back pointers 0 000070AC B003 MOV AL,error_path_not_found ; Set up for possible bad path error 0 000070AE 72E9 retc ; someone failed an operation 521 ; 522 ; ThisCDS points to correct CDS. It contains the correct text of the 523 ; current directory. Copy it in. 524 ; 0 000070B0 1E56 SaveReg 0 000070B2 36C536[0000] LDS SI,[ss:ThisCDS] ; point to CDS 0 000070B7 89FB MOV BX,DI ; point to destination 0 000070B9 035C4F ADD BX,[SI + curdir_end] ; point to backup limit 529 ; LEA SI,[SI].curdir_text ; point to text 0 000070BC 8DAD8600 LEA BP,[DI+TEMPLEN] ; regenerate end of buffer 531 %IF DBCS ;AN000; 532 ;------------------------ Start of DBCS 2/13/KK 533 Kcpylp: ;AN000; 534 LODSB ;AN000; 535 invoke TestKanj ;AN000; 536 jz Notkanjf ;AN000; 537 STOSB ;AN000; 538 MOVSB ;AN000; 539 CMP BYTE PTR [SI],0 ;AN000; 540 JNZ Kcpylp ;AN000; 541 MOV AL, '\' ;AN000; 542 STOSB ;AN000; 543 JMP SHORT GetOrig ;AN000; 544 Notkanjf: ;AN000; 545 STOSB ;AN000; 546 OR AL,AL ;AN000; 547 JNZ Kcpylp ;AN000; 548 DEC DI ;AN000;; point to NUL byte 549 550 ;------------------------ End of DBCS 2/13/KK 551 %ELSE ;AN000; 0 000070C0 E8[0000] invoke FStrCpy ; copy string. ES:DI point to end 0 000070C3 4F DEC DI ; point to NUL byte 554 %ENDIF ;AN000; 555 ; 556 ; Make sure that there is a path char at end. 557 ; 0 000070C4 B05C MOV AL,'\' 0 000070C6 263845FF CMP [ES:DI-1],AL 0 000070CA 7401 JZ GetOrig 0 000070CC AA STOSB 562 ; 563 ; Now get original string. 564 ; 565 GetOrig: 0 000070CD 4F DEC DI ; point to path char 0 000070CE 5E1F RestoreReg 568 ; 569 ; BX points to the end of the root part of the CDS (at where a path char 570 ; should be) . Now, we decide whether we use this root or extend it with the 571 ; current directory. See if the input string begins with a leading \. 572 ; 0 000070D0 E8D300 CALL PathSep ; is DS:SI a path sep? 0 000070D3 7511 JNZ PathAssure ; no, DI is correct. Assure a path char 0 000070D5 08C0 OR AL,AL ; end of string? 0 000070D7 7410 JZ DoCanon ; yes, skip. 577 ; 578 ; The string does begin with a \. Reset the beginning of the canonicalization 579 ; to this root. Make sure that there is a path char there and advance the 580 ; source string over all leading \'s. 581 ; 0 000070D9 89DF MOV DI,BX ; back up to root point. 583 SkipPath: 0 000070DB AC LODSB 0 000070DC E8[0000] invoke PathChrCmp 0 000070DF 74FA JZ SkipPath 0 000070E1 4E DEC SI 0 000070E2 08C0 OR AL,AL 0 000070E4 7403 JZ DoCanon 590 ; 591 ; DS:SI start at some file name. ES:DI points at some path char. Drop one in 592 ; for yucks. 593 ; 594 PathAssure: 0 000070E6 B05C MOV AL,'\' 0 000070E8 AA STOSB 597 ; 598 ; ES:DI point to the correct spot for canonicalization to begin. 599 ; BP is the max extent to advance DI 600 ; BX is the backup limit for .. 601 ; 602 DoCanon: 0 000070E9 E85400 CALL Canonicalize ; wham. 0 000070EC 72AB retc ; badly formatted path. 605 %IF DBCS ;AN000; 606 ;--------------------- Start of DBCS 2/13/KK 607 ; Although Cononicalize has done lots of good things for us it may also have 608 ; done e5 to 05 conversion on the fisrt char following a path sep char which is 609 ; not wanted if this a remote file as this should be left for the remote 610 ; station. Check for a leading \\ in the path buffer and call TP_check05 to 611 ; reconvert if found. 612 613 MOV DI,[ss:WFP_start] ;AN000;; ES:DI points to string 614 MOV AX,WORD PTR [ES:DI] ;AN000;; Get leading 2 chars from path buffer 615 invoke PathChrCmp ;AN000;; First char a path char? 616 JNZ TP_notremote ;AN000;; Not remote if not. 617 invoke PathChrCmp ;AN000;; Second char a path char? 618 JNZ TP_notremote ;AN000;; Not remote if not 619 CALL TP_check05 ;AN000;; Remote so convert 05 back to e5 620 TP_notremote: ;AN000; 621 ;--------------------- End of DBCS 2/13/KK 622 %ENDIF 623 ; 624 ; The string has been moved to ES:DI. Reset world to DOS context, pointers 625 ; to wfp_start and do string substitution. BP is still the max position in 626 ; buffer. 627 ; 0 000070EE 161F Context DS 629 wfp_start equ WFP_Start ; NASM port label 0 000070F0 8B3E[0000] MOV DI,[wfp_start] ; DS:SI point to string 0 000070F4 C536[0000] LDS SI,[ThisCDS] ; point to CDS 632 ASSUME DS:NOTHING 633 ; LEA SI,[SI].curdir_text ; point to text 0 000070F8 E81A02 CALL PathPref ; is there a prefix? 0 000070FB 7514 JNZ DoSplice ; no, do splice 636 ; 637 ; We have a match. Check to see if we ended in a path char. 638 ; 639 %IF DBCS ;AN000; 640 ;---------------------------- Start of DBCS 2/13/KK 641 PUSH BX ;AN000; 642 MOV BX,SI ;AN000; 643 MOV SI,WORD PTR [ss:ThisCDS] ;AN000;; point to CDS 644 LOOKDUAL: ;AN000; 645 MOV AL,BYTE PTR [SI] ;AN000; 646 invoke TESTKANJ ;AN000; 647 JZ ONEINC ;AN000; 648 INC SI ;AN000; 649 INC SI ;AN000; 650 CMP SI,BX ;AN000; 651 JB LOOKDUAL ;AN000; 652 POP BX ;AN000;; Last char was KANJI, don't look back 653 JMP SHORT Pathline ;AN000;; for path sep, there isn't one. 654 ;AN000; 655 ONEINC: ;AN000; 656 INC SI ;AN000; 657 CMP SI,BX ;AN000; 658 JB LOOKDUAL ;AN000; 659 POP BX ;AN000; 660 ;------------------------ End of DBCS 2/13/KK 661 %ENDIF ;AN000; 0 000070FD 8A44FF MOV AL,[SI-1] ; last char to match 0 00007100 E8[0000] Invoke PathChrCmp ; did we end on a path char? (root) 0 00007103 740C JZ DoSplice ; yes, no current dir here. 665 Pathline: ; 2/13/KK 0 00007105 26803D00 CMP BYTE PTR [ES:DI],0 ; end at NUL? 0 00007109 7406 JZ DoSplice 0 0000710B 47 INC DI ; point to after current path char 0 0000710C 36893E[0000] MOV [ss:Curr_Dir_End],DI ; point to correct spot 670 ; 671 ; Splice the result. 672 ; 673 DoSplice: 0 00007111 161F Context DS ; back to DOSGROUP 0 00007113 8B36[0000] MOV SI,[wfp_Start] ; point to beginning of string 0 00007117 31C9 XOR CX,CX 0 00007119 F606[0000]FF TEST byte [fSplice],-1 0 0000711E 7403 JZ SkipSplice 0 00007120 E82E01 CALL Splice ; replaces in place. 680 SkipSplice: 681 ASSUME DS:NOTHING 682 ; 683 ; The final thing is to assure ourselves that a FATREAD is done on the local 684 ; device. 685 ; 0 00007123 161F Context DS 0 00007125 C43E[0000] LES DI,[ThisCDS] ; point to correct drive 0 00007129 26F745430080 TEST word [ES:DI + curdir_flags],curdir_isnet 0 0000712F 7401C3 retnz ; net, no fatread necessary 0 00007132 E30B JCXZ Done 0 00007134 E8[0000] EnterCrit critDisk 0 00007137 E8[0000] invoke FatRead_CDS 0 0000713A E8[0000] LeaveCrit critDisk 0 0000713D B003 MOV AL,error_path_not_found ; Set up for possible bad path error 0 0000713F C3 Done: return ; any errors in carry flag. 696 EndProc TransPath 697 698 BREAK 699 700 ; 701 ; Canonicalize - copy path removing . and .. entries. 702 ; 703 ; Inputs: DS:SI - point to ASCIZ string path 704 ; ES:DI - point to buffer 705 ; BX - backup limit (offset from ES) points to slash 706 ; BP - end of buffer 707 ; Outputs: Carry Set - invalid path specification: too many .., bad 708 ; syntax, etc. 709 ; Carry Clear - 710 ; DS:DI - advanced to end of string 711 ; ES:DI - advanced to end of canonicalized form after nul 712 ; Registers modified: AX CX DX (in addition to those above) 713 714 Procedure Canonicalize,NEAR 714 ****************** warning: proc Canonicalize... [-w+user] 715 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 716 ; 717 ; We copy all leading path separators. 718 ; 0 00007140 AC LODSB ; while (PathChr (*s)) 0 00007141 E8[0000] Invoke PathChrCmp 721 %IF DBCS 722 JNZ CanonDec0 ; 2/19/KK 723 %ELSE 0 00007144 7507 JNZ CanonDec 725 %ENDIF 0 00007146 39EF CMP DI,BP ; if (d > dlim) 0 00007148 7319 JAE CanonBad ; goto error; 0 0000714A AA STOSB 0 0000714B EBF3 JMP Canonicalize ; *d++ = *s++; 730 %IF DBCS ;AN000; 731 CanonDec0: ;AN000; 2/19/KK 732 ; mov cs:Temp_Var,di ;AN000; 3/31/KK 733 %ENDIF ;AN000; 734 CanonDec: 0 0000714D 4E DEC SI 736 ; 737 ; Main canonicalization loop. We come here with DS:SI pointing to a textual 738 ; component (no leading path separators) and ES:DI being the destination 739 ; buffer. 740 ; 741 CanonLoop: 742 ; 743 ; If we are at the end of the source string, then we need to check to see that 744 ; a potential drive specifier is correctly terminated with a path sep char. 745 ; Otherwise, do nothing 746 ; 0 0000714E 31C0 XOR AX,AX 0 00007150 3804 CMP [SI],AL ; if (*s == 0) { 0 00007152 751A JNZ DoComponent 750 %IF DBCS ;AN000; 751 call chk_last_colon ;AN000; 2/18/KK 752 %ELSE ;AN000; 0 00007154 26807DFF3A CMP BYTE PTR [ES:DI-1],':' ; if (d[-1] == ':') 754 %ENDIF ;AN000; 0 00007159 7505 JNZ DoTerminate 0 0000715B B05C MOV AL,'\' ; *d++ = '\'; 0 0000715D AA STOSB 0 0000715E 88E0 MOV AL,AH 759 DoTerminate: 0 00007160 AA STOSB ; *d++ = 0; 0 00007161 F8 CLC ; return (0); 0 00007162 C3 return 763 %IF DBCS ;AN000; 764 ;---------------- Start of DBCS 2/18/KK 765 chk_last_colon proc ;AN000; 766 push si ;AN000; 767 push ax ;AN000; 768 push bx ;AN000; 769 WFP_START equ WFP_Start ; NASM port label 770 mov si,[ss:WFP_START] ;AN000;;PTM. for cd .. use beginning of buf 771 cmp si,di ;AN000;; no data stored ? 772 jb CLC02 ;AN000;;PTM. for cd .. 773 inc si ;AN000;; make NZ flag 774 JMP SHORT CLC09 ;AN000; 775 CLC02: ;AN000; 776 mov bx,di ;AN000; 777 dec bx ;AN000; 778 CLC_lop: ;AN000; 779 cmp si,bx ;AN000; 780 jb CLC00 ;AN000; 781 jne CLC09 ;AN000; 782 CLC01: ;AN000; 783 CMP BYTE PTR [ES:DI-1],':' ;AN000;; if (d[-1] == ':') 784 jmp CLC09 ;AN000; 785 CLC00: ;AN000; 786 mov al,[es:si] ;AN000; 787 inc si ;AN000; 788 invoke testkanj ;AN000; 789 je CLC_lop ;AN000; 790 inc si ;AN000; 791 jmp CLC_lop ;AN000; 792 CLC09: ;AN000; 793 pop bx ;AN000; 794 pop ax ;AN000; 795 pop si ;AN000; 796 ret ;AN000; 797 chk_last_colon endp ;AN000; 798 ;---------------- Endt of DBCS 2/18/KK 799 %ENDIF ;AN000; 800 801 CanonBad: 0 00007163 E8C801 CALL ScanPathChar ; check for path chars in rest of string 0 00007166 B003 MOV AL,error_path_not_found ; Set up for bad path error 0 00007168 7402 JZ PathEnc ; path character encountered in string 0 0000716A B002 MOV AL,error_file_not_found ; Set bad file error 806 PathEnc: 0 0000716C F9 STC 0 0000716D C3 return 809 ; 810 ; We have a textual component that we must copy. We uppercase it and truncate 811 ; it to 8.3 812 ; 813 DoComponent: ; } 0 0000716E E85200 CALL CopyComponent ; if (!CopyComponent (s, d)) 0 00007171 72FA retc ; return (-1); 816 ; 817 ; We special case the . and .. cases. These will be backed up. 818 ; 0 00007173 26833D2E CMP WORD PTR [ES:DI],'.' + (0 << 8) 0 00007177 7408 JZ Skip1 0 00007179 26813D2E2E CMP WORD PTR [ES:DI],'..' 0 0000717E 750B JNZ CanonNormal 0 00007180 4F DEC DI ; d--; 0 00007181 E82C00 Skip1: CALL SkipBack ; SkipBack (); 0 00007184 B003 MOV AL,error_path_not_found ; Set up for possible bad path error 0 00007186 72E5 retc 0 00007188 EB03 JMP CanonPath ; } 0 0000718A 90 nop ; identicalise 829 ; 830 ; We have a normal path. Advance destination pointer over it. 831 ; 832 CanonNormal: ; else 0 0000718B 01CF ADD DI,CX ; d += ct; 834 ; 835 ; We have successfully copied a component. We are now pointing at a path 836 ; sep char or are pointing at a nul or are pointing at something else. 837 ; If we point at something else, then we have an error. 838 ; 839 CanonPath: 0 0000718D E81600 CALL PathSep 0 00007190 75D1 JNZ CanonBad ; something else... 842 ; 843 ; Copy the first path char we see. 844 ; 0 00007192 AC LODSB ; get the char 0 00007193 E8[0000] Invoke PathChrCmp ; is it path char? 0 00007196 75B5 JNZ CanonDec ; no, go test for nul 0 00007198 39EF CMP DI,BP ; beyond buffer end? 0 0000719A 73C7 JAE CanonBad ; yep, error. 0 0000719C AA STOSB ; copy the one byte 851 ; 852 ; Skip all remaining path chars 853 ; 854 CanonPathLoop: 0 0000719D AC LODSB ; get next byte 0 0000719E E8[0000] Invoke PathChrCmp ; path char again? 0 000071A1 74FA JZ CanonPathLoop ; yep, grab another 0 000071A3 4E DEC SI ; back up 0 000071A4 EBA8 JMP CanonLoop ; go copy component 860 EndProc Canonicalize 861 862 BREAK 863 864 ; 865 ; PathSep - look at DS:SI and see if char is / \ or NUL 866 ; Inputs: DS:SI - point to a char 867 ; Outputs: AL has char from DS:SI (/ => \) 868 ; Zero set if AL is / \ or NUL 869 ; Zero reset otherwise 870 ; Registers modified: AL 871 872 Procedure PathSep,NEAR 872 ****************** warning: proc PathSep... [-w+user] 873 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 000071A6 8A04 MOV AL,[SI] ; get the character 875 entry PathSepGotCh ; already have character 0 000071A8 08C0 OR AL,AL ; test for zero 0 000071AA 74C1 retz ; return if equal to zero (NUL) 0 000071AC E8[0000] invoke PathChrCmp ; check for path character 0 000071AF C3 return ; and return HIS determination 880 EndProc PathSep 881 882 BREAK 883 884 ; 885 ; SkipBack - look at ES:DI and backup until it points to a / \. 886 ; Inputs: ES:DI - point to a char 887 ; BX has current directory back up limit (point to a / \) 888 ; Outputs: ES:DI backed up to point to a path char 889 ; AL has char from output ES:DI (path sep if carry clear) 890 ; Carry set if illegal backup 891 ; Carry Clear if ok 892 ; Registers modified: DI,AL 893 894 Procedure SkipBack,NEAR 894 ****************** warning: proc SkipBack... [-w+user] 895 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 896 %IF DBCS ;AN000; 897 ;-------------------------- Start of DBCS 2/13/KK 898 PUSH DS ;AN000; 899 PUSH SI ;AN000; 900 PUSH CX ;AN000; 901 PUSH ES ;AN000; 902 POP DS ;AN000; 903 MOV SI,BX ;AN000;; DS:SI -> start of ES:DI string 904 MOV CX,DI ;AN000;; Limit of forward scan is input DI 905 MOV AL,[SI] ;AN000; 906 invoke PathChrCmp ;AN000; 907 JNZ SkipBadP ;AN000;; Backup limit MUST be path char 908 CMP DI,BX ;AN000; 909 JBE SkipBadP ;AN000; 910 MOV DI,BX ;AN000;; Init backup point to backup limit 911 Skiplp: ;AN000; 912 CMP SI,CX ;AN000; 913 JAE SkipOK ;AN000;; Done, DI is correct backup point 914 LODSB ;AN000; 915 invoke Testkanj ;AN000; 916 Notkanjv equ NotKanjv ; NASM port label 917 jz Notkanjv ;AN000; 918 lodsb ;AN000;; Skip over second kanji byte 919 JMP Skiplp ;AN000; 920 NotKanjv: ;AN000; 921 invoke PathChrCmp ;AN000; 922 JNZ Skiplp ;AN000;; New backup point 923 MOV DI,SI ;AN000;; DI point to path sep 924 DEC DI ;AN000; 925 jmp Skiplp ;AN000; 926 SkipOK: ;AN000; 927 MOV AL,[ES:DI] ;AN000;; Set output AL 928 CLC ;AN000;; return (0); 929 POP CX ;AN000; 930 POP SI ;AN000; 931 POP DS ;AN000; 932 return ;AN000; 933 ;AN000; 934 SkipBadP: ;AN000; 935 POP CX ;AN000; 936 POP SI ;AN000; 937 POP DS ;AN000; 938 ;-------------------------- End of DBCS 2/13/KK 939 %ELSE ;AN000; 0 000071B0 39DF CMP DI,BX ; while (TRUE) { 0 000071B2 720B JB SkipBad ; if (d < dlim) 0 000071B4 4F DEC DI ; goto err; 0 000071B5 268A05 MOV AL,[ES:DI] ; if (pathchr (*--d)) 0 000071B8 E8[0000] invoke PathChrCmp ; break; 0 000071BB 75F3 JNZ SkipBack ; } 0 000071BD F8 CLC ; return (0); 0 000071BE C3 return ; 948 %ENDIF ;AN000; 949 SkipBad: ;err: 0 000071BF B003 MOV AL,error_path_not_found ; bad path error 0 000071C1 F9 STC ; return (-1); 0 000071C2 C3 return ; 953 EndProc SkipBack 954 955 Break 956 957 ; 958 ; CopyComponent - copy a file component from a path string (DS:SI) into ES:DI 959 ; 960 ; Inputs: DS:SI - source path 961 ; ES:DI - destination 962 ; ES:BP - end of buffer 963 ; Outputs: Carry Set - too long 964 ; Carry Clear - DS:SI moved past component 965 ; CX has length of destination 966 ; Registers modified: AX,CX,DX 967 968 Procedure CopyComponent,NEAR 968 ****************** warning: proc CopyComponent... [-w+user] 969 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 970 labelsize CopyBP, word, BP 971 labelsize CopyD, dword, BP+2 972 labelsize CopyDoff, word, BP+2 973 labelsize CopyS, dword, BP+6 974 labelsize CopySoff, word, BP+6 975 labelsize CopyTemp, byte, BP+10 0 000071C3 83EC0E SUB SP,14 ; room for temp buffer 0 000071C6 1E56065755 SaveReg 0 000071CB 89E5 MOV BP,SP 0 000071CD B42E MOV AH,'.' 0 000071CF AC LODSB 0 000071D0 AA STOSB 0 000071D1 38E0 CMP AL,AH ; if ((*d++=*s++) == '.') { 0 000071D3 7518 JNZ NormalComp 0 000071D5 E8CEFF CALL PathSep ; if (!pathsep(*s)) 0 000071D8 740B JZ NulTerm 986 TryTwoDot: 0 000071DA AC LODSB ; if ((*d++=*s++) != '.' 0 000071DB AA STOSB 0 000071DC 38E0 CMP AL,AH 0 000071DE 7557 JNZ CopyBad 0 000071E0 E8C3FF CALL PathSep 0 000071E3 7552 JNZ CopyBad ; || !pathsep (*s)) 993 NulTerm: ; return -1; 0 000071E5 30C0 XOR AL,AL ; *d++ = 0; 0 000071E7 AA STOSB 0 000071E8 897606 MOV [CopySoff],SI 0 000071EB EB47 JMP SHORT GoodRet ; } 998 NormalComp: ; else { 0 000071ED 8B7606 MOV SI,[CopySoff] 0 000071F0 E8[0000] Invoke NameTrans ; s = NameTrans (s, Name1); 0 000071F3 3B7606 CMP SI,[CopySOff] ; if (s == CopySOff) 0 000071F6 743F JZ CopyBad ; return (-1); 0 000071F8 36F606[0000]FF TEST byte [ss:fSharing],-1 ; if (!fSharing) { 0 000071FE 7510 JNZ DoPack 0 00007200 80E201 AND DL,1 ; cMeta += fMeta; 0 00007203 360016[0000] ADD [ss:cMeta],DL ; if (cMeta > 0) 0 00007208 7F2D JG CopyBad ; return (-1); 0 0000720A 7504 JNZ DoPack ; else 0 0000720C 08D2 OR DL,DL ; if (cMeta == 0 && fMeta == 0) 0 0000720E 742F JZ CopyBadPath ; return (-1); 1011 DoPack: ; } 0 00007210 897606 MOV [CopySoff],SI 0 00007213 161F Context DS 0 00007215 BE[0000] MOV SI,OFFSET NAME1 wrt DOSGroup 0 00007218 8D7E0A LEA DI,[CopyTemp] 0 0000721B 57 SaveReg 0 0000721C E8[0000] Invoke PackName ; PackName (Name1, temp); 0 0000721F 5F RestoreReg 0 00007220 E8[0000] Invoke StrLen ; if (strlen(temp)+d > bp) 0 00007223 49 DEC CX 0 00007224 034E02 ADD CX,[CopyDoff] 0 00007227 3B4E00 CMP CX,[CopyBP] 0 0000722A 730B JAE CopyBad ; return (-1); 0 0000722C 89FE MOV SI,DI ; strcpy (d, temp); 0 0000722E C47E02 LES DI,[CopyD] 0 00007231 E8[0000] Invoke FStrCpy 1027 GoodRet: ; } 0 00007234 F8 CLC 0 00007235 EB0B JMP SHORT CopyEnd ; return 0; 1030 CopyBad: 0 00007237 F9 STC 0 00007238 E8F300 CALL ScanPathChar ; check for path chars in rest of string 0 0000723B B002 MOV AL,error_file_not_found ; Set up for bad file error 0 0000723D 7503 JNZ CopyEnd 1035 CopyBadPath: 0 0000723F F9 STC 0 00007240 B003 MOV AL,error_path_not_found ; Set bad path error 1038 CopyEnd: 0 00007242 5D5F075E1F RestoreReg 0 00007247 9F LAHF 0 00007248 83C40E ADD SP,14 ; reclaim temp buffer 0 0000724B E8[0000] Invoke Strlen 0 0000724E 49 DEC CX 0 0000724F 9E SAHF 0 00007250 C3 return 1046 EndProc CopyComponent,NoCheck 1047 1048 Break 1049 1050 ; 1051 ; Splice - take a string and substitute a prefix if one exists. Change 1052 ; ThisCDS to point to physical drive CDS. 1053 ; Inputs: DS:SI point to string 1054 ; NoSetDir = TRUE => exact matches with splice fail 1055 ; Outputs: DS:SI points to thisCDS 1056 ; ES:DI points to DPB 1057 ; String at DS:SI may be reduced in length by removing prefix 1058 ; and substituting drive letter. 1059 ; CX = 0 If no splice done 1060 ; CX <> 0 otherwise 1061 ; ThisCDS points to proper CDS if spliced, otherwise it is 1062 ; left alone 1063 ; ThisDPB points to proper DPB 1064 ; Registers modified: DS:SI, ES:DI, BX,AX,CX 1065 1066 Procedure Splice,NEAR 1066 ****************** warning: proc Splice... [-w+user] 1067 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 00007251 36F606[0000]FF TEST byte [ss:Splices],-1 0 00007257 746A JZ AllDone 0 00007259 36FF36[0000]36FF36 SaveReg <,> ; TmpCDS = ThisCDS 0 00007261 [0200] 0 00007263 1E56 SaveReg 0 00007265 5F07 RestoreReg 0 00007267 31C0 XOR AX,AX ; for (i=1; s = GetCDSFromDrv (i); i++) 1074 SpliceScan: 0 00007269 E8[0000] invoke GetCDSFromDrv 0 0000726C 724B JC SpliceDone 0 0000726E FEC0 INC AL 0 00007270 F744430020 TEST word [SI + curdir_flags],curdir_splice 0 00007275 74F2 JZ SpliceScan ; if ( Spliced (i) ) { 0 00007277 57 SaveReg 0 00007278 E89A00 CALL PathPref ; if (!PathPref (s, d)) 0 0000727B 7403 JZ SpliceFound ; 1083 SpliceSkip: 0 0000727D 5F RestoreReg 0 0000727E EBE9 JMP SpliceScan ; continue; 1086 SpliceFound: 0 00007280 26803D00 CMP BYTE PTR [ES:DI],0 ; if (*s || NoSetDir) { 0 00007284 7508 JNZ SpliceDo 0 00007286 36F606[0000]FF TEST byte [ss:NoSetDir],-1 0 0000728C 75EF JNZ SpliceSkip 1091 SpliceDo: 0 0000728E 89FE MOV SI,DI ; p = src + strlen (p); 0 00007290 06 SaveReg 0 00007291 1F5F RestoreReg 0 00007293 E87900 CALL TextFromDrive1 ; src = TextFromDrive1(src,i); 0 00007296 36A1[0000] MOV AX,[ss:Curr_Dir_End] 0 0000729A 09C0 OR AX,AX 0 0000729C 7808 JS NoPoke 0 0000729E 01F8 ADD AX,DI ; curdirend += src-p; 0 000072A0 29F0 SUB AX,SI 0 000072A2 36A3[0000] MOV [ss:Curr_Dir_End],AX 1102 NoPoke: 0 000072A6 803C00 CMP BYTE PTR [SI],0 ; if (*p) 0 000072A9 7503 JNZ SpliceCopy ; *src++ = '\\'; 0 000072AB B05C MOV AL,"\" 0 000072AD AA STOSB 1107 SpliceCopy: ; strcpy (src, p); 0 000072AE E8[0000] invoke FStrCpy 0 000072B1 83C404 ADD SP,4 ; throw away saved stuff 0 000072B4 80C901 OR CL,1 ; signal splice done. 0 000072B7 EB0C JMP SHORT DoSet ; return; 1112 SpliceDone: ; } 1113 ASSUME DS:NOTHING ; ThisCDS = TmpCDS; 0 000072B9 368F06[0200]368F06 RestoreReg <,> 0 000072C1 [0000] 1115 AllDone: 0 000072C3 31C9 XOR CX,CX 1117 DoSet: 0 000072C5 36C536[0000] LDS SI,[ss:ThisCDS] ; ThisDPB = ThisCDS->devptr; 0 000072CA C47C45 LES DI,[SI + curdir_devptr] 0 000072CD 36893E[0000] MOV WORD PTR [ss:ThisDPB],DI 0 000072D2 368C06[0200] MOV WORD PTR [ss:ThisDPB+2],ES 0 000072D7 C3 return 1123 EndProc Splice 1123 ****************** warning: ***** Possible stack size error in Splice ***** [-w+user] 1124 1125 Break <$NameTrans - partially process a name> 1126 1127 ; 1128 ; $NameTrans - allow users to see what names get mapped to. This call 1129 ; performs only string substitution and canonicalization, not splicing. Due 1130 ; to Transpath playing games with devices, we need to insure that the output 1131 ; has drive letter and : in it. 1132 ; 1133 ; Inputs: DS:SI - source string for translation 1134 ; ES:DI - pointer to buffer 1135 ; Outputs: 1136 ; Carry Clear 1137 ; Buffer at ES:DI is filled in with data 1138 ; ES:DI point byte after nul byte at end of dest string in buffer 1139 ; Carry Set 1140 ; AX = error_path_not_found 1141 ; Registers modified: all 1142 1143 Procedure D_NameTrans,Near 1143 ****************** warning: proc D_NameTrans... [-w+user] 1144 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 000072D8 1E560657 SaveReg 0 000072DC BF[0000] MOV DI,OFFSET OpenBuf wrt DOSGroup 0 000072DF E8DEFC CALL TransPath ; to translation (everything) 0 000072E2 5F075E1F RestoreReg 0 000072E6 7303 JNC TransOK 0 000072E8 E9[0000] transfer SYS_Ret_Err 1151 TransOK: 0 000072EB BE[0000] MOV SI,OFFSET OpenBuf wrt DOSGroup 0 000072EE 161F Context DS 1154 GotText: 0 000072F0 E8[0000] Invoke FStrCpy 0 000072F3 E9[0000] Transfer SYS_Ret_OK 1157 EndProc D_NameTrans 1158 1159 Break 1160 1161 ; 1162 ; DriveFromText - examine DS:SI and remove a drive letter, advancing the 1163 ; pointer. 1164 ; 1165 ; Inputs: DS:SI point to a text string 1166 ; Outputs: AL has drive number 1167 ; DS:SI advanced 1168 ; Registers modified: AX,SI. 1169 1170 Procedure DriveFromText,NEAR 1170 ****************** warning: proc DriveFromText... [-w+user] 1171 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING 0 000072F6 30C0 XOR AL,AL ; drive = 0; 0 000072F8 803C00 CMP BYTE PTR [SI],0 ; if (*s && 0 000072FB 74DA retz 0 000072FD 807C013A CMP BYTE PTR [SI+1],':' ; s[1] == ':') { 0 00007301 75D4 retnz 1177 %IF DBCS ;AN000; 1178 ;--------------------- Start of DBCS 2/18/KK 1179 push ax ;AN000; 1180 mov al,[si] ;AN000; 1181 invoke testkanj ;AN000; 1182 pop ax ;AN000; 1183 retnz ;AN000; 1184 ;--------------------- End of DBCS 2/18/KK 1185 %ENDIF ;AN000; 0 00007303 AD LODSW ; drive = (*s | 020) - 'a'+1; 0 00007304 0C20 OR AL,020h 0 00007306 2C60 SUB AL,'a'-1 ; s += 2; 0 00007308 75CD retnz 0 0000730A B0FF MOV AL,-1 ; nuke AL... 0 0000730C C3 return ; } 1192 EndProc DriveFromText 1193 1194 Break 1195 1196 ; 1197 ; TextFromDrive - turn AL into a drive letter: and put it at es:di with 1198 ; trailing :. TextFromDrive1 takes a 1-based number. 1199 ; 1200 ; Inputs: AL has 0-based drive number 1201 ; Outputs: ES:DI advanced 1202 ; Registers modified: AX 1203 1204 Procedure TextFromDrive,NEAR 1204 ****************** warning: proc TextFromDrive... [-w+user] 1205 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING 0 0000730D FEC0 INC AL 1207 Entry TextFromDrive1 0 0000730F 0440 ADD AL,'A'-1 ; *d++ = drive-1+'A'; 0 00007311 B43A MOV AH,":" ; strcat (d, ":"); 0 00007313 AB STOSW 0 00007314 C3 return 1212 EndProc TextFromDrive 1213 1214 Break 1215 1216 ; 1217 ; PathPref - compare DS:SI with ES:DI to see if one is the prefix of the 1218 ; other. Remember that only at a pathchar break are we allowed to have a 1219 ; prefix: A:\ and A:\FOO 1220 ; 1221 ; Inputs: DS:SI potential prefix 1222 ; ES:DI string 1223 ; Outputs: Zero set => prefix found 1224 ; DI/SI advanced past matching part 1225 ; Zero reset => no prefix, DS/SI garbage 1226 ; Registers modified: CX 1227 1228 Procedure PathPref,NEAR 1228 ****************** warning: proc PathPref... [-w+user] 0 00007315 E8[0000] Invoke DStrLen ; get length 0 00007318 49 DEC CX ; do not include nul byte 1231 %IF DBCS ;AN000; 1232 ;----------------------- Start of DBCS 2/13/KK 1233 SaveReg ;AN000;; save char register 1234 CmpLp: ;AN000; 1235 MOV AL,[SI] ;AN000; 1236 invoke Testkanj ;AN000; 1237 jz NotKanj9 ;AN000; 1238 CMPSW ;AN000; 1239 JNZ Prefix ;AN000; 1240 DEC CX ;AN000; 1241 LOOP CmpLp ;AN000; 1242 JMP SHORT NotSep ;AN000; 1243 NotKanj9: ;AN000; 1244 CMPSB ;AN000; 1245 JNZ Prefix ;AN000; 1246 LOOP CmpLp ;AN000; 1247 ;----------------------- End of DBCS 2/13/KK 1248 %ELSE ;AN000; 0 00007319 F3A6 REPZ CMPSB ; compare 0 0000731B 75F7 retnz ; if NZ then return NZ 0 0000731D 50 SaveReg ; save char register 1252 %ENDIF ;AN000; 0 0000731E 8A44FF MOV AL,[SI-1] ; get last byte to match 0 00007321 E8[0000] Invoke PathChrCmp ; is it a path char (Root!) 0 00007324 7406 JZ Prefix ; yes, match root (I hope) 1256 NotSep: ; 2/13/KK 0 00007326 268A05 MOV AL,[ES:DI] ; get next char to match 0 00007329 E87CFE CALL PathSepGotCh ; was it a pathchar? 1259 Prefix: 0 0000732C 58 RestoreReg ; get back original 0 0000732D C3 return 1262 EndProc PathPref 1263 1264 Break 1265 1266 ; 1267 ; ScanPathChar - search through the string (pointed to by DS:SI) for 1268 ; a path separator. 1269 ; 1270 ; Input: DS:SI target string (null terminated) 1271 ; Output: Zero set => path separator encountered in string 1272 ; Zero clear => null encountered 1273 ; Registers modified: SI 1274 1275 Procedure ScanPathChar,NEAR 1275 ****************** warning: proc ScanPathChar... [-w+user] 0 0000732E AC LODSB ; fetch a character 1277 %IF DBCS ;AN000; 1278 invoke TestKanj ;AN000;; 2/13/KK 1279 jz NotKanjr ;AN000;; 2/13/KK 1280 LODSB ;AN000;; 2/13/KK 1281 OR AL,AL ;AN000;; 2/13/KK 3/31/removed 1282 JNZ ScanPathChar ;AN000;; 2/13/KK 3/31/removed 1283 INC AL ;AN000;; 2/13/KK 1284 return ;AN000;; 2/13/KK 1285 ;AN000; 1286 NotKanjr: ;AN000;; 2/13/KK 1287 %ENDIF ;AN000; 0 0000732F E876FE call PathSepGotCh 0 00007332 75FA JNZ ScanPathChar ; not \, / or NUL => go back for more 0 00007334 E8[0000] invoke PathChrCmp ; path separator? 0 00007337 C3 return 1292 EndProc ScanPathChar 1293 1294 END === Trace listing source: ../DOS/file.lst 1 ; SCCSID = @(#)file.asm 1.2 85/07/23 2 ; SCCSID = @(#)file.asm 1.2 85/07/23 3 ;TITLE FILE - Pathname related system calls 4 ;NAME FILE 5 6 ; 7 ; Pathname related system calls. These will be passed direct text of the 8 ; pathname from the user. They will need to be passed through the macro 9 ; expander prior to being sent through the low-level stuff. I/O specs are 10 ; defined in DISPATCH. The system calls are: 11 ; 12 ; $Open written 13 ; $Creat written 14 ; $ChMod written 15 ; $Unlink written 16 ; $Rename written 17 ; $CreateTempFile written 18 ; $CreateNewFile written 19 ; $Extended_Open written DOS 4.00 20 ; GetIOParms written DOS 4.00 21 ; 22 ; Revision history: 23 ; 24 ; Created: MZ 4 April 1983 25 ; A000 version 4.00 Jan. 1988 26 27 [list -] === Switch to base=008400h -> "DOSCODECODE" 34 section DOSCODECODE 35 [list -] 35 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 35 ****************** warning: out: BPB.INC... [-w+user] 35 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 35 ****************** warning: out: DEVSYM.INC... [-w+user] 35 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 45 ;.sall 46 47 EXTRN DOS_OPEN:NEAR,DOS_CREATE:NEAR,DOS_Create_New:NEAR 48 49 %IFN IBMCOPYRIGHT 50 extrn Set_EXT_mode:near 51 %ENDIF 52 53 I_need WFP_Start,WORD ; pointer to beginning of expansion 54 I_Need ThisCDS,DWORD ; pointer to curdir in use 55 I_need ThisSft,DWORD ; SFT pointer for DOS_Open 56 I_need pJFN,DWORD ; temporary spot for pointer to JFN 57 I_need JFN,WORD ; word JFN for process 58 I_need SFN,WORD ; word SFN for process 59 I_Need OpenBuf,128 ; buffer for filename 60 I_Need RenBuf,128 ; buffer for filename in rename 61 I_need Sattrib,BYTE ; byte attribute to search for 62 I_need Ren_WFP,WORD ; pointer to real path 63 I_need cMeta,BYTE 64 I_need EXTERR,WORD ; extended error code 65 I_need EXTERR_LOCUS,BYTE ; Extended Error Locus 66 i_need JShare,DWORD ; share jump table 67 I_need fSharing,BYTE ; TRUE => via ServerDOSCall 68 I_need FastOpenTable,BYTE 69 I_need CPSWFLAG,BYTE ;AN000;FT. cpsw falg 70 I_need EXTOPEN_FLAG,WORD ;AN000;FT. extended file open flag 71 I_need EXTOPEN_ON,BYTE ;AN000;FT. extended open flag 72 I_need EXTOPEN_IO_MODE,WORD ;AN000;FT. IO mode 73 I_need XA_from,BYTE ;AN000;;FT. for get/set XA 74 I_need SAVE_ES,WORD ;AN000;;FT. for get/set XA 75 I_need SAVE_DI,WORD ;AN000;;FT. for get/set XA 76 I_need SAVE_DS,WORD ;AN000;;FT. for get/set XA 77 I_need SAVE_SI,WORD ;AN000;;FT. for get/set XA 78 I_need SAVE_DX,WORD ;AN000;;FT. for get/set XA 79 I_need SAVE_BX,WORD ;AN000;;FT. for get/set XA 80 I_need SAVE_CX,WORD ;AN000;;FT. for get/set XA 81 I_need NO_FILTER_DPATH,DWORD ;AN000;; pointer to original path of dest 82 I_need Temp_Var,WORD ;AN000;; 83 I_need DOS34_FLAG,WORD ;AN000;; 84 I_need Temp_Var2,WORD ;AN000;; 85 %if debug 86 I_need BugLev,WORD 87 I_need BugTyp,WORD 88 %include "bugtyp.nas" 89 %endif 90 91 BREAK <$Open - open a file from a path string> 92 93 ; 94 ; $Open - given a path name in DS:DX and an open mode in AL, access the file 95 ; and return a handle 96 ; Inputs: DS:DX - pointer to asciz name 97 ; AL - open mode 98 ; Outputs: Carry Set - AX has error code for invalid open 99 ; Carry Clear - AX has per process handle number 100 ; Registers modified: most 101 102 Procedure D_Open,NEAR 102 ****************** warning: proc D_Open... [-w+user] 103 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 104 fmt TypSysCall,LevLog,<"Open\n"> 105 fmt TypSysCall,LevArgs,<" Mode = $x file = '$S'\n">, 0 00007338 30E4 XOR AH,AH 107 Entry D_Open2 ;AN000; 0 0000733A B516 mov ch,attr_hidden+attr_system+attr_directory 0 0000733C E86802 call SetAttrib 110 DOSGroup equ DOSGROUP ; NASM port equate 111 DOS_Open equ DOS_OPEN ; NASM port label 0 0000733F B9[0000] MOV CX,OFFSET DOS_Open ; address of routine to call 0 00007342 50 SaveReg ; Save mode on stack 114 %IF DBCS ;AN000; 115 MOV word [ss:Temp_Var],0 ;AN000;KK. set variable with 0 116 %ENDIF ;AN000; 117 118 AccessFile: 119 ; 120 ; Grab a free SFT. 121 ; 122 %IF DBCS ;AN000; 123 TEST word [ss:Temp_Var],8 ;AN000;;KK. volume id bit set ;AN000; 124 JZ novol ;AN000;;KK. no ;AN000; 125 OR word [ss:DOS34_FLAG],DBCS_VOLID ;AN000;;KK. set bit for transpath ;AN000; 126 novol: ;AN000; 127 %ENDIF ;AN000; 0 00007343 E8[0000] EnterCrit critSFT 0 00007346 E8[0000] invoke SFNFree ; get a free sfn 0 00007349 E8[0000] LeaveCrit critSFT 0 0000734C 7214 JC OpenFailJ ; oops, no free sft's 0 0000734E 36891E[0000] MOV [ss:SFN],BX ; save the SFN for later 133 fmt TypAccess,LevSFN,<"AccessFile setting SFN to $x\n">, 134 ThisSFT equ ThisSft ; NASM port label 0 00007353 36893E[0000] MOV WORD PTR [ss:ThisSFT],DI ; save the SF offset 0 00007358 368C06[0200] MOV WORD PTR [ss:ThisSFT+2],ES ; save the SF segment 137 ; 138 ; Find a free area in the user's JFN table. 139 ; 0 0000735D E8[0000] invoke JFNFree ; get a free jfn 0 00007360 7303 JNC SaveJFN 142 OpenFailJ: 0 00007362 E99900 JMP OpenFail ; there were free JFNs... try SFN 144 SaveJFN: 0 00007365 36893E[0000] MOV WORD PTR [ss:pJFN],DI ; save the jfn offset 0 0000736A 368C06[0200] MOV WORD PTR [ss:pJFN+2],ES ; save the jfn segment 0 0000736F 36891E[0000] MOV [ss:JFN],BX ; save the jfn itself 148 ; 149 ; We have been given an JFN. We lock it down to prevent other tasks from 150 ; reusing the same JFN. 151 ; 0 00007374 368B1E[0000] MOV BX,[ss:SFN] 0 00007379 26881D MOV [ES:DI],BL ; assign the JFN 0 0000737C 89D6 MOV SI,DX ; get name in appropriate place 0 0000737E BF[0000] MOV DI,OFFSET OpenBuf wrt DOSGroup ; appropriate buffer 0 00007381 51 SaveReg ; save routine to call 0 00007382 E8[0000] invoke TransPath ; convert the path 0 00007385 5B RestoreReg ; restore routine to call 0 00007386 36C536[0000] LDS SI,[ss:ThisSFT] 160 ASSUME DS:NOTHING 0 0000738B 720A JC OpenCleanJ ; no error, go and open file 0 0000738D 36803E[0000]FF CMP byte [ss:cMeta],-1 0 00007393 7405 JZ SetSearch 0 00007395 B002 MOV AL,error_file_not_found ; no meta chars allowed 165 OpenCleanJ: 0 00007397 EB56 JMP OpenClean 0 00007399 90 nop ; identicalise 168 SetSearch: 0 0000739A 58 RestoreReg ; Mode (Open), Attributes (Create) 170 ; 171 ; We need to get the new inheritance bits. 172 ; 0 0000739B 31C9 xor cx,cx 0 0000739D 81FB[0000] CMP BX,OFFSET DOS_OPEN 0 000073A1 7509 JNZ DoOper 0 000073A3 A880 TEST AL,sharing_no_inherit ; look for no inher 0 000073A5 7405 JZ DoOper 0 000073A7 247F AND AL,07Fh ; mask off inherit bit 0 000073A9 B90010 MOV CX,sf_no_inherit 180 DoOper: 0 000073AC C744020000 MOV word [SI + sf_mode],0 ; initialize mode field to 0 182 SF_mft equ sf_MFT ; NASM port equate 0 000073B1 C744330000 MOV word [SI + SF_mft],0 ; clean out sharing info 184 ; 185 ;------------------------------------------------------------HKN 8/7/88 186 ; Check if this is an extended open. If so you must set the 187 ; modes in sf_mode. Call Set_EXT_mode to do all this. See 188 ; Set_EXT_mode in creat.asm 189 ; 190 %IFN IBMCOPYRIGHT 191 0 000073B6 06 push es ; set up es:di to point to SFT 0 000073B7 57 push di 0 000073B8 1E push ds 0 000073B9 07 pop es 0 000073BA 56 push si 0 000073BB 5F pop di 0 000073BC E8[0000] call Set_EXT_mode 0 000073BF 5F pop di 0 000073C0 07 pop es 201 202 %ENDIF 203 204 ;----------------------------------------------------------------------- 205 0 000073C1 161F Context DS 0 000073C3 51 SaveReg 0 000073C4 FFD3 CALL BX ; blam! 0 000073C6 59 RestoreReg 0 000073C7 C536[0000] LDS SI,[ThisSFT] 211 ASSUME DS:NOTHING 0 000073CB 721A JC OpenE2 ;AN000;FT. chek extended open hooks first 213 ; 214 ; The SFT was successfully opened. Remove busy mark. 215 ; 216 OpenOK: 217 ASSUME DS:NOTHING 218 ; MOV AL,[SI].sf_attr_hi ;AN000;FT. save file type for EXEC 219 ; MOV BYTE PTR [Temp_Var2],AL ;AN000;FT. 0 000073CD C7040100 MOV word [SI + sf_ref_count],1 0 000073D1 094C05 OR [SI + sf_flags],CX ; set no inherit bit if necessary 222 ; 223 ; If the open mode is 70, we scan the system for other SFT's with the same 224 ; contents. If we find one, then we can 'collapse' thissft onto the already 225 ; opened one. Otherwise we use this new one. We compare uid/pid/mode/mft 226 ; 227 ; Since this is only relevant on sharer systems, we stick this code into the 228 ; sharer. 229 ; 0 000073D4 36A1[0000] MOV AX,[ss:JFN] 231 %if installed 0 000073D8 36FF1E[3000] Call far [ss:JShare + 12 * 4] 233 %else 234 Call ShCol 235 %endif 236 fmt TypAccess,LevSFN,<"AccessFile setting SFN to -1\n"> 0 000073DD 36C706[0000]FFFF MOV word [ss:SFN],-1 ; clear out sfn pointer 238 fmt TypSysCall,LevLog,<"Open/CreateXX: return $x\n">, 0 000073E4 E9[0000] transfer Sys_Ret_OK ; bye with no errors 240 ;Extended Open hooks check 241 OpenE2: ;AN000;;EO. 0 000073E7 83F857 CMP AX,error_invalid_parameter ;AN000;;EO. IFS extended open ? 0 000073EA 7504 JNZ OpenE ;AN000;;EO. no. 0 000073EC EB12 JMP OpenCritLeave ;AN000;;EO. keep handle 0 000073EE 90 nop ; identicalise 246 247 ;Extended Open hooks check 248 ; 249 ; AL has error code. Stack has argument to dos_open/dos_create. 250 ; 251 OpenClean: 252 fmt TypSysCall,LevLog,<"Return value from transpath $x\n">, 0 000073EF 5B RestoreReg ; clean off stack 254 OpenE: 255 SF_Ref_Count equ sf_ref_count ; NASM port equate 0 000073F0 C7040000 MOV word [SI + SF_Ref_Count],0 ; release SFT 0 000073F4 36C536[0000] LDS SI,[ss:pJFN] 0 000073F9 C604FF MOV BYTE PTR [SI],0FFh ; free the SFN... 0 000073FC EB02 JMP SHORT OpenCritLeave 260 261 OpenFail: 0 000073FE FB STI 0 000073FF 59 RestoreReg ; Clean stack 264 OpenCritLeave: 0 00007400 36C706[0000]FFFF MOV word [ss:SFN],-1 ; remove mark. 266 fmt TypSysCall,LevLog,<"Open/CreateXX: error $x\n">, 267 ;; File Tagging DOS 4.00 0 00007407 36833E[0000]25 CMP word [ss:EXTERR],error_Code_Page_Mismatched ;AN000;;FT. code page mismatch 0 0000740D 7503 JNZ NORERR ;AN000;;FT. no 0 0000740F E9[0000] transfer From_GetSet ;AN000;;FT. yes 271 NORERR: ;AN000; 272 273 ;; File Tagging DOS 4.00 0 00007412 E9[0000] transfer Sys_Ret_Err ; no free, return error 275 276 EndProc D_Open 276 ****************** warning: ***** Possible stack size error in D_Open ***** [-w+user] 277 278 BREAK <$Creat - create a brand-new file> 279 280 ; 281 ; $Creat - create the directory entry specified in DS:DX and give it the 282 ; initial attributes contained in CX 283 ; Inputs: DS:DX - ASCIZ path name 284 ; CX - initial attributes 285 ; Outputs: Carry set - AX has error code 286 ; Carry reset - AX has handle 287 ; Registers modified: all 288 289 Procedure D_Creat,NEAR 289 ****************** warning: proc D_Creat... [-w+user] 290 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 291 fmt TypSysCall,LevLog,<"Create\n"> 292 fmt TypSysCall,LevArgs,<" Att = $x file = '$S'\n">, 293 %IF DBCS ;AN000; 294 MOV [ss:Temp_Var],CX ;AN000;KK. set variable with attribute ;AN000; 295 %ENDIF ;AN000; 0 00007415 51 SaveReg ; Save attributes on stack 297 DOS_Create equ DOS_CREATE ; NASM port label 0 00007416 B9[0000] MOV CX,OFFSET DOS_Create ; routine to call 299 AccessSet: 300 SAttrib equ Sattrib ; NASM port label 0 00007419 36C606[0000]06 mov byte [ss:SAttrib],attr_hidden+attr_system 0 0000741F E921FF JMP AccessFile ; use good ol' open 303 EndProc D_Creat 303 ****************** warning: ***** Possible stack size error in D_Creat ***** [-w+user] 304 305 BREAK <$CHMOD - change file attributes> 306 ; 307 ; Assembler usage: 308 ; LDS DX, name 309 ; MOV CX, attributes 310 ; MOV AL,func (0=get, 1=set) 311 ; INT 21h 312 ; Error returns: 313 ; AX = error_path_not_found 314 ; AX = error_access_denied 315 ; 316 317 procedure D_CHMOD,NEAR 317 ****************** warning: proc D_CHMOD... [-w+user] 318 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 00007422 BF[0000] MOV DI,OFFSET OpenBuf wrt DOSGroup ; appropriate buffer 0 00007425 5051 SaveReg ; save function and attributes 0 00007427 89D6 MOV SI,DX ; get things in appropriate places 0 00007429 E8[0000] invoke TransPathSet ; get correct path 0 0000742C 5958 RestoreReg ; and get function and attrs back 0 0000742E 7233 JC ChModErr ; errors get mapped to path not found 0 00007430 161F Context DS ; set up for later possible calls 0 00007432 803E[0000]FF CMP byte [cMeta],-1 0 00007437 752A JNZ ChModErr 0 00007439 C606[0000]16 MOV byte [SAttrib],attr_hidden+attr_system+attr_directory 0 0000743E 2C01 SUB AL,1 ; fast way to discriminate 0 00007440 720B JB ChModGet ; 0 -> go get value 0 00007442 7416 JZ ChModSet ; 1 -> go set value 332 errLoc_Unk equ errLOC_Unk ; NASM port equate 0 00007444 C606[0000]01 MOV byte [EXTERR_LOCUS],errLoc_Unk ; Extended Error Locus 0 00007449 B001EBC5 error error_invalid_function ; bad value 335 ChModGet: 0 0000744D E8[0000] invoke Get_File_Info ; suck out the ol' info 337 ChModE equ ChmodE ; NASM port label 0 00007450 7213 JC ChModE ; error codes are already set for ret 0 00007452 E8[0000] invoke Get_User_stack ; point to user saved vaiables 340 User_CX equ user_CX ; NASM port equate 0 00007455 894404 MOV [SI + User_CX],AX ; return the attributes 0 00007458 EB8A transfer Sys_Ret_OK ; say sayonara 343 ChModSet: 0 0000745A 89C8 MOV AX,CX ; get attrs in position 0 0000745C E8[0000] invoke Set_File_Attribute ; go set 0 0000745F 7204 JC ChModE ; errors are set 0 00007461 EBF5 transfer Sys_Ret_OK 348 ChModErr: 0 00007463 B003 mov al,error_path_not_found 350 ChmodE: 0 00007465 EBE4 Transfer SYS_RET_ERR 352 EndProc D_ChMod 353 354 BREAK <$UNLINK - delete a file entry> 355 ; 356 ; Assembler usage: 357 ; LDS DX, name 358 ; IF VIA SERVER DOS CALL 359 ; MOV CX,SEARCH_ATTRIB 360 ; MOV AH, Unlink 361 ; INT 21h 362 ; 363 ; Error returns: 364 ; AX = error_file_not_found 365 ; = error_access_denied 366 ; 367 368 procedure D_UNLINK,NEAR 368 ****************** warning: proc D_UNLINK... [-w+user] 369 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 00007467 51 SaveReg ; Save possible CX input parm 0 00007468 89D6 MOV SI,DX ; Point at input string 0 0000746A BF[0000] MOV DI,OFFSET OpenBuf wrt DOSGroup ; temp spot for path 0 0000746D E8[0000] invoke TransPathSet ; go get normalized path 0 00007470 59 RestoreReg 0 00007471 72F0 JC ChModErr ; badly formed path 0 00007473 36803E[0000]FF CMP byte [ss:cMeta],-1 ; meta chars? 0 00007479 750E JNZ NotFound 0 0000747B 161F Context DS 0 0000747D B506 mov ch,attr_hidden+attr_system ; unlink appropriate files 0 0000747F E82501 call SetAttrib 0 00007482 E8[0000] invoke DOS_Delete ; remove that file 0 00007485 7204 JC UnlinkE ; error is there 383 384 0 00007487 EBD8 transfer Sys_Ret_OK ; okey doksy 386 NotFound: 0 00007489 B003 MOV AL,error_path_not_found 388 UnlinkE: 0 0000748B EBD8 transfer Sys_Ret_Err ; bye 390 EndProc D_UnLink 391 392 BREAK <$RENAME - move directory entries around> 393 ; 394 ; Assembler usage: 395 ; LDS DX, source 396 ; LES DI, dest 397 ; IF VIA SERVER DOS CALL 398 ; MOV CX,SEARCH_ATTRIB 399 ; MOV AH, Rename 400 ; INT 21h 401 ; 402 ; Error returns: 403 ; AX = error_file_not_found 404 ; = error_not_same_device 405 ; = error_access_denied 406 407 procedure D_RENAME,NEAR 407 ****************** warning: proc D_RENAME... [-w+user] 408 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 0 0000748D 511E52 SaveReg ; save source and possible CX arg 0 00007490 06 PUSH ES 0 00007491 1F POP DS ; move dest to source 0 00007492 89FE MOV SI,DI ; save for offsets 0 00007494 BF[0000] MOV DI,OFFSET RenBuf wrt DOSGroup 414 0 00007497 368936[0000] MOV WORD PTR [ss:NO_FILTER_DPATH],SI ;AN000;;IFS. save them for IFS 0 0000749C 368C1E[0200] MOV WORD PTR [ss:NO_FILTER_DPATH+2],DS ;AN000;;IFS. 417 0 000074A1 E8[0000] invoke TransPathSet ; munge the paths 0 000074A4 36FF36[0000] PUSH word [ss:WFP_Start] ; get pointer 0 000074A9 368F06[0000] POP word [ss:Ren_WFP] ; stash it 0 000074AE 5E1F59 RestoreReg ; get back source and possible CX arg 0 000074B1 72B0 epjc2: JC ChModErr ; get old error 0 000074B3 36803E[0000]FF CMP byte [ss:cMeta],-1 0 000074B9 75CE JNZ NotFound 0 000074BB 51 SaveReg ; Save possible CX arg 0 000074BC BF[0000] MOV DI,OFFSET OpenBuf wrt DOSGroup ; appropriate buffer 0 000074BF E8[0000] invoke TransPathSet ; wham 0 000074C2 59 RestoreReg 429 EPJC2 equ epjc2 ; NASM port label 0 000074C3 72EC JC EPJC2 0 000074C5 161F Context DS 0 000074C7 803E[0000]FF CMP byte [cMeta],-1 0 000074CC 72BB JB NotFound 434 435 THISCDS equ ThisCDS ; NASM port label 0 000074CE FF36[0000] PUSH WORD PTR [THISCDS] ;AN000;;MS.save thiscds 0 000074D2 FF36[0200] PUSH WORD PTR [THISCDS+2] ;AN000;;MS. 0 000074D6 BF[0000] MOV DI,OFFSET OpenBuf wrt DOSGROUP ;AN000;;MS. 0 000074D9 16 PUSH SS ;AN000;;MS. 0 000074DA 07 POP ES ;AN000;;MS.es:di-> source 0 000074DB 30C0 XOR AL,AL ;AN000;;MS.scan all CDS 442 rnloop: ;AN000; 0 000074DD E8[0000] invoke GetCDSFromDrv ;AN000;;MS. 0 000074E0 7210 JC dorn ;AN000;;MS. end of CDS 0 000074E2 E8[0000] invoke StrCmp ;AN000;;MS. current dir ? 0 000074E5 7404 JZ rnerr ;AN000;;MS. yes 0 000074E7 FEC0 INC AL ;AN000;;MS. next 0 000074E9 EBF2 JMP rnloop ;AN000;;MS. 449 rnerr: ;AN000; 0 000074EB 83C404 ADD SP,4 ;AN000;;MS. pop thiscds 0 000074EE B010EB99 error error_current_directory ;AN000;;MS. 452 dorn: ;AN000; 0 000074F2 368F06[0200] POP WORD PTR [SS:THISCDS+2] ;AN000;;MS. 0 000074F7 368F06[0000] POP WORD PTR [SS:THISCDS] ;AN000;;MS. 0 000074FC 161F Context DS 0 000074FE B516 mov ch,attr_directory+attr_hidden+attr_system; rename appropriate files 0 00007500 E8A400 call SetAttrib 0 00007503 E8[0000] invoke DOS_Rename ; do the deed 0 00007506 7283 JC UnlinkE ; errors 460 461 0 00007508 E9[0000] transfer Sys_Ret_OK 463 EndProc D_Rename 464 465 Break <$CreateNewFile - Create a new directory entry> 466 467 ; 468 ; CreateNew - Create a new directory entry. Return a file handle if there 469 ; was no previous directory entry, and fail if a directory entry with 470 ; the same name existed previously. 471 ; 472 ; Inputs: DS:DX point to an ASCIZ file name 473 ; CX contains default file attributes 474 ; Outputs: Carry Clear: 475 ; AX has file handle opened for read/write 476 ; Carry Set: 477 ; AX has error code 478 ; Registers modified: All 479 480 Procedure D_CreateNewFile,NEAR 480 ****************** warning: proc D_CreateNewFile... [-w+user] 481 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 482 fmt TypSysCall,LevLog,<"CreateNew\n"> 483 fmt TypSysCall,LevArgs,<" Att = $x file = '$S'\n">, 484 %IF DBCS ;AN000; 485 MOV [ss:Temp_Var],CX ;AN000;KK. set variable with attribute 486 %ENDIF ;AN000; 0 0000750B 51 SaveReg ; Save attributes on stack 0 0000750C B9[0000] MOV CX,OFFSET DOS_Create_New; routine to call 0 0000750F E907FF JMP AccessSet ; use good ol' open 490 EndProc D_CreateNewFile 490 ****************** warning: ***** Possible stack size error in D_CreateNewFile ***** [-w+user] 491 492 Break 493 494 ; 495 ; HexToAsciz - used to convert register into a hex number. 496 ; 497 ; Inputs: AX contains the number 498 ; ES:DI point to destination 499 ; Outputs: ES:DI updated 500 ; Registers modified: DI,CX 501 502 Procedure HexToAsciz,NEAR 502 ****************** warning: proc HexToAsciz... [-w+user] 0 00007512 B90400 mov cx,4 ; 4 digits in AX 504 GetDigit: 0 00007515 51 SaveReg ; preserve count 0 00007516 B104 mov cl,4 0 00007518 D3C0 ROL AX,CL ; move leftmost nibble into rightmost 0 0000751A 50 SaveReg ; preserve remainder of digits 0 0000751B 240F AND AL,0Fh ; grab low nibble 0 0000751D 0430 ADD AL,'0' ; turn into digit 0 0000751F 3C39 CMP AL,'9' ; bigger than 9 0 00007521 7602 JBE DoStore ; no, stash it 0 00007523 0407 ADD AL,'A'-'0'-10 ; convert into uppercase letter 514 DoStore: 0 00007525 AA STOSB ; drop in the character 0 00007526 5859 RestoreReg ; regain the number and count 0 00007528 E2EB loop GetDigit ; while there's more digits, go do 'em 0 0000752A C3 return 519 EndProc HexToAsciz 520 521 Break <$CreateTempFile - create a unique name> 522 523 ; 524 ; $CreateTemp - given a directory, create a unique name in that directory. 525 ; Method used is to get the current time, convert to a name and attempt 526 ; a create new. Repeat until create new succeeds. 527 ; 528 ; Inputs: DS:DX point to a null terminated directory name. 529 ; CX contains default attributes 530 ; Outputs: Unique name is appended to DS:DX directory. 531 ; AX has handle 532 ; Registers modified: all 533 534 Procedure D_CreateTempFile,NEAR 534 ****************** warning: proc D_CreateTempFile... [-w+user] 535 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup 536 fmt TypSysCall,LevLog,<"CreateTmp\n"> 537 fmt TypSysCall,LevArgs,<" Att = $x dir = '$S'\n">, 538 PUBLIC FILE001S,FILE001E 539 FILE001S: 540 LocalVar EndPtr,DWORD 541 LocalVar FilPtr,DWORD 542 LocalVar Attr,WORD 543 FILE001E: 0 0000752B 5589E583EC0A Enter 0 00007531 F7C1D8FF TEST CX,~ attr_changeable 0 00007535 7405 JZ OKatts ; Ok if no non-changeable bits set 547 ; 548 ; We need this "hook" here to detect these cases (like user sets one both of 549 ; vol_id and dir bits) because of the structure of the or $CreateNewFile loop 550 ; below. The code loops on error_access_denied, but if one of the non 551 ; changeable attributes is specified, the loop COULD be infinite or WILL be 552 ; infinite because CreateNewFile will fail with access_denied always. Thus we 553 ; need to detect these cases before getting to the loop. 554 ; 0 00007537 B80500 MOV AX,error_access_denied 0 0000753A EB5F JMP SHORT SETTMPERR 557 558 OKatts: 0 0000753C 894EF6 MOV [attr],CX ; save attribute 0 0000753F 8956F8 MOV [FilPtrL],DX ; pointer to file 0 00007542 8C5EFA MOV [FilPtrH],DS 0 00007545 8C5EFE MOV [EndPtrH],DS ; seg pointer to end of dir 0 00007548 1E PUSH DS 0 00007549 07 POP ES ; destination for nul search 0 0000754A 89D7 MOV DI,DX 0 0000754C 89F9 MOV CX,DI 0 0000754E F7D9 NEG CX ; number of bytes remaining in segment 568 %IF DBCS ;AN000; 569 Kloop: ;AN000;; 2/13/KK 570 MOV AL, BYTE PTR [ES:DI] ;AN000;; 2/13/KK 571 INC DI ;AN000;; 2/13/KK 572 OR AL,AL ;AN000;; 2/13/KK 573 JZ GOTEND ;AN000;; 2/13/KK 574 invoke testkanj ;AN000;; 2/13/KK 575 jz Kloop ;AN000;; 2/13/KK 576 inc di ;AN000;; Skip over second kanji byte 2/13/KK 577 CMP BYTE PTR [ES:DI],0 ;AN000;; 2/13/KK 578 JZ STOREPTH ;AN000; When char before NUL is sec Kanji byte 579 ;AN000; do not look for path char. 2/13/KK 580 jmp Kloop ;AN000; 2/13/KK 581 GOTEND: ;AN000; 2/13/KK 582 %ELSE ;AN000; 0 00007550 09C9 OR CX,CX ;AN000;MS. cx=0 ? ds:dx on segment boundary 0 00007552 7503 JNZ okok ;AN000;MS. no 0 00007554 B9FFFF MOV CX,-1 ;AN000;MS. 586 okok: ;AN000; 0 00007557 31C0 XOR AX,AX ;AN000; 0 00007559 F2AE REPNZ SCASB ;AN000; 589 %ENDIF ;AN000; 0 0000755B 4F DEC DI ; point back to the null 0 0000755C 268A45FF MOV AL,[ES:DI-1] ; Get char before the NUL 0 00007560 E8[0000] invoke PathChrCmp ; Is it a path separator? 0 00007563 7403 JZ SETENDPTR ; Yes 594 STOREPTH: 0 00007565 B05C MOV AL,'\' 0 00007567 AA STOSB ; Add a path separator (and INC DI) 597 SETENDPTR: 0 00007568 897EFC MOV [EndPtrL],DI ; pointer to the tail 599 CreateLoop: 0 0000756B 161F Context DS ; let ReadTime see variables 0 0000756D 55 SaveReg 0 0000756E E8[0000] invoke ReadTime ; go get time 0 00007571 5D RestoreReg 604 ; 605 ; Time is in CX:DX. Go drop it into the string. 606 ; 0 00007572 C47EFC les di,[EndPtr] ; point to the string 0 00007575 89C8 mov ax,cx 0 00007577 E898FF call HexToAsciz ; store upper word 0 0000757A 89D0 mov ax,dx 0 0000757C E893FF call HexToAsciz ; store lower word 0 0000757F 30C0 xor al,al 0 00007581 AA STOSB ; nul terminate 0 00007582 C556F8 LDS DX,[FilPtr] ; get name 615 ASSUME DS:NOTHING 0 00007585 8B4EF6 MOV CX,[Attr] ; get attr 0 00007588 55 SaveReg 0 00007589 E87FFF CALL D_CreateNewFile ; try to create a new file 0 0000758C 5D RestoreReg 0 0000758D 730D JNC CreateDone ; failed, go try again 621 ; 622 ; The operation failed and the error has been mapped in AX. Grab the extended 623 ; error and figure out what to do. 624 ; 625 ExtErr equ EXTERR ; NASM port label 0 0000758F 36A1[0000] mov ax,[ss:ExtErr] 0 00007593 3C50 cmp al,error_file_exists 0 00007595 74D4 jz CreateLoop ; file existed => try with new name 0 00007597 3C05 cmp al,error_access_denied 0 00007599 74D0 jz CreateLoop ; access denied (attr mismatch) 631 632 ; CMP AL,error_file_exists ; certain errors cause failure 633 ; JZ CreateLoop 634 ; CMP AL,error_access_denied 635 ; JNZ SETTMPERR ; Error out 636 ; CMP [EXTERR],error_cannot_make ; See if it's REALLY an att mismatch 637 ; JNZ CreateLoop ; It was, try again 638 ; MOV AL,error_cannot_make ; Return this "extended" error 639 640 SETTMPERR: 0 0000759B F9 STC 642 CreateDone: 0 0000759C 89EC5D Leave 0 0000759F 7203 JC CreateFail 0 000075A1 E9[0000] transfer Sys_Ret_OK ; success! 646 CreateFail: 0 000075A4 E9[0000] transfer Sys_Ret_Err 648 EndProc D_CreateTempFile 649 650 Break 651 652 ; 653 ; SetAttrib will set the search attribute (SAttrib) either to the normal 654 ; (CH) or to the value in CL if the current system call is through 655 ; serverdoscall. 656 ; 657 ; Inputs: fSharing == FALSE => set sattrib to CH 658 ; fSharing == TRUE => set sattrib to CL 659 ; Outputs: none 660 ; Registers changed: CX 661 662 procedure SetAttrib,NEAR 662 ****************** warning: proc SetAttrib... [-w+user] 663 assume ds:nothing,es:nothing 0 000075A7 36F606[0000]FF test byte [ss:fSharing],-1 0 000075AD 7502 jnz Set 0 000075AF 88E9 mov cl,ch 667 Set: 0 000075B1 36880E[0000] mov [ss:SAttrib],cl 0 000075B6 C3 return 670 EndProc SetAttrib 671 672 673 Break 674 675 ; Input: AL= 0 reserved AH=6CH 676 ; BX= mode 677 ; CL= create attribute CH=search attribute (from server) 678 ; DX= flag 679 ; DS:SI = file name 680 ; ES:DI = parm list 681 ; DD SET EA list (-1) null 682 ; DW n parameters 683 ; DB type (TTTTTTLL) 684 ; DW IOMODE 685 ; Function: Extended Open 686 ; Output: carry clear 687 ; AX= handle 688 ; CX=1 file opened 689 ; 2 file created/opened 690 ; 3 file replaced/opened 691 ; carry set: AX has error code 692 ; 693 694 695 procedure D_Extended_Open,NEAR ;AN000; 695 ****************** warning: proc D_Extended_Open... [-w+user] 696 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; 697 0 000075B7 36C606[0000]00 MOV byte [ss:XA_from],0 ;AN000;EO. init for set XA 0 000075BD 368916[0000] MOV [ss:EXTOPEN_FLAG],DX ;AN000;EO. save ext. open flag 0 000075C2 36C706[0000]0000 MOV word [ss:EXTOPEN_IO_MODE],0 ;AN000;EO. initialize IO mode 0 000075C9 F7C200FE TEST DX,reserved_bits_mask ;AN000;EO. reserved bits 0 ? 0 000075CD 7545 JNZ ext_inval2 ;AN000;EO. no 0 000075CF 88D4 MOV AH,DL ;AN000;EO. make sure flag is right 0 000075D1 80FA00 CMP DL,0 ;AN000;EO. all fail ? 0 000075D4 743E JZ ext_inval2 ;AN000;EO. yes, error 0 000075D6 80E20F AND DL,exists_mask ;AN000;EO. get exists action byte 0 000075D9 80FA02 CMP DL,2 ;AN000;EO, > 02 0 000075DC 7736 JA ext_inval2 ;AN000;EO. yes ,error 0 000075DE 80E4F0 AND AH,not_exists_mask ;AN000;EO. get no exists action byte 0 000075E1 80FC10 CMP AH,10H ;AN000;EO. > 10 0 000075E4 772E JA ext_inval2 ;AN000;EO. yes error 712 713 ; CMP DI,-1 ;AN000;EO. null parm list 714 ; JZ no_parm ;AN000;EO. yes 715 ; ;AN000;EO 716 ; PUSH CX ;AN000;EO. 717 ; ;AN000;EO. 718 ; MOV CX,[ES:DI.EXT_NUM_OF_PARM];AN000;EO. get number of parms 719 ; OR CX,CX ;AN000;EO. 0 pamrs ? 720 ; JZ parmend ;AN000;EO. yes 721 ; PUSH SI ;AN000;EO. 722 ; PUSH DS ;AN000;EO. 723 ; MOV SI,DI ;AN000;EO. 724 ; ADD SI,size EXT_OPEN_PARM ;AN000;EO. position to 1st parm 725 ; PUSH ES ;AN000;EO. 726 ; POP DS ;AN000;EO. ds:si -> parm list 727 ; CALL GetIOParms ;AN000;EO. 728 ; POP DS ;AN000;EO. 729 ; POP SI ;AN000;EO. 730 ;parmend: ;AN000;EO 731 ; POP CX ;AN000;EO. restore CX 732 ;no_parm: ;AN000;EO. 0 000075E6 368C06[0000] MOV [ss:SAVE_ES],ES ;AN000;EO. save API parms 0 000075EB 36893E[0000] MOV [ss:SAVE_DI],DI ;AN000;EO. 0 000075F0 36FF36[0000] PUSH word [ss:EXTOPEN_FLAG] ;AN000;EO. 0 000075F5 368F06[0000] POP word [ss:SAVE_DX] ;AN000;EO. 0 000075FA 36890E[0000] MOV [ss:SAVE_CX],CX ;AN000;EO. 0 000075FF 36891E[0000] MOV [ss:SAVE_BX],BX ;AN000;EO. 0 00007604 368C1E[0000] MOV [ss:SAVE_DS],DS ;AN000;EO. 0 00007609 368936[0000] MOV [ss:SAVE_SI],SI ;AN000;EO. 0 0000760E 89F2 MOV DX,SI ;AN000;EO. ds:dx points to file name 0 00007610 89D8 MOV AX,BX ;AN000;EO. ax= mode 743 744 ; TEST [EXTOPEN_FLAG],no_code_page_check ;AN000;EO. check no code page 745 ; JNZ no_cdpg_chk ;AN000;;EO. no 0 00007612 EB0B JMP SHORT goopen2 ;AN000;;EO. do nromal 747 ext_inval2: ;AN000;;EO. 748 error_Invalid_Function equ error_invalid_function ; NASM port equate 0 00007614 B001EB8C error error_Invalid_Function ;AN000;EO.. invalid function 750 ext_inval_parm: ;AN000;EO.. 0 00007618 59 POP CX ;AN000;EO.. pop up satck 0 00007619 5E POP SI ;AN000;EO.. 753 error_Invalid_data equ error_invalid_data ; NASM port equate 0 0000761A B00DEBF8 error error_Invalid_data ;AN000;EO.. invalid parms 755 error_return: ;AN000;EO. 0 0000761E C3 ret ;AN000;EO.. return with error 757 ;no_cdpg_chk: EO. 758 ; MOV [CPSWFLAG],0 ;AN000;EO.. set CPSW flag off 759 goopen2: ;AN000; 0 0000761F F7C30020 TEST BX,int_24_error ;AN000;EO.. disable INT 24 error ? 0 00007623 7406 JZ goopen ;AN000;EO.. no 762 EXT_OPEN_I24_OFF equ ext_open_I24_off ; NASM port equate 0 00007625 36800E[0000]02 OR byte [ss:EXTOPEN_ON],EXT_OPEN_I24_OFF ;AN000;EO.. set bit to disable 764 765 goopen: ;AN000; 766 EXT_OPEN_ON equ ext_open_on ; NASM port equate 0 0000762B 36800E[0000]01 OR byte [ss:EXTOPEN_ON],EXT_OPEN_ON ;AN000;EO.. set Extended Open active 0 00007631 368126[0000]FF00 AND word [ss:EXTOPEN_FLAG],0FFH ;AN000;EO.create new ? 0 00007638 36833E[0000]10 CMP word [ss:EXTOPEN_FLAG],ext_exists_fail + ext_nexists_create ;AN000;FT. 0 0000763E 7520 JNZ chknext ;AN000;;EO. no 0 00007640 E8C8FE invoke D_CreateNewFile ;AN000;;EO. yes 0 00007643 72D9 JC error_return ;AN000;;EO. error 0 00007645 36803E[0000]00 CMP byte [ss:EXTOPEN_ON],0 ;AN000;;EO. IFS does it 0 0000764B 7410 JZ ok_return2 ;AN000;;EO. yes 0 0000764D 36C706[0000]0200 MOV word [ss:EXTOPEN_FLAG],action_created_opened ;AN000;EO. creted/opened 0 00007654 36C606[0000]02 MOV byte [ss:XA_from],By_Create ;AN000;;EO. for set xa 0 0000765A E99500 JMP setXAttr ;AN000;;EO. set XAs 778 ok_return2: 0 0000765D E9[0000] transfer SYS_RET_OK ;AN000;;EO. 780 chknext: 0 00007660 36F706[0000]0100 TEST word [ss:EXTOPEN_FLAG],ext_exists_open ;AN000;;EO. exists open 0 00007667 7532 JNZ exist_open ;AN000;;EO. yes 0 00007669 E8A9FD invoke D_Creat ;AN000;;EO. must be replace open 0 0000766C 72B0 JC error_return ;AN000;;EO. return with error 0 0000766E 36803E[0000]00 CMP byte [ss:EXTOPEN_ON],0 ;AN000;;EO. IFS does it 0 00007674 74E7 JZ ok_return2 ;AN000;;EO. yes 0 00007676 36C706[0000]0200 MOV word [ss:EXTOPEN_FLAG],action_created_opened ;AN000;EO. prsume create/open 0 0000767D 36C606[0000]02 MOV byte [ss:XA_from],By_Create ;AN000;EO. for set xa 0 00007683 36F606[0000]04 TEST byte [ss:EXTOPEN_ON],ext_file_not_exists ;AN000;;EO. file not exists ? 0 00007689 7567 JNZ setXAttr ;AN000;;EO. no 0 0000768B 36C706[0000]0300 MOV word [ss:EXTOPEN_FLAG],action_replaced_opened ;AN000;;EO. replaced/opened 0 00007692 36C606[0000]00 MOV byte [ss:XA_from],0 ;AN000;EO. for set xa 0 00007698 EB58 JMP SHORT setXAttr ;AN000;;EO. set XAs 794 error_return2: 0 0000769A C3 ret ;AN000;;EO. return with error 796 ;AN000; 797 exist_open: ;AN000; 0 0000769B 36F606[0000]FF test byte [ss:fSharing],-1 ;AN000;;EO. server doscall? 0 000076A1 7402 jz noserver ;AN000;;EO. no 0 000076A3 88E9 MOV CL,CH ;AN000;;EO. cl=search attribute 801 802 noserver: 0 000076A5 E892FC invoke D_Open2 ;AN000;;EO. do open 0 000076A8 7339 JNC ext_ok ;AN000;;EO. 0 000076AA 36803E[0000]00 CMP byte [ss:EXTOPEN_ON],0 ;AN000;;EO. error and IFS call 0 000076B0 74E8 JZ error_return2 ;AN000;;EO. return with error 807 local_extopen: 808 0 000076B2 83F802 CMP AX,error_file_not_found ;AN000;;EO. file not found error 0 000076B5 75E3 JNZ error_return2 ;AN000;;EO. no, 0 000076B7 36F706[0000]1000 TEST word [ss:EXTOPEN_FLAG],ext_nexists_create;AN000;;EO. want to fail 0 000076BE 7503 JNZ do_creat ;AN000;;EO. yes 0 000076C0 EB65 JMP extexit ;AN000;;EO. yes 0 000076C2 90 nop ; identicalise 815 do_creat: 0 000076C3 36C606[0000]02 MOV byte [ss:XA_from],By_Create ;AN000;;EO. for set xa 0 000076C9 368B0E[0000] MOV CX,[ss:SAVE_CX] ;AN000;;EO. get ds:dx for file name 0 000076CE 36C536[0000] LDS SI,[ss:SAVE_SI] ;AN000;;EO. cx = attribute 0 000076D3 89F2 MOV DX,SI ;AN000;;EO. 0 000076D5 E83DFD invoke D_Creat ;AN000;;EO. do create 0 000076D8 724D JC extexit ;AN000;;EO. error 0 000076DA 36C706[0000]0200 MOV word [ss:EXTOPEN_FLAG],action_created_opened ;AN000;;EO. is created/opened 0 000076E1 EB0F JMP SHORT setXAttr ;AN000;;EO. set XAs 824 825 ext_ok: 0 000076E3 36803E[0000]00 CMP byte [ss:EXTOPEN_ON],0 ;AN000;;EO. IFS call ? 0 000076E9 7415 JZ ok_return ;AN000;;EO. yes 0 000076EB 36C706[0000]0100 MOV word [ss:EXTOPEN_FLAG],action_opened ;AN000;;EO. opened 829 setXAttr: 830 ; LES DI,DWORD PTR [SAVE_DI] ;AN000;EO. 0 000076F2 50 PUSH AX ;AN000;;EO. save handle for final 832 ; MOV BX,AX ;AN000;;EO. bx= handle 833 ; MOV AX,04H ;AN000;;EO. set extended attr by handle 834 ; PUSH DS ;AN000;;EO. save file name addr 835 ; PUSH DX ;AN000;;EO. 836 ; CMP DI,-1 ;AN000;;EO. null parm list 837 ; JZ nosetea ;AN000;;EO. yes 838 ; CMP WORD PTR [ES:DI],-1 ;AN000;;EO. null set list 839 ; JZ nosetea ;AN000;;EO. yes 840 ; LES DI,DWORD PTR [ES:DI] ;AN000;;EO. es:di -> set list 841 ; invoke $File_times ;AN000;;EO. 842 ;nosetea: ;AN000; EO 843 ; POP DX ;AN000;;EO. restore file name addr 844 ; POP DS ;AN000;;EO. 845 ; JC extexit2 ;AN000;;EO. 0 000076F3 E8[0000] invoke get_user_stack ;AN000;;EO. 0 000076F6 36A1[0000] MOV AX,[ss:EXTOPEN_FLAG] ;AN000;;EO. 848 USER_CX equ user_CX ; NASM port equate 0 000076FA 894404 MOV [SI + USER_CX],AX ;AN000;;EO. set action code for cx 0 000076FD 58 POP AX ;AN000;;EO. 851 USER_AX equ user_AX ; NASM port equate 0 000076FE 8904 MOV [SI + USER_AX],AX ;AN000;;EO. set handle for ax 853 854 ok_return: ;AN000; 0 00007700 E9[0000] transfer SYS_RET_OK ;AN000;;EO. 856 857 extexit2: ;AN000; ERROR RECOVERY 858 0 00007703 5B POP BX ;AN000;EO. close the handle 0 00007704 50 PUSH AX ;AN000;EO. save error code from set XA 0 00007705 36833E[0000]02 CMP word [ss:EXTOPEN_FLAG],action_created_opened ;AN000;EO. from create 0 0000770B 750C JNZ justopen ;AN000;EO. 0 0000770D 36C536[0000] LDS SI,[ss:SAVE_SI] ;AN000;EO. cx = attribute 0 00007712 C514 LDS DX,[SI] ;AN000;EO. 0 00007714 E850FD invoke D_UNLINK ;AN000;EO. delete the file 0 00007717 EB03 JMP SHORT reserror ;AN000;EO. 867 868 justopen: ;AN000; 0 00007719 E8[0000] invoke D_close ;AN000;EO. pretend never happend 870 reserror: ;AN000; 0 0000771C 58 POP AX ;AN000;EO. retore error code from set XA 0 0000771D EB08 JMP SHORT extexit ;AN000;EO. 873 874 875 ext_file_unfound: ;AN000; 0 0000771F B80200 MOV AX,error_file_not_found ;AN000;EO. 0 00007722 EB03 JMP SHORT extexit ;AN000;EO. 878 ext_inval: ;AN000; 0 00007724 B80100 MOV AX,error_invalid_function;AN000;EO. 880 extexit: 0 00007727 E9[0000] transfer SYS_RET_ERR ;AN000;EO. 882 883 EndProc D_Extended_Open ;AN000; 884 885 886 Break 887 888 ; 889 ; 890 ; Inputs: DS:SI -> IO parm list 891 ; CX= number of parms 892 ; Function: get IO parms from parm list 893 ; Outputs: [EXT_IOMODE]= IO mode parm 894 895 ;procedure GetIOParms,NEAR 896 ; assume ds:nothing,es:nothing 897 ; 898 ; LODSB ; get parm type ;AN000; 899 ; CMP AL,0*100B+10B ; have IOMODE ;AN000; 900 ; JE SET_IOMODE ;AN000; 901 ; AND AL,00000011B ; decode it ;AN000; 902 ; JZ SKIP_ASCIIZ ;AN000; 903 ; DEC AL ;AN000; 904 ; JZ SKIP_LEN ;AN000; 905 ;; DEC AL ;AN000; 906 ; JZ SKIP_WORD ;AN000; 907 ;SKIP_DWORD: ; copy DWORD parm ;AN000; 908 ; LODSW ;AN000; 909 ;SKIP_WORD: ; copy WORD parm ;AN000; 910 ; LODSW ;AN000; 911 ; JMP SHORT NEXT_PARM ;AN000; 912 ;SET_IOMODE: ; copy IOMODE ;AN000; 913 ; LODSW ;AN000; 914 ; MOV [EXTOPEN_IO_MODE],AX ;AN000; 915 ; JMP SHORT NEXT_PARM ;AN000; 916 ;SKIP_LEN: ; copy LENGTH parm ;AN000; 917 ; LODSW ;AN000; 918 ; ADD SI,AX ;AN000; 919 ; JMP SHORT NEXT_PARM ;AN000; 920 ;SKIP_ASCIIZ: ; copy ASCIIZ parm ;AN000; 921 ; LODSB ;AN000; 922 ; OR AL,AL ;AN000; 923 ; JNE SKIP_ASCIIZ ;AN000; 924 ;NEXT_PARM: ;AN000; 925 ; LOOP GetIOParms ;AN000; 926 ; return ;AN000; 927 ;EndProc GetIOParms ;AN000; 928 929 END 930 931 === Trace listing source: ../DOS/lock.lst 1 ; SCCSID = @(#)lock.asm 1.1 85/04/10 2 ;TITLE LOCK ROUTINES - Routines for file locking 3 ;NAME LOCK 4 5 ; 6 ; LOCK_CHECK 7 ; LOCK_VIOLATION 8 ; $LockOper 9 ; 10 ; Revision history: 11 ; A000 version 4.00 Jan. 1988 12 ; 13 %include "dosseg.nas" 1 <1> ; SCCSID = @(#)dosseg.asm 1.1 85/04/10 2 <1> ; SCCSID = @(#)dosseg.asm 1.1 85/04/10 3 <1> ; 4 <1> ; segment ordering for MSDOS 5 <1> ; 6 <1> 7 <1> %include "ddataseg.nas" 1 <2> === Switch to base=001140h -> "DOSSTART" 2 <2> section DOSSTART align=16 PUBLIC class=DOSSTART 3 <2> ; (no prior section) ; DOSSTART ENDS 4 <2> === Switch to base=001140h -> "START" 5 <2> section START align=1 PUBLIC class=START 6 <2> ; (no prior section) ; START ENDS 7 <2> === Switch to base=001140h -> "CONSTANTS" 8 <2> section CONSTANTS align=2 PUBLIC class=CONST 9 <2> ; (no prior section) ; CONSTANTS ENDS 10 <2> === Switch to base=001140h -> "DATA" 11 <2> section DATA align=2 PUBLIC class=DATA 12 <2> ; (no prior section) ; DATA ENDS 13 <2> === Switch to base=001140h -> "TABLE" 14 <2> section TABLE align=2 PUBLIC class=TABLE 15 <2> ; (no prior section) ; TABLE ENDS 16 <2> === Switch to base=001140h -> "CODE" 17 <2> section CODE align=1 PUBLIC class=CODE 18 <2> ; (no prior section) ; CODE ENDS 19 <2> === Switch to base=001140h -> "DOSDATATABLE" 20 <2> section DOSDATATABLE align=2 PUBLIC class=DOSDATACODE 21 <2> ; (no prior section) ; DOSDATATABLE ENDS 22 <2> === Switch to base=001140h -> "DOSDATACODE" 23 <2> section DOSDATACODE align=1 PUBLIC class=DOSDATACODE 24 <2> ; (no prior section) ; DOSDATACODE ENDS 25 <2> === Switch to base=001140h -> "LAST" 26 <2> section LAST align=16 PUBLIC class=LAST 27 <2> ; (no prior section) ; LAST ENDS 28 <2> 29 <2> group DOSGROUP DOSSTART START CONSTANTS DATA TABLE CODE DOSDATATABLE DOSDATACODE LAST 8 <1> 9 <1> %include "dcodeseg.nas" 1 <2> 2 <2> %ifndef DCODESEGNAS 3 <2> %assign DCODESEGNAS 1 4 <2> === Switch to base=008400h -> "DOSCODETABLE" 5 <2> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <2> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=008400h -> "DOSCODECODE" 7 <2> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <2> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=008400h -> "DOSBIOCODE" 9 <2> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=008400h -> "BIOCODE" 10 <2> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <2> 12 <2> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <2> 14 <2> %endif 10 <1> === Switch to base=001140h -> "LAST" 11 <1> section LAST 12 <1> ; (no prior section) ; LAST ENDS 14 === Switch to base=008400h -> "DOSCODECODE" 15 section DOSCODECODE 16 17 [list -] 17 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 17 ****************** warning: out: BPB.INC... [-w+user] 17 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 17 ****************** warning: out: DEVSYM.INC... [-w+user] 24 25 %ifndef IBM 26 %iassign IBM 0 27 %endif 28 %ifndef Installed 29 %iassign Installed 0 30 %endif 31 32 %iassign Installed TRUE 33 34 i_need THISSFT,DWORD 35 i_need THISDPB,DWORD 36 i_need EXTERR,WORD 37 i_need ALLOWED,BYTE 38 i_need RetryCount,WORD 39 I_need fShare,BYTE 40 I_Need EXTERR_LOCUS,BYTE ; Extended Error Locus 41 i_need JShare,DWORD 42 i_need Lock_Buffer,DWORD ;AN000; DOS 4.00 43 i_need Temp_Var,WORD ;AN000; DOS 4.00 44 45 BREAK <$LockOper - Lock Calls> 46 47 ; 48 ; Assembler usage: 49 ; MOV BX, Handle (DOS 3.3) 50 ; MOV CX, OffsetHigh 51 ; MOV DX, OffsetLow 52 ; MOV SI, LengthHigh 53 ; MOV DI, LengthLow 54 ; MOV AH, LockOper 55 ; MOV AL, Request 56 ; INT 21h 57 ; 58 ; Error returns: 59 ; AX = error_invalid_handle 60 ; = error_invalid_function 61 ; = error_lock_violation 62 ; 63 ; Assembler usage: 64 ; MOV AX, 5C?? (DOS 4.00) 65 ; 66 ; 0? lock all 67 ; 8? lock write 68 ; ?2 lock multiple 69 ; ?3 unlock multiple 70 ; ?4 lock/read 71 ; ?5 write/unlock 72 ; ?6 add (lseek EOF/lock/write/unlock) 73 ; MOV BX, Handle 74 ; MOV CX, count or size 75 ; LDS DX, buffer 76 ; INT 21h 77 ; 78 ; Error returns: 79 ; AX = error_invalid_handle 80 ; = error_invalid_function 81 ; = error_lock_violation 82 83 procedure D_LockOper,NEAR 83 ****************** warning: proc D_LockOper... [-w+user] 84 ASSUME DS:NOTHING,ES:NOTHING 85 ; MOV BP,AX ;MS. BP=AX ;AN000; 86 ; AND BP,7FH ;MS. clear bit 7 ;AN000; 87 ; CMP BP,Lock_add ;MS. supported function ? ;AN000; 88 ; JA lock_bad_func ;MS. no, ;AN000; 89 0 0000772A 3C01 CMP AL,1 ;AN000;;MS. no, 0 0000772C 770C JA lock_bad_func ;AN000;;MS. no, 92 0 0000772E 57 PUSH DI ; Save LengthLow 0 0000772F E8[0000] invoke SFFromHandle ; ES:DI -> SFT 0 00007732 7310 JNC lock_do ; have valid handle 0 00007734 5F POP DI ; Clean stack 0 00007735 B006E9[0000] error error_invalid_handle 98 lock_bad_func: 99 errLoc_Unk equ errLOC_Unk ; NASM port equate 0 0000773A 36C606[0000]01 MOV byte [ss:EXTERR_LOCUS],errLoc_Unk ; Extended Error Locus 0 00007740 B001EBF3 error error_invalid_function 102 103 ; Align_buffer call has been deleted, since it corrupts the DTA (6/5/88) P5013 104 105 lock_do: 106 ; PUSH AX ;AN000;;MS. save ax 107 ; PUSH BX ;AN000;;MS. save handle 108 ; MOV [Temp_Var],DX ;AN000;;MS. save DX 109 ; invoke Align_Buffer ;AN000;;MS. align ds:dx and set DMAADD 110 ; POP BX ;AN000;;MS. restore handle 111 ; POP AX ;AN000;;MS. save ax 112 ;AN000; 113 ; CMP BP,Unlock_all ;AN000;;MS. old function 0 or 1 ? 114 ; JA chk_lock_mul ;AN000;;MS. no, new function 115 ; TEST AL,80H ;AN000;;MS. 80H bit on ? 116 ; JZ old_33 ;AN000;;MS. no, old DOS 3.3 interface 117 ; MOV CX,1 ;AN000;;MS. adjust for new interface 118 ; ADD BP,2 ;AN000;;MS. 119 ; JMP SHORT chk_lock_mul ;AN000;;MS. 120 old_33: 0 00007744 89C3 MOV BX,AX ;AN000;;MS. save AX 122 ;AN000; 123 ;; MOV DX,[Temp_Var] ;AN000;;MS. retore DX (P5013) 6/5/88 124 0 00007746 BD[0000] MOV BP, OFFSET Lock_Buffer wrt DOSGROUP ;AN000;;MS. get DOS LOCK buffer 0 00007749 895600 MOV WORD PTR [BP + Lock_position],DX ;AN000;;MS. set low offset 0 0000774C 894E02 MOV WORD PTR [BP + Lock_position+2],CX;AN000;;MS. set high offset 0 0000774F 59 POP CX ;AN000;;MS. get low length 0 00007750 894E04 MOV WORD PTR [BP + Lock_length],CX ;AN000;;MS. set low length 0 00007753 897606 MOV WORD PTR [BP + Lock_length+2],SI ;AN000;;MS. set high length 0 00007756 B90100 MOV CX,1 ;AN000;;MS. one range 0 00007759 16 PUSH ss ;AN000;;MS. 0 0000775A 1F POP DS ;AN000;;MS. DS:DX points to 0 0000775B 89EA MOV DX,BP ;AN000;;MS. Lock_Buffer 0 0000775D A801 TEST AL,Unlock_all ;AN000;;MS. function 1 0 0000775F 7503 JNZ DOS_Unlock ;AN000;;MS. yes 0 00007761 EB20 JMP DOS_Lock ;AN000;;MS. function 0 0 00007763 90 nop ; identicalise 139 ;;chk_lock_mul: ;AN000; 140 ; POP SI ;AN000;;MS. pop low length 141 ; TEST [ES:DI.sf_flags],sf_isnet ;AN000;;MS. net handle? 142 ; JZ LOCAL_DOS_LOCK ;AN000;;MS. no 143 ; invoke OWN_SHARE ;AN000;;MS. IFS owns share ? 144 ; JNZ LOCAL_DOS_LOCK ;AN000;;MS. no 145 ; MOV BX,AX ;AN000;;MS. BX=AX 146 ; CallInstall NET_XLock,multNet,10 ;AN000;;MS. issue Net Extended Lock 147 ; MOV [Temp_Var],CX ;AN000;;MS. cx= retuened from IFS 148 ; JMP ValChk ;AN000;;MS. check return 149 ;LOCAL_DOS_LOCK: ;AN000; 150 ; CMP BP,Lock_mul_range ;AN000;;MS. lock mul range? 151 ; JNZ unmul ;AN000;;MS. lock mul range? 152 ; JMP LOCAL_LOCK ;AN000;;MS. yes 153 ;unmul: 154 ; CMP BP,Unlock_mul_range ;AN000;;MS. unlock mul range? 155 ; JZ LOCAL_UNLOCK ;AN000;;MS. yes 156 ; CMP BP,Lock_read ;AN000;;MS. lock read? 157 ; JNZ chk_write_unlock ;AN000;;MS. no 158 ; CALL Set_Lock_Buffer ;AN000;;MS. set DOS lock buffer 159 ; CALL Set_Lock ;AN000;;MS. set the lock 160 ; JC lockerror ;AN000;;MS. error 161 ; invoke $READ ;AN000;;MS. do read 162 ; JC lockerror ;AN000;;MS. error 163 ;lockend: ;AN000; 164 ; transfer SYS_RET_OK ;AN000;;MS. return 165 ;chk_write_unlock: ;AN000; 166 ; CMP BP,Write_unlock ;AN000;;MS. write unlock ? 167 ; JNZ Lock_addf ;AN000;;MS. no 168 ; CALL Set_Lock_Buffer ;AN000;;MS. set DOS lock buffer 169 ;WriteUnlock: ;AN000; 170 ; PUSH AX ;AN000;;MS. save AX for unlock 171 ; invoke $WRITE ;AN000;;MS. do write 172 ; MOV [Temp_Var],AX ;AN000;;MS. save number of bytes writ 173 ; POP AX ;AN000;;MS. restore AX 174 ; JC lockerror ;AN000;;MS. error 175 ; MOV CX,1 ;AN000;;MS. one range unlock 176 ; PUSH ss ;AN000;;MS. 177 ; POP DS ;AN000;;MS. DS:DX points to 178 ; MOV DX,OFFSET Lock_Buffer wrt DOSGROUP ;AN000;;MS. Lock_BUffer 179 ; JMP LOCAL_UNLOCK ;AN000;;MS. do unlock 180 ;Lock_addf: ;AN000; 181 ; MOV SI,WORD PTR [ES:DI.SF_Size] ;AN000;;MS. must be lock add 182 ; MOV WORD PTR [ES:DI.SF_Position],SI ;AN000;;MS. set file position to 183 ; MOV SI,WORD PTR [ES:DI.SF_Size+2] ;AN000;;MS. EOF 184 ; MOV WORD PTR [ES:DI.SF_Position+2],SI;AN000;;MS. 185 ; CALL Set_Lock_Buffer ;AN000;;MS. set DOS lock buffer 186 ; CALL Set_Lock ;AN000;;MS. set the lock 187 ; JC lockerror ;AN000;;MS. error 188 ; JMP WriteUnlock ;AN000;;MS. do write unlock 189 ;AN000;;MS. 190 DOS_Unlock: 0 00007764 26F745050080 TEST word [ES:DI + sf_flags],sf_isnet 0 0000776A 7407 JZ LOCAL_UNLOCK 193 ;; invoke OWN_SHARE ;AN000;;MS. IFS owns share ? 194 ;; JNZ LOCAL_UNLOCK ;AN000;;MS. no 195 196 multNet equ MultNET ; NASM port equate 0 0000776C B80A11CD2F CallInstall Net_Xlock,multNet,10 0 00007771 EB05 JMP SHORT ValChk 199 LOCAL_UNLOCK: 200 %if installed 0 00007773 36FF1E[1C00] Call far [ss:JShare + 7 * 4] 202 %else 203 Call clr_block 204 %endif 205 ValChk: 0 00007778 7302 JNC Lock_OK 207 lockerror: 0 0000777A EBC6 transfer SYS_RET_ERR 209 Lock_OK: 210 Temp_VAR equ Temp_Var ; NASM port label 0 0000777C 36A1[0000] MOV AX,[ss:Temp_VAR] ;AN000;;MS. AX= number of bytes 0 00007780 E9[0000] transfer SYS_Ret_OK 213 DOS_Lock: 0 00007783 26F745050080 TEST word [ES:DI + sf_flags],sf_isnet 0 00007789 7407 JZ LOCAL_LOCK 216 ;; invoke OWN_SHARE ;AN000;;MS. IFS owns share ? 217 ;; JNZ LOCAL_LOCK ;AN000;;MS. no 0 0000778B B80A11CD2F CallInstall NET_XLock,multNet,10 0 00007790 EBE6 JMP ValChk 220 LOCAL_LOCK: 221 %if installed 0 00007792 36FF1E[1800] Call far [ss:JShare + 6 * 4] 223 %else 224 Call Set_Block 225 %endif 0 00007797 EBDF JMP ValChk 227 228 EndProc D_LockOper 229 230 BREAK 231 232 ; Input: 233 ; BP = Lock_Buffer addr 234 ; CX = lock length 235 ; Function: 236 ; set the lock 237 ; Output: 238 ; carry clear ,Lock is set 239 ; DS:DX = addr of 240 ; carry set Lock is not set 241 ; DS,DX,CX preserved 242 243 ; procedure Set_Lock,NEAR ;AN000; 244 ;ASSUME DS:NOTHING,ES:NOTHING ;AN000; 245 ;AN000; 246 ; PUSH DS ;MS. save regs ;AN000; 247 ; PUSH DX ;MS. ;AN000; 248 ; PUSH CX ;MS. ;AN000; 249 ; ;AN000; 250 ; PUSH ss ;MS. ;AN000; 251 ; POP DS ;MS. DS:DX poits to Lock_Buffer ;AN000; 252 ; MOV DX,BP ;MS. ;AN000; 253 ; PUSH BX ;MS. save handle ;AN000; 254 ; PUSH AX ;MS. save functions ;AN000; 255 ; MOV CX,1 ;MS. set one lock ;AN000; 256 ;if installed ;AN000; 257 ; Call JShare + 6 * 4 ;MS. call share set block ;AN000; 258 ;else ;AN000; 259 ; Call Set_Block ;MS. ;AN000; 260 ;endif ;AN000; 261 ; POP AX ;MS. restore regs ;AN000; 262 ; POP BX ;MS. ;AN000; 263 ; POP CX ;MS. ;AN000; 264 ; POP DX ;MS. ;AN000; 265 ; POP DS ;MS. ;AN000; 266 ; return ;MS. ;AN000; 267 ; ;AN000; 268 ;EndProc Set_Lock ;AN000; 269 270 BREAK 271 272 ; Input: 273 ; ES:DI = addr of SFT 274 ; CX = lock length 275 ; Function: 276 ; set up the lock buffer 277 ; Output: 278 ; Lock_Buffer is filled with position and lock length 279 ; BP = Lock_Buffer addr 280 ; 281 282 ; procedure Set_Lock_Buffer,NEAR 283 ;ASSUME DS:NOTHING,ES:NOTHING 284 ; 285 ; MOV BP, OFFSET Lock_Buffer wrt DOSGROUP ;MS. move file position ;AN000; 286 ; MOV SI,WORD PTR [ES:DI.sf_position] ;MS. to DOS lock_buffer ;AN000; 287 ; MOV WORD PTR [BP.Lock_position],SI ;MS. ;AN000; 288 ; MOV SI,WORD PTR [ES:DI.sf_position+2] ;MS. ;AN000; 289 ; MOV WORD PTR [BP.Lock_position+2],SI ;MS. ;AN000; 290 ; MOV WORD PTR [BP.Lock_length],CX ;MS. move cx to lock_buffer ;AN000; 291 ; MOV WORD PTR [BP.Lock_length+2],0 ;MS. ;AN000; 292 ; return ;MS. ;AN000; 293 ; 294 ;EndProc Set_Lock_Buffer 295 296 ; Inputs: 297 ; Outputs of SETUP 298 ; [USER_ID] Set 299 ; [PROC_ID] Set 300 ; Function: 301 ; Check for lock violations on local I/O 302 ; Retries are attempted with sleeps in between 303 ; Outputs: 304 ; Carry clear 305 ; Operation is OK 306 ; Carry set 307 ; A lock violation detected 308 ; Outputs of SETUP preserved 309 310 procedure LOCK_CHECK,NEAR 310 ****************** warning: proc LOCK_CHECK... [-w+user] 311 DOSAssume CS,,"Lock_Check" 312 ASSUME ES:NOTHING 313 0 00007799 8B1E[0000] MOV BX,[RetryCount] ; Number retries 315 LockRetry: 0 0000779D 5350 SaveReg ; MS. save regs ;AN000; 317 %if installed 0 0000779F FF1E[2000] call far [JShare + 8 * 4] 319 %else 320 Call chk_block 321 %endif 0 000077A3 585B RestoreReg ; MS. restrore regs ;AN000; 0 000077A5 7201C3 retnc ; There are no locks 0 000077A8 E8[0000] Invoke Idle ; wait a while 0 000077AB 4B DEC BX ; remember a retry 0 000077AC 75EF JNZ LockRetry ; more retries left... 0 000077AE F9 STC 0 000077AF C3 return 329 EndProc LOCK_CHECK 330 331 ; Inputs: 332 ; [THISDPB] set 333 ; [READOP] indicates whether error on read or write 334 ; Function: 335 ; Handle Lock violation on compatibility (FCB) mode SFTs 336 ; Outputs: 337 ; Carry set if user says FAIL, causes error_lock_violation 338 ; Carry clear if user wants a retry 339 ; 340 ; DS, ES, DI, CX preserved, others destroyed 341 342 procedure LOCK_VIOLATION,NEAR 342 ****************** warning: proc LOCK_VIOLATION... [-w+user] 343 DOSAssume CS,,"Lock_Violation" 344 ASSUME ES:NOTHING 345 0 000077B0 1E PUSH DS 0 000077B1 06 PUSH ES 0 000077B2 57 PUSH DI 0 000077B3 51 PUSH CX 0 000077B4 B82100 MOV AX,error_lock_violation 351 allowed_FAIL equ Allowed_FAIL ; NASM port equate 352 allowed_RETRY equ Allowed_RETRY ; NASM port equate 0 000077B7 C606[0000]18 MOV byte [ALLOWED],allowed_FAIL + allowed_RETRY 0 000077BC C42E[0000] LES BP,[THISDPB] 0 000077C0 BF0100 MOV DI,1 ; Fake some registers 0 000077C3 89F9 MOV CX,DI 0 000077C5 268B560B MOV DX,[ES:BP + dpb_first_sector] 0 000077C9 E8[0000] invoke HARDERR_DOS 0 000077CC 59 POP CX 0 000077CD 5F POP DI 0 000077CE 07 POP ES 0 000077CF 1F POP DS 0 000077D0 3C01 CMP AL,1 0 000077D2 74DB retz ; 1 = retry, carry clear 0 000077D4 F9 STC 0 000077D5 C3 return 367 368 EndProc LOCK_VIOLATION 369 370 %IF INSTALLED 371 ; 372 ; do a retz to return error 373 ; 374 Procedure CheckShare,NEAR 374 ****************** warning: proc CheckShare... [-w+user] 375 ASSUME CS:DOSGROUP,ES:NOTHING,DS:NOTHING,SS:NOTHING 0 000077D6 36803E[0000]00 CMP byte [ss:fShare],0 0 000077DC C3 return 378 EndProc CheckShare 379 %ENDIF 380 381 END === Trace listing source: ../DOS/share.lst 1 ; SCCSID = @(#)share.asm 1.1 85/04/10 2 ;TITLE SHARING ROUTINES - Routines for file Sharing 3 ;NAME SHARE 4 5 %include "dosseg.nas" 1 <1> ; SCCSID = @(#)dosseg.asm 1.1 85/04/10 2 <1> ; SCCSID = @(#)dosseg.asm 1.1 85/04/10 3 <1> ; 4 <1> ; segment ordering for MSDOS 5 <1> ; 6 <1> 7 <1> %include "ddataseg.nas" 1 <2> === Switch to base=001140h -> "DOSSTART" 2 <2> section DOSSTART align=16 PUBLIC class=DOSSTART 3 <2> ; (no prior section) ; DOSSTART ENDS 4 <2> === Switch to base=001140h -> "START" 5 <2> section START align=1 PUBLIC class=START 6 <2> ; (no prior section) ; START ENDS 7 <2> === Switch to base=001140h -> "CONSTANTS" 8 <2> section CONSTANTS align=2 PUBLIC class=CONST 9 <2> ; (no prior section) ; CONSTANTS ENDS 10 <2> === Switch to base=001140h -> "DATA" 11 <2> section DATA align=2 PUBLIC class=DATA 12 <2> ; (no prior section) ; DATA ENDS 13 <2> === Switch to base=001140h -> "TABLE" 14 <2> section TABLE align=2 PUBLIC class=TABLE 15 <2> ; (no prior section) ; TABLE ENDS 16 <2> === Switch to base=001140h -> "CODE" 17 <2> section CODE align=1 PUBLIC class=CODE 18 <2> ; (no prior section) ; CODE ENDS 19 <2> === Switch to base=001140h -> "DOSDATATABLE" 20 <2> section DOSDATATABLE align=2 PUBLIC class=DOSDATACODE 21 <2> ; (no prior section) ; DOSDATATABLE ENDS 22 <2> === Switch to base=001140h -> "DOSDATACODE" 23 <2> section DOSDATACODE align=1 PUBLIC class=DOSDATACODE 24 <2> ; (no prior section) ; DOSDATACODE ENDS 25 <2> === Switch to base=001140h -> "LAST" 26 <2> section LAST align=16 PUBLIC class=LAST 27 <2> ; (no prior section) ; LAST ENDS 28 <2> 29 <2> group DOSGROUP DOSSTART START CONSTANTS DATA TABLE CODE DOSDATATABLE DOSDATACODE LAST 8 <1> 9 <1> %include "dcodeseg.nas" 1 <2> 2 <2> %ifndef DCODESEGNAS 3 <2> %assign DCODESEGNAS 1 4 <2> === Switch to base=008400h -> "DOSCODETABLE" 5 <2> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <2> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=008400h -> "DOSCODECODE" 7 <2> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <2> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=008400h -> "DOSBIOCODE" 9 <2> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=008400h -> "BIOCODE" 10 <2> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <2> 12 <2> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <2> 14 <2> %endif 10 <1> === Switch to base=001140h -> "LAST" 11 <1> section LAST 12 <1> ; (no prior section) ; LAST ENDS 6 === Switch to base=008400h -> "DOSCODECODE" 7 section DOSCODECODE 8 9 [list -] 9 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 9 ****************** warning: out: BPB.INC... [-w+user] 9 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 9 ****************** warning: out: DEVSYM.INC... [-w+user] 15 16 %ifndef IBM 17 %iassign IBM 0 18 %endif 19 %ifndef Installed 20 %iassign Installed 0 21 %endif 22 23 True equ TRUE ; NASM port equate 24 %iassign Installed True 25 26 i_need THISDPB,DWORD 27 i_need EXTERR,WORD 28 i_need ReadOp,BYTE 29 i_need ThisSFT,DWORD 30 i_need ALLOWED,BYTE 31 I_need RetryCount,WORD 32 i_need JShare,DWORD 33 34 ; Inputs: 35 ; [THISSFT] Points to filled in local file/device SFT for new 36 ; instance of file sf_mode ALWAYS has mode (even on FCB SFTs) 37 ; [WFP_START] has full path of name 38 ; [USER_ID] Set 39 ; [PROC_ID] Set 40 ; Function: 41 ; Check for sharing violations on local file/device access 42 ; Outputs: 43 ; Carry clear 44 ; Sharing approved 45 ; Carry set 46 ; A sharing violation detected 47 ; AX is error code 48 ; USES ALL but DS 49 50 procedure SHARE_CHECK,NEAR 50 ****************** warning: proc SHARE_CHECK... [-w+user] 51 DOSAssume CS,,"Share_Check" 52 ASSUME ES:NOTHING 53 54 %if installed 0 000077DD FF1E[0400] call far [JShare + 1 * 4] 56 %else 57 Call MFT_Enter 58 %endif 0 000077E1 C3 return 60 61 EndProc SHARE_CHECK 62 63 ; Inputs: 64 ; [THISDPB] Set 65 ; AX has error code 66 ; Function: 67 ; Handle Sharing errors 68 ; Outputs: 69 ; Carry set if user says FAIL, causes error_sharing_violation 70 ; Carry clear if user wants a retry 71 ; 72 ; DS, ES, DI preserved, others destroyed 73 74 procedure SHARE_VIOLATION,NEAR 74 ****************** warning: proc SHARE_VIOLATION... [-w+user] 75 DOSAssume CS,,"Share_Violation" 76 ASSUME ES:NOTHING 77 0 000077E2 1E PUSH DS 0 000077E3 06 PUSH ES 0 000077E4 57 PUSH DI 81 READOP equ ReadOp ; NASM port label 0 000077E5 C606[0000]00 MOV byte [READOP],0 ; All share errors are reading 83 allowed_FAIL equ Allowed_FAIL ; NASM port equate 84 allowed_RETRY equ Allowed_RETRY ; NASM port equate 0 000077EA C606[0000]18 MOV byte [ALLOWED],allowed_FAIL + allowed_RETRY 0 000077EF C42E[0000] LES BP,[THISDPB] 0 000077F3 BF0100 MOV DI,1 ; Fake some registers 0 000077F6 89F9 MOV CX,DI 0 000077F8 268B5611 MOV DX,[ES:BP + dpb_dir_sector] 0 000077FC E8[0000] invoke HARDERR_DOS 0 000077FF 5F POP DI 0 00007800 07 POP ES 0 00007801 1F POP DS 0 00007802 3C01 CMP AL,1 0 00007804 74DB retz ; 1 = retry, carry clear 0 00007806 F9 STC 0 00007807 C3 return 98 99 EndProc SHARE_VIOLATION 100 101 ; ShareEnd - terminate sharing info on a particular SFT/UID/PID. This does 102 ; NOT perform a close, it merely asserts that the sharing information 103 ; for the SFT/UID/PID may be safely released. 104 ; 105 ; Inputs: ES:DI points to an SFT 106 ; Outputs: None 107 ; Registers modified: all except DS,ES,DI 108 109 procedure ShareEnd,Near 109 ****************** warning: proc ShareEnd... [-w+user] 110 DOSAssume CS,,"ShareEnd" 111 ASSUME ES:NOTHING 112 113 %if installed 0 00007808 FF1E[0800] Call far [JShare + 2 * 4] 115 %else 116 Call MFTClose 117 %endif 0 0000780C C3 return 119 120 EndProc ShareEnd 121 122 break 123 124 ; 125 ; ShareEnter - perform a retried entry of a nodde into the sharing set. If 126 ; the max number of retries is exceeded, we notify the user via int 24. 127 ; 128 ; Inputs: ThisSFT points to the SFT 129 ; WFP_Start points to the WFP 130 ; Outputs: Carry clear => successful entry 131 ; Carry set => failed system call 132 ; Registers modified: all 133 134 Procedure ShareEnter,NEAR 134 ****************** warning: proc ShareEnter... [-w+user] 135 DOSAssume CS,,"ShareEnter" 136 assume es:nothing 137 0 0000780D 51 SaveReg 139 retry: 0 0000780E 8B0E[0000] mov cx,[RetryCount] 141 attempt: 0 00007812 C43E[0000] les di,[ThisSFT] ; grab sft 0 00007816 31C0 XOR AX,AX 0 00007818 26894533 MOV [ES:DI + sf_MFT],AX ; indicate free SFT 0 0000781C 51 SaveReg 146 Share_Check equ SHARE_CHECK ; NASM port label 0 0000781D E8BDFF call Share_Check ; attempt to enter into the sharing set 0 00007820 59 RestoreReg 0 00007821 730A jnc done ; success, let the user see this 0 00007823 E8[0000] invoke Idle ; wait a while 0 00007826 E2EA loop attempt ; go back for another attempt 152 Share_violation equ SHARE_VIOLATION ; NASM port label 0 00007828 E8B7FF call Share_violation ; signal the problem to the user 0 0000782B 73E1 jnc retry ; user said to retry, go do it 155 done: 0 0000782D 59 RestoreReg 0 0000782E C3 return 158 EndProc ShareEnter 159 160 END === Trace listing source: ../DOS/extattr.lst 1 ;TITLE EXTATTR- Extended Attributes 2 ;NAME EXTATTR 3 ; 4 ; Get or Set Extended Attributes by handle 5 ; 6 ; 7 ; GetSetEA 8 ; Set_Output 9 ; Search_EA 10 ; Copy_QEA 11 ; Set_one_EA 12 ; Get_one_EA 13 ; Get_Value 14 ; GSetDevCdpg 15 ; Get_max_EA_size 16 ; 17 ; Revision history 18 ; 19 ; A000 version 4.00 Jan. 1988 20 ; 21 ; 22 ; 23 ; 24 ; 25 ; 26 ; 27 28 [list -] === Switch to base=008400h -> "DOSCODECODE" 36 section DOSCODECODE 37 [list -] 37 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 37 ****************** warning: out: BPB.INC... [-w+user] 37 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 37 ****************** warning: out: DEVSYM.INC... [-w+user] 45 ;.sall 46 47 48 ; I_need XA_from,BYTE ;AN000; 49 50 ; I_need XA_TABLE,BYTE ;AN000; 51 ; I_need XA_TEMP,WORD ;AN000; 52 ; I_need XA_COUNT,WORD ;AN000; 53 ; I_need XA_DEVICE,BYTE ;AN000; 54 I_need XA_TYPE,BYTE ;AN000; 55 I_need SAVE_ES,WORD ;AN000; 56 I_need SAVE_DI,WORD ;AN000; 57 I_need SAVE_DS,WORD ;AN000; 58 I_need SAVE_SI,WORD ;AN000; 59 I_need SAVE_CX,WORD ;AN000; 60 I_need SAVE_BX,WORD ;AN000; 61 ; I_need XA_handle,WORD ;AN000; 62 ; I_need CPSWFLAG,BYTE ;AN000; 63 ; I_need XA_PACKET,BYTE ;AN000; 64 ; I_need MAX_EA_SIZE,WORD ;AN000; 65 ; I_need MAX_EANAME_SIZE,WORD ;AN000; 66 ; I_need THISSFT,DWORD ;AN000; 67 ;IF DBCS ;AN000; 68 ; I_need DBCS_PACKET,BYTE ;AN000; ;AN000; 69 ;ENDIF ;AN000; ;AN000; 70 ;AN000; 71 ;AN000; 72 ;AN000; 73 ;AN000; 74 ;AN000; 75 BREAK ;AN000; 76 ;AN000; 77 ; Input: [XA_type] = function code, (e.g., get,set) ;AN000; 78 ; [ThisSFT] points to SFT ;AN000; 79 ; ES:BP points to drive parameter block ;AN000; 80 ; [XA_from] = By_Create or By_EA ;AN000; 81 ; [SAVE_ES]:[SAVE_DI] points to get/set list ;AN000; 82 ; [SAVE_DS]:[SAVE_SI] points to get query list ;AN000; 83 ; [SAVE_CX] = size of buffer 84 ; [XA_device]= 1 device, 0 file ;AN000; 85 ; [XA_handle] for device ;AN000; 86 ; Function: Get or Set extended attributes by handle ;AN000; 87 ; Output: carry set: error ;AN000; 88 ; carry clear: extended attributes are successfully get/set ;AN000; 89 ; extended attribute cluster may be created ;AN000; 90 ; ;AN000; 91 ; ;AN000; 92 ; ;AN000; 93 ;AN000; 94 ;AN000; 95 procedure GetSet_XA,near ;AN000; 95 ****************** warning: proc GetSet_XA... [-w+user] 96 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; 97 98 0 0000782F 36C43E[0000] LES DI,[ss:SAVE_DI] ;AN000;;FT. ES:DI -> query list 100 ;; MOV [SAVE_BX],2 ;AN000;;FT. size returned 101 ;; XOR DX,DX ;AN000;;FT. dx=0, codepage id 102 103 XA_type equ XA_TYPE ; NASM port label 0 00007834 36803E[0000]02 CMP byte [ss:XA_type],2 ;AN000;;FT. get EA ? 0 0000783A 7526 JNZ eaname ;AN000;;FT. no 106 getEAs: ;AN000; 0 0000783C 36833E[0000]00 CMP word [ss:SAVE_CX],0 ;AN000;;FT. get max data size 0 00007842 7508 JNZ notmax ;AN000;;FT. no 109 ;; CALL Get_max_EA_size ;AN000;;FT. 110 0 00007844 B90200 MOV CX,2 ;AN000;;FT. FAKE FAKE.............. 0 00007847 732F JNC set_user_cx ;AN000;;FT. 0 00007849 EB39 JMP OKexit ;AN000;;FT. error 0 0000784B 90 nop ; identicalise 115 notmax: 0 0000784C 36833E[0000]01 CMP word [ss:SAVE_CX],1 ;AN000;;FT. buffer size =1 ? 0 00007852 7503 JNZ goodsiz ;AN000;;FT. no 118 errout: ;AN000; 0 00007854 EB2E JMP insuff_space ;AN000;;FT. no error 0 00007856 90 nop ; identicalise 121 goodsiz: ;AN000; 0 00007857 26C7050000 MOV WORD PTR [ES:DI],0 ;AN000;FT. FAKE FAKE ............... 0 0000785C B90200 MOV CX,2 ;AN000;FT. FAKE FAKE ............... 0 0000785F EB17 JMP set_user_cx ;AN000;FT. FAKE FAKE ............... 0 00007861 90 nop ; identicalise 126 127 ; SUB [SAVE_CX],2 ;AN000;;FT. minus count size 128 ; CMP [SAVE_SI],-1 ;AN000;;FT. get all ? 129 ; JNZ getsome ;AN000;;FT. no 130 ; PUSH CS ;AN000;;FT. ds:si-> EA entry addr 131 ; POP DS ;AN000;;FT. 132 ; INC DI ;AN000;;FT. 133 ; INC DI ;AN000;;FT. es:di -> address after count 134 ; MOV SI,OFFSET XA_TABLE wrt DOSGROUP ;AN000;FT. 135 ; MOV CX,XA_COUNT ;AN000;;FT. cx= number of EA entries 136 ;;;;;; 137 ;getone: 138 ; CALL GET_ONE_EA ;AN000;;FT. get EA 139 ; JC setout ;AN000;;FT. insufficient memory 140 ; INC DX ;AN000;;FT. next EA ID 141 ; LOOP getone ;AN000;;FT. next one 142 ;setout: ;AN000; 143 ; CALL Set_Output ;AN000;;FT. 144 ; OR CX,CX ;AN000;;FT. 145 ; JNZ errout ;AN000;;FT. 146 ; 147 ; JMP OKexit ;AN000;;FT. 148 eaname: 0 00007862 36803E[0000]03 CMP byte [ss:XA_type],3 ;AN000;;FT. get EA name?` 0 00007868 7403 JZ geteaname ;AN000;;FT. yes 0 0000786A EB15 JMP setea ;AN000;;FT. 0 0000786C 90 nop ; identicalise 153 geteaname: 154 ; MOV [SAVE_SI],-1 ;AN000;;FT. make get all 0 0000786D 36833E[0000]00 CMP word [ss:SAVE_CX],0 ;AN000;;FT. get max data size 0 00007873 75D7 JNZ notmax ;AN000;;FT. no 0 00007875 B90200 MOV CX,2 ;AN000;;FT. FAKE FAKE ...................... 158 ;; MOV CX,[MAX_EANAME_SIZE] ;AN000;;FT. get name size 159 set_user_cx: ;AN000; 0 00007878 E8[0000] invoke get_user_stack ;AN000;;FT. get user stack 0 0000787B 894C04 MOV [SI + user_CX],CX ;AN000;;FT. 0 0000787E EB04 JMP OKexit ;AN000;;FT. exit 0 00007880 90 nop ; identicalise 164 165 getsome: ;AN000; 166 ; LDS SI,DWORD PTR [SAVE_SI] ;AN000;;FT. 167 ; LODSW ;AN000;;FT. 168 ; MOV CX,AX ;AN000;;FT. cx=number of query entries 169 ; JCXZ setout ;AN000;;FT. yes 170 ; STOSW ;AN000;;FT. es:di -> EA 171 ;get_next_EA: ;AN000; 172 ; PUSH DS ;AN000;;FT. save ds:si 173 ; PUSH SI ;AN000;;FT. es:di 174 ; PUSH ES ;AN000;;FT. 175 ; PUSH DI ;AN000;;FT. 176 ; CALL Search_EA ;AN000;;FT. search query EA from table 177 ; JC EAnotFound ;AN000;;FT. EA not found 178 ; PUSH ES ;AN000;;FT. 179 ; POP DS ;AN000;;FT. 180 ; MOV SI,DI ;AN000;;FT. ds:si -> found EA 181 ; POP DI ;AN000;;FT. es:di -> buffer 182 ; POP ES ;AN000;;FT. 183 ; CALL GET_ONE_EA ;AN000;;FT. copy to buffer 184 ; POP SI ;AN000;;FT. 185 ; POP DS ;AN000;;FT. 186 ; JC setfinal ;AN000;;FT. memory not enough 187 ; MOV AL,[SI.QEA_NAMELEN] ;AN000;;FT. 188 ; XOR AH,AH ;AN000;;FT. 189 ; ADD AX,QEA_NAME ;AN000;;FT. 190 ; ADD SI,AX ;AN000;;FT. ds:si -> next query entry 191 ;testend: ;AN000; 192 ; LOOP get_next_EA ;AN000;;FT. do next 193 ;setfinal: ;AN000; 194 ; LDS SI,DWORD PTR [SAVE_SI] ;AN000;;FT. 195 ; MOV DX,[SI] ;AN000;;FT. 196 ; SUB DX,CX ;AN000;;FT. dx= returned count 197 ; JMP setout ;AN000;;FT. 198 ;EAnotFound: ;AN000; 199 ; POP DI ;AN000;;FT. restore regs 200 ; POP ES ;AN000;;FT. 201 ; POP SI ;AN000;;FT. 202 ; POP DS ;AN000;;FT. 203 ; 204 ; CALL COPY_QEA ;AN000;;FT. copy query EA to buffer 205 ; JC setfinal ;AN000;;FT. not enough memory 206 ; JMP testend ;AN000;;FT. 207 setea: ;AN000; 0 00007881 EB01 JMP OKexit ;AN000;;FT. FAKE FAKE .......... 0 00007883 90 nop ; identicalise 210 ; LDS SI,DWORD PTR [SAVE_DI] ;AN000;;FT. 211 ; LODSW ;AN000;;FT. 212 ; MOV CX,AX ;AN000;;FT. cx=number of query entries 213 ; OR CX,CX ;AN000;;FT. cx=0 ? 214 ; JZ OKexit ;AN000;;FT. yes 215 ;set_next: ;AN000; 216 ; CALL Search_EA ;AN000;;FT. 217 ; JNC toset ;AN000;;FT. 218 ;set_reason: ;AN000; 219 ; CLC ;AN000;;FT. clear acrry 220 ; MOV [SI.EA_RC],AL ;AN000;;FT. set reason code 221 ; DEC CX ;AN000;;FT. end of set ? 222 ; JZ OKexit ;AN000;;FT. yes 223 224 ; MOV AL,[SI.EA_NAMELEN] ;AN000;;FT. 225 ; XOR AH,AH ;AN000;;FT. 226 ; ADD AX,[SI.EA_VALLEN] ;AN000;;FT. 227 ; ADD SI,EA_NAME ;AN000;;FT. 228 ; ADD SI,AX ;AN000;;FT. es:di -> next EA entry 229 ; JMP set_next ;AN000;;FT. 230 ;toset: ;AN000; 231 ; CALL SET_ONE_EA ;AN000;;FT. set it 232 ; JMP set_reason ;AN000;;FT. 233 insuff_space: ;AN000;;FT. 234 ; MOV AX,error_not_enough_memory ;AN000;FT. insufficient memory err 235 ; STC ;AN000; 236 OKexit: ;AN000; 0 00007884 C3 return ;AN000; 238 239 EndProc GetSet_XA ;AN000; 240 241 242 ; Input: [SAVE_ES]:[SAVE_DI] points to buffer 243 ; [SAVE_BX]= returned size 244 ; DX= returned count 245 ; Function: set returned size and count ;AN000; 246 ; Output: none 247 ;AN000; 248 ;procedure Set_Output,NEAR ;AN000; 249 ; ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; 250 ; ;AN000; 251 ; LES DI,DWORD PTR [SAVE_DI] ;FT. es:di -> count ;AN000; 252 ; MOV [ES:DI],DX ;FT. ;AN000; 253 ; MOV BX,[SAVE_BX] ;FT. cx=size returned ;AN000; 254 ; invoke get_user_stack ;FT. get user stack ;AN000; 255 ; MOV [SI.user_CX],BX ;FT. ;AN000; 256 ; return ;FT. ;AN000; 257 ; ;AN000; 258 ;EndProc Set_Output ;AN000; 259 260 261 ; Input: DS:SI= query EA addr ;AN000; 262 ; Function: search the EA ;AN000; 263 ; Output: carry clear 264 ; DX= EA ID (0 codpage, 1 Filetype, etc.) 265 ; ES:DI points to found entry 266 ; carry set, not found, AL= reason code ;AN000; 267 ;AN000; 268 ;procedure Search_EA,NEAR ;AN000; 269 ; ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; 270 ; ;AN000; 271 ; PUSH CX ;FT. save entry count ;AN000; 272 ; MOV AL,EARCNOTFOUND ;FT. preset error code ;AN000; 273 ; MOV BL,[SI.QEA_NAMELEN] ;FT. ? ;AN000; 274 ; CMP [XA_TYPE],4 ;FT. set ? ;AN000; 275 ; JNZ gettyp ;FT. no ;AN000; 276 ; MOV BL,[SI.EA_NAMELEN] ;FT. ? ;AN000; 277 ;gettyp: 278 ; OR BL,BL ;FT. ;AN000; 279 ; JZ not_found ;FT. ;AN000; 280 ; PUSH CS ;FT. ds:si-> EA entry addr ;AN000; 281 ; POP ES ;FT. ;AN000; 282 ; MOV DI,OFFSET XA_TABLE wrt DOSGROUP ;FT. ;AN000; 283 ; MOV CX,XA_COUNT ;FT. cx= number of EA entries ;AN000; 284 ; XOR DX,DX ;FT. dx=0, codepage id ;AN000; 285 ; 286 ;start_find: 287 ; PUSH CX ;FT. save entry count ;AN000; 288 ; MOV CL,BL ;FT. ;AN000; 289 ; XOR CH,CH ;FT. get name len ;AN000; 290 ; PUSH SI ;FT. ;AN000; 291 ; PUSH DI ;FT. ;AN000; 292 ; CMP [XA_TYPE],4 ;FT. set ? ;AN000; 293 ; JNZ gettyp2 ;FT. no ;AN000; 294 ; ADD SI,EA_NAME ;FT. ;AN000; 295 ; JMP short updi ;FT. ;AN000; 296 ;gettyp2: 297 ; ADD SI,QEA_NAME ;FT. compare EA names ;AN000; 298 ;updi: 299 ; ADD DI,EA_NAME ;FT. ;AN000; 300 ; REP CMPSB ;FT. ;AN000; 301 ; POP DI ;FT. ;AN000; 302 ; POP SI ;FT. ;AN000; 303 ; POP CX ;FT. ;AN000; 304 ; JNZ not_matched ;FT. name not matched ;AN000; 305 ; MOV AL,EARCDEFBAD ;FT. preset error code ;AN000; 306 ; PUSH SI ;FT. ;AN000; 307 ; PUSH DI ;FT. ;AN000; 308 ; CMPSB ;FT. compare type ;AN000; 309 ; JNZ not_matched2 ;FT. type not matched ;AN000; 310 ; CMPSW ;FT. compare flags ;AN000; 311 ; JNZ not_matched2 ;FT. flag not matched ;AN000; 312 ; POP DI ;FT. ;AN000; 313 ; POP SI ;FT. found one ;AN000; 314 ; JMP SHORT found_one ;FT. ;AN000; 315 ;not_matched: 316 ; DEC CX ;FT. end of table ;AN000; 317 ; JZ not_found ;FT. yes ;AN000; 318 ; MOV AL,[ES:DI.EA_NAMELEN] ;FT. ;AN000; 319 ; XOR AH,AH ;FT. ;AN000; 320 ; 321 ; ADD DI,EA_NAME ;FT. ;AN000; 322 ; ADD DI,AX ;FT. es:di -> next EA entry ;AN000; 323 ; INC DX ;FT. increment EA ID ;AN000; 324 ; JMP start_find ;FT. ;AN000; 325 ;not_matched2: 326 ; POP DI ;FT. ;AN000; 327 ; POP SI ;FT. ;AN000; 328 ; JMP not_matched ;FT. ;AN000; 329 ;not_found: 330 ; STC ;FT. ;AN000; 331 ;found_one: 332 ; POP CX ;FT. ;AN000; 333 ; return ;FT. ;AN000; 334 ;AN000; 335 ;EndProc Search_EA ;AN000; 336 ;AN000; 337 ; Input: ES:DI= buffer address ;AN000; 338 ; DS:SI= EA entry address 339 ; [SAVE_CX]= buffer size 340 ; AL = reason code 341 ; Function: move one query entry to buffer ;AN000; 342 ; Output: carry clear 343 ; DS:SI points to next entry 344 ; ES:DI points to next entry 345 ; [SAVE_CX],[SAVE_BX], updated ;AN000; 346 ; carry set, insufficient memory error ;AN000; 347 ;AN000; 348 ;procedure COPY_QEA,NEAR ;AN000; 349 ; ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; 350 ; ;AN000; 351 ; PUSH CX ;FT. ;AN000; 352 ; MOV DL,AL ;FT. ;AN000; 353 ; MOV CX,EA_NAME -EA_TYPE ;FT. ;AN000; 354 ; 355 ; MOV BL,[SI.QEA_NAMELEN] ;FT. ;AN000; 356 ; XOR BH,BH ;FT. ;AN000; 357 ; ADD CX,BX ;FT. cx= query EA size ;AN000; 358 ; CMP CX,[SAVE_CX] ;FT. > buffer size ;AN000; 359 ; JA sizeshort2 ;FT. yes ;AN000; 360 ; PUSH CX ;FT. ;AN000; 361 ; LODSB ;FT. move type ;AN000; 362 ; STOSB ;FT. ;AN000; 363 ; LODSW ;FT. ;AN000; 364 ; STOSW ;FT. move flag ;AN000; 365 ; MOV AL,DL ;FT. move RC ;AN000; 366 ; STOSB ;FT. ;AN000; 367 ; 368 ; LODSB ;FT. move name len ;AN000; 369 ; MOV CL,AL ;FT. ;AN000; 370 ; STOSB ;FT. ;AN000; 371 ; XOR AX,AX ;FT. zero value length ;AN000; 372 ; STOSW ;FT. ;AN000; 373 ; OR CL,CL ;FT. ;AN000; 374 ; JZ zeroname ;FT. ;AN000; 375 ; XOR CH,CH ;FT. ;AN000; 376 ; 377 ; REP MOVSB ;FT. move EA to buffer ;AN000; 378 ;zeroname: 379 ; POP CX ;FT. ;AN000; 380 ; ADD [SAVE_BX],CX ;FT. bx=bx+entry size ;AN000; 381 ; SUB [SAVE_CX],CX ;FT. update buffer size ;AN000; 382 ; CLC ;FT. ;AN000; 383 ; JMP SHORT okget2 ;FT. ;AN000; 384 ; 385 ;sizeshort2: 386 ; MOV AX,error_not_enough_memory ;FT. error ;AN000; 387 ; STC ;FT. ;AN000; 388 ;okget2: 389 ; POP CX ;FT. ;AN000; 390 ; return ;FT. ;AN000; 391 ; ;AN000; 392 ;EndProc COPY_QEA ;AN000; 393 ;AN000; 394 ; Input: ES:DI= found EA entry addr ;AN000; 395 ; DS:SI= source EA entry address 396 ; DX= EA ID (0 codpage, 1 Filetype, etc.) 397 ; Function: set one EA ;AN000; 398 ; Output: carry clear 399 ; EA set 400 ; carry set, AL= reason code ;AN000; 401 ;AN000; 402 ;procedure SET_ONE_EA,NEAR ;AN000; 403 ; ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; 404 ; ;AN000; 405 ; PUSH CX ;FT. ;AN000; 406 ; MOV AL,EARCDEFBAD ;FT. prseet error code ;AN000; 407 ; MOV BX,[SI.EA_VALLEN] ;FT. ;AN000; 408 ; CMP BX,[ES:DI.EA_VALLEN] ;FT. length equal ? ;AN000; 409 ; JNZ notset ;FT. no ;AN000; 410 ; PUSH DS ;FT. ;AN000; 411 ; PUSH SI ;FT. ;AN000; 412 ; MOV AL,[SI.EA_NAMELEN] ;FT. ;AN000; 413 ; XOR AH,AH ;FT. ;AN000; 414 ; ADD SI,EA_NAME ;FT. ;AN000; 415 ; ADD SI,AX ;FT. ;AN000; 416 ; CMP DX,0 ;FT. ;AN000; 417 ; JNZ set_filetyp ;FT. ;AN000; 418 ; LODSW ;FT. ;AN000; 419 ; CMP [XA_DEVICE],0 ;FT. device ? ;AN000; 420 ; JZ notdevice ;FT. no ;AN000; 421 ; OR AX,AX ;FT. code page 0 ? ;AN000; 422 ; JZ NORM0 ;FT. yes ;AN000; 423 ; 424 ; CALL GSetDevCdPg ;FT. ;AN000; 425 ; JNC welldone ;FT. ;AN000; 426 ; CMP [CPSWFLAG],0 ;FT. code page matching on ;AN000; 427 ; JZ NORM0 ;FT. no ;AN000; 428 ; invoke SAVE_WORLD ;FT. save all regs ;AN000; 429 ; LDS SI,[THISSFT] ;FT. ds:si -> sft ;AN000; 430 ; LDS SI,[SI.sf_devptr] ;FT. ds:si -> device header ;AN000; 431 ; MOV BP,DS ;FT. save all regs ;AN000; 432 ; invoke Code_Page_Mismatched_Error ;FT. ;AN000; 433 ; CMP AL,0 ;FT. ignore ? ;AN000; 434 ; JZ NORM1 ;FT. ;AN000; 435 ; invoke RESTORE_WORLD ;FT. save all regs ;AN000; 436 ;NORM0: 437 ; MOV AL,EARCDEVERROR ;FT. ;AN000; 438 ; STC ;FT. ;AN000; 439 ; JMP SHORT sdone ;FT. ;AN000; 440 ;NORM1: 441 ; invoke RESTORE_WORLD ;FT. save all regs ;AN000; 442 ; JMP SHORT welldone ;FT. ;AN000; 443 ;notdevice: 444 ; LDS SI,[THISSFT] ;FT. ;AN000; 445 ; MOV [SI.sf_CodePage],AX ;FT. set codepege ;AN000; 446 ; JMP SHORT welldone ;FT. 447 ;set_filetyp: 448 ; LODSB ;FT. ;AN000; 449 ; LDS SI,[THISSFT] ;FT. set filtype ;AN000; 450 ; MOV [SI.sf_ATTR_HI],AL ;FT. ;AN000; 451 ; 452 ;welldone: 453 ; XOR AL,AL ;FT. success ;AN000; 454 ;sdone: 455 ; POP SI ;FT. ;AN000; 456 ; POP DS ;FT. ;AN000; 457 ;notset: 458 ; POP CX ;FT. ;AN000; 459 ; return ;FT. ;AN000; 460 ;AN000; 461 ;EndProc SET_ONE_EA ;AN000; 462 ;AN000; 463 ; Input: ES:DI= buffer address ;AN000; 464 ; DS:SI= EA entry address 465 ; [SAVE_CX]= buffer size available 466 ; [SAVE_BX]= size returned 467 ; DX= EA ID (0 codpage, 1 Filetype, etc.) 468 ; Function: move one EA entry to the buffer ;AN000; 469 ; Output: carry clear 470 ; DS:SI points to next entry 471 ; ES:DI points to next entry 472 ; [SAVE_CX],BX, updated ;AN000; 473 ; carry set, insufficient memory error ;AN000; 474 ;AN000; 475 ;procedure GET_ONE_EA,NEAR ;AN000; 476 ; ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; 477 ; ;AN000; 478 ; PUSH CX ;FT. ;AN000; 479 ; CMP [XA_TYPE],2 ;FT. type 2 ? ;AN000; 480 ; JZ gtyp2 ;FT. yes ;AN000; 481 ; MOV CX,QEA_NAME - QEA_TYPE ;FT. ;AN000; 482 ; JMP SHORT addnmlen ;FT. 483 ;gtyp2: 484 ; MOV CX,EA_NAME - EA_TYPE ;FT. cx = EA entry size ;AN000; 485 ; ADD CX,[SI.EA_VALLEN] ;FT. ;AN000; 486 ;addnmlen: 487 ; MOV AL,[SI.EA_NAMELEN] ;FT. 488 ; XOR AH,AH ;FT. ;AN000; 489 ; ADD CX,AX ;FT. ;AN000; 490 ; CMP CX,[SAVE_CX] ;FT. > buffer size ;AN000; 491 ; JA sizeshort ;FT. yes ;AN000; 492 ; PUSH CX ;FT. ;AN000; 493 ; LODSB ;FT. move type ;AN000; 494 ; STOSB ;FT. ;AN000; 495 ; LODSW ;FT. ;AN000; 496 ; STOSW ;FT. move flag ;AN000; 497 ; LODSB ;FT. EA list need RC ;AN000; 498 ; CMP [XA_TYPE],2 ;FT. ;AN000; 499 ; JNZ norc ;FT. ;AN000; 500 ; STOSB ;FT. ;AN000; 501 ;norc: 502 ; LODSB ;FT. move name len ;AN000; 503 ; STOSB ;FT. ;AN000; 504 ; MOV CL,AL ;FT. ;AN000; 505 ; XOR CH,CH ;FT. ;AN000; 506 ; LODSW ;FT. EA list need value len ;AN000; 507 ; CMP [XA_TYPE],2 ;FT. ;AN000; 508 ; JNZ novalen ;FT. ;AN000; 509 ; STOSW ;FT. ;AN000; 510 ;novalen: 511 ; 512 ; REP MOVSB ;FT. move EA to buffer ;AN000; 513 ; CMP [XA_TYPE],2 ;FT. ;AN000; 514 ; JNZ novalue ;FT. ;AN000; 515 ; CALL GET_VALUE ;FT. get value for type 2 ;AN000; 516 ;novalue: 517 ; POP CX ;FT. ;AN000; 518 ; ADD [SAVE_BX],CX ;FT. add entry size ;AN000; 519 ; LES DI,DWORD PTR [SAVE_DI] ;FT. ;AN000; 520 ; ADD DI,[SAVE_BX] ;FT. es:di -> next entry ;AN000; 521 ; SUB [SAVE_CX],CX ;FT. update buffer size ;AN000; 522 ; CLC ;FT. ;AN000; 523 ; JMP SHORT okget ;FT. ;AN000; 524 ; 525 ;sizeshort: 526 ; MOV AX,error_not_enough_memory ;FT. error ;AN000; 527 ; STC ;FT. ;AN000; 528 ;okget: 529 ; POP CX ;FT. ;AN000; 530 ; return ;FT. ;AN000; 531 ; ;AN000; 532 ;EndProc GET_ONE_EA ;AN000; 533 ;AN000; 534 ;AN000; 535 ; Input: DX= EA ID (0 codpage, 1 Filetype, etc.) 536 ; [THISSFT]= points to SFT 537 ; ES:DI= buffer address of EA value 538 ; [XA_DEVICE]=0 file, 1 device 539 ; Function: get attribute ;AN000; 540 ; Output: none ;AN000; 541 ; ;AN000; 542 ;AN000; 543 ;procedure GET_VALUE,NEAR ;AN000; 544 ; ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; 545 ; ;AN000; 546 ; PUSH DS ;FT. save ds:si ;AN000; 547 ; PUSH SI ;FT. ;AN000; 548 ; LDS SI,[ThisSFT] ;FT. ds:si -> SFT ;AN000; 549 ; 550 ; CMP DX,0 ;FT. code page ? ;AN000; 551 ; JNZ eafiltyp ;FT. no ;AN000; 552 ; CMP [XA_DEVICE],0 ;FT. device ? ;AN000; 553 ; JZ notdev ;FT. no ;AN000; 554 ; CALL GSetDevCdPg ;FT. do ioctl invoke ;AN000; 555 ; JNC okcdpg ;FT. error ? ;AN000; 556 ; PUSH DI ;FT. ;AN000; 557 ; XOR AX,AX ;FT. make code page 0 ;AN000; 558 ; LES DI,DWORD PTR [SAVE_DI] ;FT. ;AN000; 559 ; ADD DI,[SAVE_BX] ;FT. es:di -> beginning of entry ;AN000; 560 ; MOV [ES:DI.EA_RC],EARCNOTFOUND ;FT. ;AN000; 561 ; POP DI ;FT. ;AN000; 562 ; JMP SHORT okcdpg ;FT. ;AN000; 563 ;notdev: 564 ; MOV AX,[SI.sf_CodePage] ;FT. get code page from sft ;AN000; 565 ;okcdpg: 566 ; STOSW ;FT. put in buffer ;AN000; 567 ; JMP SHORT gotea ;FT. ;AN000; 568 ;eafiltyp: 569 ; MOV AL,[SI.sf_ATTR_HI] ;FT. get high attribute ;AN000; 570 ; STOSB ;FT. put in buffer ;AN000; 571 ; 572 ;gotea: 573 ; POP SI ;FT. retore regs ;AN000; 574 ; POP DS ;FT. ;AN000; 575 ; return ;FT. ;AN000; 576 ;EndProc GET_VALUE ;AN000; 577 ;AN000; 578 ;AN000; 579 ; Input: [XA_handle] = device handle ;AN000; 580 ; [XA_type] = 4 , set ;AN000; 581 ; AX= code page (set) 582 ; 2,3 get ;AN000; 583 ; Function: get or set device code page ;AN000; 584 ; Output: carry clear, AX= device code page (get) ;AN000; 585 ; carry set, error ;AN000; 586 ;AN000; 587 ;procedure GSetDevCdPg,near ;AN000; 588 ; ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; 589 ; ;AN000; 590 ; invoke SAVE_WORLD ;FT. save all regs ;AN000; 591 ; CMP [XA_type],4 ;FT. set ? ;AN000; 592 ; JZ setpg ;FT. yes ;AN000; 593 ; MOV CX,6AH ;FT. get selected code page ;AN000; 594 ; JMP SHORT dogset ;FT. ;AN000; 595 ;setpg: ;AN000; 596 ; MOV CX,4AH ;FT. set code page ;AN000; 597 ;IF DBCS 598 ; 599 ; invoke Save_World ;FT. save all regs ;AN000; 600 ; MOV BX,AX ;FT. bx= code page id ;AN000; 601 ; MOV AL,7 ;FT. get DBCS vectors ;AN000; 602 ; MOV DX,-1 ;FT. get current country ;AN000; 603 ; MOV CX,5 ;FT. minimum size ;AN000; 604 ; MOV DI,OFFSET DBCS_PACKET wrt DOSGROUP ;FT. ;AN000; 605 ; PUSH CS ;FT. ;AN000; 606 ; POP ES ;FT. ;AN000; 607 ; invoke $GetExtCntry ;FT. get DBCS vectors ;AN000; 608 ; JC nlsfunc_err ;FT. error ;AN000; 609 ; LDS SI,DWORD PTR DBCS_PACKET+1 ;FT. ;AN000; 610 ; LODSW ;FT. get vector length ;AN000; 611 ; MOV CX,AX ;FT. cx=length ;AN000; 612 ; 613 ; MOV DI,OFFSET XA_PACKET+4 wrt DOSGROUP ;FT. ;AN000; 614 ; PUSH CS ;FT. ;AN000; 615 ; POP ES ;FT. ;AN000; 616 ; REP MOVSB ;FT. ;AN000; 617 ; CLC ;FT. ;AN000; 618 ;nlsfunc_err: 619 ; invoke RESTORE_WORLD ;FT. restore all regs ;AN000; 620 ; JC deverr ;FT. ;AN000; 621 ; 622 ;ENDIF 623 ; MOV WORD PTR [XA_PACKET+2],AX ;FT. ;AN000; 624 ;dogset: ;AN000; 625 ; MOV BX,[XA_handle] ;FT. set up handle ;AN000; 626 ; PUSH CS ;FT. ds:dx -> packet ;AN000; 627 ; POP DS ;FT. ;AN000; 628 ; MOV DX,OFFSET XA_PACKET wrt DOSGROUP ;FT. ;AN000; 629 ; MOV AX,440CH ;FT. IOCTL to char device by handle ;AN000; 630 ; invoke $IOCTL ;FT. issue get code page ;AN000; 631 ; JC deverr ;FT. error ;AN000; 632 ; invoke RESTORE_WORLD ;FT. restore all regs ;AN000; 633 ; MOV AX,WORD PTR [XA_PACKET+2] ;FT. get code page ;AN000; 634 ; return ;FT. ;AN000; 635 ;deverr: ;AN000; 636 ; invoke RESTORE_WORLD ;FT. restore all regs ;AN000; 637 ; return ;FT. exit ;AN000; 638 ; ;AN000; 639 ;EndProc GSetDevCdPg ;AN000; 640 ;AN000; 641 642 ; Input: DS:SI -> query list 643 ; 644 ; Function: get max size ;AN000; 645 ; Output: CX= size 646 ; carry set error 647 ;AN000; 648 ;procedure Get_max_EA_size,NEAR ;AN000; 649 ; ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000; 650 ; ;AN000; 651 ; CMP [SAVE_SI],0FFFFH ;FT. get all ? ;AN000; 652 ; JNZ scan_query ;FT. no ;AN000; 653 ; MOV CX,[MAX_EA_SIZE] ;FT. get max EA size ;AN000; 654 ; JMP SHORT gotit ;FT. 655 ;scan_query: 656 ; LDS SI,DWORD PTR [SAVE_SI] ;FT. ds:si -> query list ;AN000; 657 ; LODSW ;FT. ax= number of entries ;AN000; 658 ; MOV [SAVE_CX],AX ;FT. ;AN000; 659 ; XOR CX,CX ;FT. set initial size to 0 ;AN000; 660 ; OR AX,AX ;FT. if no entris ;AN000; 661 ; JZ gotit ;FT. then return ;AN000; 662 ; MOV CX,2 ;FT. at lesat 2 ;AN000; 663 ;NEXT_QEA: 664 ; CALL Search_EA ;FT. search EA ;AN000; 665 ; JC serror ;FT. wrong EA ;AN000; 666 ; ADD CX,size EA ;FT. get EA size ;AN000; 667 ; ADD CL,[ES:DI.EA_NAMELEN] ;FT. ;AN000; 668 ; ADC CH,0 ;FT. ;AN000; 669 ; ADD CX,[ES:DI.EA_VALLEN] ;FT. ;AN000; 670 ; DEC CX ;FT. ;AN000; 671 ; DEC [SAVE_CX] ;FT. end of entris ;AN000; 672 ; JZ gotit ;FT. no ;AN000; 673 ; MOV AL,[SI.QEA_NAMELEN] ;FT. update to next QEA ;AN000; 674 ; XOR AH,AH ;FT. update to next QEA ;AN000; 675 ; ADD SI,AX ;FT. update to next QEA ;AN000; 676 ; ADD SI,size QEA ;FT. ;AN000; 677 ; DEC SI ;FT. ;AN000; 678 ; JMP next_QEA ;FT. do next ;AN000; 679 ;serror: 680 ; MOV AX,error_invalid_data ;FT. set initial size to 0 ;AN000; 681 ;gotit: ;FT. ;AN000; 682 ; return ;FT. exit ;AN000;;FT. exit ;AN000; 683 ; 684 ;EndProc Get_max_EA_size ;FT. exit ;AN000; ;AN000; 685 ;AN000; 686 END ;AN000; === Trace listing source: ../DOS/ifs.lst 1 2 3 4 [list -] ;AN000; === Switch to base=008400h -> "DOSCODECODE" 8 section DOSCODECODE 9 [list -] 9 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 9 ****************** warning: out: BPB.INC... [-w+user] 9 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 9 ****************** warning: out: DEVSYM.INC... [-w+user] 16 StackSize equ 180h ; gross but effective 17 18 i_need VERFLG ; verify status flag ;AN000; 19 i_need CNTCFLAG ; break status flag ;AN000; 20 i_need CPSWFLAG ; CP switch logic ON/OFF ;AN000; 21 I_need CURRENTPDB,WORD ; Current process identifier ;AN000; 22 I_need HIGH_SECTOR,WORD ;AN000; 23 I_need BUF_HASH_COUNT,WORD ;AN000; 24 I_need FAILERR,WORD ;AN000; 25 I_need USER_ID,WORD ;AN000; 26 I_need CALLDEVAD,DWORD ; ;AN000; 27 I_need SYSINITVAR,WORD ;AN000; 28 I_need MYNAME,16 ; NetBIOS name ;AN000; 29 I_need RETRYCOUNT,WORD ; retry count ;AN000; 30 I_need COUNTRY_CDPG,BYTE ;AN000; 31 i_need DAY,BYTE ; date ;AN000; 32 i_need MONTH,BYTE ;AN000; 33 i_need YEAR,WORD ;AN000; 34 i_need CURBUF,DWORD ;AN000; 35 i_need IFS_DRIVER_ERR,WORD ;AN000; 36 i_need DOS34_FLAG,WORD ; IFS function Read/Write flag ;AN000; 37 i_need Callback_SS,WORD ; ;AN000; 38 i_need Callback_SP,WORD ;AN000; 39 i_need SaveBX,WORD ;AN000; 40 i_need Temp_Var,WORD ;AN000; 41 i_need INDOS,BYTE ;AN000; 42 i_need DskStack,BYTE ;AN000; 43 i_need IOStack,BYTE ;AN000; 44 i_need Callback_flag,BYTE ;AN000; 45 46 DOSINFO STRUC ;AN000; 0 00007885 ???? bsize dw ? ;AN000; 0 00007887 ???? files dw ? ;AN000; 0 00007889 ???? fcbs1 dw ? ;AN000; 0 0000788B ???? fcbs2 dw ? ;AN000; 0 0000788D ???? buffers dw ? ;AN000; 0 0000788F ???? dw ? ;AN000; 0 00007891 ???? lastdrv dw ? ;AN000; 0 00007893 ???? secsize dw ? ;AN000; 55 DOSINFO ENDS ;AN000; 56 57 58 59 extrn ABSDRD:NEAR ;AN000; 60 extrn ABSDWRT:NEAR ;AN000; 61 extrn READTIME:NEAR ;AN000; 62 extrn CHECKFLUSH:NEAR ;AN000; 63 extrn GETCURHEAD:NEAR ;AN000; 64 65 66 ;****************************************************************************** 67 ; * 68 ; * MODULE: IFS_DOSCALL 69 ; * 70 ; * FUNCTION: IFS to DOS function request dispatcher 71 ; * 72 ; * FUNCTION: This procedure dispatches the IFS DOS service requests 73 ; * by calling various DOS service routines 74 ; * 75 ; * CALLING SEQUENCE: 76 ; * 77 ; * CALL DWORD PTR IFS_DOSCALL@ 78 ; * 79 ; * 80 ; * RETURN SEQUENCE: 81 ; * 82 ; * If AX = 0 No error 83 ; * 84 ; * If AX <> 0 Error 85 ; * AX = Error Code: 86 ; * 87 ; * 88 ; * INTERNAL REFERENCES: None 89 ; * 90 ; * 91 ; * EXTERNAL REFERENCES: STRATEGY, INTERRUPT, ABSDRD, ABSDWRT, 92 ; * FIND_SECTOR, MARK_SECTOR, WRITE_BUFFR, 93 ; * READ_BUFFR, WRITE_BUFFR, FREE_BUFFR, 94 ; * GET_DOS_INFO, FLUSH_BUFF 95 ; * 96 ; * NOTES: None 97 ; * 98 ; * REVISION HISTORY: New 99 ; * 100 ; * COPYRIGHT: "MS DOS IFS Function" 101 ; * "Version 1.00 (C) Copyright 1988 Microsoft Corporation" 102 ; * "Licensed Material - Program Property of Microsoft" 103 ; * 104 ; ************************************************************************* 105 106 107 relocated ifsentry 108 PROCEDURE IFS_DOSCALL,FAR ;AN000; 108 ****************** warning: proc IFS_DOSCALL... [-w+user] 109 assume DS:NOTHING,ES:NOTHING ;AN000; 110 0 00007885 FA CLI ; ;AN000; 112 113 extern doscode_getdosdata 114 0 00007886 1E push ds 0 00007887 50 push ax 0 00007888 E8[0000] call doscode_getdosdata 0 0000788B 8ED8 mov ds, ax 0 0000788D 58 pop ax 120 0 0000788E 80FC27 CMP AH,39 ; ;AN000; 0 00007891 7507 JNZ others ; ;AN000; 0 00007893 FE06[0000] INC byte [INDOS] ; in DOS ;AN000; 0 00007897 E9AC00 JMP Dosend_ds ; ;AN000; 125 others: 0 0000789A 80FC28 CMP AH,40 ; ;AN000; 0 0000789D 7507 JNZ others2 ; ;AN000; 0 0000789F FE0E[0000] DEC byte [INDOS] ; out DOS ;AN000; 0 000078A3 E9A000 JMP Dosend_ds ; ;AN000; 130 others2: 0 000078A6 80FC26 CMP AH,38 ; ;AN000; 0 000078A9 750D JNZ not_stack ; ;AN000; 0 000078AB 83C402 add sp, 2 0 000078AE 1E push ds 135 IOSTACK equ IOStack ; NASM port label 0 000078AF BE[0000] MOV SI,OFFSET IOSTACK wrt DOSGROUP ;AN000; 137 stacksize equ StackSize ; NASM port equate 0 000078B2 B98001 MOV CX,stacksize ;AN000; 0 000078B5 E98E00 JMP Dosend_ds ; ;AN000; 140 ; ;AN000; 141 not_stack: ; ;AN000; 0 000078B8 8F06[0000] pop word [Temp_Var] ; save ds for strcmp strcpy ;AN000; 143 assume DS:DOSGROUP ;AN000; 0 000078BC FE06[0000] INC byte [INDOS] ; in DOS ;AN000; 0 000078C0 51 PUSH CX ; save cx ;AN000; 0 000078C1 52 PUSH DX ; save cx ;AN000; 0 000078C2 8CD1 MOV CX,SS ; cx=stack ;AN000; 0 000078C4 8CDA MOV DX,ds ; cx=stack ;AN000; 0 000078C6 39D1 CMP CX,DX ; dosgroup stack ? ;AN000; 0 000078C8 5A POP DX ; save cx ;AN000; 0 000078C9 59 POP CX ; restore cx ;AN000; 0 000078CA 741C JZ withSS_SP ; yes ;AN000; 0 000078CC 8C16[0000] MOV [Callback_SS],SS ;save SS:SP ;AN000; 0 000078D0 8926[0000] MOV [Callback_SP],SP ;AN000; 0 000078D4 891E[0000] MOV [SaveBX],BX ; ;AN000; 0 000078D8 8CDB MOV BX,ds ; prepare system stack ;AN000; 0 000078DA 8ED3 MOV SS,BX ; ;AN000; 158 DSKSTACK equ DskStack ; NASM port label 0 000078DC BC[0000] MOV SP,OFFSET DSKSTACK wrt DOSGROUP ;AN000; 0 000078DF 8B1E[0000] MOV BX,[SaveBX] ; ;AN000; 0 000078E3 C606[0000]01 MOV byte [Callback_flag],1 ;set flag ;AN000; 162 withSS_SP: ; ;AN000; 0 000078E8 FB STI ;AN000; 164 ASSUME DS:NOTHING ;AN000; 165 ; OR [DOS34_FLAG],Force_I24_Fail ;AN000; 166 ; ;AN000; 167 ; cmp ah,0 ; call Strategy routine ?? ;AN000; 168 ; jne dos_chk_ah1 ; jump if not ;AN000; 169 ; CALL STRATEGY ; else call strategy routine ;AN000; 170 ; jmp dos_exit ; then exit ;AN000; 171 ;AN000; 172 ;Dos_Chk_Ah1: ;AN000; 173 ; cmp ah,1 ; call interrupt routine ;AN000; 174 ; jne dos_chk_ah2 ; jump if not ;AN000; 175 ; CALL INTERRUPT ; else call interrupt routine ;AN000; 176 ; jmp dos_exit ; then exit ;AN000; 177 ;AN000; 178 ;Dos_Chk_Ah2: ;AN000; 179 ; cmp ah,4 ;AN000; 180 ; jae Dos_Chk_Ah8 ;AN000; 181 ; mov High_Sector,si ; save HI sector word ;AN000; 182 ; mov dx,di ; save low sector ;AN000; 183 ; push es ;AN000; 184 ; invoke FIND_DPB ; ds:si -> DPB ;AN000; 185 ; mov bp,si ;AN000; 186 ; push ds ;AN000; 187 ; pop es ; es:bp -> DPB ;AN000; 188 ; pop ds ; DS:BX-->Input buffer ;AN000; 189 ; 190 ; cmp ah,2 ; absolute read ?? ;AN000; 191 ; jne dos_chk_ah3 ; jump if not ;AN000; 192 ; 193 ; invoke DSKREAD ; else do absolute read ;AN000; 194 ; jmp dos_exit ; then return ;AN000; 195 196 ;Dos_Chk_Ah3: ;AN000; 197 ; invoke DSKWRITE ; do absolute write ;AN000; 198 ; jmp dos_exit ; then exit ;AN000; 199 200 201 202 Dos_chk_ah32: ;AN000; 0 000078E9 80FC20 cmp ah,32 0 000078EC 7505 jne str_cmp ;AN000; 0 000078EE E85B00 CALL GET_DOS_INFO ; else get DOS information ;AN000; 206 dos_exit equ Dos_Exit ; NASM port label 0 000078F1 EB1A jmp SHORT dos_exit ;AN000; ;AN000; 208 str_cmp: ;AN000; 0 000078F3 368E1E[0000] mov DS,[ss:Temp_Var] ; restore DS ;AN000; 0 000078F8 80FC24 cmp ah,36 ;AN000; 0 000078FB 7505 jne str_cpy ;AN000; 0 000078FD E8[0000] invoke strcmp ; string compare ;AN000; 0 00007900 EB0B jmp SHORT dos_exit ;AN000; 214 str_cpy: ;AN000; 0 00007902 80FC25 cmp ah,37 ;AN000; 216 dos_error equ Dos_Error ; NASM port label 0 00007905 7505 jne dos_error ;AN000; 0 00007907 E8[0000] invoke strcpy ; string copy ;AN000; 0 0000790A EB01 jmp SHORT dos_exit ;AN000; 220 221 Dos_Error: ;AN000; 0 0000790C F9 stc 223 ;AN000; 224 Dos_Exit: ;AN000; 0 0000790D FA CLI ;AN000; 0 0000790E 9C PUSHF ;AN000; 227 No_Force_I24_Fail equ NO_Force_I24_Fail ; NASM port equate 0 0000790F 368326[0000]DF AND word [ss:DOS34_FLAG],No_Force_I24_Fail ;AN000; 0 00007915 36FE0E[0000] DEC byte [ss:INDOS] ; exit DOS ;AN000; 0 0000791A 36803E[0000]00 CMP byte [ss:Callback_flag],0 ;from dosgroup 0 00007920 7427 JZ noSS_SP ;yes ;AN000; 0 00007922 36C606[0000]00 MOV byte [ss:Callback_flag],0 ; ;AN000; 233 ; fl on stack 0 00007928 56 push si 0 00007929 1E push ds 0 0000792A 368E1E[0000] mov ds, [ss:Callback_SS] 0 0000792F 368B36[0000] mov si, [ss:Callback_SP] ; ds:si -> user stack 0 00007934 4E dec si 0 00007935 4E dec si ; make space for another word 0 00007936 8F04 pop word [si] ; ds 0 00007938 4E dec si 0 00007939 4E dec si 0 0000793A 8F04 pop word [si] ; si 0 0000793C 4E dec si 0 0000793D 4E dec si 0 0000793E 8F04 pop word [si] ; fl 0 00007940 1E push ds 0 00007941 17 pop ss ; switch stacks 0 00007942 89F4 mov sp, si 0 00007944 9D popf ; fl 0 00007945 5E pop si ; si 252 ; ds left on stack 253 Dosend_ds: 0 00007946 1F pop ds 0 00007947 FB STI ; ;AN000; 0 00007948 CB retf ;return ;AN000; 257 258 noSS_SP: ;AN000; 0 00007949 9D POPF 0 0000794A FB sti 0 0000794B CB retf 262 263 264 ENDPROC IFS_DOSCALL ;AN000; 265 266 267 268 269 270 ; **************************************************************************** 271 ; * 272 ; * MODULE: STRATEGY 273 ; * 274 ; * FUNCTION: Call Strategy Routine 275 ; * 276 ; * FUNCTION: This procedure dispatches the IFS DOS service requests 277 ; * by calling various DOS service functions 278 ; * 279 ; * INPUT: ES:BX ---> Device Request Header 280 ; * AL = Drive # 281 ; * 282 ; * CALL STRATEGY 283 ; * 284 ; * OUTPUT: output of driver 285 ; * 286 ; * INTERNAL REFERENCES: None 287 ; * 288 ; * 289 ; * EXTERNAL REFERENCES: GETTHISDRV 290 ; * 291 ; * NOTES: None 292 ; * 293 ; * REVISION HISTORY: New 294 ; * 295 ; ************************************************************************* 296 297 ;PROCEDURE STRATEGY,NEAR ;AN000; 298 299 ; INVOKE FIND_DPB ; get DPB from drive number ;AN000; 300 ; ; DS:SI-->DPB for drive ;AN000; 301 ; LDS DI,[DS:SI.DPB_Driver_Addr] ; get driver addres from DPB ;AN000; 302 ; MOV DX,WORD PTR [DI.SDEVSTRAT] ;get strategy routine address;AN000; 303 ;Driver_Call: ;AN000; 304 ; MOV WORD PTR [CALLDEVAD],DX ; save it ;AN000; 305 ; MOV WORD PTR [CALLDEVAD+2],DS ; ;AN000; 306 ; CALL DWORD PTR [CALLDEVAD] ; call strategy routine ;AN000; 307 ;STRAT_Exit: ;AN000; 308 ; RET ; return ;AN000; 309 310 ;ENDPROC STRATEGY ;AN000; 311 312 313 314 315 316 317 318 319 ; **************************************************************************** 320 ; * 321 ; * MODULE: INTERRUPT 322 ; * 323 ; * FUNCTION: This procedure calls the interrupt routine of the drive 324 ; * specified in the drive#. 325 ; * 326 ; * INPUT: AL = Drive # 327 ; * 328 ; * 329 ; * OUTPUT: output of driver 330 ; * 331 ; * 332 ; * INTERNAL REFERENCES: None 333 ; * 334 ; * 335 ; * EXTERNAL REFERENCES: FIND_DPB 336 ; * 337 ; * NOTES: None 338 ; * 339 ; * REVISION HISTORY: New 340 ; * 341 ; ************************************************************************* 342 343 ;PROCEDURE INTERRUPT,NEAR ;AN000; 344 345 ; INVOKE FIND_DPB ; get DPB from drive number ;AN000; 346 ; LDS DI,[DS:SI.DPB_Driver_Addr] ; get driver addres from DPB ;AN000; 347 ; MOV DX,WORD PTR [DI.SDEVINT] ; get interrupt routine addrs;AN000; 348 ; JMP Driver_Call ;AN000; 349 350 ;ENDPROC INTERRUPT ;AN000; 351 352 353 354 355 356 357 358 359 ; ************************************************************************* * 360 ; * 361 ; * MODULE: Get_Dos_Info 362 ; * 363 ; * FUNCTION: Get DOS information 364 ; * 365 ; * INPUT: AL = Dos info code 366 ; * 367 ; * OUTPUT: Dos Information in registers 368 ; * 369 ; * INTERNAL REFERENCES: None 370 ; * 371 ; * 372 ; * EXTERNAL REFERENCES: READTIME, $GETEXTCNTRY 373 ; * 374 ; * NOTES: None 375 ; * 376 ; * REVISION HISTORY: New 377 ; * 378 ; ************************************************************************* 379 380 PROCEDURE GET_DOS_INFO,NEAR ;AN000; 380 ****************** warning: proc GET_DOS_INFO... [-w+user] 381 0 0000794C 3C00 cmp al,0 ; TIME and DATE ?? ;AN000; 0 0000794E 7518 jne chk_al1 ;AN000; 384 385 ReadTime equ READTIME ; NASM port label 0 00007950 E8[0000] Invoke ReadTime ; get time in CX:DX ;AN000; 387 0 00007953 51 push cx ; save time ;AN000; 0 00007954 52 push dx ;AN000; 390 0 00007955 368B0E[0000] MOV CX,[ss:YEAR] ;AN000; 0 0000795A 81C1BC07 ADD CX,1980 ;AN000; 0 0000795E 368B16[0000] MOV DX,WORD PTR [ss:DAY] ; fetch both day and month ;AN000; 394 0 00007963 5B pop bx ; bh = seconds bl = hundredths ;AN000; 0 00007964 58 pop ax ; ah = hour al = minutes ;AN000; 397 ; cx = year dh = month ;AN000; 398 get_info_exit equ Get_Info_Exit ; NASM port label 0 00007965 EB6E jmp get_info_exit ;AN000; 0 00007967 90 nop ; identicalise 401 402 403 chk_al1: ; Active process info ?? ;AN000; 0 00007968 3C01 cmp al,1 ;AN000; 0 0000796A 750D jne chk_al2 ; no, try next ;AN000; 406 CurrentPDB equ CURRENTPDB ; NASM port label 0 0000796C 368B1E[0000] MOV BX,[ss:CurrentPDB] ; BX = active process ID ;AN000; 408 User_ID equ USER_ID ; NASM port label 0 00007971 368B16[0000] mov DX,[ss:User_ID] ; User ID ;AN000; 0 00007976 EB5D jmp get_info_exit ; exit ;AN000; 0 00007978 90 nop ; identicalise 412 413 414 chk_al2: ;AN000; 415 ; cmp al,2 ; get CPSW info ?? ;AN000; 416 ; jne chk_al3 ; jump if not ;AN000; 417 ; MOV SI,OFFSET COUNTRY_CDPG wrt DOSGROUP ;AN000; 418 ; MOV BX,[SI.ccDosCodePage] ; get dos code page id in BX ;AN000; 419 ; MOV DL,CPSWFLAG ; get CP Switch status ;AN000; 420 ; jmp get_info_exit ; exit ;AN000; 421 422 423 chk_al3: 424 ; cmp al,3 ; get CTRL BRK status ?? ;AN000; 425 ; jne chk_al4 ;AN000; 426 ; mov dl,CNTCFLAG ; DL = break status flag ;AN000; 427 ; jmp get_info_exit ; exit ;AN000; 428 429 430 chk_al4: 431 ; cmp al,4 ; get Verify status ?? ;AN000; 432 ; jne chk_al5 433 ; mov dl,VERFLG ; DL = verify status flag ;AN000; 434 ; jmp get_info_exit ; exit ;AN000; 435 436 437 chk_al5: 0 00007979 3C05 cmp al,5 ; Config.sys info ?? ;AN000; 0 0000797B 7536 jne chk_al6 ;AN000; 440 0 0000797D BE[0000] mov si,OFFSET SYSINITVAR wrt DOSGROUP ; DS:SI-->SysInitVar ;AN000; 0 00007980 1E push ds ;AN000; 0 00007981 56 push si ;AN000; 444 Sysi_SFT equ SYSI_SFT ; NASM port equate 0 00007982 C57404 lds si,[si + Sysi_SFT] ; get SFT address ;AN000; 0 00007985 8B4404 mov ax,[si + SFCount] ; get number of files ;AN000; 447 SFlink equ SFLink ; NASM port equate 0 00007988 C534 lds si,[si + SFlink] ; get next SFT table ;AN000; 0 0000798A 83FEFF cmp si,-1 ; end of table ;AN000; 0 0000798D 7403 jz nomore ; ;AN000; 0 0000798F 034404 add ax,[si + SFCount] ; ;AN000; 452 nomore: ; ;AN000; 0 00007992 26894502 mov [es:di + files],ax ; save files= value ;AN000; 0 00007996 5E pop si ;AN000; 0 00007997 1F pop ds ;AN000; 456 Sysi_MaxSec equ SYSI_MAXSEC ; NASM port equate 0 00007998 8B4410 mov ax,[si + Sysi_MaxSec] ; get maximum sector size ;AN000; 0 0000799B 2689450E mov [es:di + secsize],ax ; save files= value ;AN000; 459 Sysi_Keep equ SYSI_Keep ; NASM port equate 0 0000799F 8B441E mov ax,[si + Sysi_Keep] ; ;AN000; 0 000079A2 26894506 mov [es:di + fcbs2],ax ; ;AN000; 462 Sysi_FCB equ SYSI_FCB ; NASM port equate 0 000079A6 C5741A lds si,[si + Sysi_FCB] ; get FCB address ;AN000; 0 000079A9 8B4404 mov ax,[si + SFCount] ; get number of fcbs ;AN000; 0 000079AC 26894504 mov [es:di + fcbs1],ax ; save fcbs= value ;AN000; 0 000079B0 EB23 jmp get_info_exit ;AN000; 0 000079B2 90 nop ; identicalise 468 469 470 471 chk_al6: ;AN000; 0 000079B3 3C06 cmp al,6 ; get machine name ?? ;AN000; 473 chk_al7 equ Chk_Al7 ; NASM port label 0 000079B5 7513 jne chk_al7 ; no, check next function ;AN000; 0 000079B7 161F context DS ;AN000; 476 DOSGroup equ DOSGROUP ; NASM port equate 477 MyName equ MYNAME ; NASM port label 0 000079B9 BE[0000] mov si,offset MyName wrt DOSGroup ; DS:SI-->name string ;AN000; 479 ; ES:DI-->return buffer ;AN000; 0 000079BC 83C702 add di,2 ; skip max return size ;AN000; 0 000079BF B90F00 mov cx,15 ; name size ;AN000; 482 Chk6_Loop: ;AN000; 0 000079C2 F3A4 rep movsb ; copy machine name to return buffer;AN000; 0 000079C4 30C0 xor al,al ; set 16th byte is 0 ;AN000; 0 000079C6 AA stosb ;AN000; 0 000079C7 EB0C jmp get_info_exit ; return ;AN000; 0 000079C9 90 nop ; identicalise 488 ;AN000; 489 ;AN000; 490 Chk_Al7: ;AN000; 491 ; cmp al,7 ; get country information ?? ;AN000; 492 ; jne chk_al8 ; no, try next function ;AN000; 493 ; mov al,dl ; AL = info ID ;AN000; 494 ; mov bx,-1 ; select active code page ;AN000; 495 ; mov dx,-1 ; select active country ;AN000; 496 ; mov cx,-1 ; get all ;AN000; 497 ; INVOKE $getExtCntry ; get country info ;AN000; 498 ; jmp SHORT Get_Info_Exit ; exit ;AN000; 499 500 501 Chk_Al8: ;AN000; 0 000079CA 3C08 cmp al,8 ; get share retry count ?? ;AN000; 503 bad_param equ Bad_Param ; NASM port label 0 000079CC 7506 jne bad_param ; no, Bad parameter ;AN000; 505 RetryCount equ RETRYCOUNT ; NASM port label 0 000079CE 8B1E[0000] mov bx,[RetryCount] ; BX = Share retry count ;AN000; 0 000079D2 EB01 jmp SHORT Get_Info_Exit ; exit ;AN000; 508 509 Bad_Param: ; Bad parameter ;AN000; 0 000079D4 F9 stc ; ;AN000; 511 512 Get_Info_Exit: ; exit ;AN000; 513 0 000079D5 C3 ret ;AN000; 515 516 517 ENDPROC GET_DOS_INFO ;AN000; 518 519 520 521 522 523 524 525 526 ; ************************************************************************* * 527 ; * 528 ; * MODULE: $IFS_IOCTL 529 ; * 530 ; * FUNCTION: Handle IFS Driver IOCTL calls 531 ; * 532 ; * INPUT: AH = 6B function code 533 ; * AL = XX 00 = Drive IOCTL, 01 = Psudo device IOCTL 534 ; * CX = 00 Reserved 535 ; * BL = XX Device Number 536 ; * DS:DX Pointer to Buffer 537 ; * 538 ; * OUTPUT: 539 ; * IF CARRY = 0 No Error 540 ; * IF CARRY = 1 Error 541 ; * AX = ERROR CODE 542 ; * 543 ; * INTERNAL REFERENCES: None 544 ; * 545 ; * 546 ; * EXTERNAL REFERENCES: INT 2F 547 ; * 548 ; * NOTES: None 549 ; * 550 ; * REVISION HISTORY: New 551 ; ************************************************************************* 552 553 PROCEDURE D_IFS_IOCTL,NEAR ;AN000; 553 ****************** warning: proc D_IFS_IOCTL... [-w+user] 554 0 000079D6 50 PUSH AX ;AN000; 556 multnet equ MultNET ; NASM port equate 0 000079D7 B82F11 MOV AX,(multnet << 8) | 47 ; pass control to IFS Func ;AN000; 0 000079DA CD2F INT 2FH ;AN000; 0 000079DC 5B POP BX ;AN000; 0 000079DD 7203 JC ABB_ERR ;AN000; 0 000079DF E9[0000] TRANSFER SYS_RET_OK ; return ;AN000; 562 563 ABB_ERR: ;AN000; 0 000079E2 E9[0000] transfer SYS_RET_ERR ; error return ;AN000; 565 566 ENDPROC D_IFS_IOCTL ;AN000; 567 568 END ;AN000; 569 570