Classic Computer Magazine Archive Article from Atari Classics magazine

MORE ABOUT COLORVIEW 2.6

By Jeff Potter AC Graphics & Entertainment Editor

COLRVIEW Revisited
    My thanks to all those who responded to the first article on COLRVIEW in the June '93 issue of AC. In this article I'll discuss where to find some COLRVIEW images, as well as what some other programmers (and myself) are up to with respect to new uses for COLRVIEW. I'll finish up by giving some technical details on how to write your own programs to experiment with COLRVIEW.

Finding COLRVIEW Pictures
    The GEnie Atari 8-bit bulletin board recently moved all the COLRVIEW images and utilities to area 20, thanks to the work of sysop Craig S. Thom. Over 100 picture files have been uploaded there, courtesy of BB members. Over 50 of these have been uploaded by ANIMATSURI, also known as Wendell Hong. These are primarily Japanese Anime' images which Wendell has converted from GIF format, and are excellent at showing the clarity and saturation of colors offered by your 8-bit machine. My thanks to Wendell and the other contributors to this collection!
    Also check out the Atari Star BBS at 305-868-0211 (7pm to 6am Eastern time) in the Miami, Florida area. Sysop Guy Ferrante has a fair collection of COLRVIEW pictures (in ARC format) in file area 9, which he either downloaded or converted from GIF pictures. While you're at it, check out your local bulletin board system; if it's been around a few years it's bound to have a collection of COLRVIEW pictures.
    To those Atari 8-bit owners out there who don't telecommunicate: I would seriously consider obtaining a modem. You'll discover a whole new world of applications for your 8-bit, and communicate with a multitude of other Atari owners. I wouldn't consider my system complete if I didn't have a modem! The direct-connect SX-212 is available very inexpensively (but you may have to hunt around to find one). Lacking that modem, you must obtain an Atari 850 or ICD P:R:Connection (or some other third-party serial bus to RS232 interface) and any manufacturer's modem. Excellent Shareware terminal programs exist (check out BobTerm 1.22). Don't put it off...

Other Software
    E. Halliwell saw my COLRVIEW program some time ago and set out to correct some shortcomings in it. Namely, the three large files take up a lot of disk space, and there's no way for the viewer program to tell what resolution (GR.9 or GR. 15) the image was stored in. So he created CVSQUASH, which reads in the.R/.G/.B files, lets you set the graphics mode, lets you add a caption, and stores one (smaller) file using a run-length encoding form of compression. He then created a companion "slide show" program (CSVIEW), with a friendly user interface, that lets you view these compressed (.RGB) files one after another with a programmable delay. Both programs were written in a mixture of BASIC and machine language USR calls, so the compressing and decompressing both run very fast. These programs are available in the GEnie Atari 8-bit files area (including source code), and are shareware. The author can be reached at:
    Clay Halliwell
    407 S. 2nd Street
    Clinton, MO 64735-2107

    Adam Conover has created "Fractasia", a program that can create images of the famous Mandelbrot set. These images can be in any of several modes including COLRVIEW (you must use the original COLRVIEW program to view them, however). For those of you unfamiliar with fractal geometry, this program calculates an interesting equation in two dimensions which is like a world within itself with its incredible detail. Using this program, you can select an area of the screen to "zoom in", and recalculate. Each time you zoom in, you discover interesting nooks and crannies, and fascinating curling structures that are all part of one simple equation. No matter how fine you zoom in on the screen, more detail awaits you when it is plotted. Fractasia is written in compiled TurboBASIC, for XL/XE machines (must have 64k), and is available from the Internet archives on atari.archive.umich.edu (see atari/8bit/fracl.arc and atari/8bit/frac1arc), or directly from Adam. Fractasia is released as shareware. The author can be reached at:
    Adam Conover
    90 Plum St.
    Greenville, PA 16125

    The original APACVIEW was too large a program to attempt both GIF decoding and displaying in COLRVIEW mode. This was due to several (little-used) subroutines that tended to take a lot of room, and the general lack of memory on the old 48K Ataris. In my next program now in development, JVIEW XL, I will utilize the extra memory in the 64K and larger XL/XE series Ataris. This program will be able to read and decode GIF files and display them directly in COLRVIEW mode. You'll also have the option of saving the files in regular (.R/.G/.B) format, or compressed (.RGB) using routines borrowed from Clay Halliwell's CVSQUASH. And in response to several peoples' requests, JVIEW will also decode to GR. 8 COLRVIEW, which has 320Hx192V pixels with eight colors per pixel.

