Part II
by Robert Gault
In Part I, you found that I wanted to display Coco screen images on my web site. I needed a Windows graphic format that was compatible with the Super Basic graphics screen and simple enough to write a program to handle the conversion. Looking in an invaluable source of information, "Supercharged Bitmapped Graphics", by Steve Rimmer, Wincrest / McGraw-Hill, the BMP format appeared to be just the thing needed. BMP is a non-compressed (i.e. simple), line by line format where each byte is handle exactly as in Super Basic HSCREEN2 & 3. A BMP file is almost the same as a SAVEM file.
One complication is that the BMP format saves the picture lines in reverse order so that the file data is not in the same order as in memory. This would not matter if the Coco graphics did not extend over more than one MMU block of memory or if the $2000 byte blocks were evenly divisible by the graphic line size. Since neither of the above is true some complex logic is required to handle the graphic lines which overlap MMU blocks.
The second complication is that a header is required which contains, among other things, the color mode and palette information. BMP files come in several flavors, 1, 4, and 24 bit color. Coco3 high-res graphics come in 1, 2, and 4 bit color. That means only the Coco HSCREEN modes 2 (16 color) and 3 (2 color) can be converted, but that was good enough for me.
The exact structure of a BMP header is given in the Rimmer book. However, because I had some confusion with the explanation, I created two blank BMP files in Windows, one a 320x192x16 graphics file and the other 640x192x2. I then used a file editor to display the created headers to compare with the information in the Rimmer book.
There is one final complication, palette colors. Both the Coco and Windows have default palettes which shouldn’t be expected to be the same. Even if they were, there is no reason to expect that a Coco program should be using the default palette colors. Just to ice the cake, there is no way to tell automatically which HSCREEN mode the Coco is in after it returns to text mode. The mode information is stored at $E6 but gets changed on a return to text mode. There is no automatic method in Basic to determine whether the color set is RGB or composite. This requires several compromises in the program I finally developed. The user must inform my program of the correct HSCREEN mode used for the graphic image, whether the colors are RGB or CMP, and the program which produced the graphic must not change the palette colors on exit. For example, if the only way to stop the graphics program is to hit the RESET button and the Coco reboots, you will lose the palette colors.
Below are HSAVE.BAS, HSAVE.ASM, and HSAVE.BIN. These programs will create, on the default drive, a file with the BMP extension which has the correct BMP header with colors obtained by reading the Coco palette registers. All the reader needs to do is transfer the file from the Coco to a Windows computer.
Here is something else to consider. Following the above logic, you should be able to use graphics editor to take any Windows graphic, convert it to a 16 color BMP file, resize it to fit 320x192, transfer it to a Coco disk, and load the data into Coco graphics memory. This will be discussed in detail in Part III.
How Does It Work?
The loader program HSAVE.BAS is very short and simple.
10 DRIVE3 20 LOADM"HSAVE":POKE&HE9,0:’ POKE&HE9,1 FOR CMP 30 INPUT"INPUT FILE NAME WITHOUT EXTENSION";NAME$ 40 OPEN"O",#1,NAME$+".BMP" 50 INPUT"SELECT THE CORRECT MODE (2 OR 3): ";MODE 60 POKE&HE6,MODE 70 EXECIt’s only purpose is to get the machine language program into memory, ask the user for a file name (which it then creates), and ask the user for the HSCREEN mode and color type of the graphic. The main program HSAVE.BIN uses the following structure.
1) Set Basic to route all output to path #1, the disk file initialized by HSAVE.BAS 2) Test $E6 for the HSCREEN mode, set the file size defaults, and send the correct BMP header to the disk file. 3) Split the palette register information into the RGB components. CMP colors will be translated to RGB as needed. Expand the RGB values from 0-3 to 0-255 for typical VGA hardware. 4) Write the palette information to disk. 5) Get the correct MMU blocks of memory and send the information to the disk file in the correct line order. 6) Restore the MMU register, close the disk file, and restore the output path to the screen. 00100 * CONVERT HSCREEN TO .BMP FOR MODES 2&3 ONLY 00110 * (c) Robert Gault, Feb 1999 00120 ORG $E00 00130 START LDD #$103 DISK BUFFER #1, LDB #3 00140 STA $6F SET CONSOLE OUT 00150 LDA $E6 GET GRAPHICS MODE 00160 LEAX MODE,PCR POINT TO MODE TABLE 00170 CMPA #2 HSCREEN2 00180 LBLO ERROR 00190 CMPA #3 HSCREEN3 00200 LBHI ERROR 00210 SUBA #2 CREATE AN OFFSET 00220 MUL 00230 ABX UPDATE REG.X 00240 LDD ,X++ 00250 STD COLORS,PCR SET COLOR COUNT AND LINE SIZE 00260 LDD ,X++ 00270 STD SIZE,PCR SET PICTURE SIZE 00280 LDX ,X 00290 LEAX START,X GET PCR ADDRESS OF CORRECT HEADER 00300 LDB #HEAD2-HEAD16 GET HEADER SIZE 00310 C@ LDA ,X+ SEND HEADER TO DISK FILE 00320 JSR [$A002] CONSOLE OUT 00330 DECB 00340 BNE C@ 00350 LEAX CMP,PCR 00360 LDY #$FFB0 00370 D@ LDA ,Y 00380 LBSR CMPRGB 00390 ANDA #%1001 GET THE BLUE COMPONENT 00400 LBSR RGB 00410 LDA ,Y 00420 LBSR CMPRGB 00430 ANDA #%10010 GET THE GREEN COMPONENT 00440 LSRA 00450 LBSR RGB 00460 LDA ,Y+ 00470 LBSR CMPRGB 00480 ANDA #%100100 GET THE RED COMPONENT 00490 LSRA 00500 LSRA 00510 LBSR RGB 00520 CLRA EXTRA BYTE REQUIRED 00530 JSR [$A002] 00540 DEC COLORS,PCR 00550 BNE D@ 00560 * GET FOUR BLOCKS OF HIRES GRAPHICS AND SEND TO FILE 00570 LEAU LINE,PCR 00580 LDB WLINE,PCR 00590 STB LCOUNT,PCR 00600 CMPB #80 00610 BEQ S@ 00620 LDA #$33 00630 STA $FFA2 00640 LDX #$5800 00650 LDY #$1800 00660 BSR SEND 00670 LDA #$32 00680 BSR SEND2 00690 LDA #$31 00700 BSR SEND2 00710 LDA #$30 00720 BSR SEND2 00730 * RESET MMU REGISTER 00740 Z@ LDA #$3A 00750 STA $FFA2 00760 JSR $173 00770 CLR $6F SET CONSOLE OUT FOR SCREEN 00780 RTS 00790 S@ LDY #$1C00 00800 LDX #$5C00 00810 LDA #$31 00820 STA $FFA2 00830 BSR SEND 00840 LDA #$30 00850 BSR SEND2 00860 BRA Z@ 00870 00880 SEND2 STA $FFA2 00890 LDY #$2000 00900 LDX #$6000 00910 SEND LDA ,-X 00920 STA ,U+ 00930 LEAY -1,Y 00940 BNE D@ 00950 DEC LCOUNT,PCR 00960 BNE B@ 00970 BRA C@ 00980 B@ RTS 00990 D@ DEC LCOUNT,PCR 01000 BNE SEND 01010 C@ LDB WLINE,PCR 01020 STB LCOUNT,PCR 01030 A@ LDA ,-U 01040 JSR [$A002] 01050 DECB 01060 BNE A@ 01070 CMPY #0 01080 BNE E@ 01090 RTS 01100 E@ LEAU LINE,PCR 01110 BRA SEND 01120 01130 CMPRGB TST $E9 01140 BEQ A@ 01150 LDA A,X 01160 A@ RTS 01170 01180 CMP FCB 0,21,2,20,49,6,35,4,33,5,14,12,1,10,3,28 01190 FCB 7,17,18,22,48,34,32,37,44,40,42,13,8,11 01200 FCB 24,26,56,19,16,50,54,52,38,36,46,45,41 01210 FCB 15,9,25,27,30,63,58,23,51,55,53,39,60,47 01220 FCB 61,43,57,29,31,59,62 01230 * .BMP HEADERS WITHOUT PALETTE DATA 01240 HEAD16 FCB $42,$4D,$76,$78,$00,$00,$00,$00,$00,$00 01250 FCB $76,$00,$00,$00,$28,$00,$00,$00,$40,$01 01260 FCB $00,$00,$C0,$00,$00,$00,$01,$00,$04,$00 01270 FCB $00,$00,$00,$00,$00,$78,$00,$00,$00,$00 01280 FCB $00,$00,$00,$00,$00,$00,$10,$00,$00,$00 01290 FCB $10,$00,$00,$00 01300 HEAD2 FCB $42,$4D,$3E,$3C,$00,$00,$00,$00,$00,$00 01310 FCB $3E,$00,$00,$00,$28,$00,$00,$00,$80,$02 01320 FCB $00,$00,$C0,$00,$00,$00,$01,$00,$01,$00 01330 FCB $00,$00,$00,$00,$00,$3C,$00,$00,$00,$00 01340 FCB $00,$00,$00,$00,$00,$00,$02,$00,$00,$00 01350 FCB $02,$00,$00,$00 01360 01370 ERROR CLR $6F 01380 LEAX MESG-1,PCR 01390 JMP $B99C 01400 MESG FCC /SORRY BUT THERE IS NO MATCHING MODE!/ 01410 FCB 0 01420 01430 RGB CLRB 01440 TSTA 01450 BEQ A@ 01460 LDB #$55 01470 CMPA #1 01480 BEQ A@ 01490 LDB #$AA 01500 CMPA #8 01510 BEQ A@ 01520 LDB #$FF 01530 A@ TFR B,A 01540 JMP [$A002] 01550 01560 SIZE RMB 2 01570 COLORS RMB 1 01580 WLINE RMB 1 01590 MODE FDB $10A0,$7800,HEAD16-START,$250,$3C00,HEAD2-START 01600 LCOUNT RMB 1 01610 LINE RMB 160 01620 END START