10 REM> GenBitMap
   20 REM generates bitmap for the given image
   30 REM the program requires two ROM images:
   40 REM the original (assembled at &8000)
   50 REM the alternative (assembled >= &8100) used to check for differences
   60 REM the bitmap (if valid) is always placed in the binary image "bitmap"
   70 :
   80 ON ERROR REPORT:PRINTERL:END
   90 DIM bmbuff% &2000:REM 8K should be large enough for the bitmap
  100 bend%=bmbuff%+&2000
  110 bptr%=bend%:REM start at the end
  120 :
  130 code%=&DEC0:REM bitmap identifier
  140 dist%=&0000
  150 numbits%=&0000
  160 address%=&8000-1
  170 :
  180 INPUT "File containing ROM image assembled at &8000 => "realrom$
  190 INPUT "File containing ROM image assembled for relocation => "altrom$
  200 :
  210 rr%=OPENIN(realrom$)
  220 IF rr%=0 THEN PRINT "Could not open ";realrom$:END
  230 :
  240 ar%=OPENIN(altrom$)
  250 IF ar%=0 THEN PRINT "Could not open ";altrom$:CLOSE#rz%:END
  260 :
  270 REM -- the bitmap is stored in reverse order, with the bitmap header
  280 REM -- information stored at the end
  290 REM -- the header contains a special identifier (CODE) and the length
  300 REM -- of the bitmap in bytes
  310 bptr%=bptr%-2:REM step over ID
  320 bptr%?&00=code% MOD &0100
  330 bptr%?&01=code% DIV &0100
  340 bptr%=bptr%-2:REM step over bit count
  350 bptr%?&00=&00
  360 bptr%?&01=&00
  370 bcadr%=bptr%:REM but remember wheze we need to place it
  380 :
  390 REPEAT
  400   :
  410   bptr%=bptr%-1
  420   val%=0
  430   bc%=8
  440   :
  450   REPEAT
  460     :
  470     v1%=BGET#rr%
  480     v2%=BGET#ar%
  490     address%=address%+1
  500     :
  510     IF ((v1% >= &7F) AND (v1% <= &BF)) THEN PROCcheck
  520     :
  530   UNTIL (bc%=0) OR (EOF#rr% OR EOF#ar%)
  540   :
  550   REM check and see if the last byte in the bitmap table needs to be
  560   REM padded (this is required due to the lo-address byte being stored
  570   REM in the highest bit)
  580   IF (bc%=0) THEN PROCinsert ELSE IF (bc%>0 AND bc%<8) THEN FOR loop%=bc% TO 1 STEP -1:val%=(val%*2)+0:NEXT:PROCinsert
  590   IF bc%=8 THEN bptr%=bptr%+1
  600   :
  610 UNTIL (EOF#rr% OR EOF#ar%) OR (bptr%<bmbuff%)
  620 :
  630 IF bptr%<bmbuff% THEN PRINT "Fatal error - bitmap table underflow"
  640 :
  650 CLOSE#rr%
  660 CLOSE#ar%
  670 :
  680 bcadr%?&00=numbits% MOD &0100
  690 bcadr%?&01=numbits% DIV &0100
  700 :
  710 save$="SAVE bitmap "+STR$~bptr%+" "+STR$~bend%+" 0 0"
  720 PRINT"About to save <";save$,">"
  730 IF bptr%>=bmbuff% THEN OSCLI(save$)
  740 :
  750 END
  760 :
  770 DEFPROCinsert
  780 REM place a byte into the bitmap, and decrement pointers
  790 bptr%?&00=val%:numbits%=numbits%+1
  800 ENDPROC
  810 :
  820 DEFPROCcheck
  830 REM - check if a byte needs relocating
  840 LOCAL d%
  850 IF v1%=v2% THEN PROCaddbit(0):ENDPROC
  860 REM they are different
  870 REM check they are always the same distance apart
  880 d%=v2%-v1%
  890 IF dist%<>0 AND d%<>dist% THEN PRINT"Fatal error - difference not constant" ELSE IF dist%=0 THEN dist%=d%
  900 :
  910 PRINT "Diff at &";~address%
  920 :
  930 PROCaddbit(1)
  940 ENDPROC
  950 :
  960 DEFPROCaddbit(v%)
  970 REM - add the bit given into the structure
  980 REM   this is done by remembering the bit in the current byte
  990 REM   bc% : global that holds the bit count within the current byte
 1000 REM   val% : global that holds the current byte
 1010 bc%=bc%-1
 1020 val%=(val%*2)+v%
 1030 ENDPROC