Hi-Res Coco3 Graphics to BMP and Back Again

Part III

by Robert Gault

This time we are going to look at a method to display BMP files on the Coco. This will not be a completely automatic process. First the graphics files must be converted with a graphics editor on your Windows computer to a 320x225x16 format. That is not too much to ask as there are several good editors that can be obtained from the internet for free.

Converting your files to a constant format greatly simplifies the task of writing a program to display them on the Coco. Other more complex programs are available for both OS-9 and Basic that do not require file pretreatment but these have code too complex to make a good article for a magazine.

Below your will find HLOAD.BAS and HLOAD.ASM. As in Part II, the Basic program is just a short loader for HLOAD.BIN and queries the user for a file name. The flow in HLOAD.BIN is as follows:

1) Set the input path to #1, the disk file initialized by the loader.
2) Skip through the header bytes and read the graphics mode. Test for 1 or 4 bit color and exit with an error if neither.
3) Adjust screen size and line width based on the file mode and inform Basic.
4) Initiate the correct HSCREEN mode.
5) Read the palette colors from the file and convert them into palette sets (see text)
6) Initialize the Coco palette with temporary colors to use during loading.
7) Load into memory the pixel data.
8) Initiate palette swaping to increase the color range from 64 to as many as 1000 possible colors.

Most of the above was discussed going from Coco to Windows in Part II. What will be new here is a technique for displaying a palette range greater than 64 colors. Oldtimers with the Coco will remember that there have been Coco digitizers since the early ‘80s. One unit, RASCAN, had a most unusual option. It displayed pictures in color in a "4096" color mode with the claim that 4096 colors could be on screen at one time. This was achieved with a hardware separation of a color image into red, green, and blue components, which were displayed in dithered gray scale on three separate screens. On command, these screens were flipped through at a rate of 60Hz while changing the palette selection such that you saw alternately red, green, and blue screens. The composite effect was full color with a pronounced flicker.

An OS-9 program, viewgif, uses a two screen flicker and blends two color images which are close to but not the correct colors. The blend looks correct and the flicker is greatly reduced and almost not noticeable.

These methods work because our eyes are RGB devices. We see using light sensitive nerve cells located on the retina, the back surface of the eye. There are two type of optic nerves cones (color vision) and rods (nightime black and white). There are three types of cone cells distinguished by pigmentation which absorbs light of one of three colors, red, green, or blue. Therefore any method of blending red, green, or blue light will permit us to see in full color.

There is one more method that the Coco can use to blend color (excluding dithering which I won’t discuss) which is to have a single picture screen and change only the palette registers. There is an advantage in this method over the two just described in that less memory is used. The disadvantage is minimal consisting of a decrease in palette range but it occurs only because dithering is not used as it is in RASCAN or viewgif. Nevertheless, any 16 colors from a range of 1000 can be used per picture with a three palette flicker.

HLOAD offers two options chosen during the assembly process. You can choose the three palette cycle and get 1000 colors with noticeable flicker or a two palette cycle, 100 colors, and very little flicker. I have found the best choice depends on the picture being viewed. The obvious approach is to assemble both ways and select the method at run time.

Caveats

Note that the code in Part 1 saves a 320 by 192 image while the code here loads a 320 by 225 image. If you should want to reload saved images, you should modify HLOAD.ASM for a 320 by 192 screen.

Both HSAVE.ASM and HLOAD.ASM will attempt both RGB and CMP color sets. I stand by the picture quality of the RGB option but not the CMP. The translation table is from Spectral Associates book "Super Extended Basic Unravelled." I could never get satifactory colors on my composite monitor using this table. But if you read the explanation of RGB vs CMP colors in Part 1, you may believe as I do that the task is almost hopeless.
 

10 DRIVE3:POKE&HE9,0:' 0=RGB 1=CMP
20 LOADM"HLOAD":' TRY COMPILING BOTH 2 & 3 PALETTE FLICKER
30 ONBRK GOTO70
40 PRINT:INPUT"INPUT FILE NAME WITHOUT EXTENSION";NAME$
50 OPEN"I",#1,NAME$+".BMP"
60 EXEC
70 RGB:PRINT"CONTINUE (Y OR N) ";
80 A$=INKEY$:IFA$="Y"THEN40ELSEIFA$=""THEN80

