c0.asm
上传用户:super_houu
上传日期:2008-09-21
资源大小:4099k
文件大小:20k
源码类别:

DVD

开发平台:

Others

  1. page 60, 132
  2. name c0
  3. title Paradigm C++ real/extended address mode startup code
  4. ;
  5. ; Embedded System Startup Code for Paradigm C++
  6. ; Copyright (C) 1996, 2000 Paradigm Systems.  All rights reserved.
  7. ;
  8. ; $Revision: 11 $
  9. ; $NoKeywords: $
  10. ;
  11. ; *********************************************************************
  12. ; Permission to modify and distribute object files based on this
  13. ; source code is granted to licensed users of Paradigm C++.
  14. ;
  15. ; Under no circumstances is this source code to be re-distributed
  16. ; without the express permission of Paradigm Systems.
  17. ; *********************************************************************
  18. ;
  19. ; Make sure that this startup module is specified first when linking
  20. ; the application.  Requires Paradigm Assembler 5.0 or later to assemble.
  21. ;
  22. ;  pasm /mx /d__MDL__ c0.asm
  23. ;
  24. ; where
  25. ;  __MDL__ is one of the following:
  26. ;
  27. ;  __s__ Small memory model startup code
  28. ;  __m__ Medium memory model startup code
  29. ;  __c__ Compact memory model startup code
  30. ;  __l__ Large memory model startup code
  31. ;  __h__ Huge memory model startup code
  32. ;
  33. ; These macros are handled in a helper include file.
  34. ;
  35. .8086 ; Required for target independence
  36. ;
  37. ; The macro __ADDR24__ can be used to enable 24-bit address space support.
  38. ;
  39. ; The _ALIGN_ macro aligns selected segments on the preferred boundary for
  40. ; the application.
  41. ;
  42. I49OPTIM=1
  43. IFNDEF __ADDR24__
  44. _PAD_ = 16
  45. _ALIGN_ equ <para>
  46. ELSE
  47. _PAD_ = 256
  48. _ALIGN_ equ <page>
  49. ENDIF
  50. ;
  51. ; Some options can be disabled to reduce the size of the startup code
  52. ; and run-time library helper code.  Simply place a semicolon in front
  53. ; of the following definitions to remove support for selected item.
  54. ;
  55. ;    __ENABLE_FARDATA         Includes code to initialize class FAR_DATA
  56. ;    __ENABLE_FARBSS          Includes code to initialize class FAR_BSS
  57. ;    __ENABLE_EXCEPTIONS      Includes C++ exception handling support
  58. ;    __ENABLE_TERMINATORS     Includes support for exit terminators
  59. ;
  60. IFNDEF I49OPTIM
  61. __ENABLE_FARDATA = 1
  62. __ENABLE_FARBSS = 1
  63. __ENABLE_EXCEPTIONS = 1
  64. __ENABLE_TERMINATORS = 1
  65. ENDIF
  66. ;
  67. ; Be aware that changes made to the startup code can affect the correctness of your
  68. ; application or the run-time library code.
  69. ;
  70. locals @@ ; Define local symbols
  71. INCLUDE ServicesIncludestartup.inc ; Macros/assembly language definitions
  72. INCLUDE ServicesIncludec0.inc ; Compiler-specific definitions
  73. SHOW <Paradigm C++ Startup Support>
  74. subttl Segment ordering/alignment section
  75. page
  76. ;
  77. ; Segment and group declarations.  The order of these declarations is
  78. ; used to control the order of segments in the .ROM file since the
  79. ; Paradigm linker copies segments in the same order they
  80. ; are encountered in the object files.
  81. ;
  82. ; Make sure that this startup module is specified first when linking
  83. ; the application.
  84. ;
  85. % DefSeg _TEXT,      _ALIGN_,  public,  CODE,       <> ; Default code
  86. ;
  87. ; The following segments are used to hold the linked initializers
  88. ; and terminators.  These permit automatic initialization of code
  89. ; without startup source modification and should be located in ROM.
  90. ; Terminators are not implemented since an application will normally
  91. ; not return to the startup code but are supported for run-time library
  92. ; compatibility.
  93. ;
  94. % DefSeg _INIT_,     _ALIGN_,  public,  INITDATA,   IGROUP ; Initializers
  95. % DefSeg _INITEND_,  byte,     public,  INITDATA,   IGROUP
  96. % DefSeg _EXIT_,     para,     public,  EXITDATA,   IGROUP ; Terminators
  97. % DefSeg _EXITEND_,  byte,     public,  EXITDATA,   IGROUP
  98. ;
  99. ; The following segments are used to mark the place for ROM copies
  100. ; of initialized data for use by the startup code.
  101. ;
  102. % DefSeg _RD,        _ALIGN_,  public,  ROMDATA,       <>
  103. % DefSeg _ERD,       _ALIGN_,  public,  ENDROMDATA,    <>
  104. IFNDEF I49OPTIM
  105. % DefSeg _BRFD,      _ALIGN_,  public,  ROMFARDATA,    <>
  106. % DefSeg _ERFD,      _ALIGN_,  public,  ENDROMFARDATA, <>
  107. ENDIF
  108. IFDEF DEBUG_CACHE_ISSUES
  109. % DefSeg _BDDC,       _ALIGN_,  public,  FAR_CONST, <> ; Start DSP_DATA_CLASS class
  110. ENDIF
  111. ;
  112. ; The following segments form the Paradigm C++ DGROUP.  The startup code
  113. ; requires thatthe segments in DGROUP follow the Paradigm C++ standard.
  114. ; The order of these segments/classes must not be changed since the
  115. ; startup code assumes a specific relationship between classes.
  116. ;
  117. % DefSeg _DATA,      _ALIGN_,  public,  DATA,       DGROUP ; Initialized data
  118. % DefSeg _CVTSEG,    word,     public,  DATA,       DGROUP ; Output conversion support
  119. % DefSeg _SCNSEG,    word,     public,  DATA,       DGROUP ; Input conversion support
  120. % DefSeg _BSS,       para,     public,  BSS,        DGROUP ; Uninitialized data
  121. % DefSeg _NVRAM,     para,     public,  NVRAM,      DGROUP   ; Non-volatile data segment
  122. IFDEF I49OPTIM
  123. % DefSeg _NHEAP,     _ALIGN_,  stack,   NHEAP,      DGROUP ; Near heap is in DGROUP
  124. ENDIF
  125. IFNDEF I49OPTIM
  126. % DefSeg _EDATA,     para,     public,  EDATA,      DGROUP   ; End of default data segments
  127. ENDIF
  128. ;
  129. ; The stack in Paradigm C++ is in or out of DGROUP depending on the
  130. ; memory model.
  131. ;
  132. IF @DataSize EQ MM_NEAR
  133. % DefSeg _NHEAP,     _ALIGN_,  stack,   STACK,      DGROUP ; Near heap is in DGROUP
  134. % DefSeg _STACK,     para,     stack,   STACK,      DGROUP ; Stack is in DGROUP
  135. % DefSeg _ESTACK,    para,     stack,   STACK,      DGROUP
  136. ELSE
  137. % DefSeg _STACK,     _ALIGN_,  stack,   STACK,      SGROUP ; Stack is in its own group
  138. % DefSeg _ESTACK,    para,     stack,   STACK,      SGROUP
  139. ENDIF ; MM_NEAR
  140. ;
  141. ; These are the segments that form the FAR_DATA class which contains any non-const
  142. ; initialized far objects.  Class FAR_DATA is followed by class ENDFAR_DATA, which
  143. ; is needed to calculate the size of class FAR_DATA at run-time.
  144. ;
  145. IFNDEF I49OPTIM
  146. % DefSeg _BFD,       _ALIGN_,  public,  FAR_DATA,   <> ; Start FAR_DATA class
  147. % DefSeg _EFD,       _ALIGN_,  public,  ENDFAR_DATA,<> ; End FAR_DATA class
  148. ENDIF
  149. ;
  150. ; These are the segments that form the FAR_CONST class which contains any constant
  151. ; initialized far objects.  Class FAR_CONST is followed by class ENDFAR_CONST, which
  152. ; is needed to calculate the size of class FAR_CONST at run-time.
  153. ;
  154. % DefSeg _BFC,       _ALIGN_,  public,  FAR_CONST,   <> ; Start FAR_CONST class
  155. % DefSeg _EFC,       _ALIGN_,  public,  ENDFAR_CONST,<> ; End FAR_CONST class
  156. ;
  157. ; These are the segments that form the FAR_BSS class which contains any uninitialized
  158. ; far objects.  Class FAR_BSS is followed by class ENDFAR_BSS, which is needed to
  159. ; calculate the size of class FAR_BSS at run-time.
  160. ;
  161. IFNDEF I49OPTIM
  162. % DefSeg _BFB,       _ALIGN_,  public,  FAR_BSS,    <> ; Start FAR_BSS class
  163. % DefSeg _EFB,       _ALIGN_,  public,  ENDFAR_BSS, <> ; End FAR_BSS class
  164. ENDIF
  165. ;
  166. ; The following segments will be used to implement the far heap, if dynamic
  167. ; memory management support is enabled.
  168. ;
  169. IFNDEF I49OPTIM
  170. % DefSeg _FARHEAP,   _ALIGN_,  public,  FAR_HEAP,   <> ; Far heap start
  171. % DefSeg _EFH,       _ALIGN_,  public,  ENDFAR_HEAP,<> ; Far heap end
  172. ENDIF
  173. ;
  174. ; External references
  175. ;
  176. ExtProc main ; User application entry point
  177. ExtProc exit ; Called should main() ever return
  178. IFDEF __ENABLE_EXCEPTIONS
  179. ExtProc _ExceptInit ; Exception handling initialization
  180. ENDIF
  181. IFDEF __ENABLE_FARDATA
  182. ExtProc _CopyFarData ; Pull in far data support
  183. ENDIF
  184. IFDEF __ENABLE_FARBSS
  185. ExtProc _InitFarBss ; Pull in far bss support
  186. ENDIF
  187. public _sw_startup
  188. subttl Startup/initialization code
  189. page
  190. _TEXT segment
  191. assume cs:_TEXT
  192. BegProc _startup, far ; Startup code entry point
  193.  ;Init power up variables, the values are not changed during sw reset
  194.     mov ax,DGROUP
  195.     mov ds,ax
  196.     mov al,55h
  197.  mov bx,offset DGROUP:_g_power_state
  198.     mov ds:[bx],al
  199.     mov al,01h
  200.  mov bx,offset DGROUP:_g_bIsAuxModeOn
  201.     mov ds:[bx],al
  202.     
  203. _sw_startup: ; Startup code entry point
  204. ;
  205. ; Disable interrupts and force the forward direction
  206. ;
  207. cli
  208. cld
  209. ;
  210. ; Set up the stack according to the memory model.  The default Paradigm
  211. ; model is to have the stack after the heap in the small and medium
  212. ; memory models.
  213. ;
  214. IF @DataSize EQ MM_NEAR
  215. mov ax, DGROUP
  216. mov ss, ax
  217. mov sp, offset DGROUP:_stack_top
  218. assume ss:DGROUP
  219. ELSE
  220. mov ax, _STACK
  221. mov ss, ax
  222. mov sp, offset SGROUP:_stack_top
  223. assume ss:_STACK
  224. ENDIF ; @DataSize
  225. INITIALIZE_STACK = 1 ; used only when CHECK_STACK_SIZE is define
  226. IFDEF INITIALIZE_STACK
  227. ;// Initialize stack of main task with 0cafeh
  228. mov ax, SGROUP
  229. mov es, ax
  230.    mov bx, ax ;safe the value for CORE stack length calculation
  231. assume es:SGROUP
  232. mov   ax, 0fecah
  233. mov di, offset SGROUP:_stack_bottom
  234.    ;// calculate length of the main stack
  235. mov cx, offset SGROUP:_stack_top
  236. sub cx, di
  237. shr cx, 1
  238. jcxz short fill_main_stack
  239.    ;// fill main stack with AX
  240. rep stosw
  241. fill_main_stack:
  242. ENDIF ;INITIALIZE_STACK
  243. ;
  244. ; Prepare the segment registers for initialization.  The initialized
  245. ; data is assumed to have been located in the class ROMDATA which begins
  246. ; with the segment _RD.
  247. ;
  248. mov ax, DGROUP
  249. mov es, ax
  250. mov ax, _RD
  251. mov ds, ax
  252. assume ds:_RD, es:DGROUP
  253. ;
  254. ; Copy DGROUP initialized data from its position in ROM to the target
  255. ; address in RAM.  Because this is a group, there is never more than
  256. ; 64K of data to copy.
  257. ;
  258. mov si, offset _romdata_start
  259. mov di, offset DGROUP:_data_start
  260. mov cx, offset DGROUP:_bss_start
  261. sub cx, di
  262. shr cx, 1
  263. jcxz short $$1
  264. rep movsw
  265. $$1:
  266. ;
  267. ; Zero out the BSS area - always less than 64KB
  268. ;
  269. mov ax, DGROUP
  270. mov ds, ax
  271. mov es, ax
  272. assume ds:DGROUP, es:DGROUP
  273. xor ax, ax
  274. mov di, offset DGROUP:_bss_start
  275. mov cx, offset DGROUP:_nvram_start
  276. sub cx, di
  277. shr cx, 1
  278. jcxz short $$5
  279. rep stosw
  280. $$5:
  281. ;
  282. ; Memory is now initialized.  We need to initialize the exception handling
  283. ; logic if enabled.
  284. ;
  285. mov bp, ax
  286. IFDEF __ENABLE_EXCEPTIONS
  287. push bp
  288. call __ExceptInit
  289. pop ax
  290. ENDIF
  291. ;
  292. ; Fill in value of _stklen so stack checking will work
  293. ;
  294. IF @DataSize EQ MM_NEAR
  295. mov ax, offset DGROUP:_stack_top
  296. sub ax, offset DGROUP:_stack_bottom
  297. mov _stklen, ax
  298. ELSE
  299. mov ax, offset SGROUP:_stack_top
  300. sub ax, offset SGROUP:_stack_bottom
  301. mov _stklen, ax
  302. IFDEF I49OPTIM
  303.    GlobalW _heaplen ; Needed for heap checking logic
  304. ENDIF
  305. ENDIF
  306. ;
  307. ; Linked in initializers are in their own group.  Load pointers to the start
  308. ; and end of the table and call the code that processes them.
  309. ;
  310. mov si, offset IGROUP:InitStart
  311. mov di, offset IGROUP:InitEnd
  312. mov ax, IGROUP
  313. mov es, ax
  314. assume es:nothing
  315. call Initialize
  316. ;
  317. ; Call the C/C++ entry point main() - initialization is complete and user
  318. ; application can take control.
  319. ;
  320. ;sti
  321. call main
  322. ;
  323. ; A return from main() is application dependent.  We will call exit() and it can decide
  324. ; what the appropriate behavior will be.
  325. ;
  326. push ax
  327. call exit
  328. IFDEF I49OPTIM
  329. ; !!! We should never get her !!!
  330. jmp _startup
  331. ENDIF
  332. EndProc _startup
  333. page
  334. ;
  335. ; Function: Initialize
  336. ;
  337. ; Call all of the linked-in initializers in the _INIT_ segment.  These
  338. ; are a series of pointers to routines which are guaranteed to
  339. ; execute before main() is called.  The advantage of this approach is
  340. ; that the initialization will be made by virtue of the code being
  341. ; linked in, without any modification to the startup code.
  342. ;
  343. ; This implementation permits the initializers to be kept in ROM,
  344. ; even though there is no ordering of the initializers.  The register
  345. ; use is as follows:
  346. ;  SI - initializers start
  347. ;  DI - initializers end
  348. ;  CX - number of initializers not processed
  349. ;  BX - current initializer
  350. ;  AH - current priority
  351. ;
  352. Initialize proc near
  353. mov ax, di ; Compute the number of initializers
  354. sub ax, si
  355. sub dx, dx
  356. mov cx, SIZE InitRec
  357. idiv cx
  358. mov cx, ax ; Number of initializers in the table
  359. jcxz short @@InitDone
  360. sub ah, ah ; Start with the highest priority
  361. @@PriTop:
  362. mov bx, si ; Point to the start of the table
  363. @@NextInit:
  364. cmp bx, di ; Check if this pass is done
  365. jae short @@PriBottom
  366. cmp es:[bx.pri], ah ; Compare against the current priority
  367. jne short @@TableBottom
  368. push es ; Save registers we don't want trashed
  369. push ax
  370. push bx
  371. push cx
  372. push si
  373. push di
  374. cmp es:[bx.ctype], MM_NEAR ; Is it near or far?
  375. je short @@NearCall
  376. call dptr es:[bx.foff] ; Call the initializer
  377. jmp short @@Cleanup
  378. @@NearCall:
  379. call wptr es:[bx.foff] ; Call the initializer
  380. @@Cleanup:
  381. pop di ; Restore the registers
  382. pop si
  383. pop cx
  384. pop bx
  385. pop ax
  386. pop es
  387. dec cx
  388. jz short @@InitDone
  389. @@TableBottom:
  390. add bx, SIZE InitRec
  391. jmp @@NextInit
  392. @@PriBottom:
  393. inc ah ; Process the next priority
  394. jmp @@PriTop
  395. @@InitDone:
  396. ret
  397. Initialize endp
  398. ;
  399. ; Called by the exit handling code to execute C++ static destructors and
  400. ; any #pragma exit routines.
  401. ;
  402. __cleanup proc dist
  403. public  __cleanup
  404. IFDEF __ENABLE_TERMINATORS
  405. ; Call cleanup routines
  406. mov ax, IGROUP
  407. mov es, ax
  408. push si
  409. push di
  410. mov si, offset IGROUP:ExitStart
  411. mov di, offset IGROUP:ExitEnd
  412. call Cleanup
  413. pop di
  414. pop si
  415. ENDIF
  416. ret
  417. __cleanup endp
  418. IFDEF __ENABLE_TERMINATORS
  419. ;
  420. ; Function: Cleanup
  421. ;
  422. ; Call all of the linked-in terminators in the _EXIT_ segment.
  423. ;
  424. ; This implementation permits the terminators to be kept in ROM,
  425. ; even though there is no ordering of the terminators.  The register
  426. ; use is as follows:
  427. ;  SI - terminators start
  428. ;  DI - terminators end
  429. ;  CX - number of terminators not processed
  430. ;  BX - current terminators
  431. ;  AH - current priority
  432. ;
  433. Cleanup proc near
  434. mov ax, di ; Compute the number of terminators
  435. sub ax, si
  436. sub dx, dx
  437. mov cx, SIZE InitRec
  438. idiv cx
  439. mov cx, ax ; Number of terminators in the table
  440. jcxz @@ExitDone
  441. sub ah, ah ; Start with the highest priority
  442. @@PriTop:
  443. mov bx, si ; Point to the start of the table
  444. @@NextInit:
  445. cmp bx, di ; Check if this pass is done
  446. jae @@PriBottom
  447. cmp es:[bx.pri], ah ; Compare against the current priority
  448. jne @@TableBottom
  449. push es ; Save registers we don't want trashed
  450. push ax
  451. push bx
  452. push cx
  453. push si
  454. push di
  455. cmp es:[bx.ctype], MM_NEAR ; Is it near or far?
  456. je @@NearCall
  457. call dptr es:[bx.foff] ; Call the terminator
  458. jmp short @@Cleanup
  459. @@NearCall:
  460. call wptr es:[bx.foff] ; Call the terminator
  461. @@Cleanup:
  462. pop di ; Restore the registers
  463. pop si
  464. pop cx
  465. pop bx
  466. pop ax
  467. pop es
  468. dec cx
  469. jz @@ExitDone
  470. @@TableBottom:
  471. add bx, SIZE InitRec
  472. jmp @@NextInit
  473. @@PriBottom:
  474. inc ah ; Process the next priority
  475. jmp @@PriTop
  476. @@ExitDone:
  477. ret
  478. Cleanup endp
  479. ENDIF
  480. _TEXT ends
  481. subttl Data declarations
  482. page
  483. ;
  484. ; Run-time libraries and other modules can insert initializers in this
  485. ; segment.  Initializers are executed by priority, and by link order
  486. ; when the same priority.  Static destructors are not implemented since
  487. ; we assume that the application never terminates.
  488. ;
  489. _INIT_ segment
  490. LabelD InitStart
  491. _INIT_ ends
  492. _INITEND_ segment
  493. LabelD InitEnd
  494. _INITEND_ ends
  495. _EXIT_ segment
  496. LabelD ExitStart
  497. _EXIT_ ends
  498. _EXITEND_ segment
  499. LabelD ExitEnd
  500. db 16 dup (0) ; Force the next segment to a new paragraph
  501. _EXITEND_ ends
  502. ;
  503. ; These are the segment definitions for class DATA, BSS, NVRAM, and STACK.
  504. ; thh size of class DATA is calculated by subtracting the offset of _DATA
  505. ; from the offset _BSS.  The size of the BSS is done by subtracting the
  506. ; offset of _BSS from the offset of _NVRAM.  We don't ever initialize the
  507. ; segment _NVRAM so we don't care about the size.
  508. ;
  509. ; Class NVRAM is followed by class EDATA which is used to mark the end of the
  510. ; default data segments.
  511. ;
  512. _DATA segment
  513. LabelB _data_start, public ; Offset zero within the DATA class
  514. LabelB DATASEG@, public ; Symbol used to find data segment
  515. ;
  516. ; The check string must NOT be moved or changed without changing the null
  517. ; pointer check logic
  518. ;
  519. NULL db 4 dup (0)
  520. ChkStr db 'NULL CHECK'
  521. db 2 dup (0)
  522. db 4 dup (0) ; Destructor count
  523. db 2 dup (0) ; Exception list
  524. db 4 dup (0) ; Exception vptr
  525. db 6 dup (0) ; Reserved
  526. GlobalW _Exception_list, -1 ; List of exception handlers
  527. GlobalW _8086, 0 ; Cpu type
  528. _DATA ends
  529. _CVTSEG  segment ; Stream I/O conversion helpers
  530. LabelW  _RealCvtVector, public
  531. _CVTSEG  ends
  532. _SCNSEG  segment
  533. LabelW   _ScanTodVector, public
  534. _SCNSEG  ends
  535. _BSS segment ; Start of BSS is the end of initialized data
  536. LabelB _bss_start, public ; Offset zero within the BSS class
  537. GlobalW _stklen ; Needed for stack checking logic
  538. _BSS ends
  539. _NVRAM segment ; Start of NVRAM is the end of uninitialized data
  540. LabelB _nvram_start, public ; Offset zero within the NVRAM class
  541. LabelB  g_power_state, public ; g_power_state hold the power up status and should not be changed
  542. db ?
  543. LabelB  g_bIsAuxModeOn, public ; g_bIsAuxModeOn hold the status of player
  544. db ?
  545. LabelB  bHDCPProducKeys, public ; g_power_state hold the power up status and should not be changed
  546. db ?
  547. _NVRAM ends
  548. IFNDEF I49OPTIM
  549. _EDATA segment ; Default static data class end marker
  550. LabelB _staticdata_end, public ; Offset of the end of static data
  551. db _PAD_ dup (0) ; Force the next segment to a new paragraph
  552. _EDATA ends
  553. ENDIF
  554. ;
  555. ; Create the default application stack and an end marker that allows the stack
  556. ; size to be set using the linker.  These segments must be contiguous to correctly
  557. ; initialize the SS:SP registers.
  558. ;
  559. IF @DataSize EQ MM_NEAR
  560. _NHEAP segment
  561. LabelW _nearheap_start, public ; Define the start of the default heap
  562. LabelW _stack_bottom, public ; Define the bottom of the default stack
  563. _NHEAP ends
  564. ENDIF ; @DataSize EQ MM_NEAR
  565. IFDEF I49OPTIM
  566. _NHEAP segment
  567. LabelW _nearheap_start, public ; Define the start of the default heap
  568. _NHEAP ends
  569. ENDIF
  570. _STACK segment
  571. LabelW STACKSEG@, public ; Symbol used to find the stack segment
  572. LabelW _stack_segment, public ; Define a label for the default stack segment
  573. IF @DataSize NE MM_NEAR
  574. LabelW _stack_bottom, public ; Define the bottom of the default stack
  575. ENDIF ; @DataSize NE MM_NEAR
  576. _STACK ends
  577. _ESTACK segment
  578. LabelW _stack_top, public ; Define the bottom of the default stack
  579. ;D_SUPPORT_SACD db _PAD_ dup (0) ; Mark the end of the stack and prevent an alias
  580. db (0) ; Mark the end of the stack and prevent an alias
  581. _ESTACK ends
  582. ;
  583. ; These are segment definitions for the classes ROMDATA and ENDROMDATA.  Class
  584. ; ROMDATA never contains anything (it is filled in by a Paradigm LOCATE DUP
  585. ; directive).  Class ENDROMDATA is used to mark the end of class ROMDATA and
  586. ; prevent a segment alias (since class ROMDATA will have zero length).
  587. ;
  588. ; NOTE: You can't take the address of segments in class ENDROMDATA as they are
  589. ;       aliased with class ROMDATA.
  590. ;
  591. _RD segment
  592. LabelB _romdata_start, public ; Mark the start of class ROMDATA
  593. _RD ends
  594. _ERD segment
  595. LabelB _romdata_end, public ; Mark the end of class ROMDATA
  596. db _PAD_ dup (0) ; Force the next segment to a new paragraph
  597. _ERD ends
  598. ;
  599. ; These are the four segments we defined above to support the FAR_DATA class.
  600. ; Here we open each segment and define a label that we can take the address of
  601. ; for the purposes of finding the length of class FAR_DATA, and the starting
  602. ; addresses of the classes FAR_DATA and ROMFARDATA.
  603. ;
  604. IFNDEF I49OPTIM
  605. _BFD segment
  606. LabelB _fardata_start, public ; Mark the start of far initialized data
  607. _BFD ends
  608. _EFD segment
  609. LabelB _fardata_end, public ; Mark the end of far initialized data
  610. db _PAD_ dup (0) ; Force the next segment to a new paragraph
  611. _EFD ends
  612. ENDIF
  613. _BFC segment
  614. LabelB _farconst_start, public ; Mark the start of far constant data
  615. _BFC ends
  616. _EFC segment
  617. LabelB _farconst_end, public ; Mark the end of far const data
  618. db _PAD_ dup (0) ; Force the next segment to a new paragraph
  619. _EFC ends
  620. IFNDEF I49OPTIM
  621. _BFB segment
  622. LabelB _farbss_start, public ; Mark the start of far uninitialized data
  623. _BFB ends
  624. _EFB segment
  625. LabelB _farbss_end, public ; Mark the end of far uninitialized data
  626. db _PAD_ dup (0) ; Force the next segment to a new paragraph
  627. _EFB ends
  628. _BRFD segment
  629. LabelB _romfardata_start, public ; Mark the start of class ROMFARDATA
  630. _BRFD ends
  631. _ERFD segment
  632. LabelB _romfardata_end, public ; Mark the end of the ROMFARDATA
  633. db _PAD_ dup (0) ; Force the next segment to a new paragraph
  634. _ERFD ends
  635. _FARHEAP segment
  636. LabelW _farheap_start, public          ; Mark the start of the far heap
  637. _FARHEAP ends
  638. _EFH segment
  639. LabelW _farheap_end, public           ; Mark the end of the far heap
  640. db _PAD_ dup (0) ; Pad the end of the far heap
  641. _EFH ends
  642. ENDIF
  643. end _startup ; Program entry point