PokeDatW

Adding binary data to your BASIC program is usually done using DATA statements. But why not just cut out the middleman?

This routine outputs the binary file as an SBASIC FuNction in a temporary file that can then be merged with your program. Ie it doesnt append the data to your main program file, so dont, dont give that as your output filename or your program could get overwritten!

PokeDatW uses POKE_W directly rather than first reading the DATA statments and then poking the data read. This version uses word sized bites of data. It turns out the long word data bites get garbled. (Perhaps only on QPC2 etc, due to endian issues? Yet to find out..) Long HEX is fine too, but needs SBASIC and Qlib V3.45+ to compile.

Qdos doesnt allow POKExx to have multiple data statements following the target address, as SMSQ/E and Minerva do, eg POKE_W address, a, b, c,.., so the output of PokeDatW wont work there. It turns out that QLib uses the OS'es version of POKExx, so even if compiled with QLib, the output of this routine wont work on Qdos systems. I havent tried with Turbo.

Update: You could use my compatibility toolkit PEEK & POKE to add multi-data POKEs. Compiled in with Qlib 3.45+ the object code should work across all platforms.

For an example of output, see here.


10 rem                             PokeDatW
11 :
12 rem     Harness to test
13 fnm$ = 'win1_prg_spr_mks_MyMenu_men':   rem Input binary
14 fno$ = 'ram1_data_bas':                 rem Output statements
15 nl   = 20:                              rem Number of items per line
16 lin% = 1000:                            rem Start line number
17 lni% = 10:                              rem Line number increment
18 :
19 ERT PokeDatW(fnm$, fno$, nl, lin%, lni%)
20 :
21 :
100 rem + ------------------------------------------------------------------------ +
101 rem |<                                PokeDatW                                >|
102 rem + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +
103 rem |          Add data to an S*BASIC program using word-sized POKEs           |
104 rem |                                                                          |
105 rem |   ifn$ = input filename                                                  |
106 rem |   ofn$ = output filename                                                 |
107 rem |   nil  = number of items per line                                        |
108 rem |   stl% = start line number                                               |
109 rem |   inc% = line number increment (or 0 => no line numbers)                 |
110 rem |                                                                          |
111 rem | Note: No checking for line number overrun!                               |
112 rem | Note: DIV and MOD may fail for large files (Qdos). Use LDIV/LMOD         |
113 rem | instead                                                                  |
114 rem + ------------------------------------------------------------------------ +
115 rem | V0.01, pjw, March 12th 2019, based on earlier work                       |
116 rem + ------------------------------------------------------------------------ +
500 :
502 DEFine FuNction PokeDatW(ifn$, ofn$, nil, stl%, inc%)
504 LOCal col, row, ch, fl, ad, dad, r, b, lno%
506 :
508 rem     Load data to process
510 ch = FOP_IN(ifn$): IF ch < 0: RETurn ch
512 fl = FLEN(#ch): CLOSE#ch
514 ad = ALCHP(fl)
516 LBYTES ifn$, ad
518 :
520 dad = 0: lno% = stl% - inc%
522 :
524 rem     Start outputting
526 ch = FOP_NEW(ofn$): IF ch <0: RECHP ad: RETurn ch
528 :
530 PRINT#ch; LI$; 'def fn Dat'\ LI$; 'loc dad'
532 PRINT#ch; LI$; 'rem'! ifn$ \ LI$; ':'
534 PRINT#ch; LI$; 'dad = alchp('; fl; ')'\ LI$; ':'
536 :
538 rem     Output bulk of rows
540 IF fl >= nil THEN
542  FOR col = 0 TO fl - nil STEP nil
544   PRINT#ch; LI$; 'poke_w dad +'! col; ', ';
546   :
548   FOR row = col TO col + nil - 4 STEP 2
550    PRINT#ch; PEEK_W(ad + row); ', ';
552   END FOR row
554   :
556   PRINT#ch; PEEK_W(ad + row + 2)
558   :
560  END FOR col
562 ELSE
564  col = -nil
566 END IF
568 :
570 rem     Last row (if any)
572 r = fl - INT(fl / nil) * nil
574 b = r MOD 2
576 r = INT(r / 2) * 2
578 :
580 IF r > 2 THEN
582  PRINT#ch; LI$; 'poke_w dad +'! col + nil; ', ';
584  FOR row = col + nil TO col + nil + r - 4 STEP 2
586   PRINT#ch; PEEK_W(ad + row); ', ';
588  END FOR row
590  :
592  PRINT#ch; PEEK_W(ad + row + 2)
594 ELSE
596  IF r = 2 THEN
598   row = col + nil + r - 2
600   PRINT#ch; LI$; 'poke_w dad +'! row; ','! PEEK_W(ad + row)
602  END IF
604 END IF
606 :
608 rem     Last byte (if any)
610 IF b THEN
612  row = col + nil + r
614  PRINT#ch; LI$; 'poke   dad +'! row; ', '; PEEK(ad + row)
616 END IF
618 :
620 PRINT#ch; LI$; ':'\ LI$; 'ret dad'\ LI$; 'enddef Dat'\ LI$; ':'
622 :
624 RECHP ad: CLOSE#ch
626 RETurn 0
628 END DEFine PokeDatW
630 :
632 :
634 DEFine FuNction LI$
636 IF inc% = 0: RETurn ''
638 lno% = lno% + inc%: RETurn lno% & ' '
640 END DEFine LI$
642 :
644 :
  
Generated with sb2htm on 2019 Jun 05
©pjwitte March 2oi9