00100 * CONVERT BMP TO HGRAPHICS SCREEN 
00110 * SINGLE SCREEN WITH 2 OR 3 PALETTE FLIPS PER CYCLE
00120 * (C) ROBERT GAULT FEB 1999
00130 
00140 * SET CYCLE TO 2 OR 3 TO DETERMINE MODE OF ACTION
00150 CYCLE     EQU     3
00160 
00170           ORG     $E00
00180 START     LDD     #$11D           DISK BUFFER #1, COUNT = 29
00190           STA     $6F             SET CONSOLE OUT
00200 A@        JSR     $A176           SKIP 28 BYTES IN HEADER, KEEP 29
00210           DECB
00220           BNE     A@
00230           PSHS    A               SAVE DATA
00240 * DETERMINE THE BMP MODE
00250           LDD     #$10A0          16 COLORS, 160 BYTES PER LINE
00260           STA     COLORS,PCR
00270           STB     WLINE,PCR
00280           LDB     #2              HSCREEN MODE
00290           STB     $E6             TELL BASIC
00300           LDA     ,S
00310           CMPA    #4              IS THIS MODE 2?
00320           LBHI    ERROR
00330           BEQ     B@
00340           LDD     #$5002          BYTES PER LINE, COLOR COUNT
00350           STB     COLORS,PCR
00360           INCB
00370           STB     $E6             TELL BASIC THE HSCREEN MODE
00380           STA     WLINE,PCR
00390           LDA     ,S
00400           CMPA    #1              IS THIS MODE 3?
00410           LBNE    ERROR
00420 B@        LEAS    1,S
00430           JSR     $E6A5           SET HSCREEN
00440           LDA     #%1111110       $7E
00450           STA     $FF99           SET 320X225X16
00460           LDB     #25             SKIP TO PALETTE COLORS
00470 C@        JSR     $A176           CONSOLE IN
00480           DECB
00490           BNE     C@
00500           LEAY    PALET,PCR
00510 D@        LEAX    DECODE,PCR      POINT TO DECODER TABLE
00520           LBSR    RGB             GET BLUE VALUE
00530           LDA     ,X+             SET PALETTES
00540           STA     ,Y
00550           LDA     ,X+
00560           STA     16,Y
00570           COND    CYCLE.EQU.3
00580           LDA     ,X
00590           STA     32,Y
00600           LEAX    DECODE+30,PCR
00610           ENDC
00620           COND    CYCLE.EQU.2
00630           LEAX    DECODE+14,PCR
00640           ENDC
00650           LBSR    RGB             GET GREEN VALUE
00660           LBSR    TRANSL          COMBINE WITH BLUE
00670           COND    CYCLE.EQU.3
00680           LEAX    DECODE+60,PCR
00690           ENDC
00700           COND    CYCLE.EQU.2
00710           LEAX    DECODE+28,PCR
00720           ENDC
00730           LBSR    RGB             GET RED VALUE
00740           LBSR    TRANSL          COMBINE WITH BLUE GREEN
00750           JSR     $A176           SKIP A BYTE
00760           LEAY    1,Y             UPDATE POINTER
00770           DEC     COLORS,PCR
00780           BNE     D@
00790           TST     $E9
00800           BEQ     R@
00810           LBSR    RGBCMP          CONVERT THE RGB COLORS TO CMP
00820 R@        LBSR    LDSCRN          SET INITIAL PALETTE COLORS
00830 * GET FOUR BLOCKS OF HIRES GRAPHICS AND SEND TO SCREEN
00840           LDB     WLINE,PCR       GET THE SCREEN WIDTH IN BYTES
00850           STB     LCOUNT,PCR
00860           LEAU    LINE,PCR        POINT TO REVERSAL BUFFER
00870           CMPB    #160            HSCREEN2 BYTE WIDTH
00880           BNE     S@
00890           LDA     #$34            MMU BLOCK NUMBER
00900           STA     $FFA2           $4000-$6000
00910           LDX     #$4CA0          END OF SCREEN +1
00920           LDY     #$CA0           BYTES IN LAST BLOCK
00930           BSR     SEND            MOVE THE SCREEN DATA
00940           LDA     #$33            NEXT BLOCK NUMBER
00950           BSR     MMUSET
00960           BSR     SEND2
00970           LDA     #$32
00980           BSR     MMUSET
00990           BSR     SEND2
01000           LDA     #$31
01010           BSR     MMUSET
01020           BSR     SEND2
01030           LDA     #$30
01040           BSR     MMUSET
01050           BSR     SEND2
01060 * RESET MMU REGISTER
01070 X@        LDA     #$3A
01080           STA     $FFA2
01090           CLR     $6F             SET CONSOLE OUT FOR SCREEN
01100           LBRA    FLIP            NOW DISPLAY THE PICTURE AND FLIP THE PALETTE
01110 S@        LDX     #$4650          POINTERS FOR HSCREEN3
01120           LDY     #$650
01130           LDA     #$32
01140           STA     $FFA2
01150           BSR     SEND
01160           LDA     #$31
01170           BSR     MMUSET
01180           BSR     SEND2
01190           LDA     #$30
01200           BSR     MMUSET
01210           BSR     SEND2
01220           BRA     X@
01230 
01240 MMUSET    STA     $FFA2
01250           LDX     #$6000
01260           LDY     #$2000
01270           RTS
01280 
01290 SEND      JSR     $A176           CONSOLE IN
01300           STA     ,U+             STORE IN BUFFER
01310           DEC     LCOUNT,PCR
01320           BNE     SEND
01330           LDB     WLINE,PCR
01340           STB     LCOUNT,PCR      RESET COUNTER
01350 SEND2     LDA     ,-U             MOVE BUFFER TO MEMORY
01360           STA     ,-X             INVERTS SCREEN ABOUT HORIZON
01370           LEAY    -1,Y            FILLED MMU BLOCK?
01380           BNE     C@
01390           DECB
01400           RTS
01410 C@        DECB
01420           BNE     SEND2
01430           LEAU    LINE,PCR        DO ANOTHER SCREEN LINE
01440           BRA     SEND
01450 
01460 TRANSL    LDA     ,X+             FILL PALETTE TRIFOLD
01470           ORA     ,Y
01480           STA     ,Y
01490           LDA     ,X+
01500           ORA     16,Y
01510           STA     16,Y
01520           COND    CYCLE.EQU.3
01530           LDA     ,X
01540           ORA     32,Y
01550           STA     32,Y
01560           ENDC
01570           RTS
01580 
01590 COLORS    RMB     1
01600 
01610 ERROR     CLR     $6F
01620           LEAS    1,S           RESET STACK, SEE START OF PROGRAM
01630           LEAX    MESG-1,PCR
01640           JMP     $B99C         PRINT ERROR AND RETURN TO BASIC
01650 MESG      FCC     /SORRY BUT THERE IS NO MATCHING MODE!/
01660           FCB     0
01670 
01680 RGB       JSR     $A176
01690           PSHS    X,B
01700           LEAX    INTENS,PCR
01710           COND    CYCLE.EQU.3
01720           LDB     #9
01730           ENDC
01740           COND    CYCLE.EQU.2
01750           LDB     #6
01760           ENDC
01770           CLR     ,S
01780 A@        CMPA    ,X+
01790           BLO     B@
01800           INC     ,S
01810           DECB
01820           BNE     A@
01830 B@        LDB     ,S+
01840           COND    CYCLE.EQU.3
01850           LDA     #3
01860           MUL
01870           ENDC
01880           COND    CYCLE.EQU.2
01890           LSLB
01900           ENDC
01910           PULS    X
01920           ABX
01930           RTS
01940           COND    CYCLE.EQU.3
01950 INTENS    FCB     14,43,71,100,128,156,185,213,242
01960           ENDC
01970           COND    CYCLE.EQU.2
01980 INTENS    FCB     21,64,107,149,192,235
01990           ENDC
02000 
02010 LDSCRN    LEAX    PALET,PCR       GET TEMPORARY PALETTE COLORS
02020           LDY     #$FFB0
02030           LDB     #16
02040 A@        LDA     ,X
02050           STA     ,Y+
02060           LEAX    1,X
02070           DECB
02080           BNE     A@
02090           RTS
02100 
02110 PALET     RMB     16      *BLUE
02120           RMB     16      *GREEN
02130           RMB     16      *RED
02140           COND    CYCLE.EQU.3
02150 * RGB BLUE
02160 DECODE    FCB     00,00,00,01,00,00,01,01,00,01,01,01,08,01,01
02170           FCB     08,08,01,08,08,08,09,08,08,09,09,08,09,09,09
02180 * RGB GREEN
02190           FCB     00,00,00,00,00,02,00,02,02,02,02,02,02,02,16
02200           FCB     16,02,16,16,16,16,16,18,16,16,18,18,18,18,18
02210 * RGB RED
02220           FCB     00,00,00,00,04,00,00,04,04,00,04,04,04,32,04
02230           FCB     04,32,32,32,32,32,36,32,32,36,36,32,36,36,36
02240           ENDC
02250           COND    CYCLE.EQU.2
02260 DECODE    FCB     00,00,01,00,01,01,08,01
02270           FCB     08,08,09,08,09,09
02280 
02290           FCB     00,00,02,00,02,02,02,16
02300           FCB     16,16,16,18,18,18
02310 
02320           FCB     00,00,04,00,04,04,32,04
02330           FCB     32,32,36,32,36,36
02340           ENDC
02350 
02360 RGBCMP    LEAX    PALET,PCR
02370           LEAY    CMP,PCR
02380           LDB     #16
02390 A@        LDA     ,X
02400           LDA     A,Y
02410           STA     ,X
02420           LDA     16,X
02430           LDA     A,Y
02440           STA     16,X
02450           COND    CYCLE.EQU.3
02460           LDA     32,X
02470           LDA     A,Y
02480           STA     32,X
02490           ENDC
02500           LEAX    1,X
02510           DECB
02520           BNE     A@
02530           RTS
02540 
02550 CMP       FCB     0,12,2,14,7,9,5,16,28,44,13,29,11,27,10,43
02560           FCB     18,17,34,33,3,1,19,50,30,45,31,46,15,60,47
02570           FCB     61,23,8,21,6,39,24,38,54,25,42,26,58,24,41
02580           FCB     40,56,20,4,35,51,37,53,36,52,32,59,49,62,55
02590           FCB     57,63,48
02600 
02610 LCOUNT    RMB     1
02620 
02630 *THREE-COLOR COLOR SYSTEM FOR THE COCO 320 MODE
02640 *SELECTABLE FOR RGB OR CMP COLORS
02650 
02660 FLIP      ORCC    #$50
02670           LDD     #$FF
02680           STA     $FF40
02690           STS     STACK,PCR
02700           BSR     CLOCK
02710           STA     $FFD9   SET FAST CPU CLOCK
02720           LDA     #$7B    SETUP FAST KEY TEST
02730           STA     $FF02
02740 LOOP      BSR     PAL1
02750           BSR     PAL2
02760           COND    CYCLE.EQU.3
02770           BSR     PAL3
02780           ENDC
02790           BSR     KEYS
02800           BCS     A@
02810           BEQ     LOOP    NO KEYS
02820 A@        BRA     EXIT
02830 
02840 STACK     RMB     2
02850 SPEED     RMB     1
02860 
02870 EXIT      CLRA
02880           STA     $E6
02890 A@        BSR     KEYS
02900           BNE     A@
02910           JSR     $E019
02920           JSR     $173
02930           LDX     #$FFD8
02940           LDA     SPEED,PCR
02950           STA     A,X     SET CPU CLOCK SPEED
02960           LDS     STACK,PCR
02970           ANDCC   #$AF
02980           RTS
02990 
03000 * FAST KEY TEST FOR COLOR OR EXIT; SPACEBAR OR BREAK
03010 
03020 KEYS      LDA     $FF00
03030           COMA
03040           LSLA
03050           LSLA
03060           RTS
03070 
03080 *$FF9D-$FF9E = VERTICAL OFFSET
03090 
03100 PAL1      BSR     VSYNC
03110           LEAX    PALET,PCR
03120           BRA     STORE
03130 
03140 PAL2      BSR     VSYNC
03150           LEAX    PALET+16,PCR
03160           BRA     STORE
03170 
03180 PAL3      BSR     VSYNC
03190           LEAX    PALET+32,PCR
03200           BRA     STORE
03210 
03220 STORE     LDB     #16
03230           LDY     #$FFB0
03240 A@        LDA     ,X+
03250           STA     ,Y+
03260           DECB
03270           BNE     A@
03280           RTS
03290 FLAG      RMB     1
03300 
03310 VSYNC     LDA     $FF02
03320 VLOOP     LDA     $FF03
03330           BPL     VLOOP
03340           LDA     $FF02
03350           RTS
03360 
03370 CLOCK     CLRB
03380           BSR     VSYNC
03390           LDA     $FF00
03400 CKLOOP    INCB
03410           LDA     $FF01
03420           BPL     CKLOOP
03430           CLRA
03440           CMPB    #6
03450           BLO     SETSPD
03460           INCA
03470 SETSPD    STA     SPEED,PCR
03480           RTS
03490 
03500 WLINE     RMB     1
03510 SIZE      RMB     2
03520 LINE      RMB     160
03530 
03540           END     START