ChipMaster's bwBASIC This also includes history going back to v2.10. *WARN* some binary files might have been corrupted by CRLF.
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.
 
 
 
 
 
 

776 lines
16 KiB

  1. /***************************************************************
  2. bwx_iqc.c Environment-dependent implementation
  3. of Bywater BASIC Interpreter
  4. for IBM PC and Compatibles
  5. using the Microsoft QuickC (tm) Compiler
  6. Copyright (c) 1993, Ted A. Campbell
  7. Bywater Software
  8. email: tcamp@delphi.com
  9. Copyright and Permissions Information:
  10. All U.S. and international rights are claimed by the author,
  11. Ted A. Campbell.
  12. This software is released under the terms of the GNU General
  13. Public License (GPL), which is distributed with this software
  14. in the file "COPYING". The GPL specifies the terms under
  15. which users may copy and use the software in this distribution.
  16. A separate license is available for commercial distribution,
  17. for information on which you should contact the author.
  18. ***************************************************************/
  19. /*---------------------------------------------------------------*/
  20. /* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */
  21. /* 11/1995 (eidetics@cerf.net). */
  22. /* */
  23. /* Those additionally marked with "DD" were at the suggestion of */
  24. /* Dale DePriest (daled@cadence.com). */
  25. /*---------------------------------------------------------------*/
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <setjmp.h>
  29. #include <bios.h>
  30. #include <graph.h>
  31. #include <signal.h>
  32. #include "bwbasic.h"
  33. #include "bwb_mes.h"
  34. extern int prn_col;
  35. extern jmp_buf mark;
  36. short oldfgd;
  37. long oldbgd;
  38. int reset_mode = FALSE;
  39. static int iqc_setpos( void );
  40. /***************************************************************
  41. FUNCTION: main()
  42. DESCRIPTION: As in any C program, main() is the basic
  43. function from which the rest of the
  44. program is called. Some environments,
  45. however, provide their own main() functions
  46. (Microsoft Windows (tm) is an example).
  47. In these cases, the following code will
  48. have to be included in the initialization
  49. function that is called by the environment.
  50. ***************************************************************/
  51. int
  52. main( int argc, char **argv )
  53. {
  54. #if MS_CMDS
  55. struct videoconfig vc;
  56. short videomode;
  57. /* Save original foreground, background, and text position. */
  58. _getvideoconfig( &vc );
  59. oldfgd = _gettextcolor();
  60. oldbgd = _getbkcolor();
  61. if ( vc.mode != _TEXTC80 )
  62. {
  63. if ( _setvideomode( _TEXTC80 ) == 0 )
  64. {
  65. _getvideoconfig( &vc );
  66. prn_xprintf( stderr, "Failed to set color video mode\n" );
  67. }
  68. else
  69. {
  70. reset_mode = FALSE;
  71. }
  72. }
  73. else
  74. {
  75. reset_mode = FALSE;
  76. }
  77. #endif /* MS_CMDS */
  78. bwb_init( argc, argv );
  79. #if INTERACTIVE
  80. setjmp( mark );
  81. #endif
  82. /* now set the number of colors available */
  83. * var_findnval( co, co->array_pos ) = (bnumber) vc.numcolors;
  84. /* main program loop */
  85. while( !feof( stdin ) ) /* condition !feof( stdin ) added in v1.11 */
  86. {
  87. bwb_mainloop();
  88. }
  89. return (0);
  90. }
  91. /***************************************************************
  92. FUNCTION: bwx_signon()
  93. DESCRIPTION:
  94. ***************************************************************/
  95. int
  96. bwx_signon( void )
  97. {
  98. sprintf( bwb_ebuf, "\r%s %s\n", MES_SIGNON, VERSION );
  99. prn_xprintf( stdout, bwb_ebuf );
  100. sprintf( bwb_ebuf, "\r%s\n", MES_COPYRIGHT );
  101. prn_xprintf( stdout, bwb_ebuf );
  102. sprintf( bwb_ebuf, "\r%s\n", MES_COPYRIGHT_2 ); /* JBV 1/97 */
  103. prn_xprintf( stdout, bwb_ebuf );
  104. #if PERMANENT_DEBUG
  105. sprintf( bwb_ebuf, "\r%s\n", "Debugging Mode" );
  106. prn_xprintf( stdout, bwb_ebuf );
  107. #else
  108. sprintf( bwb_ebuf, "\r%s\n", MES_LANGUAGE );
  109. prn_xprintf( stdout, bwb_ebuf );
  110. #endif
  111. return TRUE;
  112. }
  113. /***************************************************************
  114. FUNCTION: bwx_message()
  115. DESCRIPTION:
  116. ***************************************************************/
  117. int
  118. bwx_message( char *m )
  119. {
  120. #if DEBUG
  121. _outtext( "<MES>" );
  122. #endif
  123. _outtext( m );
  124. return TRUE;
  125. }
  126. /***************************************************************
  127. FUNCTION: bwx_putc()
  128. DESCRIPTION:
  129. ***************************************************************/
  130. extern int
  131. bwx_putc( char c )
  132. {
  133. static char tbuf[ 2 ];
  134. tbuf[ 0 ] = c;
  135. tbuf[ 1 ] = '\0';
  136. _outtext( tbuf );
  137. return TRUE;
  138. }
  139. /***************************************************************
  140. FUNCTION: bwx_error()
  141. DESCRIPTION:
  142. ***************************************************************/
  143. int
  144. bwx_errmes( char *m )
  145. {
  146. static char tbuf[ MAXSTRINGSIZE + 1 ]; /* this memory should be
  147. permanent in case of memory
  148. overrun errors */
  149. if (( prn_col != 1 ) && ( errfdevice == stderr ))
  150. {
  151. prn_xprintf( errfdevice, "\n" );
  152. }
  153. if ( CURTASK number == 0 )
  154. {
  155. sprintf( tbuf, "\n%s: %s\n", ERRD_HEADER, m );
  156. }
  157. else
  158. {
  159. sprintf( tbuf, "\n%s %d: %s\n", ERROR_HEADER, CURTASK number, m );
  160. }
  161. #if INTENSIVE_DEBUG
  162. prn_xprintf( stderr, "<ERR>" );
  163. #endif
  164. prn_xprintf( errfdevice, tbuf );
  165. return TRUE;
  166. }
  167. /***************************************************************
  168. FUNCTION: bwx_input()
  169. DESCRIPTION: As implemented here, the input facility
  170. is a hybrid of _outtext output (which allows
  171. the color to be set) and standard output
  172. (which does not). The reason is that I've
  173. found it helpful to use the DOS facility
  174. for text entry, with its backspace-delete
  175. and recognition of the SIGINT, depite the
  176. fact that its output goes to stdout.
  177. ***************************************************************/
  178. int
  179. bwx_input( char *prompt, char *buffer )
  180. {
  181. #if INTENSIVE_DEBUG
  182. prn_xprintf( stdout, "<INP>" );
  183. #endif
  184. prn_xprintf( stdout, prompt );
  185. fgets( buffer, MAXREADLINESIZE, stdin );
  186. prn_xprintf( stdout, "\n" ); /* let _outtext catch up */
  187. * prn_getcol( stdout ) = 1; /* reset column */
  188. return TRUE;
  189. }
  190. /***************************************************************
  191. FUNCTION: bwx_terminate()
  192. DESCRIPTION:
  193. ***************************************************************/
  194. void
  195. bwx_terminate( void )
  196. {
  197. #if MS_CMDS
  198. if ( reset_mode == TRUE )
  199. {
  200. _setvideomode( _DEFAULTMODE );
  201. /* Restore original foreground and background. */
  202. _settextcolor( oldfgd );
  203. _setbkcolor( oldbgd );
  204. }
  205. #endif
  206. exit( 0 );
  207. }
  208. /***************************************************************
  209. FUNCTION: bwx_shell()
  210. DESCRIPTION:
  211. ***************************************************************/
  212. #if COMMAND_SHELL
  213. extern int
  214. bwx_shell( struct bwb_line *l )
  215. {
  216. static char *s_buffer;
  217. static int init = FALSE;
  218. static int position;
  219. /* get memory for temporary buffer if necessary */
  220. if ( init == FALSE )
  221. {
  222. init = TRUE;
  223. /* Revised to CALLOC pass-thru call by JBV */
  224. if ( ( s_buffer = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
  225. {
  226. bwb_error( err_getmem );
  227. return FALSE;
  228. }
  229. }
  230. /* get the first element and check for a line number */
  231. #if INTENSIVE_DEBUG
  232. sprintf( bwb_ebuf, "in bwx_shell(): line buffer is <%s>.", l->buffer );
  233. bwb_debug( bwb_ebuf );
  234. #endif
  235. position = 0;
  236. adv_element( l->buffer, &position, s_buffer );
  237. if ( is_numconst( s_buffer ) != TRUE ) /* not a line number */
  238. {
  239. #if INTENSIVE_DEBUG
  240. sprintf( bwb_ebuf, "in bwx_shell(): no line number, command <%s>.",
  241. l->buffer );
  242. bwb_debug( bwb_ebuf );
  243. #endif
  244. if ( system( l->buffer ) == 0 )
  245. {
  246. iqc_setpos();
  247. return TRUE;
  248. }
  249. else
  250. {
  251. iqc_setpos();
  252. return FALSE;
  253. }
  254. }
  255. else /* advance past line number */
  256. {
  257. adv_ws( l->buffer, &position ); /* advance past whitespace */
  258. #if INTENSIVE_DEBUG
  259. sprintf( bwb_ebuf, "in bwx_shell(): line number, command <%s>.",
  260. l->buffer );
  261. bwb_debug( bwb_ebuf );
  262. #endif
  263. if ( system( &( l->buffer[ position ] ) ) == 0 )
  264. {
  265. iqc_setpos();
  266. return TRUE;
  267. }
  268. else
  269. {
  270. iqc_setpos();
  271. return FALSE;
  272. }
  273. }
  274. }
  275. #endif
  276. /***************************************************************
  277. FUNCTION: iqc_setpos()
  278. DESCRIPTION:
  279. ***************************************************************/
  280. static int
  281. iqc_setpos( void )
  282. {
  283. union REGS ibm_registers;
  284. /* call the BDOS function 0x10 to read the current cursor position */
  285. ibm_registers.h.ah = 3;
  286. ibm_registers.h.bh = (unsigned char) _getvisualpage();
  287. int86( 0x10, &ibm_registers, &ibm_registers );
  288. /* set text to this position */
  289. _settextposition( ibm_registers.h.dh, ibm_registers.h.dl );
  290. /* and move down one position */
  291. prn_xprintf( stdout, "\n" );
  292. return TRUE;
  293. }
  294. #if COMMON_CMDS
  295. /***************************************************************
  296. FUNCTION: bwb_edit()
  297. DESCRIPTION:
  298. ***************************************************************/
  299. struct bwb_line *
  300. bwb_edit( struct bwb_line *l )
  301. {
  302. char tbuf[ MAXSTRINGSIZE + 1 ];
  303. char edname[ MAXSTRINGSIZE + 1 ];
  304. struct bwb_variable *ed;
  305. FILE *loadfile;
  306. ed = var_find( DEFVNAME_EDITOR );
  307. str_btoc( edname, var_getsval( ed ));
  308. sprintf( tbuf, "%s %s", edname, CURTASK progfile );
  309. #if INTENSIVE_DEBUG
  310. sprintf( bwb_ebuf, "in bwb_edit(): command line <%s>", tbuf );
  311. bwb_debug( bwb_ebuf );
  312. #else
  313. system( tbuf );
  314. #endif
  315. /* open edited file for read */
  316. if ( ( loadfile = fopen( CURTASK progfile, "r" )) == NULL )
  317. {
  318. sprintf( bwb_ebuf, err_openfile, CURTASK progfile );
  319. bwb_error( bwb_ebuf );
  320. iqc_setpos();
  321. return bwb_zline( l );
  322. }
  323. /* clear current contents */
  324. bwb_new( l ); /* Relocated by JBV (bug found by DD) */
  325. /* and (re)load the file into memory */
  326. bwb_fload( loadfile );
  327. iqc_setpos();
  328. return bwb_zline( l );
  329. }
  330. /***************************************************************
  331. FUNCTION: bwb_renum()
  332. DESCRIPTION: This function implements the BASIC RENUM
  333. command by shelling out to a default
  334. renumbering program called "renum".
  335. Added by JBV 10/95
  336. SYNTAX: RENUM
  337. ***************************************************************/
  338. #if ANSI_C
  339. struct bwb_line *
  340. bwb_renum( struct bwb_line *l )
  341. #else
  342. struct bwb_line *
  343. bwb_renum( l )
  344. struct bwb_line *l;
  345. #endif
  346. {
  347. char tbuf[ MAXSTRINGSIZE + 1 ];
  348. FILE *loadfile;
  349. sprintf( tbuf, "renum %s\0", CURTASK progfile );
  350. #if INTENSIVE_DEBUG
  351. sprintf( bwb_ebuf, "in bwb_renum(): command line <%s>", tbuf );
  352. bwb_debug( bwb_ebuf );
  353. #else
  354. system( tbuf );
  355. #endif
  356. /* open edited file for read */
  357. if ( ( loadfile = fopen( CURTASK progfile, "r" )) == NULL )
  358. {
  359. sprintf( bwb_ebuf, err_openfile, CURTASK progfile );
  360. bwb_error( bwb_ebuf );
  361. iqc_setpos();
  362. return bwb_zline( l );
  363. }
  364. /* clear current contents */
  365. bwb_new( l ); /* Relocated by JBV (bug found by DD) */
  366. /* and (re)load the file into memory */
  367. bwb_fload( loadfile );
  368. iqc_setpos();
  369. return bwb_zline( l );
  370. }
  371. /***************************************************************
  372. FUNCTION: bwb_files()
  373. DESCRIPTION:
  374. ***************************************************************/
  375. struct bwb_line *
  376. bwb_files( struct bwb_line *l )
  377. {
  378. char tbuf[ MAXVARNAMESIZE + 1 ];
  379. char finame[ MAXVARNAMESIZE + 1 ];
  380. char argument[ MAXVARNAMESIZE + 1 ];
  381. struct bwb_variable *fi;
  382. struct exp_ese *e;
  383. fi = var_find( DEFVNAME_FILES );
  384. str_btoc( finame, var_getsval( fi ));
  385. /* get argument */
  386. adv_ws( l->buffer, &( l->position ));
  387. switch( l->buffer[ l->position ] )
  388. {
  389. case '\0':
  390. case '\r':
  391. case '\n':
  392. argument[ 0 ] = '\0';
  393. break;
  394. default:
  395. e = bwb_exp( l->buffer, FALSE, &( l->position ) );
  396. if ( e->type != STRING )
  397. {
  398. bwb_error( err_mismatch );
  399. return bwb_zline( l );
  400. }
  401. str_btoc( argument, exp_getsval( e ) );
  402. break;
  403. }
  404. sprintf( tbuf, "%s %s", finame, argument );
  405. #if INTENSIVE_DEBUG
  406. sprintf( bwb_ebuf, "in bwb_files(): command line <%s>", tbuf );
  407. bwb_debug( bwb_ebuf );
  408. #else
  409. system( tbuf );
  410. #endif
  411. iqc_setpos();
  412. return bwb_zline( l );
  413. }
  414. #endif /* COMMON_CMDS */
  415. #if INTERACTIVE
  416. /***************************************************************
  417. FUNCTION: fnc_inkey()
  418. DESCRIPTION: This C function implements the BASIC INKEY$
  419. function. It is implementation-specific.
  420. ***************************************************************/
  421. extern struct bwb_variable *
  422. fnc_inkey( int argc, struct bwb_variable *argv )
  423. {
  424. static struct bwb_variable nvar;
  425. char tbuf[ MAXSTRINGSIZE + 1 ];
  426. static int init = FALSE;
  427. /* initialize the variable if necessary */
  428. if ( init == FALSE )
  429. {
  430. init = TRUE;
  431. var_make( &nvar, STRING, "fnc_inkey" );
  432. }
  433. /* check arguments */
  434. #if PROG_ERRORS
  435. if ( argc > 0 )
  436. {
  437. sprintf( bwb_ebuf, "Two many arguments to function INKEY$()" );
  438. bwb_error( bwb_ebuf );
  439. return &nvar;
  440. }
  441. #else
  442. if ( fnc_checkargs( argc, argv, 0, 0 ) == FALSE )
  443. {
  444. return NULL;
  445. }
  446. #endif
  447. /* body of the INKEY$ function */
  448. if ( _bios_keybrd( _KEYBRD_READY ) == 0 )
  449. {
  450. tbuf[ 0 ] = '\0';
  451. }
  452. else
  453. {
  454. tbuf[ 0 ] = (char) _bios_keybrd( _KEYBRD_READ );
  455. tbuf[ 1 ] = '\0';
  456. }
  457. /* assign value to nvar variable */
  458. str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
  459. /* return value contained in nvar */
  460. return &nvar;
  461. }
  462. #endif /* INTERACTIVE */
  463. #if MS_CMDS
  464. /***************************************************************
  465. FUNCTION: bwb_cls()
  466. DESCRIPTION: This C function implements the BASIC CLS
  467. command. It is implementation-specific.
  468. ***************************************************************/
  469. extern struct bwb_line *
  470. bwb_cls( struct bwb_line *l )
  471. {
  472. _clearscreen( _GCLEARSCREEN );
  473. return bwb_zline( l );
  474. }
  475. /***************************************************************
  476. FUNCTION: bwb_locate()
  477. DESCRIPTION: This C function implements the BASIC LOCATE
  478. command. It is implementation-specific.
  479. ***************************************************************/
  480. extern struct bwb_line *
  481. bwb_locate( struct bwb_line *l )
  482. {
  483. struct exp_ese *e;
  484. int row, column;
  485. /* get first argument */
  486. e = bwb_exp( l->buffer, FALSE, &( l->position ));
  487. row = (int) exp_getnval( e );
  488. /* advance past comma */
  489. adv_ws( l->buffer, &( l->position ));
  490. if ( l->buffer[ l->position ] != ',' )
  491. {
  492. bwb_error( err_syntax );
  493. return bwb_zline( l );
  494. }
  495. ++( l->position );
  496. /* get second argument */
  497. e = bwb_exp( l->buffer, FALSE, &( l->position ));
  498. column = (int) exp_getnval( e );
  499. /* position the cursor */
  500. _settextposition( row, column );
  501. return bwb_zline( l );
  502. }
  503. /***************************************************************
  504. FUNCTION: bwb_color()
  505. DESCRIPTION: This C function implements the BASIC COLOR
  506. command. It is implementation-specific.
  507. ***************************************************************/
  508. extern struct bwb_line *
  509. bwb_color( struct bwb_line *l )
  510. {
  511. struct exp_ese *e;
  512. int color;
  513. /* get first argument */
  514. e = bwb_exp( l->buffer, FALSE, &( l->position ));
  515. color = (int) exp_getnval( e );
  516. #if INTENSIVE_DEBUG
  517. sprintf( bwb_ebuf, "Setting text color to %d", color );
  518. bwb_debug( bwb_ebuf );
  519. #endif
  520. _settextcolor( (short) color );
  521. #if INTENSIVE_DEBUG
  522. sprintf( bwb_ebuf, "Set text color to %d", color );
  523. bwb_debug( bwb_ebuf );
  524. #endif
  525. /* advance past comma */
  526. adv_ws( l->buffer, &( l->position ));
  527. if ( l->buffer[ l->position ] == ',' )
  528. {
  529. ++( l->position );
  530. /* get second argument */
  531. e = bwb_exp( l->buffer, FALSE, &( l->position ));
  532. color = (int) exp_getnval( e );
  533. #if INTENSIVE_DEBUG
  534. sprintf( bwb_ebuf, "Setting background color to %d", color );
  535. bwb_debug( bwb_ebuf );
  536. #endif
  537. /* set the background color */
  538. _setbkcolor( (long) color );
  539. #if INTENSIVE_DEBUG
  540. sprintf( bwb_ebuf, "Setting background color to %d\n", color );
  541. bwb_debug( bwb_ebuf );
  542. #endif
  543. }
  544. return bwb_zline( l );
  545. }
  546. #endif /* MS_CMDS */