Technical Details Of COLRVIEW
    I won't delve into detail on how Atari display lists and display list interrupts work here. I'll refer you to one of several texts that include good descriptions (among them De Re Atari, the Atari Technical Reference Notes, COMPUTE!s series of books, etc.).
    There are two ways to arrange the display list(s) to produce the COLRVIEW effect. One way is to store the color data in three RAM areas, separated by color. With this method you would need three display lists, and each display list would do a Load Memory Scan (LMS) instruction for every line. The LMS instructions within each display list would rotate among the red, green, and blue screen RAM areas. A Vertical Blank Interrupt (VBI) selects one of the three display lists at the start of each field. A display list interrupt (DLI) loads the color registers correctly to "paint" the correct color on a per-line basis. This is the way Clay Halliwell's CSVIEW creates the COLRVIEW displays; his source code is available on GEnie.
    I considered using this method in my programs, but realized it used a lot of memory dedicated to display lists alone (over 1700 bytes). That, plus each display list must not cross a 1024 byte boundary in RAM (a limitation of the ANTIC display IC). Instead, I selected the other method: arranging the screen areas not by color, but in the order shown in the diagram from the first article (where the first screen goes RGBRGB, the second one goes GBRGBR, the third BRGBRG). Then I only need one display list which I modify in the Vertical Blank Interrupt (VBI) to change just the starting address and the midpoint address. I initially load the entire red, green, and blue data into three separate screens (7680 bytes each). I then "shuffle" the data to put it in red/green/blue "line" order. In this way, the display list can be quite simple, as I don't have to do a Load Memory Scan (LMS) on every line.
    With either method, a Display List Interrupt (DLI) must be running constantly to change the background color (for GR.9) or all four colors (for GR.15) on every raster line. Although my method is a little harder to understand, I describe it here because it's the method I chose to implement. I'll include the subroutine I use to shuffle from one representation (red, green, blue screens in contiguous memory) to the other (first, second, and third screens in contiguous memory).
    Bear in mind my discussion here is meant for the assembly language programmer. The subroutines presented here can be dropped in place around another program, but they can't stand alone. So, let's get started... .

Display List & Interrupt Routines
    My display list has 16 blank lines at the beginning, the last one containing a DLI. Only one DLI is actually called for the entire screen, since it runs continuously during the display period (leaving no time for any other process to execute). This locks out things like serial I/O, preventing you from doing neat things like loading another picture while you display one, or doing modem communication. Oh well, compromises have to be made in the name of 4096 colors!
    I then do a single LMS in the selected graphics mode (9, 15, or maybe 8) and give the starting address of one of my three screens. The next 95 bytes can be ordinary display instructions. The display list breaks before the 97th line to do another LMS instruction. That's because ANTIC can't allow screen memory to cross a 4-kilobyte memory boundary. So I always arrange my screen memory to split nicely in half, with 96 lines before a 4K boundary, and 96 lines after one. After this we can include another 95 bytes of display instructions. At the end we do a "Jump on Vertical Blank" type instruction, and point to the beginning of the display list. Simple enough...
    For the purpose of keeping track of which screen is being displayed, I created a variable called FLAG. This variable is incremented in the VBI, is clamped so it always remains between 0 and 2, and used as an index into a small table of screen memory starting addresses. I load the starting and midpoint addresses from this table, and poke them into my display list just after the two LMS instructions (at line 0 and 96). The VBI routine ends by calling the (immediate mode) system vertical blank routine (SYSVBV).
    The DLI routines also depend on FLAG to tell them what the starting line's color is going to be. From that point on the DLIs rotate changing the appropriate color registers from red to green to blue in order. A line counter ensures that only 192 lines will be processed in this way, and the STA WSYNC ensures that the color register(s) are only changed during horizontal retrace, where you can't see it happening.

Loading And Shuffling
    I'll assume you want to write a program to load or create COLRVIEW screens. The constants TOPSCX, TOPSCY, and TOPSCZ describe the starting address of the three color screens. You would load your three files into these areas (red, green, blue, respectively), call SHUFFL to shuffle them into the correct order, then turn ColrView on. After you're done viewing this picture, you would turn COLRVIEW off to disable all the VBI and DLIs. To restore the three color screens to contiguous blocks of red, green, and blue, merely call SHUFFL two more times.

