Hi-Res Coco3 Graphics to BMP and Back Again

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 EXEC
It’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