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 DRIVE3It’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.
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
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