prnval.asm
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:27k
源码类别:

操作系统开发

开发平台:

Visual C++

  1. TITLE PRNVAL - Print values
  2. page 56,132
  3. ;***
  4. ; PRNVAL - Print values
  5. ;
  6. ; Copyright <C> 1986, Microsoft Corporation
  7. ;
  8. ;Purpose:
  9. ;
  10. ; This module contains B$P<term><type> and B$PEOS interfaces.
  11. ;
  12. ; The PRINT, WRITE, and LPRINT statements have a large number of
  13. ; runtime calls that can be generated, based on the list of
  14. ; expressions given. There is a unique preamble call for each such
  15. ; statement (except PRINT), to correctly set up flags, vectors, etc.
  16. ; The actual printing call itself is one of 15 possibilities, based
  17. ; on the argument type, and one of three possible ways of terminating
  18. ; the print: ',', ';', or EOL. Each of these 15 calls is in the
  19. ; form B$P<term><type> where <term> specifies the print termination
  20. ; method, and <type> specifies the type of the argument.
  21. ;
  22. ; <term>:
  23. ; C == ',' (i.e., something like 'PRINT X,' was specified)
  24. ; S == ';'
  25. ; E == EOL (neither ',' nor ';' was specified)
  26. ;
  27. ; <type>:
  28. ; I2 == two byte integer
  29. ; I4 == four byte integer
  30. ; R4 == single precision real
  31. ; R8 == double precision real
  32. ; SD == string
  33. ;
  34. ; Thus, for example, a call to B$PER4 would be used to print a s.p.
  35. ; value and terminate with a EOL.
  36. ;
  37. ; The list of expressions can be of any size; for each additional
  38. ; expression, another one of the fifteen possible runtime calls is
  39. ; generated. After the last such expression, a call to B$PEOS is
  40. ; generated (if not terminated with EOL). If no expression is
  41. ; specified, a NULL string is printed, so 'PRINT' would generate a
  42. ; call to B$PESD with a null string as the parameter (print a string,
  43. ; terminate with EOL).
  44. ;
  45. ;******************************************************************************
  46. INCLUDE switch.inc
  47. INCLUDE rmacros.inc
  48. ;Code segments:
  49. useSeg DK_TEXT  ;disk I/O
  50. useSeg MT_TEXT  ;floating point math.
  51. useSeg NH_TEXT  ;near heap
  52. useSeg ER_TEXT  ;error handling
  53. useSeg CN_TEXT  ;concole I/O
  54. ;Data segments:
  55. useSeg CONST ;constant definitions
  56. useSeg _DATA ;initialized variables
  57. useSeg _BSS ;uninitialized variables
  58. INCLUDE seg.inc
  59. INCLUDE baslibma.inc
  60. INCLUDE devdef.inc
  61. INCLUDE files.inc
  62. INCLUDE rtps.inc ; constants shared with QBI
  63. INCLUDE idmac.inc
  64. SUBTTL local constant definitions
  65. page
  66. CLMWID EQU 14 ;column width
  67. COMA EQU 0 ;comma
  68. SEMI EQU 1 ;semicolumn
  69. EOL EQU 2 ;forced EOL
  70. TTY EQU 0 ;default for b$PTRFIL is TTY
  71. PRSTM EQU 0 ;print statement
  72. CHANL EQU 1 ;#
  73. USING EQU 2 ;using
  74. WRSTM EQU 4 ;write statement
  75. LPSTM EQU 8 ;lprint statement
  76. InpDefault EQU 0FFH ;default for b$Finput
  77. SUBTTL data definitions
  78. page
  79. sBegin CONST
  80. labelW TTYVEC ;vector for PRINT
  81. staticW ,B$TTY_GPOS ;cursor position
  82. staticW ,B$TTY_GWID ;line width
  83. staticW ,B$$TCR ;force EOL
  84. staticW ,B$TTY_SOUT ;write one character
  85. staticW ,B$TYPSTR ;write a string with BX=*sd
  86. staticW ,B$TYPCNT ;write a string with CX=length
  87. staticW ,B$OUTCNT ;write a string char. by char.
  88. staticW ,TTY_PRTCHK ; check if EOL needs to be forced
  89. sEnd
  90. sBegin _DATA
  91. externB b$PRFG ;print flag, may be combined from below
  92. ;0: PRINT stmt
  93. ;1: # (channel)
  94. ;2: USING
  95. ;4: WRITE stmt
  96. ;8: LPRINT stmt
  97. ;e.g. 3 means PRINT # USING
  98. labelW <PUBLIC,b$VECS> ; print value vectors
  99. staticW VPOS,B$TTY_GPOS ;cursor position
  100. staticW VWID,B$TTY_GWID ;line width
  101. staticW VWCLF,B$$TCR ;force EOL
  102. staticW VWCH,B$TTY_SOUT ;write one character
  103. staticW VTYP,B$TYPSTR ;BX=*sd
  104. staticW VTYPCNT,B$TYPCNT  ;BX=*sd, CX=length
  105. staticW VOUTCNT,B$OUTCNT  ;SI=point to string, CX=length
  106. staticW VPRTCHK,TTY_PRTCHK ; check if EOL needs to be forced
  107. SizeOfVecs EQU (($-b$VECS)/2) ;length of b$VECS table in words
  108. globalB b$FInput,InpDefault ;Where is input comming from
  109. globalW b$GetOneVal,<DK_TEXTOFFSET NoGetValAssert> ; vector
  110. ;to routine which INPUT will
  111. ;will use to get next data
  112. globalW b$pGetValDefault,<DK_TEXTOFFSET NoGetValAssert> 
  113. ;if no input statement is
  114. ;present, attempts to call
  115. ;indirect through b$GetOneVal
  116. ;will die by assertion in
  117. ;non-release runtimes.
  118. globalW b$pFLUSH,Near_Ret,1 ;conditional vector for B$FLUSH
  119. externB b$CRTWIDTH  ; screen width
  120. sEnd
  121. sBegin _BSS
  122. globalW b$PUSG,,1 ;print using routine
  123. EVEN ; for safety
  124. externW b$TempSD ; static string descriptor
  125. globalW b$StkBottom,,1 ; used to clean the stack after TTY inp
  126. externW b$?TYP ; [b$VTYP|b$TTYP] (defined in global.inc)
  127. externB b$VTYP ; value type (defined in global.inc)
  128. externB b$TTYP ; terminator type (defined in global.inc)
  129. externW b$PTRFIL ; print channel #
  130. externW b$pSTDALCTMP ; indirect B$STDALCTMP vector
  131. externB b$LPTFDB  ; FDB for line printer
  132. externB b$Buf1
  133. sEnd
  134. SUBTTL code externals
  135. page
  136. sBegin DK_TEXT
  137. externNP B$CNTRL ; needed during B$WRIT
  138. sEnd
  139. sBegin MT_TEXT
  140. externNP B$FOUTBX
  141. sEnd
  142. sBegin CN_TEXT
  143. externNP B$TTY_GPOS ;cursor position
  144. externNP B$TTY_GWID ;line width
  145. externNP B$$TCR ;force EOL
  146. externNP B$TTY_SOUT ;write one character
  147. externNP B$TYPSTR  ;write a string with BX=*sd
  148. externNP B$TYPCNT  ;write a string with CX=length
  149. externNP B$OUTCNT  ;write a string char. by char.
  150. sEnd
  151. assumes CS,DK_TEXT
  152. sBegin DK_TEXT
  153. SUBTTL print interfaces -- B$P<term><type>(<param>)
  154. page
  155. ;***
  156. ; B$P<term><type>(<param>) -- print an item for :
  157. ; PRINT, PRINT #, PRINT USING, PRINT # USING,
  158. ; WRITE, WRITE #,
  159. ; LPRINT, LPRINT USING.
  160. ;
  161. ;Purpose:
  162. ; These are interfaces to the compiler.  Each entry point sets up
  163. ; (1) types of value & terminator, and
  164. ; (2) a pointer to that item,
  165. ;  and then fall through PRINT, which performs actual printing job.
  166. ;
  167. ; <term>, <type> & <param> may vary as follows:
  168. ; <term>:
  169. ; C: Comma used as terminator
  170. ; S: Semi used as terminator
  171. ; E: End of statement used as terminator
  172. ; <type>:
  173. ; I2: Two byte integer
  174. ; I4: Four byte integer
  175. ; SD: String (string descriptor)
  176. ; <param>:
  177. ; A parameter of type <type> to be printed.
  178. ;
  179. ;
  180. ;Entry:
  181. ; Parameter was pushed in stack.
  182. ; <type> Val = Number if <type> is numerical type
  183. ;     = String descriptor if <type> is string
  184. ;
  185. ;Exit:
  186. ; through B$PRINT
  187. ;Uses:
  188. ; none
  189. ;Exceptions:
  190. ;
  191. ;*******************************************************************************
  192. ;========================
  193. ; Print I2, |
  194. ;========================
  195. cProc B$PCI2,<PUBLIC,FAR>
  196. cBegin nogen ;no stack frame generated
  197. MOV AX,COMA SHL 8 + VT_I2 ;AX=[terminator type | value type]
  198. JMP SHORT B$PRINT ;print this item
  199. cEnd nogen ;no code generated
  200. ;========================
  201. ; Print I2; |
  202. ;========================
  203. cProc B$PSI2,<PUBLIC,FAR>
  204. cBegin nogen ;no stack frame generated
  205. MOV AX,SEMI SHL 8 + VT_I2 ;AX=[terminator type | value type]
  206. JMP SHORT B$PRINT ;print the item
  207. cEnd nogen ;no code generated
  208. ;========================
  209. ; Print I2 |
  210. ;========================
  211. cProc B$PEI2,<PUBLIC,FAR>
  212. cBegin nogen ;no stack frame generated
  213. MOV AX,EOL SHL 8 + VT_I2 ;AX=[terminator type | value type]
  214. JMP SHORT B$PRINT ;print the item
  215. cEnd nogen ;no code generated
  216. ;========================
  217. ; Print I4, |
  218. ;========================
  219. cProc B$PCI4,<PUBLIC,FAR>
  220. cBegin nogen ;no stack frame generated
  221. MOV AX,COMA SHL 8 + VT_I4 ;AX=[terminator type | value type]
  222. JMP SHORT B$PRINT ;print the item
  223. cEnd nogen ;no code generated
  224. ;========================
  225. ; Print I4; |
  226. ;========================
  227. cProc B$PSI4,<PUBLIC,FAR>
  228. cBegin nogen ;no stack frame generated
  229. MOV AX,SEMI SHL 8 + VT_I4 ;AX=[terminator type | value type]
  230. JMP SHORT B$PRINT ;print the item
  231. cEnd nogen ;no code generated
  232. ;========================
  233. ; Print I4 |
  234. ;========================
  235. cProc B$PEI4,<PUBLIC,FAR>
  236. cBegin nogen ;no stack frame generated
  237. MOV AX,EOL SHL 8 + VT_I4 ;AX=[terminator type | value type]
  238. JMP SHORT B$PRINT ;print the item
  239. cEnd nogen ;no code generated
  240. ;========================
  241. ; Print a$, |
  242. ;========================
  243. cProc B$PCSD,<PUBLIC,FAR>
  244. cBegin nogen ;no stack frame generated
  245. MOV AX,COMA SHL 8 + VT_SD ;AX=[terminator type | value type]
  246. JMP SHORT B$PRINT ;print the item
  247. cEnd nogen ;no code generated
  248. ;========================
  249. ; Print a$; |
  250. ;========================
  251. cProc B$PSSD,<PUBLIC,FAR>
  252. cBegin nogen ;no stack frame generated
  253. MOV AX,SEMI SHL 8 + VT_SD ;AX=[terminator type | value type]
  254. JMP SHORT B$PRINT ;print the item
  255. cEnd nogen ;no code generated
  256. ;========================
  257. ; Print a$ |
  258. ;========================
  259. cProc B$PESD,<PUBLIC,FAR>
  260. cBegin nogen ;no stack frame generated
  261. MOV AX,EOL SHL 8 + VT_SD ;AX=[terminator type | value type]
  262. cEnd nogen ;no code generated
  263. SUBTTL actual routine to print an item
  264. page
  265. ;***
  266. ;B$PRINT - continue the print interfaces to print an item
  267. ;
  268. ;Purpose:
  269. ; Print an item for PRINT/WRITE/LPRINT statement.
  270. ;
  271. ; Printing an item is affected by:
  272. ; (1) whether it's a 'print using'
  273. ; (2) whether it prints a string (numbers need to be translated)
  274. ; (3) whether it is a print stmt or is a write stmt.
  275. ; In case of write stmt, the following are different:
  276. ; (a) no leading blank for a positive number if '+' omitted
  277. ; (b) no ending space for a number
  278. ; (c) string delimited by '"'
  279. ; (d) comma delimiting items
  280. ;
  281. ; One major difference here is that numbers also use the string output
  282. ; routine to print on a device.  The string output routine outputs one
  283. ; string a time, if it fits the rest of the line, which is faster than
  284. ; iteratively outputs one character a time.
  285. ;
  286. ; Certainly, one piece of code, which serves such many functions, can't
  287. ; be as clean as some simple routines do.  However, there still has its
  288. ; logic as follows:
  289. ;
  290. ; B$PRINT (TerminatorType_&_ValueType)
  291. ; {
  292. ;     if channel on, test the mode is not input
  293. ; if error then give "bad file mode"
  294. ;     get pointer of the item to be printed from stack
  295. ;     set up types
  296. ;
  297. ;     /* print the item */
  298. ;
  299. ;     if the request was PRINT USING, then
  300. ; call print using routine
  301. ;     else /* not a PRINT USING */
  302. ; if the request was printing a number, then
  303. ;     translate the number into digital string
  304. ;     if the request was a WRITE statement, then
  305. ; special process the leading & ending space
  306. ; else /* printing a string */
  307. ;     if the request was a WRITE statement, then
  308. ; special process the string delimitor
  309. ; print the string
  310. ;
  311. ;     /* process the terminator */
  312. ;
  313. ;     if the terminator was a EOL, then force a carrage return
  314. ;     if the terminator was a COMMA, then fill the rest of the column
  315. ; with blanks
  316. ;     if the terminator was a SEMI-COLUMN and the request was a WRITE
  317. ; statement, then print a ','
  318. ;
  319. ;     /* handle the exit process explicitly */
  320. ;
  321. ;     play around with BP and SP
  322. ;
  323. ;     /* When exit the stack looks like : */
  324. ;     /* __________________ */
  325. ;     /* | SI  | */
  326. ;     /* |----------------| */
  327. ;     /* |  DS (if ?WIN)  | */
  328. ;     /*   BP -->|----------------| */
  329. ;     /* | BP  | */
  330. ;     /* |----------------| */
  331. ;     /* |    Ret offset  | */
  332. ;     /* |----------------| */
  333. ;     /* |    Ret segment | */
  334. ;     /*  Val -->|----------------| */
  335. ;     /* |    Parameter  | */
  336. ;     /* (variable len) ................  */
  337. ;     /* ................  */
  338. ;     /*       old SP -->|----------------| */
  339. ;     /* |________________| */
  340. ;     /* */
  341. ; }
  342. ;Entry:
  343. ; [AH] = [terminator type]
  344. ; [AL] = [value type]
  345. ; in stack,
  346. ; Val = first word of item, where item is either I2,I4,R4,R8 or sd/psd
  347. ;Exit:
  348. ; none
  349. ;Uses:
  350. ; none
  351. ;Exceptions:
  352. ; bad file mode
  353. ; I/O error or Disk full error when flush the buffer if a EOL encountered
  354. ;*******************************************************************************
  355. ;NOTE!: This routine has a manually
  356. ;generated epilogue due to variable number
  357. ;of parameters.  If you change the prologue,
  358. ;here you must also change the epilogue
  359. ;further down.
  360. cProc B$PRINT,<PUBLIC,FAR>,<SI> ;common routine, has to be declared
  361. ; as FAR for setting up stack frame correctly.
  362. ; SI saved
  363. ParmW Val ;dummy parameter, which points to the first
  364. ; byte of the actual parameter regardless how
  365. ; many bytes it is;  this also forces to set
  366. ; up the stack frame
  367. cBegin ;stack frame is set up and SI is saved
  368. MOV [b$?TYP],AX ;set up b$VTYP & b$TTYP
  369. LEA BX,Val ;get the address of parameter
  370. CMP AL,VT_SD ; is this a string parm?
  371. JNZ ChkString ; brif not - BX has the pointer to the value
  372. MOV BX,[BX]  ; if SD, BX has the value, not pointer
  373. ChkString:
  374. TEST [b$PRFG],USING ;is print using on ?
  375. JNZ PRTUSG ;Brif yes
  376. CMP AL,VT_SD ;printing a string ?
  377. JZ PRTSTR ;Brif yes
  378. ;[2] At this moment, [BX]=*I2,*I4,*R4 or *R8. 
  379. ; Currently B$FOUTBX changes all registers except BP.  This has to be
  380. ; changed later on.
  381. CALL B$FOUTBX ; Hopefully, the return from B$FOUTBX
  382. ;  are BX containing the address of the
  383. ; string and AX is the length
  384. MOV SI,BX ; SI=*Number
  385. TEST [b$PRFG],WRSTM ;is write statement on ?
  386. JNZ WRTVAL ;Brif is write stmt
  387. ADD BX,AX ;bx points to the terminate byte (00)
  388. INC AX ;increment the length of the digital string
  389. MOV BYTE PTR [BX]," " ;Number always followed by " "
  390. ;Note: the static buffer for translating a
  391. ; number must at least one byte longer
  392. ; than the maximum possible length.
  393. cCall MAKESD ;[BX]=*sd on return
  394. PRTIT1:  ;at this entry, check whether a EOL is needed
  395. PUSH BX ;save psd
  396. cCall [VPRTCHK] ; CY if room is not enough (possibly a EOL
  397. ; was already forced), needs AX=len of string
  398. POP BX ;get back psd
  399. PRTIT2:  ;at this entry, no check for EOL (write)
  400. PUSH BX ; save psd
  401. CALL [VTYP] ;print the string, needs [BX]=psd
  402. POP BX ; get back psd
  403. CALL [b$pSTDALCTMP] ; deallocate the temp if it is
  404. PRTEND:
  405. MOV AL,[b$TTYP] ; get delimiter type
  406. CBW ; extend to use word ops
  407. DEC AX ; test for EOL delimiter
  408. JG PRTCLF ; Brif end with LF-CR
  409. TEST [b$PRFG],WRSTM ;is write stmt on ?
  410. JZ PRTEND2  ; Brif not
  411. MOV AL,"," ; here if comma or semi and write stmt
  412. CALL [VWCH] ;write the character
  413. JMP SHORT PRINTX ;exit to caller
  414. WRTVAL:  ;write stmt take off the leading " "
  415. CMP BYTE PTR [BX]," " ;is first a blank ?
  416. JNZ WTMKSD ;Brif not, go make sd & print it
  417. INC SI ;skip the leading blank if write statement
  418. DEC AX ;decrement the length
  419. WTMKSD:
  420. cCall MAKESD ;[BX]=*sd
  421. JMP SHORT PRTIT2 ;go print it
  422. PRTUSG:
  423. ; print using, so make QBI compatable.
  424. CMP AH,COMA ; PRINT USING COMMA?
  425. JNE NotComma ; brif not -- don't alter terminator
  426. MOV b$TTYP,SEMI ; change comma to semicolon
  427. NotComma:
  428. CALL [b$PUSG] ;print using is handled specially
  429. JMP SHORT PRTEND ;process the terminator
  430. PRTSTR:  ;when enter, BX=*sd
  431. MOV AX,[BX]  ; AX = length of string
  432. TEST [b$PRFG],WRSTM ; is write stmt on ?
  433. JZ PRTIT1 ;Brif not, go printing string
  434. MOV AL,'"' ;'"' is the delimitor of write string
  435. PUSH BX ; save psd
  436. CALL [VWCH] ;print '"'
  437. POP BX ; restore psd
  438. CALL [VTYP] ;output the string
  439. CALL [b$pSTDALCTMP] ; deallocate the temp if it is
  440. MOV AL,'"' ;'"' is the delimitor of write string
  441. CALL [VWCH] ;print it
  442. JMP SHORT PRTEND ;process the terminator
  443. PRTCLF:
  444. CALL [VWCLF]  ;force a EOL
  445. cCall BPEOS ;epilog for PRINT
  446. JMP SHORT PRINTX ;exit to caller
  447. PRTEND2: ; here if comma or semi and NOT write stmt
  448. INC AX ; test for semi delimitor
  449. JNZ PRINTX ; go exit, done if semi-colon
  450. PRTCMA:
  451. CALL [VPOS] ;[AH]=current cursor position
  452. MOV AL,AH ;position in AL
  453. XOR AH,AH ;prepare for DIV
  454. ;Note: can't use CBW here, since the range
  455. ; is 0 - 255 (unsigned)
  456. MOV CL,CLMWID ;get field length
  457. DIV CL ;AH=remainder, is the position in this column
  458. SUB CL,AH ;spaces needed to fill this column
  459. XCHG AX,CX ; put count in AL
  460. CBW ;extend to a word
  461. PUSH AX ;save count of patching spaces
  462. ADD AX,CLMWID ;account for width of next column
  463. cCall [VPRTCHK] ; CY if room is not enough to fit (possibly
  464. ; a EOL was forced)
  465. POP CX ;get back count in CX
  466. JB PRINTX ;no need to patch spaces
  467. CALL B$OutBlanks ; output CX blanks
  468. PRINTX:  ;pop SI & exit to caller
  469. POP SI ; restore
  470. POP BP
  471. POP CX ; [CX] = return offset
  472. POP DX ; [DX:CX] = return address
  473. POP BX ; discard 1st word of parameter
  474. MOV AL,BYTE PTR [b$?TYP] ; [AL] = type byte
  475. TEST AL,VT_SD ; NZ if I2 or SD, i.e., if 1-word parm
  476. JNZ PRINTX_5 ; Jump if we don't need to pop more
  477. POP BX ; Discard 2nd word of parameter
  478. TEST AL,8 ; R8 or currency (8-byte values)?
  479. JZ PRINTX_5 ; no, don't pop any more
  480. POP BX ; discard 3rd word of parameter
  481. POP BX ; discard 4th word of parameter
  482. PRINTX_5:
  483. PUSH DX ; put back seg...
  484. PUSH CX ; ... and offset of far return address
  485. RET ; and return
  486. cEnd nogen ;no code generated
  487. SUBTTL supporting routines for print an item
  488. page
  489. ;***
  490. ;PRTCHK -- check whether there is room for the printing string
  491. ;
  492. ;Purpose:
  493. ; Check whether there is room for the printing string.  If it isn't,
  494. ; force a EOL if the current position is not in col. 1.
  495. ;
  496. ; Prtchk(len_of_str)
  497. ; register int len_of_str
  498. ; {
  499. ;     register int d_width
  500. ;     register int current_pos
  501. ;
  502. ;     if ((d_width=vwid()) != 255)
  503. ; if ( (len_of_str > 255) ||
  504. ;      ((d_width - (current_pos=vpos()) - len_of_str) < 0) )
  505. ; {   if (current_pos != 0) /* 0-relative */
  506. ; vclf()
  507. ;     Set_CY
  508. ; }
  509. ; }
  510. ;
  511. ;Entry:
  512. ; register AX = len_of_str
  513. ;
  514. ;Exit:
  515. ; CY if room left is not enough (may or may not force a EOL)
  516. ;
  517. ;Uses:
  518. ; None
  519. ;
  520. ;Exceptions:
  521. ; None
  522. ;*******************************************************************************
  523. cProc B$PRTCHK,<NEAR,PUBLIC>
  524. cBegin
  525. XCHG DX,AX ; length in DX
  526. CALL [VWID] ;[AH] = device width
  527. CMP AH,255 ;is device a file ?
  528. JZ CHKEXT ;exit (with NC)
  529. MOV AL,AH ;[AL] = device width
  530. JMP SHORT PRTCHK1
  531. cEnd <nogen>
  532. cProc TTY_PRTCHK,<NEAR>
  533. cBegin
  534. XCHG DX,AX ; length in DX
  535. MOV AL,b$CRTWIDTH ; AL = device width
  536. PRTCHK1:
  537. CALL [VPOS] ;[AH] = current position
  538. OR DH,DH ; more than 255 char to print?
  539. JNZ FORCE ; force a EOL
  540. SUB AL,AH ;amount left on line
  541. JB FORCE ;If no room on line, need new line
  542. CMP AL,DL ;will amount requested fit?
  543. JAE CHKEXT ;exit (with NC)
  544. FORCE:
  545. OR AH,AH ;is current position 0 (at col 1)
  546. JZ NOCRLF ;do not print EOL if at col 1
  547. CALL [VWCLF]  ;force EOL
  548. NOCRLF:
  549. STC ;indicate room is not enough
  550. Near_Ret: ;near return for vector
  551. CHKEXT:
  552. cEnd ;end of PRTCHK
  553. ;***
  554. ;MAKESD -- make a static string descriptor
  555. ;
  556. ;Purpose:
  557. ; Make a static string descriptor (in b$TempSD) which points to the
  558. ; input string.  Major changes with revision [38].
  559. ;
  560. ; WARNING !!! This routine assumes that the word preceding the string
  561. ; WARNING !!! is available to be used as the string header
  562. ;
  563. ;Entry:
  564. ; [SI] = address of the string
  565. ; [AX] = length of the string
  566. ;
  567. ;Exit:
  568. ; [BX] = address of static descriptor (b$TempSD)
  569. ; b$TempSD & b$TempStrPtr set up as SD.
  570. ;
  571. ;Uses:
  572. ; Backs up SI by 2.
  573. ;
  574. ;*******************************************************************************
  575. cProc MAKESD,<NEAR> ;private local routine
  576. cBegin
  577. MOV BX,OFFSET DGROUP:b$TempSD ; get the offset
  578. MOV WORD PTR [BX],AX ; length goes first
  579. MOV WORD PTR [BX+2],SI ; string pointer next
  580. cEnd
  581. ;***
  582. ;BPEOS -- actual code to terminate a print statement.
  583. ;
  584. ;Purpose:
  585. ; This routine is called by either the interface B$PEOS or B$PExx
  586. ; (print an item which terminated with a EOL)
  587. ; If FV_FARSTR, deallocate "using" string here if it was a temp.
  588. ;Entry:
  589. ; b$PTRFIL is the pointer/handle to FDB
  590. ;Exit:
  591. ; b$PTRFIL & b$PRFG are reset
  592. ;Uses:
  593. ; none
  594. ;Exceptions:
  595. ; I/O error or disk full error (when flush the buffer)
  596. ;*******************************************************************************
  597. cProc BPEOS,<NEAR>,<SI> ;was part of $PV4, SI saved
  598. cBegin
  599. MOV SI,[b$PTRFIL] ;get the pointer to FDB
  600. OR SI,SI ;is file 0 ? (TTY)
  601. JZ PEOSX ;Brif tty output, reset flags and exit
  602. MOV [b$PTRFIL],TTY ; clear out active FDB block
  603. FDB_PTR ES,SI,SI ;(ES:)[SI] = *FDB
  604. CMP SI,OFFSET DGROUP:b$LPTFDB ;is line printer ?
  605. JE PEOSX ;Brif LPRINT
  606. TEST FileDB.FD_FLAGS,FL_CHAR ;check for character device file
  607. JZ PEOSX ;Brif not character device
  608. CALL [b$pFLUSH] ; is character device, flush buffer
  609. ; was save and restore registers AX,BX,CX &
  610. ; DX in $PV4
  611. PEOSX:
  612. TEST [b$PRFG],WRSTM+LPSTM+CHANL ;was LPRINT, WRITE or # ?
  613. MOV [b$PRFG],PRSTM ;reset the print flag
  614. JZ NoSetVec
  615. MOV SI,OFFSET DGROUP:TTYVEC
  616. ;get source to fill in
  617. cCall B$WCHSET ;reset vector to default, needs SI
  618. NoSetVec:
  619. cEnd ;pop SI & exit to caller
  620. SUBTTL print/input interface -- B$PEOS [4]
  621. page
  622. ;***
  623. ;B$PEOS -- epilog for PRINT/WRITE/LPRINT/INPUT[#]/READ
  624. ;
  625. ;Purpose:
  626. ; if print, then clear out active FDB block, and flush buffer in case
  627. ; of a character device, also reset print flags
  628. ; if input, reset input flag & variable
  629. ;
  630. ; NOTE: this routine plays around with the stack pointer and stack frame
  631. ; pointer (BP).  Be really careful when save something in the
  632. ; stack.
  633. ;Entry:
  634. ; [b$PTRFIL] is the pointer to FDB
  635. ; [b$FInput] is the flag for input
  636. ; [b$PRFG] is the flag for print
  637. ;Exit:
  638. ; b$PTRFIL & b$PRFG & b$FInput (also b$GetOneVal) are reset
  639. ;Uses:
  640. ; none
  641. ;Exceptions:
  642. ; I/O error or disk full error (when flush the buffer (BPEOS))
  643. ;*******************************************************************************
  644. cProc B$PEOS,<PUBLIC,FAR>
  645. cBegin
  646. PUSH BP
  647. MOV BP,SP ;set up stack frame explicitly, since error
  648. ; could happen when flushing the buffer
  649. PUSH ES
  650. MOV AL,[b$Finput] ; get flag
  651. OR AL,AL ; test it
  652. JS TryPrint ; either READ stmt or default, try print
  653. JNZ RstFlags ; was disk input, just reset flags
  654. PUSH SI ; save SI
  655. PUSH DI ; save DI
  656. MOV DI,[b$StkBottom] ; DI is the stack bottom
  657. DEC DI ; one word above
  658. DEC DI
  659. MOV SI,SP ; SI points to the BP
  660. ADD SI,10 ;[12] SI points to ret_seg
  661. MOV CX,3 ; 3 words to move
  662. STD ; the move has to be from memory high to
  663. ;  low to avoid overlapping
  664. PUSH DS
  665. POP ES
  666. REP MOVSW ; mov BP and return addr to new location
  667. CLD ; clear direction
  668. MOV BP,DI ; stack frame has to be changed
  669. ADD BP,2 ; new locaton of old BP (later on,
  670. ;  "MOV SP,BP" will clean the stack)
  671. POP DI ; get back DI
  672. POP SI ; get back SI
  673. RstFlags:
  674. cCall B$InpReset ; reset input flag if this is input stmt
  675. JMP SHORT EosExit
  676. TryPrint: ; either print or READ stmt may be here,
  677. ;  however, next call, BPEOS, won't hurt
  678. ;  if it is READ stmt
  679. cCall BPEOS ;try print flush the buffer and reset flags
  680. EosExit:
  681. POP ES
  682. MOV SP,BP ;remove stack frame
  683. POP BP
  684. cEnd ;pop BP & exit
  685. SUBTTL set up print dispatch vector
  686. page
  687. ;***
  688. ;B$WCHSET -- set up print dispatch vector
  689. ;
  690. ;Purpose:
  691. ; b$VECS is the dispatch vector for PRINT/WRITE/LPRINT, which contains
  692. ; the address for different functions.  The functions are:
  693. ; b$VECS:
  694. ; VPOS -- current cursor position
  695. ; VWID -- device line width
  696. ; VWCLF -- force EOL
  697. ; VWCH -- write one character
  698. ; VTYP -- write a string with a given *sd
  699. ; VTYPCNT -- write a string with length in CX
  700. ; VOUTCNT -- write a string char. by char.
  701. ; VPRTCHK -- check if EOL needs to be forced
  702. ;Entry:
  703. ; [SI] points to the source which will fill in the b$VECS
  704. ;Exit:
  705. ; b$VECS is set up
  706. ;Uses:
  707. ; SI
  708. ;Exceptions:
  709. ; none
  710. ;*******************************************************************************
  711. cProc B$WCHSET,<PUBLIC,NEAR>,<DI,ES> ;save ES,DI
  712. cBegin
  713. PUSH DS
  714. POP ES ; can't assume ES=DS, set them equal
  715. MOV DI,OFFSET DGROUP:b$VECS
  716. MOV CX,SizeOfVecs ;count of words to copy
  717. REP MOVSW
  718. cEnd ;pop DI,ES and exit to caller
  719. ;*** 
  720. ; B$OutBlanks -- output a string of blanks.  Added with [22].
  721. ;
  722. ;Purpose:
  723. ; Save some code, and eliminate a static buffer of blanks.
  724. ; Doesn't print anything if count not in range 1-32767.
  725. ;
  726. ;Entry:
  727. ; CX = number of blanks to output
  728. ;Exit:
  729. ; None
  730. ;Uses:
  731. ; Per convention
  732. ;Exceptions:
  733. ; None
  734. ;
  735. ;******************************************************************************
  736. cProc B$OutBlanks,<PUBLIC,NEAR>,<SI,DI> ; Save SI,DI
  737. cBegin
  738. OR CX,CX ; negative or zero byte count
  739. JLE OutExit  ; brif no blanks to output
  740. DbAssertRel CX,BE,2*FILNAML,DK_TEXT,<B$OutBlanks: cnt too large>    
  741. PUSH CX ;save cnt
  742. PUSH SS ;ES = DGROUP
  743. POP ES
  744. MOV DI,OFFSET DGROUP:b$Buf1 
  745. PUSH DI
  746. INC CX ;round byte count to word count
  747. SHR CX,1
  748. MOV AX,'  ' 
  749.     REP STOSW ;fill with spaces
  750. POP SI ;DS:SI = string
  751. POP CX ;CX = count
  752. CALL [VOUTCNT] ;print the spaces
  753. OutExit:
  754. cEnd ;exit to caller
  755. page
  756. ;***
  757. ;NoGetValAssert - Assertion code for calls through [b$GetOneVal].
  758. ;
  759. ;Purpose:
  760. ; The variable [b$GetVal] is reset with common code to point to
  761. ; the default READ/INPUT entry point.  When no INPUT/READ statement
  762. ; is used in a program linked /O, there is no need to drag in the
  763. ; READ code.  So, b$GetVal is initialized to point to this routine
  764. ; for this case. If someone inadvertently tries to call through
  765. ; b$GetVal when no READ/INPUT code is loaded, it will be caught here.
  766. ; Added with revision [27].
  767. ;Entry:
  768. ; none
  769. ;Exit:
  770. ; none
  771. ;Uses:
  772. ; none
  773. ;Exceptions:
  774. ; none
  775. ;*******************************************************************************
  776. cProc NoGetValAssert,<NEAR>
  777. cBegin
  778. DbHalt <DK_TEXT>,<Tried to call B$ReadVal when it wasn't loaded>
  779. cEnd
  780. page
  781. ;***
  782. ;B$InpReset -- reset flag and variables for INPUT related statement
  783. ;
  784. ;Purpose:
  785. ; Reset flag and variables for input related statement.
  786. ; Moved to this file with [23]
  787. ;
  788. ;Entry:
  789. ; none
  790. ;
  791. ;Exit:
  792. ; [b$FInput] = InpDefault
  793. ; [b$GetOneItem] = OFFSET B$ReadItem
  794. ; [b$PTRFIL] = TTY
  795. ;
  796. ;Uses:
  797. ; none
  798. ;
  799. ;Exceptions:
  800. ; none
  801. ;*******************************************************************************
  802. cProc B$InpReset,<PUBLIC,NEAR>
  803. cBegin
  804. MOV [b$FInput],InpDefault
  805. ;reset input flag
  806. ; If input was pulled in, then this points to B$ReadVal, if no READ/INPUT
  807. ; statement was used, then this really points to the assertion routine
  808. ; NoGetValAssert
  809. PUSH AX
  810. MOV AX,[b$pGetValDefault] ;get default value for READ/INPUT
  811. MOV [b$GetOneVal],AX ;reset get item routine
  812. POP AX
  813. MOV [b$PTRFIL],TTY ;reset to TTY
  814. cEnd ;exit to caller
  815. SUBTTL interface for WRITE preamble
  816. page
  817. ; B$WRIT moved here from PR0A.ASM and modified for greater /O modularity.
  818. ;Revision number [25] applies to entire routine.
  819. ;***
  820. ;B$WRIT -- preamble for WRITE statement [25]
  821. ;void B$WRIT(void)
  822. ;
  823. ;Purpose:
  824. ; This is the only preamble for WRITE statement. This routine sets up
  825. ; flag for WRITE statement.  BASCOM 2.0 uses two preambles,
  826. ; $WRI for WRITE and $WRD for WRITE #.
  827. ;
  828. ; The flag, b$PRFG, is set to 4 (WRSTM) to indicate a WRITE statement
  829. ; is processing. If it is a WRITE #, then B$CHOU will OR the flag,
  830. ; b$PRFG, with 1 (CHANL) to indicate a special channel is being used.
  831. ;Entry:
  832. ; none
  833. ;Exit:
  834. ; b$PRFG is set to WRSTM (WRITE statement is on going)
  835. ; uses default vectors, same as PRINT.
  836. ;Uses:
  837. ; none
  838. ;Exceptions:
  839. ; none
  840. ;*******************************************************************************
  841. cProc B$WRIT,<PUBLIC,FAR,FORCEFRAME> ; stack frame generated explicitly
  842. cBegin
  843. OR [b$PRFG],WRSTM ; set flag indicating WRITE stmt is on going
  844. CALL B$CNTRL ; check for control chars during print
  845. cEnd ; return to caller
  846. sEnd ;end of DK_TEXT
  847. END