PATCHING PC-BASIC PROGRAMS FOR RAINBOW GW-BASIC Arne Reinert March 9 1989 Getting a PC-BASIC (BASICA, PC GWBASIC) to run on RAINBOW GW-BASIC sometimes just needs changing a few commands. Generally, Rainbow GW-BASIC (henceforth called GWBASIC) is a subset of BASICA; change a few lines, chop off a few extensions to SCREEN commands, and voila! It might work. Then again it might not, but it's worth a try! First, get the BASIC program into ASCII, so you can use an editor to search-and-replace offending commands. Do this by loading it into BASIC, then saving it again with the `A' option. SAVE "",A then edit with YFE (Your Favorite Editor) to search-and-replace known offending commands beforehand. Then load it back into BASIC, run it, and keep tracking down offending lines. Sometimes it's easier to fix line by line in BASIC, sometimes to exit and fix with an editor. COMMON OFFENDING COMMANDS BEEP: This is a common and easiest to fix culprit. Do a universal search-and-replace of BEEP with "PRINT CHR$(7);" (the ; at the end prevents unwanted linefeeds.) Works just like BEEP in BASICA too. LOCATE , : where = 25. Causes "Error 5 Illegal Function Call" since the Rainbow has only 24 lines. Replace all LOCATE 25 with LOCATE 24. This may cause the bottom line to overwrite whatever else was intended to be on line 24 though. For BASIC programs to run on both I use: LOCATE BL%, with BL% set to 24 or 25. SCREEN RESOLUTION: Ignore it, and sometimes all that happens is GWBASIC graphics screens will have blank bottom and right borders. But this is crude, and text won't line up with graphics the same if it's supposed to. Here's my error trapping so I don't have to change code between CGA, VGA, and RAINBOW anymore. Elsewhere in the program (not shown) it sets X,Y pixels per character so text lines up with graphics. BL% = text bottom line; BLT% = graphics bottom line, they're different only in VGA screen 11. ON ERROR GOTO 30000 50 LOCATE 25, 1 'If RAINBOW, ON ERROR will set RE$ = "RNB" 52 CLS : SCREEN 11 'If CGA, ON ERROR will set RE$ = "CGA" 54 RE$ = "VGA": SCREEN 0 'If no error, then re$ = "VGA" 56 IF RE$ = "RNB" THEN BL% = 24: BLT% = 24: HIPIX = 800: LIXPIX = 384: HIYPIX = 240: LIYPIX = 240: KOL = 3: hires% = 2 'Rainbow 57 IF RE$ = "CGA" THEN BL% = 25: BLT% = 25: HIXPIX = 640: LIXPIX = 320: HIYPIX = 200: LIYPIX = 204: KOL = 1: hires% = 2 'CGA 58 IF RE$ = "VGA" THEN BL% = 30: BLT% = 25: HIXPIX = 630: LIXPIX = 320: HIYPIX = 480: LIYPIX = 200: KOL = 1: hires% = 11 'VGA . . . . (Lines in ON ERROR trap routine) 30010 IF ERL = 50 THEN RE$ = "RNB": RESUME 56 30012 IF ERL = 52 THEN RE$ = "CGA": RESUME 56 After this, it gets harder. Further incompatibilitys can be more subtle and/or difficult. I keep some programs in 2 versions, usually named .RNB and .IBM PLAY, PEN, STRIG: Eliminate (or just `comment out' ) any commands using them. Rainbows got no music, pens, or joystick triggers. SCREEN: Screen 0,1,2 by itself is alright, but eliminate anything afterwards. These will be ,mode ,burst ,apage ,vpage extensions not available in GWBASIC. (rarely used, anyway) COLOR (n,n): Perfectly legal in GWBASIC, but values might have different effects, like bold, blinking screen. Removing might help. KEY TRAPS AND KEY SCANNING OTHER than ON KEY(n) where n = 1 to 14. KEYS 1-10 work the same (on slightly different function keys) on both. Keys 11-14 are the number pad cursor keys, not the imitation DEC cursor keys on the enhanced 101 keyboard. Code example below. ON KEY(15-20), and often key-polling routines. These use scan codes which are different for PC's and Rainbows. If it's any consolation, they're simpler on the Rainbow. Here is an example of trapping the DEC cursor keys, and the `enhanced AT keyboard' extra cursor keys (like DEC's), by polling INKEY$ values. IBM CODE 130 v$ = INKEY$: V2$ = MID$(v$, 2) 131 IF v$ = "" GOTO 140 132 IF ASC(V2$) = 72 then ... 'H 133 IF ASC(V2$) = 75 ... 'K 134 IF ASC(V2$) = 77 ... 'M 135 IF ASC(V2$) = 80 ... 'P INKEY$ of the `enhanced' cursor keys returns a 2 byte string with first byte null, [CHR$(0)], hence the V2$ = MID$(V$,2) to get the meaningful second byte. RAINBOW code does the same thing. INKEY$ returns 1 byte. Simpler. 130 V$ = INKEY$ 131 IF V$ = "" GOTO 140 132 IF ASC(V$) = 30 then ... 'ASCII 28-31 not printable 133 IF ASC(V$) = 29 ... 134 IF ASC(V$) = 28 ... 135 IF ASC(V$) = 31 ... GET, PUT graphics: There's a subtle deficiency, er, difference in the Rainbow's graphics GET PUT. The following code draws (not scaled properly but representative) PC Rainbow (0,0) \ (0,0) \ before \ \ WINDOW after / \ (0,0) / (0,0) \ 10 CLS:KEY OFF:SCREEN 2 15 DIM GRAFARRAY%(50) 'To hold LINE drawn in 20 20 LINE (10,10)-(20,20) 30 GET (10,10)-(20,20),GRAFARRAY% : PUT (30,30),GRAFARRAY% 40 WINDOW (0,0)-(640,200) 'Logically invert the screen 60 PUT (10,10),GRAFARRAY%:PUT (30,30),GRAFARRAY% GWBASIC doesn't logically adjust the stored object coordinates to match the logically adjusted screen coordinates. PUT/GET graphics images is a very powerful BASICA function, but virtually useless with Rainbow WINDOWed screens. PEEKs and POKEs, DEF SEG: Muddy to impassible terrain. These usually diddle video memory and hardware. For TEXT video memory, a similar PEEK/POKE substitution can be made (see below). For GRAPHICS video memory, it can't, because CGA video pixels use PEEK/POKEable DOS memory above 640k, whereas RAINBOW graphics video is on a separate graphics card. TEXT MEMORY: PC's text video uses 16K, hex B0000 - B3FFF (that's 704 - 720k), with character/attribute in alternate even/odd bytes. Rainbow's uses 8K; EE000 - EEFFF character, EF000 - EFFFF attribute (896 - 900k 900 - 904k ) PC's text attribute is a byte; low 4 bits for foreground color, high 4 bits for background color. Rainbows text attribute is 4 bits for REVERSE, BOLD, BLINK, UNDERSCORE (no color, but underline is underlined!) So the PC command: DEF SEG &HB000 : POKE I,J would substitute on the Rainbow as: DEF SEG &HEE00 : POKE I/2,J if I was even; J is ASCII value of character. DEF SEG &HEF00 : POKE (I-1)/2, K ifJ was odd; but attribute K is different too. So you can PEEK/POKE the CHARACTER, but the ATTRIBUTE is trickier. BSAVE/BLOAD: Binary executable code and text screens, yes; graphics screens, no, for reasons listed above. PC: DEF SEG &HB000: BSAVE , , , hold 4 screens of 80 x 25 text Rainbow: DEF SEG &HEOO0: BSAVE , , , hold 1 screen of 80 x 24 text, so must be adjusted. DEF SEG=0:POKE 1050,PEEK(1052): Flushes the PC keyboard buffer. There presumably is something equivalent for the Rainbow, but I don't know it. All the above are things I've twiddled to get PC BASIC programs to run on the Rainbow. Sometimes they've worked, sometimes not. Total failure usually involves PEEKs and POKEs.