Leaked source code of windows server 2003
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.

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