Turning COLRVIEW On/Off
    If you always load the same mode (GR.9, 15, or 8) files, you don't have to modify the display list. Otherwise you might have to write a routine to detect the graphics mode has changed and go through the display list to change the LMS and display instructions. See the listing of the display list for details.
    Next you would JSR CVON. This routine first saves the current addresses of the display list and VBI routines, changes the ANTIC pointers to point to the custom display list, and sets the GTIA mode if necessary. It calls the system routine SETVBV, which ensures the vertical blank interrupt is correctly set in time for the next vertical blank interval. CVON then sets up the display list interrupt, and enables both VBIs and DLIs. Turning off COLRVIEW is done by calling CVOFF. This first turns off the VBIs and DLIs, so you can safely redirect the VBI pointers without fear of crashing. Then it restores the old display list and VBI routines, and turns off the GTIA mode. It then allows VBIs once again and exits.

Wrapping Up
    These subroutines have been plucked right from my working source code, so they should work correctly. But in the course of transcribing and submitting for publishing, there's always a chance something won't work. If you get stuck trying to use them, drop me a letter or some e-mail. I'll do what I can to help.
    I hope this helped some of you to gain a more thorough understanding of COLRVIEW. I hope to see more of you writing applications with it in the future. Good luck!

;**********************************
; COLRVIEW subroutines for
; Atari Classics
; by Jeff Potter Aug. 17, 1993
; CIS: 74030,2020 GEnie: JDPOTTER
; Internet: potter@sunny.dab.ge.com
;
;**********************************
; Display list, GR.9 COLRVIEW
; Caution: don't allow this to
; cross a 1K boundary.
; Same display list works for GR.8.
; For GR.15, change $4F to $4E and
; $0F to $0E below.
;**********************************
;
DLLIST: DB $70,$30,$B0         ;16 blanks, DLL
        DB $4F                 ;LMS GR.8/9
DLTOP:  DW TOPSCX              ;starting adrs
        DB $0F,$0F,$0F,$0F,$0F ;GR. 0/9
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
;
        DB $4F                 ;LMS GR.8/9
DLMID:  DW MIDSCX              ;mid-scrn adrs
        DB $0F,$0F,$0F,$0F,$0F ;GR. 0/9
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
        DB $0F,$0F,$0F,$0F,$0F
;
        DB $41                 ;Jump on VBI
        DW DLLIST              ;back to top
;
;**********************************
; Vertical Blank Service Routine
;**********************************
;
MYVBI:  PHA
        TXA
        PHA
;
; increment flag byte
;
        INC FLAG
        LDA FLAG
        CMP #3
        BCC OK
;
        LDA #0
        STA FLAG
;
; Redirect display list to point
; to appropriate screen area
;
OK      ASL A
        TAX
        LDA TOPSCR,X
        STA DLTOP
        LDA TOPSCR+1,X
        STA DLTOP+1
;
        LDA MIDSCR,X
        STA DLMID
        LDA MIDSCR+I,X
        STA DLMID+1
;
        PLA
        TAX
        PLA
        JMP SYSVBV;exit(im.mode)
;
;**********************************
; Display List Interrupt Routine
; Graphics 9, colrview
;**********************************
;
DLI1:   PHA
        TXA
        PHA
;
        LDX #192
        SEC
        LDA FLAG
        BEQ THRED        ;0
        SBC #1
        BEQ THGRN        ;1
        BNE THBLU        ;2
;
THRED   LDA #$30
        STA WSYNC
        STA COLBK
        DEX
        BEQ OUT9
;
THGRN   LDA #$D0
        STA WSYNC
        STA COLBK
        DEX
        BEQ OUT9
;
THBLU   LDA #$80
        STA WSYNC
        STA COLBK
        DEX
        BNE THRED
;
OUT9    LDA #$00

        STA WSYNC
        STA COLBK
;
        PLA

        TAX
        PLA
        RTI
;**********************************
; Display List Interrupt Routine
; Graphics 15, colrview
;**********************************
;
DLI2:   PHA
        TXA
        PHA
;
        LDX #192
        SEC
        LDA FLAG
        BEQ RED02        ;0
        SBC #1
        BEQ GRN02        ;1
        BNE BLU02        ;2
;
RED02   LDA #$36
       
STA WSYNC
        STA COLPF0
       
LDA #$3A
       
STA COLPF1
       
LDA #$3E
       
STA COLPF2
;
       
DEX
       
BEQ OUT15
;
GRN02   LDA #$D6
       
STA WSYNC
       
STA COLPF0
       
LDA #$DA
       
STA COLPF1
       
LDA #$DE
       
STA COLPF2
;
       
DEX
       
BEQ OUT15
;
BLU02   LDA #$86
       
STA WSYNC
       
STA COLPF0
       
LDA #$8A
       
STA COLPF1
       
LDA #$8E
       
STA COLPF2
;
       
DEX
       
