Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4007 lines
93 KiB

  1. page ,160
  2. title bios system initialization
  3. ;
  4. ;----------------------------------------------------------------------------
  5. ;
  6. ; Modification history
  7. ;
  8. ; 26-Feb-1991 sudeepb Ported for NT DOSEm
  9. ;----------------------------------------------------------------------------
  10. break macro ; dummy empty macro
  11. endm
  12. include version.inc
  13. include biosseg.inc
  14. include sysvar.inc
  15. include curdir.inc
  16. include pdb.inc
  17. include exe.inc
  18. include sf.inc
  19. include arena.inc
  20. include syscall.inc
  21. include devsym.inc
  22. include ioctl.inc
  23. include biostruc.inc
  24. include dossym.inc
  25. include dosmac.inc
  26. include mult.inc
  27. include dossvc.inc
  28. include dbgsvc.inc
  29. include cmdsvc.inc
  30. include xmssvc.inc
  31. include vint.inc
  32. Bios_Code segment
  33. extrn BCode_start:near
  34. extrn BCode_end:near
  35. extrn seg_reinit:far
  36. Bios_Code ends
  37. include devmark.inc
  38. include cputype.inc
  39. true equ 0ffffh
  40. false equ 0
  41. cr equ 13
  42. lf equ 10
  43. tab equ 9
  44. ;multMULT equ 4ah
  45. multMULTGETHMAPTR equ 1
  46. multMULTALLOCHMA equ 2
  47. stacksw equ true ;include switchable hardware stacks
  48. mycds_size equ 71 ; size of curdir_list. if it is not
  49. ;the same, then will generate compile error.
  50. if DEBUG ; BUGBUG - Jeez, remove this!
  51. dossize equ 0b200h
  52. else
  53. dossize equ 0a000h
  54. endif
  55. if ibmjapver
  56. noexec equ true
  57. else
  58. noexec equ false
  59. endif
  60. ; if mycds_size <> curdirlen,then force a compilatiaon error.
  61. if mycds_size ne curdirlen
  62. %out !!! sysinit1 compilation failed. different cds size !!!
  63. .errne mycds_size eq curdirlen
  64. endif
  65. if not ibmjapver
  66. extrn re_init:far
  67. endif
  68. ifdef TAIWAN
  69. extrn cdosinit:near
  70. endif
  71. ;---------------------------------------
  72. Bios_Data segment
  73. ;equates for main stack and stack initialization program
  74. if stacksw
  75. extrn NextStack:dword ; Win386 Instance table stuff
  76. extrn IT_StackLoc:dword ; we have to plug in so that our
  77. extrn IT_StackSize:word ; stacks can be instanced
  78. entrysize equ 8
  79. mincount equ 8
  80. defaultcount equ 9
  81. maxcount equ 64
  82. minsize equ 32
  83. defaultsize equ 128
  84. maxsize equ 512
  85. allocbyte equ 0
  86. intlevel equ 1
  87. savedsp equ 2
  88. savedss equ 4
  89. newsp equ 6
  90. free equ 0
  91. allocated equ 1
  92. overflowed equ 2
  93. clobbered equ 3
  94. ; external variables in ibmbio for int19h handling rouitne.
  95. extrn int19sem:byte
  96. irp aa,<02,08,09,0a,0b,0c,0d,0e,70,72,73,74,76,77>
  97. extrn int19old&aa:dword
  98. endm
  99. endif
  100. ;---------------------------------------
  101. ; external variable defined in ibmbio module for multi-track
  102. multrk_on equ 10000000b ;user spcified mutitrack=on,or system turns
  103. ; it on after handling config.sys file as a
  104. ; default value,if multrk_flag = multrk_off1.
  105. multrk_off1 equ 00000000b ;initial value. no "multitrack=" command entered.
  106. multrk_off2 equ 00000001b ;user specified multitrack=off.
  107. extrn multrk_flag:word
  108. ;
  109. ;SR; Win386 present flag
  110. ;
  111. extrn IsWin386:BYTE
  112. ;
  113. ;SR; Added for SetFocus routine for WIN386 support
  114. ;
  115. extrn V86_Crit_SetFocus:far
  116. extrn xms:dword ; entry point for xms driver
  117. extrn inHMA:byte ; flag meaning we're running high
  118. extrn FreeHMAPtr:word
  119. extrn MoveDOSIntoHMA:dword
  120. extrn SysinitPresent:byte
  121. extrn DemInfoFlag:byte
  122. extrn spc_mse_int10:dword
  123. extrn int29Perf:dword
  124. extrn outchr:near
  125. Bios_Data ends
  126. ; NTVDM 16-Sep-1992 Jonle
  127. ; Softpc Kbd, mouse, emm drivers
  128. SpcKbdSeg segment
  129. extrn InstSpcKbd:near
  130. extrn SpcKbdBeg:byte
  131. extrn SpcKbdEnd:byte
  132. extrn int10h_vector:near
  133. SpcKbdSeg ends
  134. SpcMseSeg segment
  135. extrn InstSpcMse:near
  136. extrn SpcMseBeg:byte
  137. extrn SpcMseEnd:byte
  138. SpcMseSeg ends
  139. SpcEmmSeg segment
  140. extrn InitSpcEmm:near
  141. extrn SpcEmmBeg:byte
  142. extrn SpcEmmEnd:byte
  143. extrn SI_end:byte
  144. SpcEmmSeg ends
  145. sysinitseg segment
  146. assume cs:sysinitseg, ds:nothing,es:nothing,ss:nothing
  147. extrn badcom:byte
  148. extrn condev:byte
  149. extrn auxdev:byte
  150. extrn prndev:byte
  151. extrn commnd:byte
  152. extrn devmark_addr:word
  153. extrn setdevmarkflag:byte
  154. extrn pathstring:byte
  155. extrn print:near
  156. extrn int24:near
  157. extrn mem_err:near
  158. extrn doconf:near
  159. extrn multi_pass:near
  160. extrn badload:near
  161. extrn error_line:near
  162. extrn ShrinkUMB:near
  163. extrn UnlinkUMB:near ;M002
  164. extrn AllocUMB:near
  165. extrn toomanydrivesmsg:byte ; M029
  166. ;NTVDM
  167. extrn MseDev:byte ; internal mouse driver name
  168. extrn AllocUMBLow:near ; mem alloc for new internal drivers
  169. extrn bEchoConfig:byte
  170. extrn config:byte
  171. public current_dos_location
  172. public device_list
  173. public sysi_country
  174. public memory_size
  175. public default_drive
  176. public buffers
  177. public files
  178. public num_cds
  179. public sysinit
  180. public cntryfilehandle
  181. public command_line
  182. if stacksw ; internal stack information
  183. public stack_count
  184. public stack_size
  185. public stack_addr
  186. endif
  187. public dosinfo
  188. public fcbs
  189. public keep
  190. public confbot
  191. public alloclim
  192. public zero
  193. public sepchr
  194. public count
  195. public chrptr
  196. public org_count
  197. public bufptr
  198. public memlo
  199. public prmblk
  200. public memhi
  201. public ldoff
  202. public area
  203. public packet
  204. public unitcount
  205. public break_addr
  206. public bpb_addr
  207. public drivenumber
  208. public config_size
  209. public install_flag
  210. public com_level
  211. public cmmt
  212. public cmmt1
  213. public cmmt2
  214. public cmd_indicator
  215. public linecount
  216. public showcount
  217. public buffer_linenum
  218. public donotshownum
  219. public h_buffers
  220. public configmsgflag
  221. public do_install_exec
  222. public multi_pass_id
  223. public temp_bcode_seg
  224. public seg_reinit_ptr
  225. public toomanydrivesflag ; M029
  226. sysinit$:
  227. if stacksw
  228. .sall
  229. ; interrupt level 2, 3, 4, 5, 6, 7,(10, 11, 12, 14, 15 - at level)
  230. ; should follow the standard interrupt sharing scheme which has
  231. ; a standard header structure.
  232. ; fyi, the following shows the relations between
  233. ; the interrupt vector and interrupt level.
  234. ; vec(hex) 2 8 9 a b c d e 70 72 73 74 76 77
  235. ; lvl(deci) 9 0 1 2 3 4 5 6 8 10 11 12 14 15
  236. ; msstack module modifies the following interrupt vectors
  237. ; to meet the standard interrupt sharing standard;
  238. ; a, b, c, d, e, 72, 73, 74, 76, 77.
  239. ; also, for interrupt level 7 and 15, the firstflag in a standard header
  240. ; should be initialized to indicat whether this interrupt handler is
  241. ; the first (= 80h) or not. the firstflag entry of int77h's
  242. ; program header is initialized in this module.
  243. ; firstflag is only meaningful for interrupt level 7 and 15.
  244. ;
  245. ; user specifies the number of stack elements - default = 9
  246. ; minimum = 8
  247. ; maximum = 64
  248. ;
  249. ; intercepts asynchronous hardware interrupts only
  250. ;
  251. ; picks a stack from pool of stacks and switches to it
  252. ;
  253. ; calls the previously saved interrupt vector after pushing flags
  254. ;
  255. ; on return, returns the stack to the stack pool
  256. ;
  257. ; this is a modification of stacks:
  258. ; 1. to fix a bug which was causing the program to take up too much space.
  259. ; 2. to dispense stack space from hi-mem first rather than low-mem first.
  260. ; . clobbers the stack that got too big instead of innocent stack
  261. ; . allows system to work if the only stack that got too big was the most
  262. ; deeply nested one
  263. ; 3. disables nmi interrupts while setting the nmi vector.
  264. ; 4. double checks that a nested interrupt didn't get the same stack.
  265. ; 5. intercepts ints 70, 72-77 for pc-ats and other future products
  266. even
  267. dw 0 ; spare field but leave these in order
  268. stackcount dw 0
  269. stackat dw 0
  270. stacksize dw 0
  271. stacks dw 0
  272. dw 0
  273. firstentry dw stacks
  274. lastentry dw stacks+(defaultcount*entrysize)-entrysize
  275. nextentry dw stacks+(defaultcount*entrysize)-entrysize
  276. ; these are the individual interrupt handlers
  277. assume ds:nothing,es:nothing,ss:nothing
  278. public int02
  279. public old02
  280. old02 dd 0
  281. int02 proc far
  282. ;; NTVDM support for pc convertable is NOT NEEDED 10-Aug-1992 Jonle
  283. ;;
  284. ;; *********************************************************************
  285. ;;
  286. ;; this is special support for the pc convertible / nmi handler
  287. ;;
  288. ;; on the pc convertible, there is a situation where an nmi can be
  289. ;; caused by using the "out" instructions to certain ports. when this
  290. ;; occurs, the pc convertible hardware *guarantees* that **nothing**
  291. ;; can stop the nmi or interfere with getting to the nmi handler. this
  292. ;; includes other type of interrupts (hardware and software), and
  293. ;; also includes other type of nmi's. when any nmi has occured,
  294. ;; no other interrtupt (hardware, software or nmi) can occur until
  295. ;; the software takes specific steps to allow further interrupting.
  296. ;;
  297. ;; for pc convertible, the situation where the nmi is generated by the
  298. ;; "out" to a control port requires "fixing-up" and re-attempting. in
  299. ;; otherwords, it is actually a "restartable exception". in this
  300. ;; case, the software handler must be able to get to the stack in
  301. ;; order to figure out what instruction caused the problem, where
  302. ;; it was "out"ing to and what value it was "out"ing. therefore,
  303. ;; we will not switch stacks in this situation. this situation is
  304. ;; detected by interrogating port 62h, and checking for a bit value
  305. ;; of 80h. if set, *****do not switch stacks*****.
  306. ;;
  307. ;; *********************************************************************
  308. ;
  309. ; push ax
  310. ; push es
  311. ; mov ax,0f000h
  312. ; mov es,ax
  313. ; cmp byte ptr es:[0fffeh],mdl_convert ;check if convertible
  314. ; pop es
  315. ; jne normal02
  316. ;
  317. ; in al,62h
  318. ; test al,80h
  319. ; jz normal02
  320. ;
  321. ;special02:
  322. ; pop ax
  323. ; jmp dword ptr old02
  324. ;
  325. ;normal02:
  326. ; pop ax
  327. ;
  328. call do_int_stacks
  329. dw old02
  330. int02 endp
  331. public int08
  332. public old08
  333. old08 dd 0
  334. int08 proc far
  335. call do_int_stacks
  336. dw old08
  337. int08 endp
  338. public int09
  339. public old09
  340. old09 dd 0
  341. int09 proc far
  342. ; keyboard interrupt must have a three byte jump, a nop and a zero byte
  343. ; as its first instruction for compatibility reasons
  344. ifidn <09>,<09>
  345. jmp short keyboard_lbl
  346. nop
  347. db 0
  348. keyboard_lbl label near
  349. endif
  350. call do_int_stacks
  351. dw old09
  352. int09 endp
  353. public int70
  354. public old70
  355. old70 dd 0
  356. int70 proc far
  357. call do_int_stacks
  358. dw old70
  359. int70 endp
  360. irp a,<0a,0b,0c,0d,0e,72,73,74,76,77>
  361. public int&a
  362. public old&a
  363. public firstflag&a
  364. int&a proc far
  365. jmp short entry_int&a&_stk
  366. old&a dd 0 ;forward pointer
  367. dw 424bh ;compatible signature for int. sharing
  368. firstflag&a db 0 ;the firstly hooked.
  369. jmp short intret_&a ;reset routine. we don't care this.
  370. db 7 dup (0) ;reserved for future.
  371. entry_int&a&_stk:
  372. call do_int_stacks
  373. dw old&a
  374. intret_&a:
  375. jmp DOIRET
  376. int&a endp
  377. endm
  378. DOCLI:
  379. FCLI
  380. ret
  381. DOSTI:
  382. FSTI
  383. ret
  384. DOIRET:
  385. FIRET
  386. ;********************************************************************
  387. ;common routines
  388. ; do interrupt stack switching. the fake return address holds
  389. ; a pointer to the far-pointer of the actual interrupt
  390. ; service routine
  391. do_int_stacks:
  392. push ax
  393. push bp
  394. push es
  395. mov es, cs:[stacks+2] ; get segment of stacks
  396. mov bp,nextentry ; get most likely candidate
  397. mov al,allocated
  398. xchg es:byte ptr allocbyte[bp],al ; grab the entry
  399. cmp al,free ; still avail?
  400. jne notfree02
  401. sub nextentry,entrysize ; set for next interrupt
  402. found02:
  403. mov es:word ptr savedsp[bp],sp ; save sp value
  404. mov es:word ptr savedss[bp],ss ; save ss also
  405. mov ax,bp ; temp save of table offset
  406. mov bp,es:word ptr newsp[bp] ; get new sp value
  407. cmp es:[bp],ax ; check for offset into table
  408. jne foundbad02
  409. push bp
  410. mov bp,sp
  411. mov ax,8[bp] ; get offset of interrupt vector
  412. pop bp
  413. push es ; ss:sp = new stack
  414. pop ss
  415. mov sp,bp
  416. mov bp,ax ; get pointer to interrupt vector
  417. mov bp,cs:[bp]
  418. pushf ; go execute the real interrupt handler
  419. call cs:dword ptr [bp] ; call the old interrupt vector
  420. mov bp,sp ; retrieve the table offset for us
  421. mov bp,es:[bp] ; but leave it on the stack
  422. mov ss,es:word ptr savedss[bp] ; get old stack back
  423. mov sp,es:word ptr savedsp[bp]
  424. mov es:byte ptr allocbyte[bp],free ; free the entry
  425. mov nextentry,bp ; setup to use next time
  426. newerror02:
  427. pop es
  428. pop bp ; saved on entry
  429. pop ax ; saved on entry
  430. add sp,2 ; lose the fake return address
  431. intret_02:
  432. jmp DOIRET ; done with this interrupt
  433. notfree02:
  434. cmp al,allocated ; error flag
  435. je findnext02 ; no, continue
  436. xchg es:byte ptr allocbyte[bp],al ; yes, restore error value
  437. findnext02:
  438. call longpath
  439. jmp found02
  440. foundbad02:
  441. cmp bp,firstentry
  442. jc findnext02
  443. mov bp,ax ; flag this entry
  444. mov es:byte ptr allocbyte[bp],clobbered
  445. jmp findnext02 ; keep looking
  446. longpath:
  447. mov bp,lastentry ; start with last entry in table
  448. lploopp:
  449. cmp es:byte ptr allocbyte[bp],free ; is entry free?
  450. jne inuse ; no, try next one
  451. mov al,allocated
  452. xchg es:byte ptr allocbyte[bp],al ; allocate entry
  453. cmp al,free ; is it still free?
  454. je found ; yes, go use it
  455. cmp al,allocated ; is it other than allocated or free?
  456. je inuse ; no, check the next one
  457. mov es:byte ptr allocbyte[bp],al ; yes, put back the error state
  458. inuse:
  459. cmp bp,firstentry
  460. je fatal
  461. sub bp,entrysize
  462. jmp lploopp
  463. found:
  464. ret
  465. fatal proc near
  466. ; NTVDM support for pc convertable is NOT NEEDED 10-Aug-1992 Jonle
  467. ;
  468. ; push ds
  469. ; mov ax, 0f000h ;look at the model byte
  470. ; mov ds, ax
  471. ; cmp ds:byte ptr [0fffeh], mdl_convert ;convertible?
  472. ; pop ds
  473. ; jne skip_nmis
  474. ;
  475. ; mov al,07h ; disable pc convertible nmis
  476. ; out 72h,al
  477. ;
  478. ;skip_nmis:
  479. call DOCLI ; disable and mask
  480. mov al,0ffh ; all other ints
  481. out 021h,al
  482. out 0a1h,al
  483. mov si,cs
  484. mov ds,si
  485. mov si,offset fatal_msg
  486. ;SR;
  487. ; We set all foci to this VM to issue the stack failure message
  488. ;
  489. push ax
  490. push ds
  491. mov ax,Bios_Data
  492. mov ds,ax
  493. assume ds:Bios_Data
  494. test ds:[IsWin386],1
  495. pop ds
  496. pop ax
  497. assume ds:nothing
  498. jz fatal_loop ;win386 not present, continue
  499. call V86_Crit_SetFocus ;set focus to this VM
  500. ;
  501. ;SR; We do not bother about the returned status of this call.
  502. ;
  503. fatal_loop:
  504. lodsb
  505. cmp al,'$'
  506. je fatal_done
  507. mov bl,7
  508. mov ah,14
  509. int 010h ; whoops, this enables ints
  510. jmp fatal_loop
  511. fatal_done:
  512. jmp fatal_done
  513. fatal endp
  514. include msbio.cl5 ;fatal stack error message
  515. .xall
  516. public endstackcode
  517. endstackcode label byte
  518. endif
  519. sysinit:
  520. jmp goinit
  521. ;
  522. ;----------------------------------------------------------------------------
  523. ;
  524. DDHighInfo struc
  525. ddhigh_CSegPtr dd ? ; pointer to code segment to be relocated
  526. ddhigh_CSegLen dw ? ; length of code segment to be relocated
  527. ddhigh_CallBak dd ? ; pointer to the call back routine
  528. DDHighInfo ends
  529. public runhigh
  530. runhigh db 0h
  531. dosinfo dd 0 ; address of the DOS Sysini Variables
  532. dos_temp_location label dword
  533. dosinit dw 0
  534. current_dos_location dw 0
  535. device_list dd 0
  536. sysi_country dd 0 ; pointer to country table in dos
  537. dos_segreinit dw 0,0 ; room for dword
  538. lo_doscod_size dw 0 ; dos code size when in low mem
  539. hi_doscod_size dw 0 ; dos code size when in HMA
  540. def_php dw 0
  541. ; M022--
  542. ; pointer for calling into Bios_Code for re-initializing segment values.
  543. ; call with ax = new segment for Bios_Code. Notice that we'll
  544. ; call it in its temporary home, cuz seg_reinit won't get moved to
  545. ; the new home.
  546. seg_reinit_ptr label dword
  547. dw offset Bios_Code:seg_reinit
  548. temp_bcode_seg dw Bios_Code
  549. ;variables for stack initialization program.
  550. if stacksw
  551. stack_count dw defaultcount
  552. stack_size dw defaultsize
  553. stack_addr dd 0
  554. endif
  555. ; various default values
  556. memory_size dw 1
  557. RPLMemTop dw 0
  558. default_drive db 0 ;initialized by ibminit.
  559. buffers dw -1 ; initialized during buffer allocation
  560. h_buffers dw 0 ; # of the heuristic buffers. initially 0.
  561. singlebuffersize dw ? ; maximum sector size + buffer header
  562. files db 8 ; enough files for pipe
  563. fcbs db 4 ; performance for recycling
  564. keep db 0 ; keep original set
  565. num_cds db 1 ; minimum needed is 1, so that initialization does'nt have a problem
  566. confbot dw ?
  567. alloclim dw ?
  568. DirStrng db "A:\",0 ; string for the root directory of a drive
  569. command_line db 2,0,"P" ;default command.com args
  570. db 125 dup (0)
  571. zero db 0
  572. sepchr db 0
  573. linecount dw 0 ; line count in config.sys
  574. showcount db ' ',cr,lf,'$' ; used to convert linecount to ascii.
  575. buffer_linenum dw 0 ; line count for "buffers=" command if entered.
  576. buf_prev_off dw 0
  577. if not noexec
  578. comexe exec0 <0,command_line,default_drive,zero>
  579. endif
  580. ;------------------------------------------------------------------
  581. ; variables for install= command.
  582. multi_pass_id db 0 ; parameter passed to multi_pass
  583. ; indicating the pass number
  584. ; 0 - do scan for DOS=HIGH/LOW
  585. ; 1 - load device drivers
  586. ; 2 - was to load IFS
  587. ; now it is unused
  588. ; 3 - do install=
  589. ; >3 - nop
  590. install_flag dw 0
  591. have_install_cmd equ 00000001b ; config.sys has install= commands
  592. has_installed equ 00000010b ; sysinit_base installed.
  593. config_size dw 0 ; size of config.sys file. set by sysconf.asm
  594. sysinit_base_ptr dd 0 ; pointer to sysinit_base
  595. sysinit_ptr dd 0 ; returning addr. from sysinit_base
  596. checksum dw 0 ; used by sum_up
  597. ldexec_fcb db 20 dup (' ') ;big enough
  598. ldexec_line db 0 ;# of parm characters
  599. ldexec_start db ' '
  600. ldexec_parm db 80 dup (0)
  601. instexe exec0 <0,ldexec_line,ldexec_fcb,ldexec_fcb>
  602. ;------------------------------------------------------------------
  603. ;variables for comment=
  604. com_level db 0 ;level of " " in command line
  605. cmmt db 0 ;length of comment string token
  606. cmmt1 db 0 ;token
  607. cmmt2 db 0 ;token
  608. cmd_indicator db ?
  609. donotshownum db 0
  610. ;------------------------------------------------------------------
  611. count dw 0
  612. org_count dw 0
  613. chrptr dw 0
  614. cntryfilehandle dw 0
  615. old_area dw 0
  616. impossible_owner_size dw 0 ; paragraph
  617. ;------------------------------------------------------------------
  618. bucketptr label dword
  619. bufptr label dword ;leave this stuff in order!
  620. memlo dw 0
  621. prmblk label word
  622. memhi dw 0
  623. ldoff dw 0
  624. area dw 0
  625. packet db 24 ; was 22
  626. db 0
  627. db 0 ;initialize code
  628. dw 0
  629. db 8 dup (?)
  630. unitcount db 0
  631. break_addr dd 0
  632. bpb_addr dd 0
  633. drivenumber db 0
  634. configmsgflag dw 0 ; used to control "error in config.sys line #" message
  635. toomanydrivesflag db 0 ;>24 fixed disk partitions flag ; M029
  636. BCodeSeg dw Bios_Code
  637. ;SR;
  638. ; This is the communication block between the DOS and the BIOS. It starts at
  639. ;the SysinitPresent flag. Any other data that needs to be communicated
  640. ;to the DOS should be added after SysinitPresent. The pointer to this block
  641. ;is passed to DOS as part of the DOSINIT call.
  642. ;
  643. BiosComBlock dd Bios_Data:SysinitPresent
  644. tempstack db 80h dup (?)
  645. goinit:
  646. ifdef JAPAN
  647. mov ah,50h ; set crt mode
  648. mov al,0
  649. mov bx,81 ; for JAPAN
  650. int 10h
  651. mov ah,50h ; set keyboard mode
  652. mov al,0
  653. mov bx,81 ; for JAPAN
  654. int 16h
  655. endif
  656. cld
  657. ;; Before we installed spckbd.asm (we hook a lot of vectors there),
  658. ;; we shouldn't invoke any interrupt calls directly to bios(they will
  659. ;; go directly to ROM bios). Since we do know what exactly those ROM
  660. ;; bios(s) do, a safer manner is to issue bop to our 32 bits side.
  661. ;; int 12h ; Get Memory in 1k
  662. BOP 12h
  663. mov cl,6
  664. shl ax,cl ;convert to 16-byte blocks(segment no.)
  665. mov cx,ax
  666. dec cx ; one para for an arena at end of mem
  667. ; in case of UMBs
  668. mov memory_size,cx
  669. push cs
  670. pop ds
  671. xor si,si
  672. mov di,si
  673. mov ax, offset sysinitgrp:SI_end ; need this much room for sysinit
  674. call off_to_para
  675. sub cx,ax
  676. ; we need to leave room for the DOS and for the BIOS
  677. ; code above sysinit in memory
  678. ;
  679. sub cx,dossize/16 ; leave this much room for DOS
  680. mov ax,offset BCode_end
  681. call off_to_para ; leave this much room for BIOS code
  682. sub cx,ax
  683. mov es,cx ; offset where sysinit will be located
  684. mov cx,offset sysinitgrp:SI_end
  685. shr cx,1 ;divide by 2 to get words
  686. rep movsw ;relocate sysinit
  687. push es ; push relocated segment
  688. mov ax,offset sysin
  689. push ax ; push relocated entry point
  690. retf ; far jump to relocated sysinit
  691. ; move the dos to its proper location
  692. sysin:
  693. assume ds:nothing,es:nothing,ss:nothing
  694. mov ax, Bios_Data ; point DS to BIOS data
  695. mov ds, ax
  696. assume ds:Bios_Data
  697. mov word ptr MoveDOSIntoHMA+2, cs ; set seg of routine to move DOS
  698. mov SysinitPresent, 1 ; flag that MoveDOSIntoHMA can be called
  699. SVC SVC_ISDEBUG
  700. mov DemInfoFlag, al
  701. test al,ISDBG_DEBUGGEE
  702. je @f
  703. SAVEREG <bx,dx,es>
  704. mov bx, cs ; current base of BIOS
  705. xor cx, cx
  706. mov dx, current_dos_location; get offset of end of code
  707. sub dx, bios_data ; add in length of data segment
  708. REPT 4
  709. shl dx, 1
  710. rcl cx, 1
  711. endm
  712. mov ax, SYMOP_LOAD SHL 8 + ID_NTIO
  713. SVC SVC_DEMSYSTEMSYMBOLOP
  714. mov bx, 1 ; bugbug: Hardcoded segment number
  715. mov ax, ds ; low segment location
  716. mov es, ax ; relocated segment
  717. mov ax, SYMOP_MOVE SHL 8 + ID_NTIO
  718. SVC SVC_DEMSYSTEMSYMBOLOP
  719. RESTOREREG <es,dx,bx>
  720. @@:
  721. ; first move the MSDOS.SYS image up to a harmless place
  722. ; on top of our new sysinitseg
  723. mov ax,offset sysinitgrp:SI_end ; how big is sysinitseg?
  724. call off_to_para
  725. mov cx,cs ; pick a buffer for msdos above us
  726. add ax,cx
  727. mov es,ax
  728. xor si,si
  729. mov di,si
  730. mov ds,[current_dos_location] ; where it is (set by msinit)
  731. assume ds:nothing
  732. mov cx,dossize/2
  733. rep movsw
  734. mov [current_dos_location],es
  735. ; The DOS code is ORGed at a non-zero value to allow it to be located in
  736. ; HIMEM. Thus, the DOS segment location must be adjusted accordingly.
  737. mov ax,ds:word ptr 3 ; get offset of dos
  738. mov [dosinit],ax ; that's the entry point offset
  739. call off_to_para ; subtract this much from segment
  740. sub [current_dos_location],ax
  741. ; BIOS code is moved to the top of memory
  742. ; until it is determined whether it will be running in HIMEM or not.
  743. ; now put Bios_Code up on top of that. Assume Bios_Code + dossize < 64k
  744. mov ax,es
  745. add ax,dossize/16 ; get paragraph of end of dos
  746. mov es,ax
  747. xchg ax,temp_bcode_seg ; swap with original home of Bios_Code
  748. mov ds,ax ; point to loaded image of Bios_Code
  749. assume ds:nothing
  750. mov si,offset BCode_start
  751. mov di,si
  752. mov cx,offset BCode_end
  753. sub cx,si
  754. shr cx,1
  755. rep movsw ; move Bios_Code into place
  756. mov ax,es ; tell it what segment it's in
  757. call [seg_reinit_ptr] ; far call to seg_reinit in Bios_Code (M022)
  758. ; now call dosinit while it's in its temporary home
  759. les di,cs:[BiosComBlock] ; ptr to BIOS communication block
  760. lds si,cs:[device_list] ; set for call to dosinit
  761. assume ds:nothing, es:nothing
  762. mov dx,cs:[memory_size] ; set for call to dosinit
  763. call DOCLI
  764. mov ax,cs
  765. mov ss,ax
  766. align 2 ; assembler wouldn't let me do an "and 0fffeh"
  767. locstack label byte ; on the mov sp,offset locstack
  768. mov sp,offset locstack ; set stack
  769. call DOSTI
  770. ; This call to DOSINIT will relocate the DOS data from its present location
  771. ; at the top of memory, to its final location in low memory just above the
  772. ; BIOS data. It will then build important DOS data structures in low
  773. ; memory following the DOS data. It returns (among many other things) the
  774. ; new starting address of free memory.
  775. call [dos_temp_location] ; call dosinit
  776. ;es:di -> sysinitvars_ext
  777. mov [def_php],ds ; save pointer to PSP
  778. mov [hi_doscod_size],ax ; size of doscode (including exepatch)
  779. mov [lo_doscod_size],cx ; (not including exepatch)
  780. mov [dos_segreinit],dx ; save offset of segreinit
  781. mov ax,word ptr es:[di.sysi_initvars]
  782. mov word ptr dosinfo,ax
  783. mov ax,word ptr es:[di.sysi_initvars+2]
  784. mov word ptr [dosinfo+2],ax ;set the sysvar pointer
  785. mov ax,word ptr es:[di.sysi_country_tab]
  786. mov word ptr [sysi_country],ax
  787. mov ax,word ptr es:[di.sysi_country_tab+2]
  788. mov word ptr [sysi_country+2],ax ;set the sysi_country pointer
  789. mov es,[current_dos_location] ; give dos its temporary loc.
  790. mov [dos_segreinit+2],es
  791. ;
  792. les di,dosinfo ;es:di -> dosinfo
  793. clc ;get the extended memory size
  794. ; execute the get extended memory size subfunction in the bios int 15h
  795. ; if the function reports an error do nothing else store the extended
  796. ; memory size reported at the appropriate location in the dosinfo buffer
  797. ; currently pointed to by es:di. use the offsets specified in the
  798. ; definition of the sysinitvars struct in inc\sysvar.inc
  799. mov ah,88h
  800. ;; IBM ps/2 90 int 15(ah = 88h) read a coms byte(0B6h) which we don't support.
  801. ;; it returns 0 on this query.
  802. ;; we issue a bop to 32bits to get the real extended memeory size
  803. ;; int 15h ;check extended memory size
  804. BOP 15h
  805. ;; jc no_ext_memory
  806. mov es:[di].sysi_ext_mem,ax ;save extended memory size
  807. ;; or ax, ax
  808. no_ext_memory:
  809. mov ax,es:[di.sysi_maxsec] ; get the sector size
  810. add ax,bufinsiz ; size of buffer header
  811. mov [singlebuffersize],ax ; total size for a buffer
  812. SVC SVC_DEMGETBOOTDRIVE
  813. mov [default_drive],al
  814. mov es:[di.sysi_boot_drive],al ; set sysi_boot_drive
  815. ; determine if 386 system...
  816. if 1
  817. get_cpu_type ; macro to determine cpu type
  818. cmp ax,2 ; is it a 386?
  819. jne not_386_system ; no: don't mess with flag
  820. endif
  821. mov es:[di.sysi_dwmove],1
  822. not_386_system:
  823. mov al,es:[di.sysi_numio]
  824. mov drivenumber,al ; save start of installable block drvs
  825. mov ax,cs
  826. sub ax,11h ; room for PSP we will copy shortly
  827. mov cx,[singlebuffersize] ; temporary single buffer area
  828. shr cx,1
  829. shr cx,1 ; divide size by 16...
  830. shr cx,1
  831. shr cx,1 ; ...to get paragraphs...
  832. inc cx ; ... and round up
  833. ; cas note: this unorthodox paragraph rounding scheme wastes a byte if
  834. ; [singlebuffersize] ever happens to be zero mod 16. Could this
  835. ; ever happen? Only if the buffer overhead was zero mod 16, since
  836. ; it is probably safe to assume that the sector size always will be.
  837. ;
  838. ; mohans also found a bug in CONFIG.SYS processing where it replaces
  839. ; EOF's with cr,lf's, without checking for collision with [confbot].
  840. ; perhaps the extra byte this code guarantees is what has kept that
  841. ; other code from ever causing a problem???
  842. sub ax,cx
  843. mov [confbot],ax ; temp "unsafe" location
  844. ; push es ; preserve pointer to DOSINFO data
  845. ; push di
  846. ; setup and initialize the temporary buffer
  847. ; les di,es:[di.sysi_buf] ;get the buffer chain entry pointer
  848. ; mov word ptr es:[di.Dirty_Buff_Count],0
  849. ; mov word ptr es:[di.Buff_Queue],0
  850. ; mov word ptr es:[di.Buff_Queue+2],ax
  851. ; mov es,ax
  852. ; xor ax,ax
  853. ; mov di,ax ;es:di -> single buffer
  854. ; mov es:[di.buf_next],ax ;points to itself
  855. ; mov es:[di.buf_prev],ax ;points to itself
  856. ; mov word ptr es:[di.buf_id],00ffh ;free buffer,clear flag
  857. ; mov word ptr es:[di.buf_sector],0
  858. ; mov word ptr es:[di.buf_sector+2],0
  859. ; pop di ; restore pointer to DOSINFO data
  860. ; pop es
  861. push cs
  862. pop ds
  863. assume ds:sysinitseg
  864. call tempcds ; set up cdss so re_init and sysinit
  865. ; can make disk system calls
  866. assume ds:nothing ; tempcds trashes ds
  867. mov ds,[def_php] ; retreive pointer to PSP returned by DOSINIT
  868. if not ibmjapver
  869. call re_init ; re-call the bios
  870. endif
  871. call DOSTI ; ints ok
  872. cld ; make sure
  873. ; dosinit has set up a default "process" (php) at ds:0. we will move it out
  874. ; of the way by putting it just below sysinit at end of memory.
  875. mov bx,cs
  876. sub bx,10h
  877. mov es,bx
  878. xor si,si
  879. mov di,si
  880. mov cx,80h
  881. rep movsw
  882. mov word ptr es:[pdb_jfn_pointer + 2],es ; relocate
  883. mov ah,set_current_pdb
  884. int 21h ; tell dos we moved it
  885. push ds ; preserve DS returned by DOSINIT
  886. push cs
  887. pop ds ; point DS to sysinitseg
  888. assume ds:sysinitseg
  889. ; set up temp. critical error handler
  890. mov dx,offset int24 ;set up int 24 handler
  891. mov ax,(set_interrupt_vector shl 8) or 24h
  892. int 21h
  893. cmp byte ptr [TooManyDrivesFlag],0 ;Q: >24 partitions? M029
  894. je no_err ; N: continue M029
  895. mov dx,offset TooManyDrivesMsg ; Y: print error message M029
  896. call print ; M029
  897. no_err: ; M029
  898. pop ds ; start of free memory
  899. assume ds:nothing
  900. mov dl,[default_drive]
  901. or dl,dl
  902. jz nodrvset ; bios didn't say
  903. dec dl ; a = 0
  904. mov ah,set_default_drive
  905. int 21h ;select the disk
  906. nodrvset:
  907. ;
  908. ; Process the CONFIG.SYS file
  909. ;
  910. ProcessConfig:
  911. ;
  912. ; NTVDM store temp file name for config.sys, 23-Nov-1992 Jonle
  913. ;
  914. push ds
  915. push cs
  916. pop ds
  917. assume ds:sysinitseg
  918. mov dx,offset config ; ds:dx points file description
  919. CMDSVC SVC_GETCONFIGSYS
  920. pop ds
  921. assume ds:nothing
  922. ifndef TAIWAN
  923. call doconf ;do pre-scan for dos=high/low
  924. else ; taiwan
  925. call chkoemlocaldrv
  926. mov cs:oemdriverinst,ax
  927. call cdosinit
  928. push es
  929. push bx
  930. pop bx
  931. pop es
  932. call maketempvector ;make dummy int service routine
  933. call doconf ;do pre-scan for dos=high/low
  934. call chklocalexist ;check if local dev drv exist
  935. ;if not found,system halt
  936. call recovercsiint ;recover csi interrupt vector
  937. endif ; taiwan
  938. ; Now, we decide what to do with the DOS code.
  939. ; It will either be relocated to low memory, above the DOS data structures,
  940. ; or else it will be located in HiMem, in which case a stub with the DOS
  941. ; code entry points will be located in low memory. Dos_segreinit is used
  942. ; to tell the DOS data where the code has been placed, and to install the
  943. ; low memory stub if necessary. If the DOS is going to go into HiMem, we
  944. ; must first initialize it in its present location and load the installable
  945. ; device drivers. Then, if a HiMem driver has been located, we can actually
  946. ; relocate the DOS code into HiMem.
  947. ;
  948. ; M025 begin
  949. cmp runhigh, 0 ; Did user choose to run low ?
  950. je dont_install_stub ; yes, don't install dos low mem stub
  951. ;
  952. ;------ user chose to load high
  953. ;
  954. mov es,[current_dos_location] ; give dos its temporary loc.
  955. xor ax,ax ; ax = 00 ---> install stub
  956. call cs:dword ptr [dos_segreinit] ; call dos segreinit
  957. jmp short do_multi_pass
  958. ;
  959. ;------ User chose to load dos low
  960. ;
  961. dont_install_stub:
  962. xor bx, bx ; M012
  963. ; don't use int 21 call to alloc mem
  964. call MovDOSLo ; move it !
  965. mov ax, 1 ; dont install stub
  966. mov es, current_dos_location; set_dos_final_position set it up
  967. call dword ptr dos_segreinit ; inform dos about new seg
  968. do_multi_pass:
  969. call AllocFreeMem ; allocate all the free mem
  970. ; & update [memhi] & [area]
  971. ; start of free memory.
  972. ; M025 end
  973. ; NTVDM
  974. ; Copy softpc keyboard driver resident code to start of free mem
  975. ; Install Softpc IVT hooks
  976. mov al,devmark_spc
  977. call setdevmark
  978. mov es, cs:[devmark_addr]
  979. mov word ptr es:[arena_name], 'BK'
  980. mov word ptr es:[arena_name+2], 'D'
  981. cld
  982. mov ax,[memhi]
  983. push ds
  984. mov cx,Bios_Data
  985. mov ds,cx
  986. assume ds:Bios_Data
  987. mov word ptr spc_mse_int10,offset int10h_vector
  988. mov word ptr spc_mse_int10+2,ax
  989. mov word ptr int29Perf,offset outchr ; sudeepb 03-Nov-1992
  990. mov word ptr int29Perf+2,ds ; added for int10 performance
  991. pop ds
  992. assume ds:nothing
  993. mov es,ax ;es dest seg. for SpcKbd
  994. push es
  995. push cs
  996. pop ds ;ds src seg for SpcKbd
  997. mov si,offset sysinitgrp:SpcKbdBeg
  998. mov cx,offset sysinitgrp:SpcKbdEnd
  999. sub cx,si
  1000. xor di,di
  1001. mov [memlo],cx
  1002. or [setdevmarkflag],for_devmark
  1003. call round
  1004. rep movsb
  1005. pop ds
  1006. call sysinitgrp:InstSpcKbd
  1007. ; save value of int09 for int 09 hardware stack disable
  1008. xor ax,ax
  1009. mov ds,ax
  1010. mov si, 09h*4
  1011. lodsw
  1012. mov word ptr cs:old09, ax
  1013. lodsw
  1014. mov word ptr cs:old09+2, ax
  1015. ; save value of int08 for int 08 hardware stack disable
  1016. mov si, 08h*4
  1017. lodsw
  1018. mov word ptr cs:old08, ax
  1019. lodsw
  1020. mov word ptr cs:old08+2, ax
  1021. ; NTVDM
  1022. ; Attempt to init emm memory manager. if we have emm
  1023. ; then load internal emm stub device driver.
  1024. ;
  1025. ; check if emm memory is available
  1026. mov ax, [memhi]
  1027. inc ax ;1 para for arena header
  1028. mov ds, ax ;expected seg for emm drv
  1029. call sysinitgrp:InitSpcEmm
  1030. cmp ax, 0
  1031. jne NoEmmServices
  1032. ; fill in the arena name
  1033. mov al, devmark_device
  1034. call setdevmark
  1035. mov es, cs:[devmark_addr]
  1036. mov word ptr es:[arena_name], 'ME'
  1037. mov word ptr es:[arena_name+2], 'M'
  1038. ; copy in emm stub driver code
  1039. cld
  1040. mov ax,[memhi]
  1041. mov es,ax
  1042. push es ;save for diddling devheader
  1043. push cs
  1044. pop ds
  1045. mov si,offset sysinitgrp:SpcEmmBeg
  1046. mov cx,offset sysinitgrp:SpcEmmEnd
  1047. sub cx,si
  1048. xor di,di
  1049. mov [memlo],cx
  1050. or [setdevmarkflag],for_devmark
  1051. call round
  1052. rep movsb
  1053. ; link in emm stub driver
  1054. ; so apps can find emm driver
  1055. pop ds
  1056. xor si, si ;ds:si = device header
  1057. les di, cs:[dosinfo] ;es:di = to dos info
  1058. mov cx,word ptr es:[di.sysi_dev] ;dx:cx = head of list
  1059. mov dx,word ptr es:[di.sysi_dev+2]
  1060. mov word ptr es:[di.sysi_dev],si ;set head of list in dos
  1061. mov word ptr es:[di.sysi_dev+2],ds
  1062. mov word ptr ds:[si], cx ;link in the driver
  1063. mov word ptr ds:[si+2], dx
  1064. NoEmmServices:
  1065. ; Now, process config.sys some more.
  1066. ; Load the device drivers and install programs
  1067. inc cs:multi_pass_id ; multi_pass_id = 1
  1068. call multi_pass ; load device drivers
  1069. ; NTVDM
  1070. ; Install Softpc Mouse driver in UMB if can else in LOW memory
  1071. ; This must be done after himem.sys is loaded for umb support
  1072. ;
  1073. mov cx, offset sysinitgrp:SpcMseEnd
  1074. sub cx, offset sysinitgrp:SpcMseBeg ; cx, size of SpceMse
  1075. mov di, offset MseDev
  1076. push cs
  1077. pop es ; es:di, dest
  1078. push cx ; preserve cx
  1079. call AllocUMBLow
  1080. pop cx
  1081. push es ; save to pass to InstSpcMse
  1082. mov si, offset sysinitgrp:SpcMseBeg
  1083. push cs
  1084. pop ds ; ds:si, Source of SpcMse code
  1085. rep movsb
  1086. pop ds
  1087. call sysinitgrp:InstSpcMse
  1088. call ShrinkUMB
  1089. call UnlinkUMB ; unlink all UMBs ;M002
  1090. inc cs:multi_pass_id ; multi_pass_id = 2
  1091. call multi_pass ; was load ifs (now does nothing)
  1092. call endfile ; setup fcbs, files, buffers etc
  1093. ;
  1094. ;Reset SysinitPresent flag here. This is needed for the special fix for lying
  1095. ;to device drivers. This has been moved up to this point to avoid problems
  1096. ;with overlays called from installed programs
  1097. ;
  1098. mov ax,Bios_Data
  1099. mov es,ax ; point ES to bios data
  1100. assume es:Bios_Data
  1101. mov es:SysinitPresent,0 ; clear SysinitPresent flag
  1102. test install_flag,have_install_cmd ; are there install commands?
  1103. jz dolast ; no, no need for further processing
  1104. inc cs:multi_pass_id ; mult_pass_id = 3
  1105. call multi_pass ; execute install= commands
  1106. dolast:
  1107. assume es:nothing
  1108. ; [area] has the segment address for the allocated memory of sysinit, confbot.
  1109. ; free the confbot area used for config.sys and sysinit itself.
  1110. ; Now if DOS is supposed to run high, we actually move it into high memory
  1111. ; (if HiMem manager is available).
  1112. ;
  1113. ; There is also this little hack for CPM style DOS calls that needs to
  1114. ; be done when A20 is set...
  1115. cmp runhigh, 0ffh ; are we still waiting to be moved?
  1116. jne @f ; no, our job is over
  1117. call LoadDOSHiOrLo
  1118. @@:
  1119. cmp runhigh, 0 ; are we running low
  1120. je @f ; yes, no CPM hack needed
  1121. call CPMHack ; make ffff:d0 same as 0:c0
  1122. @@:
  1123. ; We are now done with CONFIG.SYS processing
  1124. ConfigDone:
  1125. ;; let NTVDM knows that we have done config.sys processing
  1126. xor al, al ;config.sys done
  1127. BOP BOP_NOTIFICATION ;
  1128. call AllocUMB ; allocate remaining UMBs if there are any
  1129. mov cs:[donotshownum],1 ; done with config.sys. do not show line number message.
  1130. mov es,[area]
  1131. assume es:nothing
  1132. mov ah,49h ; free allocated memory for command.com
  1133. int 21h
  1134. test cs:[install_flag],has_installed ; sysinit_base installed?
  1135. jz skip_free_sysinitbase ; no.
  1136. ;set block from the old_area with impossible_owner_size.
  1137. ;this will free the unnecessary sysinit_base that had been put in memory to
  1138. ;handle install= command.
  1139. push es
  1140. push bx
  1141. mov es,cs:[old_area]
  1142. mov bx,cs:[impossible_owner_size]
  1143. mov ah,setblock
  1144. int 21h
  1145. mov ax,es
  1146. dec ax
  1147. mov es,ax ;point to arena
  1148. mov es:[arena_owner],8 ;set impossible owner
  1149. mov word ptr es:[arena_name], 'DS' ; System Data
  1150. pop bx
  1151. pop es
  1152. skip_free_sysinitbase:
  1153. if noexec
  1154. mov bp,ds ;save command.com segment
  1155. push ds
  1156. pop es
  1157. mov bx,cs
  1158. sub bx,10h ; point to current php
  1159. mov ds,bx
  1160. xor si,si
  1161. mov di,si
  1162. mov cx,80h
  1163. rep movsw ; copy it to new location for shell
  1164. mov word ptr es:[pdb_jfn_pointer + 2],es ; relocate
  1165. mov bx,es
  1166. mov ah,set_current_pdb
  1167. int 21h ; tell dos we moved it
  1168. mov es:[pdb_parent_pid],es ;we are the root
  1169. endif ; noexec
  1170. push cs
  1171. pop ds ; point DS to sysinitseg
  1172. assume ds:sysinitseg
  1173. ; set up the parameters for command
  1174. mov si,offset command_line+1
  1175. if noexec
  1176. mov di,81h
  1177. else
  1178. push ds
  1179. pop es
  1180. mov di,si
  1181. endif
  1182. mov cl,-1
  1183. comtranlp: ;find length of command line
  1184. inc cl
  1185. lodsb
  1186. stosb ;copy command line in
  1187. or al,al
  1188. jnz comtranlp
  1189. dec di
  1190. mov al,cr ; cr terminate
  1191. stosb
  1192. if noexec
  1193. mov es:[80h],cl ; set up header
  1194. mov al,[default_drive]
  1195. mov es:[5ch],al
  1196. else
  1197. mov [command_line],cl ;count
  1198. endif
  1199. mov dx,offset commnd ;now pointing to file description
  1200. if noexec
  1201. mov es,bp ;set load address
  1202. mov bx,100h
  1203. call dfil ;read in command
  1204. jc comerr
  1205. mov ds,bp
  1206. mov dx,80h
  1207. mov ah,set_dma ;set disk tranfer address
  1208. int 21h
  1209. call DOCLI
  1210. mov ss,bp
  1211. mov sp,dx
  1212. call DOSTI
  1213. xor ax,ax ;push a word of zeros
  1214. push ax
  1215. push bp ;set high part of jump address
  1216. mov ax,100h
  1217. push ax ;set low part of jump address
  1218. retf ;crank up command!
  1219. else ; not noexec
  1220. ; we are going to open the command interpreter and size it as is done in
  1221. ; ldfil. the reason we must do this is that sysinit is in free memory. if
  1222. ; there is not enough room for the command interpreter,exec will probably
  1223. ; overlay our stack and code so when it returns with an error sysinit won't be
  1224. ; here to catch it. this code is not perfect (for instance .exe command
  1225. ; interpreters are possible) because it does its sizing based on the
  1226. ; assumption that the file being loaded is a .com file. it is close enough to
  1227. ; correctness to be usable.
  1228. push dx ; save pointer to name
  1229. ; first, find out where the command interpreter is going to go.
  1230. mov bx,0ffffh
  1231. mov ah,alloc
  1232. int 21h ;get biggest piece
  1233. mov ah,alloc
  1234. int 21h ; second time gets it
  1235. jc memerrjx ; oooops
  1236. mov es,ax
  1237. mov ah,dealloc
  1238. int 21h ; give it right back
  1239. mov bp,bx
  1240. ; es:0 points to block,and bp is the size of the block
  1241. ; in para.
  1242. ; we will now adjust the size in bp down by the size of sysinit. we
  1243. ; need to do this because exec might get upset if some of the exec
  1244. ; data in sysinit is overlayed during the exec.
  1245. mov bx,[memory_size] ; get location of end of memory
  1246. mov ax,cs ; get location of beginning of sysinit
  1247. sub bx,ax ; bx is size of sysinit in para
  1248. add bx,11h ; add the sysinit php
  1249. sub bp,bx ; sub sysinit size from amount of free memory
  1250. jc memerrjx ; if there isn't even this much memory, give up
  1251. mov ax,(open shl 8) ;open the file being execed
  1252. stc ;in case of int 24
  1253. int 21h
  1254. jc comerr ; ooops
  1255. mov bx,ax ;handle in bx
  1256. xor cx,cx
  1257. xor dx,dx
  1258. mov ax,(lseek shl 8) or 2
  1259. stc ;in case of int 24
  1260. int 21h ; get file size in dx:ax
  1261. jc comerr
  1262. ; convert size in dx:ax to para in ax
  1263. add ax,15 ; round up size for conversion to para
  1264. adc dx,0
  1265. call off_to_para
  1266. mov cl,12
  1267. shl dx,cl ; low nibble of dx to high nibble
  1268. or ax,dx ; ax is now # of para for file
  1269. add ax,10h ; 100h byte php
  1270. cmp ax,bp ; will command fit in available mem?
  1271. jb okld ; jump if yes.
  1272. memerrjx:
  1273. jmp mem_err
  1274. okld:
  1275. mov ah,close
  1276. int 21h ; close file
  1277. pop dx ; recover pointer to name
  1278. push cs ; point es to sysinitseg
  1279. pop es
  1280. mov bx,offset comexe ; point to exec block
  1281. mov word ptr [bx.exec0_com_line+2],cs ; set segments
  1282. mov word ptr [bx.exec0_5c_fcb+2],cs
  1283. mov word ptr [bx.exec0_6c_fcb+2],cs
  1284. xor ax,ax ;load and go
  1285. mov ah,exec
  1286. stc ;in case of int 24
  1287. int 21h ;go start up command
  1288. endif
  1289. ; note fall through if exec returns (an error)
  1290. comerr:
  1291. mov dx,offset badcom ;want to print command error
  1292. extrn badfil:near
  1293. call badfil
  1294. public stall
  1295. stall: SVC SVC_DEMEXITVDM ; Will Kill The VDM
  1296. ;
  1297. ;----------------------------------------------------------------------------
  1298. ; procedure : AllocFreeMem
  1299. ;
  1300. ; Allocate Max memory from DOS to find out where to load DOS.
  1301. ; DOS is at temporary location when this call is being made
  1302. ;
  1303. ; Inputs : None
  1304. ; Outputs: The biggest chunk of memory is allocated (all mem at init time)
  1305. ; [area] & [memhi] set to the para value of the start of the
  1306. ; free memory.
  1307. ;
  1308. ; Uses : AX, BX
  1309. ;
  1310. ;----------------------------------------------------------------------------
  1311. ;
  1312. AllocFreeMem proc near
  1313. assume es:nothing, ds:nothing
  1314. mov bx,0ffffh
  1315. mov ah,alloc
  1316. int 21h ;first time fails
  1317. mov ah,alloc
  1318. int 21h ;second time gets it
  1319. mov [area],ax
  1320. mov [memhi],ax ; memhi:memlo now points to
  1321. ret
  1322. ; start of free memory
  1323. AllocFreeMem endp
  1324. ; start M000
  1325. include msbio.cl6
  1326. ; end M000
  1327. ;
  1328. ;----------------------------------------------------------------------------
  1329. ;
  1330. ; procedure : LoadDOSHiOrLo
  1331. ;
  1332. ; Tries to move DOS into HMA. If it fails then loads
  1333. ; DOS into Low memory.
  1334. ;
  1335. ;----------------------------------------------------------------------------
  1336. ;
  1337. LoadDOSHiOrLo proc near
  1338. call TryToMovDOSHi ; Try moving it into HMA (M024)
  1339. jc LdngLo ; If that don't work...
  1340. ret
  1341. LdngLo:
  1342. push cs
  1343. pop ds
  1344. mov ah, 9
  1345. mov dx, offset DOSLOMSG ; inform user that we are
  1346. int 21h ; loading low
  1347. ; actually move the dos, and reinitialize it.
  1348. mov bx, 1 ; M012
  1349. ; use int 21 alloc for mem
  1350. call MovDOSLo
  1351. mov es,[current_dos_location] ; give dos its temporary loc.
  1352. xor ax,ax ; ax = 00 ---> install stub
  1353. call cs:dword ptr [dos_segreinit] ; call dos segreinit
  1354. mov runhigh, 0 ; mark that we are running lo
  1355. ret
  1356. LoadDOSHiOrLo endp
  1357. ;
  1358. ;----------------------------------------------------------------------------
  1359. ;
  1360. ; procedure : TryToMovDOSHi
  1361. ;
  1362. ; This tries to move DOS into HMA.
  1363. ; Returns CY if it failed.
  1364. ; If it succeeds returns with carry cleared.
  1365. ;
  1366. ;
  1367. ;----------------------------------------------------------------------------
  1368. ;
  1369. public TryToMovDOSHi
  1370. TryToMovDOSHi proc near
  1371. call MovDOSHi
  1372. jc ttldhx
  1373. mov es,[current_dos_location] ; give dos its temporary loc.
  1374. xor ax,ax ; ax = 00 ---> install stub
  1375. call cs:dword ptr [dos_segreinit] ; call dos segreinit
  1376. mov runhigh, 1
  1377. clc
  1378. ttldhx:
  1379. ret
  1380. TryToMovDOSHi endp
  1381. ;
  1382. ;----------------------------------------------------------------------------
  1383. ;
  1384. ; procedure : MovDOSHi
  1385. ;
  1386. ; Tries to allocate HMA and Move DOS/BIOS code into HMA
  1387. ;
  1388. ; Returns : CY if it failed
  1389. ;
  1390. ;----------------------------------------------------------------------------
  1391. ;
  1392. MovDOSHi proc near
  1393. call AllocHMA
  1394. jc mdhx ; did we get HMA?
  1395. mov ax, 0ffffh ; yes, HMA seg = 0ffffh
  1396. mov es, ax
  1397. ; actually move the BIOS and DOS
  1398. call MovBIOS ; First move BIOS into HMA
  1399. ; ES:DI points to free HMA after BIOS
  1400. mov cx, hi_doscod_size ; pass the code size of DOS
  1401. ; when it is in HMA
  1402. call MovDOS ; and move it
  1403. ; ES:DI points to free HMA after DOS
  1404. call SaveFreeHMAPtr ; Save the Free HMA ptr
  1405. clc
  1406. mdhx:
  1407. ret
  1408. MovDOSHi endp
  1409. ;
  1410. ;----------------------------------------------------------------------------
  1411. ;
  1412. ; procedure : MovDOSLo
  1413. ;
  1414. ; Allocates memory from DOS and moves BIOS/DOS code into it
  1415. ;
  1416. ;----------------------------------------------------------------------------
  1417. ;
  1418. MovDOSLo proc near
  1419. call AllocMemForDOS ;
  1420. mov es, ax ; pass the segment to MovBIOS
  1421. call MovBIOS
  1422. ;
  1423. ;------ ES:DI points memory immediately after BIOS
  1424. ;
  1425. mov cx, lo_doscod_size ; DOS code size when loaded
  1426. ; low
  1427. call MovDOS
  1428. ret
  1429. MovDOSLo endp
  1430. ;
  1431. ;----------------------------------------------------------------------------
  1432. ;
  1433. ; procedure : MovBIOS
  1434. ;
  1435. ; Moves BIOS code into requested segment
  1436. ;
  1437. ; In : ES - segment to which BIOS is to be moved
  1438. ; ( it moves always into offset BCode_Start)
  1439. ;
  1440. ; Out : ES:DI - pointer to memory immediately after BIOS
  1441. ;
  1442. ;----------------------------------------------------------------------------
  1443. ;
  1444. MovBIOS proc near
  1445. mov ds, temp_bcode_seg ; current BIOS code seg
  1446. mov si, offset BCode_Start
  1447. mov di, si
  1448. mov cx, offset BCode_End
  1449. sub cx, si ; size of BIOS
  1450. shr cx, 1 ; Both the labels are para
  1451. ; aligned
  1452. rep movsw
  1453. push es
  1454. push di ; save end of BIOS
  1455. mov ax, es
  1456. mov BCodeSeg, ax ; save it for later use
  1457. call [seg_reinit_ptr] ; far call to seg_reinit (M022)
  1458. pop di
  1459. pop es ; get back end of BIOS
  1460. ret
  1461. MovBIOS endp
  1462. ;
  1463. ;----------------------------------------------------------------------------
  1464. ;
  1465. ; procedure : MovDOS
  1466. ;
  1467. ; Moves DOS code into requested area
  1468. ;
  1469. ; In : ES:DI - pointer to memory where DOS is to be moved
  1470. ; CX - size of DOS code to be moved
  1471. ;
  1472. ; Out : ES:DI - pointer to memory immediately after DOS
  1473. ;
  1474. ;----------------------------------------------------------------------------
  1475. ;
  1476. MovDOS proc near
  1477. push es
  1478. push di
  1479. lds si, dos_temp_location ; current location of DOS
  1480. rep movsb
  1481. pop bx ; get back offset into which
  1482. ; DOS was moved
  1483. mov ax, dosinit ; get the offset at which DOS
  1484. ; wants to run
  1485. sub ax, bx
  1486. call off_to_para
  1487. pop bx ; get the segment at which
  1488. ; we moved DOS into
  1489. sub bx, ax ; Adjust segment
  1490. mov current_dos_location, bx ; and save it
  1491. ret
  1492. MovDOS endp
  1493. ;
  1494. ;----------------------------------------------------------------------------
  1495. ;
  1496. ; procedure : AllocMemForDOS
  1497. ;
  1498. ; Allocate memory for DOS/BIOS code from DOS !!!
  1499. ;
  1500. ; Out : AX - seg of allocated memoryblock
  1501. ;
  1502. ;----------------------------------------------------------------------------
  1503. ;
  1504. AllocMemForDOS proc near
  1505. mov ax, offset BCode_end
  1506. sub ax, offset BCode_start ; BIOS code size
  1507. add ax, lo_doscod_size ; + DOS code size
  1508. add ax, 15
  1509. call off_to_para ; convert to para
  1510. or bx, bx ; M012
  1511. ; can we use int 21 for alloc
  1512. mov bx, ax
  1513. jz update_arena ; M012
  1514. mov ah, 48h ; request DOS
  1515. int 21h
  1516. jc FatalErr ; IF ERR WE ARE HOSED
  1517. sub ax, 3 ; Take care ORG 30h of
  1518. ; BIOS code
  1519. mov es, ax
  1520. mov word ptr es:[20h+arena_owner], 08h ; mark it as system
  1521. mov word ptr es:[20h+arena_name], 'CS' ; code area
  1522. ret
  1523. ;
  1524. ; M012 : BEGIN
  1525. ;
  1526. update_arena:
  1527. push ds
  1528. push di
  1529. push cx
  1530. push dx
  1531. lds di, dosinfo ; get ptr to DOS var
  1532. dec di
  1533. dec di ; Arena head is immediately
  1534. ; before sysvar
  1535. mov es, ds:[di] ; es = arena head
  1536. mov cx, es:[arena_size] ; cx = total low mem size
  1537. cmp cx, bx ; is it sufficient ?
  1538. jb FatalErr ; no, fatal error
  1539. mov dl, es:[arena_signature]
  1540. mov ax, es
  1541. add ax, bx ; ax = new arena head
  1542. mov ds:[di], ax ; store it in DOS data area
  1543. mov ds, ax
  1544. mov byte ptr ds:[arena_signature], dl ; type of arena
  1545. mov word ptr ds:[arena_owner], 0 ; free
  1546. sub cx, bx ; size of the new block
  1547. mov word ptr ds:[arena_size], cx ; store it in the arena
  1548. mov ax, es ; return seg to the caller
  1549. sub ax, 3 ; Take care ORG 30h of
  1550. ; BIOS code
  1551. pop dx
  1552. pop cx
  1553. pop di
  1554. pop ds
  1555. ret
  1556. ;
  1557. ; M012 : END
  1558. ;
  1559. FatalErr:
  1560. push cs
  1561. pop ds
  1562. mov dx, offset FEMsg
  1563. mov ah, 9h
  1564. int 21h
  1565. cli
  1566. hlt
  1567. AllocMemForDOS endp
  1568. ;
  1569. ;----------------------------------------------------------------------------
  1570. ;
  1571. ; procedure : AllocHMA
  1572. ;
  1573. ; grab_the_hma tries to enable a20 and make sure there is memory
  1574. ; up there. If it gets any sort of error, it will return with
  1575. ; carry set so that we can resort to running low.
  1576. ;
  1577. ; It also returns ES: -> 0ffffh if it returns success
  1578. ;
  1579. ;----------------------------------------------------------------------------
  1580. ;
  1581. AllocHMA proc near
  1582. assume ds:nothing,es:nothing
  1583. ;
  1584. ; cas note: The pre-286 check is no longer needed here since the
  1585. ; presence of XMS is sufficient. However, this code hasn't
  1586. ; been deleted because it can be recycled for skipping the
  1587. ; extra pass of CONFIG.SYS and assuming we're running low
  1588. ; in the case of a pre-286.
  1589. ;
  1590. ;; see if we're running on a pre-286. If not, force low.
  1591. ;
  1592. ; xor ax,ax
  1593. ; pushf ; save flags (like int)
  1594. ; push ax
  1595. ; popf
  1596. ; pushf
  1597. ; pop ax
  1598. ; popf ; restore original flags (like int)
  1599. ; and ax,0f000h
  1600. ; cmp ax,0f000h ; 8088/8086?
  1601. ; jz grab_hma_error
  1602. ;
  1603. push ds
  1604. mov ax,Bios_Data
  1605. mov ds,ax
  1606. assume ds:Bios_Data
  1607. call IsXMSLoaded
  1608. jnz grabhma_error
  1609. mov ax,4310h
  1610. int 2fh ; get the vector into es:bx
  1611. mov word ptr xms,bx
  1612. mov word ptr xms+2,es
  1613. mov ah,1 ; request HMA
  1614. mov dx,0ffffh
  1615. call xms
  1616. dec ax
  1617. jz @f ; error if not able to allocate HMA
  1618. ;
  1619. ;------ Himem may be lying because it has allocated mem for int 15
  1620. ;
  1621. mov ah, 88h
  1622. int 15h
  1623. cmp ax, 64 ; less than 64 K of hma ?
  1624. jb grabhma_error
  1625. @@: mov ah,5 ; localenableA20
  1626. call xms
  1627. dec ax
  1628. jnz grabhma_error ; error if couldn't enable A20
  1629. mov ax,0ffffh
  1630. mov es,ax
  1631. mov es:word ptr 10h,1234h ; see if we can really read/write there
  1632. cmp es:word ptr 10h,1234h
  1633. jnz grabhma_error ; don't try to load there if XMS lied
  1634. clc
  1635. pop ds
  1636. ret
  1637. grabhma_error:
  1638. stc
  1639. pop ds
  1640. assume ds:nothing
  1641. ret
  1642. AllocHMA endp
  1643. ;
  1644. ;----------------------------------------------------------------------------
  1645. ;
  1646. ; procedure : IsXMSLoaded
  1647. ;
  1648. ; Checks whether a XMS driver is loaded
  1649. ;
  1650. ; Returns : Z flag set if XMS driver loaded
  1651. ; Z flag reset if no XMS drivers are present
  1652. ;
  1653. ;----------------------------------------------------------------------------
  1654. ;
  1655. public IsXMSLoaded
  1656. IsXMSLoaded proc near
  1657. mov ax,4300h
  1658. int 2fh
  1659. cmp al,80h ; XMS installed?
  1660. ret
  1661. IsXMSLoaded endp
  1662. ;
  1663. ;
  1664. ;----------------------------------------------------------------------------
  1665. ; procedure : FTryToMovDOSHi
  1666. ;
  1667. ; Called from HMA suballoc calls
  1668. ;
  1669. ;----------------------------------------------------------------------------
  1670. ;
  1671. ;
  1672. public FTryToMovDOSHi
  1673. FTryToMovDOSHi proc far
  1674. push ax
  1675. push bx
  1676. push cx
  1677. push dx
  1678. push si
  1679. push di
  1680. push ds
  1681. push es
  1682. cmp runhigh, 0ffh
  1683. jne @f
  1684. call TryToMovDOSHi
  1685. @@:
  1686. pop es
  1687. pop ds
  1688. pop di
  1689. pop si
  1690. pop dx
  1691. pop cx
  1692. pop bx
  1693. pop ax
  1694. ret
  1695. FTryToMovDOSHi endp
  1696. ;
  1697. ;----------------------------------------------------------------------------
  1698. ;
  1699. ; procedure : SaveFreeHMAPtr
  1700. ;
  1701. ; Save the Free HMA pointer in BIOS variable for later use.
  1702. ; (INT 2f ax==4a01 call returns pointer to free HMA)
  1703. ; Normalizes the pointer to ffff:xxxx format and stores only
  1704. ; the offset.
  1705. ;
  1706. ; Inputs : ES:DI - pointer to free HMA
  1707. ; Output : FreeHMAPtr in BIOS data segment updated
  1708. ;
  1709. ;----------------------------------------------------------------------------
  1710. ;
  1711. SaveFreeHMAPtr proc near
  1712. mov bx, es
  1713. mov ax, 0ffffh ; HMA segment
  1714. sub ax, bx
  1715. add di, 15 ; para round
  1716. and di, 0fff0h
  1717. mov cl, 4
  1718. shl ax, cl
  1719. sub di, ax
  1720. push ds
  1721. mov ax, Bios_Data
  1722. mov ds, ax
  1723. assume ds:Bios_Data
  1724. mov FreeHMAPtr, di
  1725. mov inHMA, 0ffh
  1726. pop ds
  1727. assume ds:nothing
  1728. ret
  1729. SaveFreeHMAPtr endp
  1730. ;
  1731. ;
  1732. ;----------------------------------------------------------------------------
  1733. ;
  1734. ; procedure : CPMHack
  1735. ;
  1736. ; Copies the code from 0:c0 into ffff:0d0h
  1737. ; for CPM comatibilty
  1738. ;
  1739. ;----------------------------------------------------------------------------
  1740. ;
  1741. CPMHack proc near
  1742. push ds
  1743. mov cx, 0ffffH
  1744. mov es, cx ; ES = FFFF
  1745. xor cx, cx
  1746. mov ds, cx ; DS = 0
  1747. mov si, 0c0h
  1748. mov di, 0d0h
  1749. mov cx, 5
  1750. cld
  1751. rep movsb ; move 5 bytes from 0:C0 to FFFF:D0
  1752. pop ds
  1753. ret
  1754. CPMHack endp
  1755. ;
  1756. ;----------------------------------------------------------------------------
  1757. ;
  1758. ; procedure : off_to_para
  1759. ;
  1760. ;----------------------------------------------------------------------------
  1761. ;
  1762. off_to_para proc near
  1763. shr ax,1
  1764. shr ax,1
  1765. shr ax,1
  1766. shr ax,1
  1767. ret
  1768. off_to_para endp
  1769. ;** TempCDS - Create (Temporary?) CDS
  1770. ;
  1771. ; ENTRY ?? BUGBUG
  1772. ; (DS) = SysInitSeg
  1773. ; EXIT ?? BUGBUG
  1774. ; USES ?? BUGBUG
  1775. public tempcds
  1776. Procedure TempCDS
  1777. assume ds:sysinitseg
  1778. les di,dosinfo
  1779. mov cl,byte ptr es:[di.sysi_numio]
  1780. xor ch,ch ; (cx) = # of block devices
  1781. mov es:[di.sysi_ncds],cl ; one CDS per device
  1782. mov al,cl
  1783. mov ah,size curdir_list
  1784. mul ah ; (ax) = byte size for those CDSs
  1785. call pararound ; (ax) = paragraph size for CDSs
  1786. mov si,[confbot]
  1787. ; BUGBUG - we don't update confbot - won't someone else use it?
  1788. sub si,ax
  1789. mov [alloclim],si ; can't alloc past here!
  1790. mov word ptr es:[di.sysi_cds + 2],si
  1791. mov ax,si
  1792. mov word ptr es:[di.sysi_cds],0 ; set address of CDS list
  1793. assume ds:nothing
  1794. mov es,ax
  1795. xor di,di ; (es:di) = address of 1st CDS
  1796. ;* Initialize our temporary CDSs.
  1797. ;
  1798. ; (cx) = count of CDSs left to process
  1799. ; (si) = 0 based drive being processed
  1800. ; (es:di) = address of next CDS
  1801. fooset:
  1802. xor dx,dx ; indicator to stop removable checks
  1803. foogo:
  1804. mov ax,word ptr DirStrng
  1805. .errnz CURDIR_TEXT ; setup the root as the curdir
  1806. stosw
  1807. mov ax,word ptr DirStrng+2
  1808. stosw
  1809. xor ax,ax
  1810. push cx
  1811. .errnz CURDIR_FLAGS - CURDIR_TEXT - size CURDIR_TEXT
  1812. mov cx,curdir_flags - 4
  1813. rep stosb ; zero out rest of CURDIR_TEXTs
  1814. ; Here es:di points to CURDIR_FLAGS
  1815. or dx,dx ; have we found one fixed drive?
  1816. jnz fixed_drv2 ; NZ -> yes dont do IOCTL check
  1817. cmp byte ptr DirStrng, 'B'
  1818. jbe not_fixed ; 'A' and 'B' are always removable
  1819. mov bl,byte ptr DirStrng
  1820. sub bl,'A'
  1821. inc bl ; C is 3
  1822. mov ax,4408h
  1823. int 21h ; Is drive removable
  1824. jc fixed_drv ; Could'nt find means NET hence fixed
  1825. or ax,ax
  1826. jnz fixed_drv
  1827. not_fixed:
  1828. mov ax,CURDIR_LOCAL OR CURDIR_INUSE
  1829. jmp short fill_in
  1830. fixed_drv:
  1831. inc dx
  1832. fixed_drv2:
  1833. mov ax,CURDIR_LOCAL OR CURDIR_INUSE OR CURDIR_NT_FIX
  1834. fill_in:
  1835. FOLLOWS CURDIR_FLAGS,CURDIR_TEXT,2
  1836. stosw ; Save Flags
  1837. mov ax,2
  1838. FOLLOWS CURDIR_END,CURDIR_FLAGS,2
  1839. stosw ; Save CURDIR_END
  1840. inc byte ptr DirStrng
  1841. pop cx
  1842. loop foogo
  1843. mov byte ptr DirStrng,"A"
  1844. ret
  1845. EndProc TempCDS
  1846. ;** EndFile - Build DOS structures
  1847. ;
  1848. ; This procedure is called after the config.sys has been processed and
  1849. ; installable device drivers have been loaded (but before "install="
  1850. ; programs are loaded) to create the dos structures such as SFTs, buffers,
  1851. ; FCBs, CDSs, etc. It also loads the sysinit_base module in low memory
  1852. ; to allow for the safe EXECing of "install=" programs. All memory
  1853. ; above these structures is deallocated back to DOS.
  1854. ;
  1855. ; ENTRY ?? BUGBUG
  1856. ; EXIT ?? BUGBUG
  1857. ; USES ?? BUGBUG
  1858. ;------------------------------------------------------------------------------
  1859. ; allocate files
  1860. ;------------------------------------------------------------------------------
  1861. endfile:
  1862. ; we are now setting up final cdss,buffers,files,fcss strings etc. we no
  1863. ; longer need the space taken by the temp stuff below confbot,so set alloclim
  1864. ; to confbot.
  1865. ; if this procedure has been called to take care of install= command,
  1866. ; then we have to save es,si registers.
  1867. push ds
  1868. mov ax,Bios_Data
  1869. mov ds,ax
  1870. assume ds:Bios_Data
  1871. cmp multrk_flag,multrk_off1 ;=0,multrack= command entered?
  1872. jne multrk_flag_done
  1873. or multrk_flag,multrk_on ; default will be on.
  1874. multrk_flag_done:
  1875. pop ds
  1876. assume ds:nothing
  1877. mov ax,[confbot]
  1878. mov [alloclim],ax
  1879. push cs
  1880. pop ds
  1881. extrn round:near
  1882. call round
  1883. mov al,[files]
  1884. sub al,5
  1885. jbe dofcbs
  1886. push ax
  1887. mov al,devmark_files
  1888. call setdevmark ; set devmark for sfts (files)
  1889. pop ax
  1890. xor ah,ah ; do not use cbw instruction!!!!!
  1891. ; it does sign extend.
  1892. mov bx,[memlo]
  1893. mov dx,[memhi]
  1894. lds di,dosinfo ;get pointer to dos data
  1895. lds di,[di+sysi_sft] ;ds:bp points to sft
  1896. mov word ptr [di+sflink],bx
  1897. mov word ptr [di+sflink+2],dx ;set pointer to new sft
  1898. push cs
  1899. pop ds
  1900. les di,dword ptr [memlo] ;point to new sft
  1901. mov word ptr es:[di+sflink],-1
  1902. mov es:[di+sfcount],ax
  1903. mov bl,size sf_entry
  1904. mul bl ;ax = number of bytes to clear
  1905. mov cx,ax
  1906. add [memlo],ax ;allocate memory
  1907. mov ax,6
  1908. add [memlo],ax ;remember the header too
  1909. or [setdevmarkflag],for_devmark
  1910. call round ; check for mem error before the stosb
  1911. add di,ax
  1912. xor ax,ax
  1913. rep stosb ;clean out the stuff
  1914. ;------------------------------------------------------------------------------
  1915. ; allocate fcbs
  1916. ;------------------------------------------------------------------------------
  1917. dofcbs:
  1918. push cs
  1919. pop ds
  1920. call round
  1921. mov al,devmark_fcbs ;='x'
  1922. call setdevmark
  1923. mov al,[fcbs]
  1924. xor ah,ah ; do not use cbw instruction!!!!!
  1925. ; it does sign extend.
  1926. mov bx,[memlo]
  1927. mov dx,[memhi]
  1928. lds di,dosinfo ;get pointer to dos data
  1929. assume ds:nothing
  1930. mov word ptr [di+sysi_fcb],bx
  1931. mov word ptr [di+sysi_fcb+2],dx ;set pointer to new table
  1932. mov bl,cs:keep
  1933. xor bh,bh
  1934. mov [di+sysi_keep],bx
  1935. push cs
  1936. pop ds
  1937. assume ds:sysinitseg
  1938. les di,dword ptr [memlo] ;point to new table
  1939. mov word ptr es:[di+sflink],-1
  1940. mov es:[di+sfcount],ax
  1941. mov bl,size sf_entry
  1942. mov cx,ax
  1943. mul bl ;ax = number of bytes to clear
  1944. add [memlo],ax ;allocate memory
  1945. mov ax,size sf-2
  1946. add [memlo],ax ;remember the header too
  1947. or [setdevmarkflag],for_devmark
  1948. call round ; check for mem error before the stosb
  1949. add di,ax ;skip over header
  1950. mov al,"A"
  1951. fillloop:
  1952. push cx ; save count
  1953. mov cx,size sf_entry ; number of bytes to fill
  1954. cld
  1955. rep stosb ; filled
  1956. mov word ptr es:[di-(size sf_entry)+sf_ref_count],0
  1957. mov word ptr es:[di-(size sf_entry)+sf_position],0
  1958. mov word ptr es:[di-(size sf_entry)+sf_position+2],0
  1959. pop cx
  1960. loop fillloop
  1961. ;------------------------------------------------------------------------------
  1962. ; allocate cdss
  1963. ;------------------------------------------------------------------------------
  1964. buf1:
  1965. call round
  1966. push ax
  1967. mov ax,devmark_cds ;='l'
  1968. call setdevmark
  1969. pop ax
  1970. les di,dosinfo
  1971. mov cl,byte ptr es:[di.sysi_numio]
  1972. ;NTVDM Ignore the lastdrive command. There exists only one cds for all
  1973. ; network drives and dos has already set sysi_numio to be
  1974. ; num real drives + 1 for all network drives 17-Aug-1992 Jonle
  1975. ;
  1976. ; cmp cl,[num_cds]
  1977. ; jae gotncds ; user setting must be at least numio
  1978. ; mov cl,[num_cds]
  1979. ;gotncds:
  1980. ;
  1981. xor ch,ch
  1982. mov es:[di.sysi_ncds],cl
  1983. mov ax,[memhi]
  1984. mov word ptr es:[di.sysi_cds + 2],ax
  1985. mov ax,[memlo]
  1986. mov word ptr es:[di.sysi_cds],ax
  1987. mov al,cl
  1988. mov ah,size curdir_list
  1989. mul ah
  1990. call pararound
  1991. add [memhi],ax
  1992. or [setdevmarkflag],for_devmark
  1993. call round ; check for mem error before initializing
  1994. assume ds:nothing
  1995. les di,es:[di.sysi_cds]
  1996. call fooset
  1997. ;------------------------------------------------------------------------------
  1998. ; allocate space for internal stack
  1999. ;------------------------------------------------------------------------------
  2000. if stacksw
  2001. push cs
  2002. pop ds
  2003. assume ds:sysinitseg
  2004. doinstallstack:
  2005. mov ax,[stack_count] ; stack_count = 0?
  2006. or ax,ax ;then,stack size must be 0 too.
  2007. jz skipstack ;don't install stack.
  2008. ; dynamic relocation of stack code.
  2009. call round ;[memhi] = seg. for stack code
  2010. ;[memlo] = 0
  2011. ; set devmark block into memory for mem command
  2012. ; devmark_id = 's' for stack
  2013. mov al,devmark_stk ;='s'
  2014. call setdevmark
  2015. mov ax,[memhi]
  2016. mov es,ax ;es -> seg. the stack code is going to move.
  2017. assume es:nothing
  2018. push cs
  2019. pop ds
  2020. xor si,si ;!!we know that stack code is at the beginning of sysinit.
  2021. xor di,di
  2022. mov cx,offset endstackcode
  2023. mov [memlo],cx
  2024. call round ;have enough space for relocation?
  2025. rep movsb
  2026. push ds ; stick the location of the NextStack entry
  2027. mov ax,Bios_Data ; into the Win386 Instance Data tables
  2028. mov ds,ax
  2029. assume ds:Bios_Data
  2030. mov word ptr NextStack,offset nextentry
  2031. mov word ptr NextStack+2,es
  2032. mov ax,[memlo]
  2033. mov word ptr [stack_addr],ax ;set for stack area initialization
  2034. mov word ptr IT_StackLoc,ax ; pass it as Instance Data, too
  2035. mov ax,[memhi] ;this will be used by stack_init routine.
  2036. mov word ptr [stack_addr+2],ax
  2037. mov word ptr IT_StackLoc+2,ax
  2038. ; space for internal stack area = stack_count(entrysize + stack_size)
  2039. mov ax,entrysize
  2040. add ax,[stack_size]
  2041. mul [stack_count]
  2042. mov IT_StackSize,ax ; pass through to Instance Tables
  2043. pop ds ; no more need to access Instance Table
  2044. assume ds:nothing
  2045. call pararound ; convert size to pargraphs
  2046. add [memhi],ax
  2047. or [setdevmarkflag],for_devmark ;to set the devmark_size for stack by round routine.
  2048. call round ; check for memory error before
  2049. ; continuing
  2050. call stackinit ; initialize hardware stack. cs=ds=sysinitseg,es=relocated stack code & data
  2051. skipstack:
  2052. endif
  2053. push cs
  2054. pop ds
  2055. assume ds:sysinitseg
  2056. mov al,[files]
  2057. xor ah,ah ; do not use cbw instruction!!!!!
  2058. ; it does sign extend.
  2059. mov cx,ax
  2060. xor bx,bx ;close standard input
  2061. mov ah,close
  2062. int 21h
  2063. ;; go directly to the handle table; donot close any invalid handles
  2064. push si
  2065. mov ah, Get_Current_PDB ;
  2066. int 21h
  2067. les si, es:[pdb_jfn_pointer]
  2068. mov bx, 2
  2069. rcclloop:
  2070. cmp byte ptr es:[bx][si], 0FFh ;skip invalid handle
  2071. je skip_the_handle
  2072. mov ah,close ; need output so we can print message
  2073. int 21h ; in case we can't get new one open.
  2074. skip_the_handle:
  2075. inc bx
  2076. loop rcclloop
  2077. pop si
  2078. mov dx,offset condev
  2079. mov al,2
  2080. mov ah,open ;open con for read/write
  2081. stc ; set for possible int 24
  2082. int 21h
  2083. jnc goaux
  2084. call badfil
  2085. jmp short goaux2
  2086. goaux: push ax
  2087. mov bx,1 ;close standard output
  2088. mov ah,close
  2089. int 21h
  2090. pop ax
  2091. mov bx,ax ;new device handle
  2092. mov ah,xdup
  2093. int 21h ;dup to 1,stdout
  2094. mov ah,xdup
  2095. int 21h ;dup to 2,stderr
  2096. goaux2: mov dx,offset auxdev
  2097. mov al,2 ;read/write access
  2098. extrn open_dev:near
  2099. call open_dev
  2100. mov dx,offset prndev
  2101. mov al,1 ;write only
  2102. call open_dev
  2103. ;global rearm command for shared interrupt devices attached in the system;
  2104. ;shared interrupt attachment has some problem when it issues interrupt
  2105. ;during a warm reboot. once the interrupt is presented by the attachment,
  2106. ;no further interrupts on that level will be presented until a global rearm
  2107. ;is issued. by the request of the system architecture group, msbio will
  2108. ;issue a global rearm after every device driver is loaded.
  2109. ;to issue a global rearm: ;for pc1,xt,palace
  2110. ;
  2111. ; out 02f2h,xx ; interrupt level 2
  2112. ; out 02f3h,xx ; interrupt level 3
  2113. ; out 02f4h,xx ; interrupt level 4
  2114. ; out 02f5h,xx ; interrupt level 5
  2115. ; out 02f6h,xx ; interrupt level 6
  2116. ; out 02f7h,xx ; interrupt level 7
  2117. ;
  2118. ; for pc at,in addition to the above commands,
  2119. ; need to handle the secondary interrupt handler
  2120. ;
  2121. ; out 06f2h,xx ; interrupt level 10
  2122. ; out 06f3h,xx ; interrupt level 11
  2123. ; out 06f4h,xx ; interrupt level 12
  2124. ; out 06f6h,xx ; interrupt level 14
  2125. ; out 06f7h,xx ; interrupt level 15
  2126. ;
  2127. ; for round-up machine
  2128. ;
  2129. ; none.
  2130. ; where xx stands for any value.
  2131. ;
  2132. ; for your information,after naples level machine,the system service bios
  2133. ; call (int 15h),function ah=0c0h returns the system configuration parameters
  2134. ;
  2135. ;
  2136. ; Sudeepb 31-Dec-1991 Commented out for NT
  2137. if 0
  2138. push ax
  2139. push bx
  2140. push dx
  2141. push es
  2142. mov al,0ffh ;reset h/w by writing to port
  2143. mov dx,2f2h ;get starting address
  2144. out dx,al ; out 02f2h,0ffh
  2145. inc dx
  2146. out dx,al ; out 02f3h,0ffh
  2147. inc dx
  2148. out dx,al ; out 02f4h,0ffh
  2149. inc dx
  2150. out dx,al ; out 02f5h,0ffh
  2151. inc dx
  2152. out dx,al ; out 02f6h,0ffh
  2153. inc dx
  2154. out dx,al ; out 02f7h,0ffh
  2155. ;sb secondary global rearm
  2156. mov ax,0f000h ;get machine type
  2157. mov es,ax
  2158. cmp byte ptr es:[0fffeh],0fch ;q:is it a at type machine
  2159. je startrearm ; *if at no need to check
  2160. mov ah,0c0h ;get system configuration
  2161. int 15h ; *
  2162. jc finishrearm ; *jmp if old rom
  2163. ; test feature byte for secondary interrupt controller
  2164. test es:[bx.bios_sd_featurebyte1],scndintcontroller
  2165. je finishrearm ;jmp if it is there
  2166. startrearm:
  2167. mov al,0ffh ;write any pattern to port
  2168. mov dx,6f2h ;get starting address
  2169. out dx,al ;out 06f2h,0ffh
  2170. inc dx ;bump address
  2171. out dx,al ;out 06f3h,0ffh
  2172. inc dx ;bump address
  2173. out dx,al ;out 06f4h,0ffh
  2174. inc dx ;bump address
  2175. inc dx ;bump address
  2176. out dx,al ;out 06f6h,0ffh
  2177. inc dx ;bump address
  2178. out dx,al ;out 06f7h,0ffh
  2179. finishrearm:
  2180. pop es
  2181. pop dx
  2182. pop bx
  2183. pop ax
  2184. endif
  2185. ; global rearm end *******************
  2186. ;------------------------------------------------------------------------------
  2187. ; allocate sysinit_base for install= command
  2188. ;------------------------------------------------------------------------------
  2189. ; sysinit_base allocation.
  2190. ; check if endfile has been called to handle install= command.
  2191. set_sysinit_base:
  2192. ;--------------------------------------------------------------------------
  2193. ;sysinit_base will be established in the secure area of
  2194. ;lower memory when it handles the first install= command.
  2195. ;sysinit_base is the place where the actual exec function will be called and
  2196. ;will check sysinit module in high memory if it is damaged by the application
  2197. ;program. if sysinit module has been broken,then "memory error..." message
  2198. ;is displayed by sysinit_base.
  2199. ;--------------------------------------------------------------------------
  2200. push ax ; set devmark for mem command
  2201. mov ax,[memhi]
  2202. sub ax,[area]
  2203. mov [impossible_owner_size],ax ;remember the size in case.
  2204. mov al,devmark_inst
  2205. call setdevmark
  2206. pop ax
  2207. mov di,[memhi]
  2208. mov es,di
  2209. assume es:nothing
  2210. mov word ptr [sysinit_base_ptr+2],di ; save this entry for the next use.
  2211. xor di,di
  2212. mov word ptr [sysinit_base_ptr],di ; es:di -> destination.
  2213. mov si,offset sysinit_base ;ds:si -> source code to be relocated.
  2214. mov cx,(offset end_sysinit_base) - (offset sysinit_base)
  2215. add [memlo],cx
  2216. or cs:[setdevmarkflag],for_devmark
  2217. call round ; check mem error. also,readjust memhi for the next use.
  2218. rep movsb ; reallocate it.
  2219. mov word ptr [sysinit_ptr],offset sysinitptr ; returing address from
  2220. mov word ptr [sysinit_ptr+2],cs ; sysinit_base back to sysinit.
  2221. or [install_flag],has_installed ; set the flag.
  2222. ;------------------------------------------------------------------------------
  2223. ; free the rest of the memory from memhi to confbot. still from confbot to
  2224. ; the top of the memory will be allocated for sysinit and config.sys if
  2225. ; have_install_cmd.
  2226. ;------------------------------------------------------------------------------
  2227. call round
  2228. mov bx,[memhi]
  2229. mov ax,[area]
  2230. mov [old_area],ax ; save [area]
  2231. mov es,ax ;calc what we needed
  2232. sub bx,ax
  2233. mov ah,setblock
  2234. int 21h ;give the rest back
  2235. push es
  2236. mov ax,es
  2237. dec ax
  2238. mov es,ax ;point to arena
  2239. mov es:[arena_owner],8 ;set impossible owner
  2240. mov word ptr es:[arena_name], 'DS' ; System Data
  2241. pop es
  2242. mov bx,0ffffh
  2243. mov ah,alloc
  2244. int 21h
  2245. mov ah,alloc
  2246. int 21h ; allocate the rest of the memory
  2247. mov [memhi],ax ; start of the allocated memory
  2248. mov [memlo],0 ; to be used next.
  2249. ;;;; at this moment,memory from [memhi]:0 to top-of-the memory is
  2250. ;;;; allocated.
  2251. ;;;; to protect sysinit,confbot module (from confbot (or =alloclim at
  2252. ;;;; this time) to the top-of-the memory),here we are going to
  2253. ;;;; 1). "setblock" from memhi to confbot.
  2254. ;;;; 2). "alloc" from confbot to the top of the memory.
  2255. ;;;; 3). "free alloc memory" from memhi to confbot.
  2256. ;memory allocation for sysinit,confbot module.
  2257. mov es,ax
  2258. mov bx,[confbot]
  2259. sub bx,ax ; confbot - memhi
  2260. dec bx ; make a room for the memory block id.
  2261. dec bx ; make sure!!!.
  2262. mov ah,setblock
  2263. int 21h ; this will free (confbot to top of memory)
  2264. mov bx,0ffffh
  2265. mov ah,alloc
  2266. int 21h
  2267. mov ah,alloc
  2268. int 21h ; allocate (confbot to top of memory)
  2269. mov [area],ax ; save allocated memory segment.
  2270. ; need this to free this area for command.com.
  2271. mov es,[memhi]
  2272. mov ah,49h ; free allocated memory.
  2273. int 21h ; free (memhi to confbot(=area))
  2274. endfile_ret:
  2275. ret
  2276. ; End of "EndFile" DOS structure configuration.
  2277. ;-------------------------------------------------------------------------
  2278. ; Do_Install_Exec
  2279. ;
  2280. ; This procedure is used to EXEC a program being loaded via the
  2281. ; "install=" mechanism in config.sys. It does this by setting up
  2282. ; the parameters, and then jumping to sysinit_base, which has been
  2283. ; setup in low memory. When complete, sysinit_base will jump back
  2284. ; up to this procedure (if sysinit remains uncorrupted by the installed
  2285. ; program).
  2286. do_install_exec proc near ; now,handles install= command.
  2287. push si ; save si for config.sys again.
  2288. ; we are going to call load/exec function.
  2289. ; set es:bx to the parameter block here;;;;;;;
  2290. ; set ds:dx to the asciiz string. remember that we already has 0
  2291. ; after the filename. so parameter starts after that. if next
  2292. ; character is a line feed (i.e. 10),then assume that the 0
  2293. ; we already encountered used to be a carrage return. in this
  2294. ; case,let's set the length to 0 which will be followed by
  2295. ; carridge return.
  2296. ; es:si -> command line in config.sys. points to the first non blank
  2297. ;character after =.
  2298. push es
  2299. push ds
  2300. pop es
  2301. pop ds ; es->sysinitseg,ds->confbot seg
  2302. assume ds:nothing
  2303. mov dx,si ; ds:dx->file name,0 in config.sys image.
  2304. xor cx,cx
  2305. cld
  2306. mov cs:ldexec_start,' ' ; clear out the parm area
  2307. mov di,offset ldexec_parm
  2308. installfilename: ; skip the file name
  2309. lodsb ; al = ds:si; si++
  2310. cmp al,0
  2311. je got_installparm
  2312. jmp installfilename
  2313. got_installparm: ; copy the parameters to ldexec_parm
  2314. lodsb
  2315. mov es:[di],al
  2316. cmp al,lf ; line feed?
  2317. je done_installparm
  2318. inc cl ; # of char. in the parm.
  2319. inc di
  2320. jmp got_installparm
  2321. done_installparm:
  2322. mov byte ptr cs:[ldexec_line],cl ; length of the parm.
  2323. cmp cl,0 ;if no parm,then
  2324. jne install_seg_set ; let the parm area
  2325. mov byte ptr cs:[ldexec_start],cr ; starts with cr.
  2326. install_seg_set:
  2327. mov word ptr cs:0,0 ; make a null environment segment
  2328. mov ax,cs ; by overlap jmp instruction of sysinitseg.
  2329. ;hkn; the environment pointer is made 0. so the current environment ptr.
  2330. ;hkn; will be the same as pdb_environ which after dosinit is 0.
  2331. mov cs:[instexe.exec0_environ],0 ; set the environment seg.
  2332. mov word ptr cs:[instexe.exec0_com_line+2],ax ; set the seg.
  2333. mov word ptr cs:[instexe.exec0_5c_fcb+2],ax
  2334. mov word ptr cs:[instexe.exec0_6c_fcb+2],ax
  2335. call sum_up
  2336. mov es:checksum,ax ; save the value of the sum
  2337. xor ax,ax
  2338. mov ah,exec ; load/exec
  2339. mov bx,offset instexe ; es:bx -> parm block.
  2340. push es ; save es,ds for load/exec
  2341. push ds ; these registers will be restored in sysinit_base.
  2342. jmp cs:dword ptr sysinit_base_ptr ; jmp to sysinit_base to execute
  2343. ; load/exec function and check sum.
  2344. ;j.k. this is the returning address from sysinit_base.
  2345. sysinitptr: ; returning far address from sysinit_base
  2346. pop si ; restore si for config.sys file.
  2347. push es
  2348. push ds
  2349. pop es
  2350. pop ds ; now ds - sysinitseg,es - confbot
  2351. jnc exec_exit_code
  2352. push si ; error in loading the file for install=.
  2353. call badload ; es:si-> path,filename,0.
  2354. pop si
  2355. jmp short install_exit_ret
  2356. exec_exit_code:
  2357. mov ah,4dh
  2358. int 21h
  2359. cmp ah,3 ;only accept "stay resident" prog.
  2360. je install_exit_ret
  2361. call error_line ;inform the user
  2362. stc
  2363. install_exit_ret:
  2364. ret
  2365. do_install_exec endp
  2366. ;** ParaRound - Round Up length to paragraph multiple
  2367. ;
  2368. ; ParaRound rounds a byte count up to a multiple of 16, then divides
  2369. ; by 16 yielding a "length in paragraphs" value.
  2370. ;
  2371. ; ENTRY (ax) = byte length
  2372. ; EXIT (ax) = rounded up length in paragraphs
  2373. ; USES ax, flags
  2374. Procedure ParaRound
  2375. add ax,15
  2376. rcr ax,1
  2377. shr ax,1
  2378. shr ax,1
  2379. shr ax,1
  2380. ret
  2381. EndProc ParaRound
  2382. ;------------------------------------------------------------------------------
  2383. ; sysinit_base module.
  2384. ;
  2385. ; This module is relocated by the routine EndFile to a location in low
  2386. ; memory. It is then called by SYSINIT to perform the EXEC of programs
  2387. ; that are being loaded by the "install=" command. After the EXEC call
  2388. ; completes, this module performs a checksum on the SYSINIT code (at the
  2389. ; top of memory) to be sure that the EXECed program did not damage it.
  2390. ; If it did, then this module will print an error message and stop the
  2391. ; system. Otherwise, it returns control to SYSINIT.
  2392. ;
  2393. ;
  2394. ;in: after relocation,
  2395. ; ax = 4b00h - load and execute the program dos function.
  2396. ; ds = confbot. segment of config.sys file image
  2397. ; es = sysinitseg. segment of sysinit module itself.
  2398. ; ds:dx = pointer to asciiz string of the path,filename to be executed.
  2399. ; es:bx = pointer to a parameter block for load.
  2400. ; SI_end (byte) - offset vaule of end of sysinit module label
  2401. ; bigsize (word) - # of word from confbot to SI_end.
  2402. ; chksum (word) - sum of every byte from confbot to SI_end in a
  2403. ; word boundary moduler form.
  2404. ; sysinit_ptr (dword ptr) - return address to sysinit module.
  2405. ;
  2406. ;note: sysinit should save necessary registers and when the control is back
  2407. public sysinit_base
  2408. sysinit_base:
  2409. mov word ptr cs:sysinit_base_ss,ss ; save stack
  2410. mov word ptr cs:sysinit_base_sp,sp
  2411. int 21h ; load/exec dos call.
  2412. mov ss,word ptr cs:sysinit_base_ss ; restore stack
  2413. mov sp,word ptr cs:sysinit_base_sp
  2414. pop ds ; restore confbot seg
  2415. pop es ; restore sysinitseg
  2416. jc sysinit_base_end ; load/exec function failed.
  2417. ; at this time,i don't have to worry about
  2418. ; that sysinit module has been broken or not.
  2419. call sum_up ; otherwise,check if it is good.
  2420. cmp es:checksum,ax
  2421. je sysinit_base_end
  2422. ; memory broken. show "memory allocation error" message and stall.
  2423. mov ah,9
  2424. push cs
  2425. pop ds
  2426. mov dx,offset mem_alloc_err_msgx - sysinit_base
  2427. int 21h
  2428. jmp $ ; hang here!!!!
  2429. sysinit_base_end: jmp es:sysinit_ptr ;return back to sysinit module
  2430. sum_up:
  2431. ;in: es - sysinitseg.
  2432. ;out: ax - result
  2433. ;
  2434. ;remark: since this routine will only check starting from "locstack" to the end of
  2435. ; sysinit segment,the data area, and the current stack area are not
  2436. ; coverd. in this sense,this check sum routine only gives a minimal
  2437. ; gaurantee to be safe.
  2438. ;
  2439. ;first sum up confbot seg.
  2440. push ds
  2441. mov ax,es:confbot
  2442. mov ds,ax
  2443. xor si,si
  2444. xor ax,ax
  2445. mov cx,es:config_size ; if config_size has been broken,then this
  2446. ;whole test better fail.
  2447. shr cx,1 ; make it a word count
  2448. jz sum_sys_code ; when config.sys file not exist.
  2449. sum1:
  2450. add ax,ds:word ptr [si]
  2451. inc si
  2452. inc si
  2453. loop sum1
  2454. ;now,sum up sysinit module.
  2455. sum_sys_code:
  2456. mov si,offset locstack ; starting after the stack.
  2457. ; this does not cover the possible stack code!!!
  2458. mov cx,offset sysinitgrp:SI_end ; SI_end is the label at the end of sysinit
  2459. sub cx,si ; from after_checksum to SI_end
  2460. shr cx,1
  2461. sum2:
  2462. add ax,es:word ptr [si]
  2463. inc si
  2464. inc si
  2465. loop sum2
  2466. pop ds
  2467. ret
  2468. sysinit_base_ss equ $-sysinit_base
  2469. dw ?
  2470. sysinit_base_sp equ $-sysinit_base
  2471. dw ?
  2472. mem_alloc_err_msgx:
  2473. include msbio.cl4 ; memory allocation error message
  2474. end_sysinit_base label byte
  2475. ;------------------------------------------------------------------------------
  2476. ; ibmstack initialization routine.
  2477. if stacksw
  2478. .sall
  2479. ;
  2480. ; to follow the standard interrupt sharing scheme, msstack.asm
  2481. ; has been modified. this initialization routine also has to
  2482. ; be modified because for the interrupt level 7 and 15, firstflag
  2483. ; should be set to signal that this interrupt handler is the
  2484. ; first handler hooked to this interrupt vector.
  2485. ; we determine this by looking at the instruction pointed by
  2486. ; this vector. if it is iret, then this handler should be the
  2487. ; first one. in our case, only the interrupt vector 77h is the
  2488. ; interrupt level 15. (we don't hook interrupt level 7.)
  2489. ;
  2490. ; the followings are mainly due to m.r.t; ptm fix of p886 12/3/86
  2491. ; some design changes are needed to the above interrupt sharing
  2492. ; method. the above sharing scheme assumes that 1). interrupt
  2493. ; sharing is never done on levels that have bios support. 2). "phantom"
  2494. ; interrupts would only be generated on levels 7 and 15.
  2495. ; these assumptions are not true any more. we have to use the firstflag
  2496. ; for every level of interrupt. we will set the firstflag on the following
  2497. ; conditions:
  2498. ;
  2499. ; a. if the cs portion of the vector is 0000, then "first"
  2500. ; b. else if cs:ip points to valid shared header, then not "first"
  2501. ; c. else if cs:ip points to an iret, then "first"
  2502. ; d. else if cs:ip points to dummy, then "first"
  2503. ;
  2504. ; where dummy is - the cs portion must be f000, and the ip portion must
  2505. ; be equal to the value at f000:ff01. this location is the initial value
  2506. ; from vector_table for interrupt 7, one of the preserved addresses in all
  2507. ; the bioses for all of the machines.
  2508. ;
  2509. ; system design group requests bios to handle the phantom interrupts.
  2510. ;
  2511. ; the "phantom" interrupt is an illegal interrupt such as an interrupt
  2512. ; produced by the bogus adapter card even without interrupt request is
  2513. ; set. more specifically, 1). the 8259 has a feature when running in
  2514. ; edge triggered mode to latch a pulse and present the interrupt when
  2515. ; the processor indicates interrupt acknowledge (inta). the interrupt
  2516. ; pulse was exist at the time of inta to get a "phantom" interrupt.
  2517. ; 2). or, this is caused by adapter cards placing a glitch on the
  2518. ; interrupt line.
  2519. ;
  2520. ; to handle those "phantom" interrupts, the main stack code will check
  2521. ; the own firstflag, and if it is not "first" (which means the forward
  2522. ; pointer points to the legal shared interrupt handler), then pass the
  2523. ; control. if it is the first, then the following action should be
  2524. ; taken. we don't have to implement skack logic in this case.
  2525. ;
  2526. ; to implement this logic, we rather choose a simple method.
  2527. ; if ont of the above "firstflag" conditions is met, we are not
  2528. ; going to hook this interrupt vector. the reason is if the original
  2529. ; vector points to "iret" and do nothing, we don't need
  2530. ; to implement the stack logic for it. this will simplify implementation
  2531. ; while maintaining compatibility with the old version of dos.
  2532. ; this implies that in the main stack code, there might be a stack code
  2533. ; that will never be used, a dead code.
  2534. ;
  2535. ;in - cs, ds -> sysinitseg, es -> relocated stack code & data.
  2536. page
  2537. assume ds:sysinitseg
  2538. stackinit proc near
  2539. push ax
  2540. push ds
  2541. push es
  2542. push bx
  2543. push cx
  2544. push dx
  2545. push di
  2546. push si
  2547. push bp
  2548. ;currently es -> stack code area
  2549. mov ax, cs:[stack_count] ;defined in cs
  2550. mov es:[stackcount], ax ;defined in stack code area
  2551. mov ax, [stack_size] ;in cs
  2552. mov es:[stacksize], ax
  2553. mov ax, word ptr cs:[stack_addr] ; offset
  2554. mov word ptr es:[stacks], ax
  2555. mov ax, word ptr cs:[stack_addr+word] ; segment
  2556. mov word ptr es:[stacks+word], ax
  2557. ; initialize the data fields with the parameters
  2558. ; "firstentry" will always be at stacks
  2559. mov bp, word ptr es:stacks ; get offset of stack
  2560. mov es:firstentry,bp
  2561. ; the stacks will always immediately follow the table entries
  2562. mov ax,entrysize
  2563. mov cx,es:stackcount
  2564. mul cx
  2565. add ax,bp
  2566. mov es:stackat,ax
  2567. mov bx,ax
  2568. sub bx,2
  2569. ; zero the entire stack area to start with
  2570. mov di,es:stackat
  2571. mov ax,es:stacksize
  2572. mul cx
  2573. mov cx,ax
  2574. xor ax,ax
  2575. push es
  2576. pop ds ;ds = relocated stack code seg.
  2577. assume ds:nothing
  2578. ;now, ds -> stack code area
  2579. mov es, word ptr ds:[stacks+2] ; get segment of stack area.
  2580. cld
  2581. rep stosb
  2582. mov cx, ds:stackcount
  2583. ; loop for "count" times, building a table entry
  2584. ; cs = sysinitseg, ds = relocated stack code seg , es = segment of stack space
  2585. ; cx = number of entries
  2586. ; es:bp => base of stacks - 2
  2587. ; es:bx => first table entry
  2588. buildloop:
  2589. mov es:byte ptr allocbyte[bp],free
  2590. mov es:byte ptr intlevel[bp],al ;ax = 0
  2591. mov es:word ptr savedsp[bp],ax
  2592. mov es:word ptr savedss[bp],ax
  2593. add bx,ds:stacksize
  2594. mov es:word ptr newsp[bp],bx
  2595. mov es:[bx],bp
  2596. add bp,entrysize
  2597. loop buildloop
  2598. sub bp,entrysize
  2599. mov ds:lastentry,bp
  2600. mov ds:nextentry,bp
  2601. ; NTVDM support for pc convertable is NOT NEEDED 10-Aug-1992 Jonle
  2602. ; push ds
  2603. ; mov ax, 0f000h ;look at the model byte
  2604. ; mov ds, ax
  2605. ; cmp ds:byte ptr [0fffeh], mdl_convert ;convertible?
  2606. ; pop ds
  2607. ; jne skip_disablenmis
  2608. ;
  2609. ; mov al,07h ; disable convertible nmis
  2610. ; out 72h,al
  2611. ;
  2612. ;skip_disablenmis:
  2613. xor ax,ax
  2614. mov es,ax ;es - segid of vector table at 0
  2615. assume es:nothing ;ds - relocated stack code segment
  2616. call DOCLI
  2617. irp aa,<02,70>
  2618. mov si,aa&h*4 ;pass where vector is to be adjusted
  2619. mov di, offset int19old&aa ;we have to set old&aa for int19 handler too.
  2620. mov bx,offset old&aa ;pass where to save original owner pointer
  2621. mov dx,offset int&aa ;pass where new handler is
  2622. call new_init_loop ;adjust the vector to new handler,
  2623. ; saving pointer to original owner
  2624. endm
  2625. ; NTVDM int 08, 09, special handling 24-Jan-1993 Jonle
  2626. ;
  2627. ; These Ints are usually done in the macro above with int 02,70
  2628. ; However, we don't need stack swapping as long as no device
  2629. ; driver has hooked it. These ints are also left alone so that
  2630. ; softpc will know if they have been hooked by an app.
  2631. mov si, 09h*4
  2632. mov ax, word ptr es:[si+0]
  2633. cmp word ptr old09, ax
  2634. jne do_I9StkSwap
  2635. mov ax, word ptr es:[si+2]
  2636. cmp word ptr old09+2, ax
  2637. je skip_I9StkSwap
  2638. do_I9StkSwap:
  2639. mov di, offset int19old09
  2640. mov bx,offset old09
  2641. mov dx,offset int09
  2642. call new_init_loop
  2643. skip_I9StkSwap:
  2644. mov si, 08h*4
  2645. mov ax, word ptr es:[si+0]
  2646. cmp word ptr old08, ax
  2647. jne do_I8StkSwap
  2648. mov ax, word ptr es:[si+2]
  2649. cmp word ptr old08+2, ax
  2650. je skip_I8StkSwap
  2651. do_I8StkSwap:
  2652. mov di, offset int19old08
  2653. mov bx,offset old08
  2654. mov dx,offset int08
  2655. call new_init_loop
  2656. skip_I8StkSwap:
  2657. irp aa,<0a,0b,0c,0d,0e,72,73,74,76,77> ;shared interrupts
  2658. mov si,aa&h*4 ;pass where vector is to be adjusted
  2659. push ds ;save relocated stack code segment
  2660. lds bx, es:[si] ;ds:bx -> original interrupt handler
  2661. push ds
  2662. pop dx ;dx = segment value
  2663. cmp dx,0
  2664. jz int&aa&_first
  2665. cmp byte ptr ds:[bx],0cfh ;does vector point to an iret?
  2666. jz int&aa&_first
  2667. cmp word ptr ds:[bx.6],424bh ;magic offset (see int&aa, msstack.inc)
  2668. jz int&aa&_not_first
  2669. cmp dx,0f000h ;rom bios segment
  2670. jnz int&aa&_not_first
  2671. push es
  2672. push dx
  2673. mov dx,0f000h
  2674. mov es,dx
  2675. cmp bx,word ptr es:0ff01h
  2676. pop dx
  2677. pop es
  2678. jz int&aa&_first
  2679. int&aa&_not_first: ;not the first. we are going to hook vector.
  2680. pop ds
  2681. mov di, offset int19old&aa ;we have to set old&aa for int19 handler too.
  2682. mov bx, offset old&aa ;pass where to save original owner pointer
  2683. mov dx, offset int&aa ;pass where new handler is
  2684. call new_init_loop ;adjust the vector to new handler, saving
  2685. ;pointer to original owner.
  2686. jmp short int&aa&_end
  2687. int&aa&_first: ;the first. don't have to hook stack code.
  2688. pop ds
  2689. int&aa&_end:
  2690. endm
  2691. ; NTVDM support for pc convertable is NOT NEEDED 10-Aug-1992 Jonle
  2692. ; push ds
  2693. ; mov ax, 0f000h ;loook at the model byte
  2694. ; mov ds, ax
  2695. ; cmp ds:byte ptr [0fffeh], mdl_convert ;pc convertible?
  2696. ; pop ds
  2697. ; jne skip_enablenmis
  2698. ;
  2699. ; mov al,27h ; enable convertible nmis
  2700. ; out 72h,al
  2701. ;
  2702. ; skip_enablenmis:
  2703. call DOSTI
  2704. mov ax,Bios_Data
  2705. mov ds,ax
  2706. assume ds:Bios_Data
  2707. mov [int19sem],1 ; indicate that int 19
  2708. ; initialization is complete
  2709. pop bp ; restore all
  2710. pop si
  2711. pop di
  2712. pop dx
  2713. pop cx
  2714. pop bx
  2715. pop es
  2716. pop ds
  2717. assume ds:sysinitseg
  2718. pop ax
  2719. ret
  2720. stackinit endp
  2721. new_init_loop proc near
  2722. ;input: si=ofset into vector table of the particular int vector being adjusted
  2723. ; bx=ds:offset of oldxx, where will be saved the pointer to original owner
  2724. ; dx=ds:offset of intxx, the new interrupt handler
  2725. ; di=offset value of int19old&aa variable in bios.
  2726. ; es=zero, segid of vector table
  2727. ; ds=relocated stack code segment
  2728. mov ax,es:[si+0] ;remember offset in vector
  2729. mov word ptr ds:[bx],ax ; to original owner in ds
  2730. mov ax,es:[si+2] ;remember segid in vector
  2731. mov word ptr ds:[bx]+2,ax ; to original owner in ds
  2732. push ds
  2733. mov ax,Bios_Data
  2734. mov ds,ax ;set int19oldxx value in bios for
  2735. mov ax,es:[si+0] ;int 19 handler
  2736. mov word ptr ds:[di],ax
  2737. mov ax,es:[si+2]
  2738. mov word ptr ds:[di]+2,ax
  2739. pop ds
  2740. mov word ptr es:[si+0],dx ;set vector to point to new int handler
  2741. mov es:[si+2],ds
  2742. ret
  2743. new_init_loop endp
  2744. .xall
  2745. endif
  2746. ;------------------------------------------------------------------------------
  2747. public setdevmark
  2748. setdevmark proc
  2749. ;set the devmark for mem command.
  2750. ;in: [memhi] - the address to place devmark
  2751. ; [memlo] = 0
  2752. ; al = id for devmark_id
  2753. ;out: devmark established.
  2754. ; the address saved in cs:[devmark_addr]
  2755. ; [memhi] increase by 1.
  2756. push es
  2757. push cx
  2758. mov cx,cs:[memhi]
  2759. mov cs:[devmark_addr],cx
  2760. mov es,cx
  2761. mov es:[devmark_id],al
  2762. inc cx
  2763. mov es:[devmark_seg],cx
  2764. pop cx
  2765. pop es
  2766. inc cs:[memhi]
  2767. ret
  2768. setdevmark endp
  2769. ifdef TAIWAN
  2770. ;---------------------
  2771. ; entry : none
  2772. ; exit : ax = 0 --> oem local driver not found
  2773. ; = 1 --> oem local driver found
  2774. ; destore : ds,es,bx,cx,dx,si,di
  2775. ; description :
  2776. ; search config.sys to find oem local driver.
  2777. ; oem local driver should in \csi\driver\ directory .
  2778. ; if (found oem local driver in config.sys)
  2779. ; ax=1;
  2780. ; else
  2781. ; ax=0;
  2782. ; return;
  2783. ; ps. please see state diagram for state description.
  2784. ;---------------------
  2785. chkoemlocaldrv proc near
  2786. push es
  2787. push ds
  2788. push bx
  2789. push cx
  2790. push dx
  2791. push di
  2792. push si
  2793. call chkconfig
  2794. pop si
  2795. pop di
  2796. pop dx
  2797. pop cx
  2798. pop bx
  2799. pop ds
  2800. pop es
  2801. ret
  2802. chkoemlocaldrv endp
  2803. config_sys db "C:\CONFIG.SYS",0
  2804. sizeofconfig dw 0
  2805. filehandle dw 0
  2806. workingmemptr dw 0
  2807. deviceid db "DEVICE"
  2808. csidrvid db "CSI\DRIVER\"
  2809. localdrvname dw 0
  2810. chkconfig proc near
  2811. call preprocess
  2812. jnc initstate
  2813. jmp notfoundret
  2814. ;
  2815. ; processing config.sys
  2816. ;
  2817. ; state 0
  2818. ; ds:si --> current line ( end of line is oah or 0dh )
  2819. initstate:
  2820. mov si,dx
  2821. state_0:
  2822. push cs
  2823. pop es
  2824. mov di,offset deviceid
  2825. mov cx,3
  2826. repz cmpsw
  2827. jz state_1
  2828. mov ax,0ffffh
  2829. jmp state_10
  2830. state_1:
  2831. lodsb
  2832. cmp al,' '
  2833. jz state_1
  2834. cmp al,'='
  2835. jz state_2
  2836. state_10a:
  2837. jmp state_10
  2838. state_2:
  2839. lodsb
  2840. cmp al,' '
  2841. jz state_2
  2842. cmp al,'\'
  2843. jz state_5
  2844. cmp al,'A'
  2845. jb state_10a
  2846. cmp al,'z'
  2847. ja state_10a
  2848. state_3:
  2849. dec si
  2850. mov cs:[localdrvname],si
  2851. inc si
  2852. state_4:
  2853. lodsb
  2854. cmp al,':'
  2855. jz state_6
  2856. jmp state_10
  2857. state_5:
  2858. dec si
  2859. mov cs:[localdrvname],si
  2860. inc si
  2861. jmp state_7
  2862. state_6:
  2863. lodsb
  2864. cmp al,'\'
  2865. jz state_7
  2866. cmp al,'c'
  2867. jne state_10a
  2868. inc si
  2869. state_7:
  2870. mov di,offset csidrvid
  2871. mov cx,11
  2872. repz cmpsb
  2873. jnz state_10a
  2874. state_8:
  2875. lodsb
  2876. cmp al,'1'
  2877. jb state_10
  2878. cmp al,'z'
  2879. ja state_10
  2880. state_9:
  2881. tryopenlocaldrv:
  2882. mov dx,cs:[localdrvname]
  2883. mov si,dx
  2884. chknextbyte:
  2885. lodsb
  2886. cmp al,0h
  2887. jz openfile
  2888. cmp al,' '
  2889. jne chknextbyte
  2890. dec si
  2891. mov byte ptr ds:[si],0
  2892. openfile:
  2893. mov ax,3d00h ; open config.sys
  2894. stc
  2895. int 21h
  2896. jc notfoundret
  2897. mov bx,ax ; bx = file handle
  2898. mov ah,3eh
  2899. int 21h ; close local driver
  2900. jc notfoundret
  2901. jmp foundret
  2902. state_10:
  2903. cmp al,1ah ; look current char. == eof ?
  2904. jz notfoundret
  2905. lodsb
  2906. cmp al,0
  2907. jz newlinestate
  2908. cmp al,1ah
  2909. jz notfoundret
  2910. jmp state_10
  2911. newlinestate:
  2912. lodsb
  2913. cmp al,1ah
  2914. jz notfoundret
  2915. cmp al,0
  2916. jz newlinestate
  2917. dec si
  2918. jmp state_0
  2919. notfoundret:
  2920. mov ax,0
  2921. jmp freemem
  2922. foundret:
  2923. mov ax,1
  2924. freemem:
  2925. push ax
  2926. call freememory
  2927. pop ax
  2928. ret
  2929. chkconfig endp
  2930. preprocess proc near
  2931. push cs
  2932. pop ds
  2933. mov dx,offset config_sys
  2934. mov ax,3d00h ; open config.sys
  2935. stc
  2936. int 21h
  2937. jc errorfile
  2938. ; get size of config.sys
  2939. mov bx,ax ; bx = file handle
  2940. mov cs:[filehandle],bx
  2941. xor cx,cx
  2942. xor dx,dx
  2943. mov ax,4202h ; move file ptr
  2944. int 21h
  2945. mov cs:[sizeofconfig],ax ; ax == size of config.sys
  2946. xor dx,dx ; ignore more than 64k of config
  2947. mov ax,4200h ; mov file ptr to beginning of file
  2948. int 21h
  2949. ; allocate for config.sys
  2950. mov ax,cs:[sizeofconfig]
  2951. add ax,15 ; change to para
  2952. rcr ax,1
  2953. shr ax,1
  2954. shr ax,1
  2955. shr ax,1
  2956. add ax,20h
  2957. mov bx,ax ; size of memory in para
  2958. mov ah,48h
  2959. int 21h
  2960. jc memerr
  2961. ; ax --> free memory
  2962. mov cs:[workingmemptr],ax
  2963. ; read config.sys
  2964. mov bx,cs:[filehandle] ; file handle
  2965. mov cx,cs:[sizeofconfig] ; byte count of reading
  2966. xor dx,dx
  2967. mov ds,ax ; ds:dx --> buffer
  2968. mov ah,3fh
  2969. int 21h
  2970. jc errorfile
  2971. ; translate to upper case
  2972. call transtoupper
  2973. clc
  2974. ret
  2975. errorfile:
  2976. memerr:
  2977. stc
  2978. ret
  2979. preprocess endp
  2980. ; entry : ds:dx --> buffer
  2981. ; exit : none
  2982. ; description : translate all letter in buffer to upper type
  2983. ; ps ,don't change ds:dx
  2984. transtoupper proc near
  2985. cld
  2986. mov cx,cs:[sizeofconfig]
  2987. mov si,dx
  2988. transnext:
  2989. lodsb
  2990. cmp al,'A'
  2991. jb chklfcr
  2992. cmp al,'z'
  2993. ja chkcounter
  2994. sub al,'a'-'A'
  2995. mov ds:[si-1],al
  2996. jmp chkcounter
  2997. chklfcr:
  2998. cmp al,0dh
  2999. jz setzero
  3000. cmp al,0ah
  3001. jz setzero
  3002. jmp chkcounter
  3003. setzero:
  3004. mov al,0
  3005. mov ds:[si-1],al
  3006. chkcounter:
  3007. loop transnext
  3008. ret
  3009. transtoupper endp
  3010. ;entry : none ( free memory block ptr in [workingmem] )
  3011. ;exit : none
  3012. freememory proc near
  3013. mov ax,cs:[workingmemptr]
  3014. mov es,ax
  3015. mov ah,49h
  3016. int 21h
  3017. ret
  3018. freememory endp
  3019. ; name : maketempvector
  3020. ; entry : es:bx -->
  3021. ; dd original int 9 vector ( offfset ,segment )
  3022. ; dd original int 10h vector ( offfset ,segment )
  3023. ; dd original int 16h vector ( offfset ,segment )
  3024. ;
  3025. ; exit : none
  3026. ; description : 1. save local driver table in static area
  3027. ; 2. make temp. vector for int9 ,10h ,16h
  3028. ;
  3029. oemdriverinst dw 0
  3030. orgvectblptr dd 0
  3031. db 0eah
  3032. dummyint9 dd 0
  3033. db 0eah
  3034. dummyint10h dd 0
  3035. db 0eah
  3036. dummyint16h dd 0
  3037. csiint9 dd 0
  3038. csiint10h dd 0
  3039. csiint16h dd 0
  3040. maketempvector proc near
  3041. push ds
  3042. push ax
  3043. push di
  3044. push si
  3045. push cx
  3046. ; save table ptr
  3047. mov word ptr cs:[orgvectblptr],bx
  3048. mov word ptr cs:[orgvectblptr+2],es
  3049. cmp cs:oemdriverinst,0
  3050. jnz ignoreint9
  3051. ; make temp. vector for int 9 ,
  3052. mov bx,9 ; int #
  3053. push cs
  3054. pop es
  3055. mov di,offset csiint9 ; es:di --> store area for csi vector
  3056. push cs
  3057. pop ds
  3058. mov si,offset dummyint9 ; ds:si --> dummy int service
  3059. call dummyvector
  3060. ignoreint9:
  3061. ; make temp. vector for int 10h
  3062. mov bx,10h ; int #
  3063. push cs
  3064. pop es
  3065. mov di,offset csiint10h ; es:di --> store area for csi vector
  3066. push cs
  3067. pop ds
  3068. mov si,offset dummyint10h ; ds:si --> dummy int service
  3069. call dummyvector
  3070. ; make temp. vector for int 16h
  3071. mov bx,16h ; int #
  3072. push cs
  3073. pop es
  3074. mov di,offset csiint16h ; es:di --> store area for csi vector
  3075. push cs
  3076. pop ds
  3077. mov si,offset dummyint16h ; ds:si --> dummy int service
  3078. call dummyvector
  3079. pop cx
  3080. pop si
  3081. pop di
  3082. pop ax
  3083. pop ds
  3084. ret
  3085. maketempvector endp
  3086. ;name : dummyvector
  3087. ; entey : ds:si --> dummy int sevice routine
  3088. ; es:di --> point to csi vector store area
  3089. ; bx == int number
  3090. ; exit : none
  3091. ; description :
  3092. ; setting dummy vector of int 9 ,10h,16h
  3093. ; for recover csi vector
  3094. ; /* phase 1*/
  3095. ; [ds:si]=[0:bx*4]
  3096. ; [ds:si+2]=[0:bx*4+2]
  3097. ; /* phase 2*/
  3098. ; [es:di]=[0:bx*4]
  3099. ; [es:di+2]=[0:bx*4+2]
  3100. ; /* phase 2*/
  3101. ; [0:bx*4]=si-1;
  3102. ; [0:bx*4+2]=ds;
  3103. dummyvector proc near
  3104. shl bx,1 ; bx <- bx*4
  3105. shl bx,1 ; ie ,get offset of vector
  3106. ; phase 1
  3107. ; es --> 0
  3108. ; es:bx --> cpu int vector table
  3109. xor ax,ax
  3110. push es
  3111. mov es,ax
  3112. mov ax,es:[bx] ; get offset ds-->0
  3113. mov ds:[si],ax ; store offset
  3114. mov ax,es:[bx+2] ; get offset ds-->0
  3115. mov ds:[si+2],ax ; store segment
  3116. pop es
  3117. ; phase 2
  3118. ; ds --> 0
  3119. ; ds:bx --> cpu int vector table
  3120. xor ax,ax
  3121. push ds
  3122. mov ds,ax
  3123. mov ax,ds:[bx] ; get offset
  3124. mov es:[di],ax ; store offset
  3125. mov ax,ds:[bx+2] ; get offset
  3126. mov es:[di+2],ax ; store segment
  3127. pop ds
  3128. ; phase 3
  3129. ; es --> 0
  3130. ; es:bx --> cpu int vector table
  3131. xor ax,ax
  3132. push es
  3133. mov es,ax
  3134. dec si
  3135. mov es:[bx],si
  3136. mov ax,ds
  3137. mov es:[bx+2],ax
  3138. pop es
  3139. ret
  3140. dummyvector endp
  3141. ; name : recovercsiint
  3142. ; entry : none
  3143. ; exit :none
  3144. ; description :
  3145. ; recover int 9 ,10h,16h ,for csi vector
  3146. recovercsiint proc near
  3147. push es
  3148. push ds
  3149. push ax
  3150. push bx
  3151. push cx
  3152. push dx
  3153. push si
  3154. push di
  3155. ;recover int 9
  3156. cmp cs:oemdriverinst,0
  3157. jnz ignoreint9recover
  3158. push cs
  3159. pop ds
  3160. mov si,offset dummyint9
  3161. push cs
  3162. pop es
  3163. mov di,offset csiint9
  3164. mov bx,9
  3165. mov ax,0
  3166. call recoverint
  3167. ignoreint9recover:
  3168. ; recover int 10h
  3169. push cs
  3170. pop ds
  3171. mov si,offset dummyint10h
  3172. push cs
  3173. pop es
  3174. mov di,offset csiint10h
  3175. mov bx,10h
  3176. mov ax,0+4
  3177. call recoverint
  3178. ;recover int 16h
  3179. push cs
  3180. pop ds
  3181. mov si,offset dummyint16h
  3182. push cs
  3183. pop es
  3184. mov di,offset csiint16h
  3185. mov bx,16h
  3186. mov ax,0+4+4
  3187. call recoverint
  3188. pop di
  3189. pop si
  3190. pop dx
  3191. pop cx
  3192. pop bx
  3193. pop ax
  3194. pop ds
  3195. pop es
  3196. ret
  3197. recovercsiint endp
  3198. ; name : recoverint
  3199. ; entey : ds:si --> dummy int sevice routine
  3200. ; es:di --> point to csi vector store area
  3201. ; bx == int number
  3202. ; ax == 0 ; int 9
  3203. ; 4 ; int 10h
  3204. ; 4+4 ; int 16h
  3205. ; exit : none
  3206. ; description :
  3207. ; 1. if( [0:bx*4] == si-1 .and. [es:bx*4+2] == ds )
  3208. ; {
  3209. ; [0:bx*4] = [es:di];
  3210. ; [0:bx*4+2] = [es:di+2];
  3211. ; }
  3212. ; else
  3213. ; {
  3214. ; /* phase 1 */
  3215. ; [ds:si] = [(*orgvectblptr)+ax]
  3216. ; [ds:si+2]= [(*orgvectblptr)+ax+2];
  3217. ; /* phase 2 */
  3218. ; [orgvectblptr+ax) ]=[0:bx*4] ;
  3219. ; [orgvectblptr+ax+2 ]=[0:bx*4+2] ;
  3220. ; /* phase 3 */
  3221. ; [0:bx*4] = [es:di];
  3222. ; [0:bx*4+2] = [es:di+2];
  3223. ;
  3224. ;
  3225. ; }
  3226. ;
  3227. recoverint proc near
  3228. ;chek vector change ?
  3229. ; es --> 0
  3230. push es
  3231. mov cx,ax
  3232. xor ax,ax
  3233. mov es,ax
  3234. shl bx,1
  3235. shl bx,1 ; es:bx --> cpu int vector
  3236. mov ax,si
  3237. dec ax
  3238. cmp es:[bx],ax ; offset same ?
  3239. jne vectorbechanged
  3240. mov ax,ds
  3241. cmp es:[bx+2],ax ; segmnet same ?
  3242. jne vectorbechanged
  3243. pop es
  3244. ; vector not be changed
  3245. ; ds --> 0
  3246. xor ax,ax
  3247. mov ds,ax ; ds:bx --> cpu int vector
  3248. mov ax,es:[di]
  3249. mov ds:[bx],ax
  3250. mov ax,es:[di+2]
  3251. mov ds:[bx+2],ax
  3252. ret
  3253. vectorbechanged:
  3254. ;phase 1
  3255. ; di:es --> addres of local driver
  3256. pop es
  3257. push di
  3258. push es
  3259. mov di,word ptr cs:[orgvectblptr]
  3260. mov es,word ptr cs:[orgvectblptr+2]
  3261. add di,cx
  3262. mov ax,es:[di]
  3263. mov ds:[si],ax
  3264. mov ax,es:[di+2]
  3265. mov ds:[si+2],ax
  3266. ;phase2
  3267. ; di:es --> addres of local driver
  3268. ; ds --> 0
  3269. push ds
  3270. xor ax,ax
  3271. mov ds,ax
  3272. mov ax,ds:[bx] ; ds:bx --> cpu int vector
  3273. mov es:[di],ax
  3274. mov ax,ds:[bx+2]
  3275. mov es:[di+2],ax
  3276. pop ds
  3277. pop es
  3278. pop di
  3279. ;phase3
  3280. ; ds --> 0
  3281. xor ax,ax
  3282. push ds
  3283. mov ds,ax
  3284. mov cx,es:[di]
  3285. mov ds:[bx],cx ; ds:bx --> cpu int vector
  3286. mov cx,es:[di+2]
  3287. mov ds:[bx+2],cx
  3288. pop ds
  3289. ret
  3290. recoverint endp
  3291. ;name : chklocalexist
  3292. ;entry : none
  3293. ;exit :none
  3294. ; descriptin : check local driver exist ?
  3295. ; if not exist system halt !
  3296. ; otherwise null return
  3297. chklocalexist proc near
  3298. push ax
  3299. push cx
  3300. push dx
  3301. mov ah,0dbh
  3302. mov al,80h ; module_extsysutil
  3303. mov cx,01 ; syscmd_extquerysysmode
  3304. int 16h
  3305. test ax,8000h ; bit 15 on
  3306. jnz csisystemerror ; no,system halt
  3307. ; yes ,dx == country id
  3308. push dx ; save current id
  3309. mov dx,58h
  3310. mov ah,0dbh
  3311. mov al,80h ; module_extsysutil
  3312. mov cx,02 ; syscmd_extsetsysmode
  3313. int 16h
  3314. test ax,8000h ; bit 15 on
  3315. jnz localdrvnotfound ; no ,local driver error
  3316. pop cx
  3317. cmp cx,dx ; current id == previous id ?
  3318. jnz localdrvnotfound ; no ,local driver error
  3319. pop dx
  3320. pop cx
  3321. pop ax
  3322. ret
  3323. localdrvnotfound:
  3324. csisystemerror:
  3325. push cs
  3326. pop ds
  3327. mov dx,offset bootfailmsg
  3328. mov ah,9
  3329. int 21h
  3330. cli
  3331. hlt
  3332. ret
  3333. chklocalexist endp
  3334. endif
  3335. sysinitseg ends
  3336. end