BNE RED02
;
OUT15   LDA #0
       
STA WSYNC
       
STA COLBK
       
STA COLPF2   ;black bgnd
       
LDA #$0A
       
STA COLPF1   ;white chars
;
       
PLA
       
TAX
       
PLA
       
RTI
;
;**********************************
; Display List Interrupt Routine
; Graphics 8, colrview
;**********************************
;
DLI3:   PHA
       
TXA
       
PHA
;
       
LDX #192
       
SEC
       
LDA FLAG
       
BEQ RED8        ;0
       
SBC #1
       
BEQ GRN8        ;1
       
BNE BLU8        ;2
;
RED8    LDA #$30
       
STA WSYNC
       
STA COLPF2
       
DEX
       
BEQ OUT8
;
GRN8    LDA #$D0
       
STA WSYNC
       
STA COLPF2
       
DEX
       
BEQ OUT8
;
BLU8    LDA #$80
       
STA WSYNC
       
STA COLPF2
       
DEX
       
BNE RED8
;
OUT8    LDA #$00
       
STA WSYNC
       
STA COLPF2
;
       
PLA
       
TAX
       
PLA
       
RTI
;
;**********************************
; SHUFFL subroutine, called to
; Swap color bytes around
;**********************************
;
SHUFFL: LDA #LOW[TOPSCX]
       
STA REDPNT
       
LDA #HIGH[TOPSCX]
       
STA REDPNT+1
;
       
LDA #LOW[TOPSCY]
       
STA GRNPNT
       
LDA #HIGH[TOPSCY]
       
STA GRNPNT+1
;
       
LDA #LOW[TOPSCZ]
       
STA BLUPNT
       
LDA #HIGH[TOPSCZ]
       
STA BLUPNT+1
;
       
LDA #0
       
STA LINCNT
;
TOPP:   LDY #40
;
ROW1:   LDA (REDPNT),Y
       
STA HOLD
       
LDA (GRNPNT),Y
       
STA (REDPNT),Y
       
LDA (BLUPNT),Y
       
STA (GRNPNT),Y
       
LDA HOLD
       
STA (BLUPNT),Y
       
INY
       
CPY #80
       
BNE ROW1
;
ROW2:   LDA (BLUPNT),Y
       
STA HOLD
       
LDA (GRNPNT),Y
       
STA (BLUPNT),Y
       
LDA (REDPNT),Y
       
STA (GRNPNT),Y
       
LDA HOLD
       
STA (REDPNT),Y
       
INY
       
CPY #120
       
BNE ROW2
;
       
CLC
       
LDA REDPNT
       
ADC #120
       
STA REDPNT
       
LDA REDPNT+1
       
ADC #0
       
STA REDPNT+1
;
       
CLC
       
LDA GRNPNT
        A
DC #120
       
STA GRNPNT
       
LDA GRNPNT+1
       
ADC #0
       
STA GRNPNT+1
;
       
CLC
       
LDA BLUPNT
       
ADC #120
       
STA BLUPNT
       
LDA BLUPNT+1
       
ADC #0
       
STA BLUPNT+1
;
       
INC LINCNT
       
LDA LINCNT
       
CMP #64
       
BNE TOPP
       
RTS
;
;**********************************
; ENABLE ColrView Screen
;**********************************
; save location of current
; display list and VBI routine
;
CVON:   LDA SDLSTL
       
STA SAVDLS
       
LDA SDLSTL+1
       
STA SAVDLS+1
;
       
LDA VVBLKI
       
STA SAVVBI
       
LDA VVBLKI+1
       
STA SAVVBI+l
;
; point to custom display list
;
       
LDA #LOW[DLLIST]
       
STA SDLSTL
       
LDA #HIGH[DLLIST]
       
STA SDLSTL+1
;
       
LDA #$40   ;0 for GR.15/8
       
STA GPRIOR
       
STA PRIOR
;
;
point to VBI routine
;
       
LDY #LOW[MYVBI]
       
LDX #HIGH[MYVBI]
       
LDA #$06   ;immediate mode
       
JSR SETVBV
;
;
point to DLI routine (change
;
DLIl to 2 or 3 as required)
;
       
LDA #LOW[DLIl]
       
STA VDSLST
       
LDA #HIGH[DLI1]
       
STA VDSLST+1
;
;
enable VBIs and DLIs
;
       
LDA #$E0
       
STA NMIEN
;
       
RTS    ;that's all:
;
;**********************************
; DISABLE ColrView Screen
;**********************************
CV0FF:  LDA #$20 ;avoid changing
       
STA NMIEN;during a VBI
;