You are currently viewing Atari Coarse Scroll Demo

Atari Coarse Scroll Demo

Ever since I first learned about display lists on my Atari 65xe computer, I realized that one day I wanted to create my own Atari Coarse Scroll Demo with an enhanced coarse scrolling effect. This example demonstrates a program that allows the screen to move in any in any direction using a joystick controller. It also changes some of the characters on the screen using a process known as a Redefined Character Set

As you can learn from my Display list page, every time a GRAPHICS command is used on the Atari home computer, the ANTIC microprocessor builds a display list to create the screen affect you see. Anytime you add 16 to the GRAPHICS command, it removes the text window that appears in modes GRAPHICS 1 and above.

Atari Display List Lines

The Atari Coarse Scroll Demo program below generates a display list to the screen, fills the memory randomly with a brick wall scattered around (as a redefined character), and utilizes joystick control to scroll the screen in any direction.

For our example, I set the top line to GRAPHICS 0 to emulate a display panel. Below this the screen will contain a black background with GRAPHICS 1. This tutorial will cover the display list a little in depth if you decide not the visit the link on the page yet.

Display List in depth

As mentioned earlier, the Atari computer utilizes a microprocessor chip known as ANTIC that allows the generation of the data you see on the screen. When a display list is being created, it takes into account the overscan lines at the top of the screen. These are indicated by the number 112 (or $70 in hexadecimal), which occupy the first 3 lines (appearing as a black top border).

The next line shows a 66 ($42 in hexadecimal) to tell the ANTIC chip that a memory address will appear on the line scan line. So the two lines proceeding this will be listed in a (low/high byte) order to point to address of the beginning of screen memory.

Atari Scan Lines

After this will begin a series of repeating numbers to emulate the GRAPHICS 1 screen for each individual scan line for our Atari Coarse Scroll Demo. A scan line is a single blank line going from left to right across the screen. So each scan line you draw to the screen (by POKEing into into memory), will begin to cover the screen with black lines (when using GRAPHICS 1 and above).

Close to the end of the display list will be the number 66. This is an instruction that informs ANTIC to wait for a vertical blank before returning to the beginning of the display list. See the Atari Raster Scan page for further information and clarification.

Atari Smooth Scrolling

The Atari Coarse Scroll Demo program utilizes a process known as coarse scrolling. This runs inside a vertical blank interrupt to create a smoother effect and scrolls the individual pixels (scan lines) on the screen (54276 – hexadecimal = $D404). It was written in assembly language using the MAC/65 cartridge.

I’m hoping to evolve this eventually into a full scrolling game on the Atari 65xe home computer. It will also have the ability to run in the Altirra emulator once it is complete. It has always been a dream of mine to create an original commercial game for this system.

Finally the program code for the Atari Coarse Scroll Demo is listed below for your viewing pleasure! 

10 .OPT OBJ,NO LIST
20 ;******************************
30 ;* VBI JOYSTICK FINE SCROLLER *
40 ;* (Vertical & Horizontal *
50 ;* with redefined char set *
60 ;******************************
70 ;Created by SM on 9/15/12
80 ;
90 ;From Assembly Language Programming
100 ;for the Atari Computers
110 ;
120 ; SAVE #D:VBISCRL2.M65
130 ;
140 *= 24500
150 JMP FILL
160 ;
170 DLIST = 1536 ;where dlist is
180 HSCROL = 54276
190 SAVMSC = 88 ;disp.mem.addr
200 SDLSTL = 560 ;DL address
210 SETVBV = 58460 ;to set VB vector
220 XITVBV = 58466
230 ;
240 CHSET = 57344
250 CHBASE = 756
260 MVSRCE = 176
270 MVDEST = MVSRCE+2
280 CHRADR = MVDEST+2
290 NEWADR = 20480
300 TABLEN = 1024
310 LENPTR = 24576
320 RAMCHR = LENPTR+2
330 ;

340 FILL
350 ;
360 ;clear memory 34000+
370 ;208+132*256 = 34000
380 ;
390 LDA #208 ;get low byte
400 STA 203
410 LDA #132 ;get hi byte
420 STA 204
430 LDX #23 ;get range
440 RST LDY #0 ;fill start loc.
450 LPR LDA #0 ;clear memory
460 STA (203),Y ;begin fill
470 INY ;keep going
480 BNE LPR ;loop rnd fill
490 INC 204 ;nxt hi byte
500 DEX ;keep going
510 BNE RST ;loop back
520 ;Now fill with random
530 ;wall characters
540 LDA #208 ;get low byte
550 STA 203
560 LDA #132 ;get hi byte
570 STA 204
580 LDX #23 ;get range
590 RST2 LDY #0 ;fill start loc.
600 LPR2 LDA 53770 ;any random value
610 AND #1 ;mask bit 32
620 NOP ;#1 wall char
630 STA (203),Y ;begin fill
640 INY ;keep going
650 BNE LPR2 ;loo rnd fill
660 INC 204 ;nxt hi byte
670 DEX ;keep going
680 BNE RST2 ;loop back
690 ;

700 INIT
710 ; PLA ;keep stack neat
720 LDA #112 ;8 blank scan line
730 STA DLIST ;into the first
740 STA DLIST+1 ;3 lines of the
750 STA DLIST_2 ;display list
760 LDY #24 ;# of lines in DL
770 LDX #6 ;set counter
780 LOOP LDA #118 ;LMS+GRAPHICS 0+ scroll
790 STA DLIST,X ;into display list
800 INX ;keep counter
810 LDA SAVMSC ;get disp.mem.addr
820 STA DLIST,X ;into display list
830 INX ;keep counter going
840 LDA SAVMSC+1 ;get high byte
850 SEC ;set up subtraction
860 SBC #24 ;make room for display
870 STA DLIST,X ;into display list
880 INX ;counter is going
890 DEY ;one line done
900 LDA #118 ;LMS+horz scroll
910 STA DLIST,X ;into disp list
920 INX ;counter is going
930 LDA DLIST-3,X ;get last memory
940 CLC ;setup addition
950 ADC #250 ;line=250 bytes
960 STA DLIST,X ;into disp list
970 INX ;counter is going
980 LDA DLIST-3,X ;get last memory
990 ADC #0
1000 STA DLIST,X ;into disp list
1010 INX ;counter is going
1020 DEY ;another line done
1030 BNE LOOP ;finished? NO
1040 LDA #65 ;YES;JVB instruction
1050 STA DLIST,X ;into disp list
1060 INX ;counter is going
1070 LDA #0 ;page 6 low byte
1080 STA DLIST,X ;into disp list
1090 STA SDLSTL ;tell Atari also
1100 INX ;counter is going
1110 LDA #6 ;pg. 6 high byte
1120 STA DLIST,X ;into disp list
1130 STA SDLSTL+1 ;tell Atari
1140 ;

1150 LDA #66
1160 STA DLIST+3
1170 STA DLIST+11
1180 LDA #64
1190 STA DLIST+4
1200 LDA #156
1210 STA DLIST+5
1220 LDA #3+160+32
1230 STA 33999
1240 STA 33998
1250 LDA #52
1260 STA 708
1270 LDA #132
1280 STA 711
1290 ;
1300 JSR MOVDAT
1310 ;******************************
1320 ; insert scrolling routine into
1330 ; the deferred vertical blank
1340 ;******************************
1350 ;
1360 STVBI
1370 LDY # 1380 LDX # >VBI ;get hi byte
1390 LDA #7 ;deferred vector
1400 JSR SETVBV ;set the vector
1410 TRAP JMP TRAP

1420 ;******************************
1430 ; save accumulator and x reg
1440 ;******************************
1450 ;
1460 VBI
1470 PHA ;save accum
1480 TXA ;transfer X reg
1490 PHA ;and save it
1500 ; TYA
1510 PHA
1520 JYSTK
1530 LDA 632 ;read STICK(0)
1540 CMP #7 ;horiz scroll
1550 BEQ SCLRT ;to the right
1560 CMP #11 ;horiz scroll
1570 BEQ SCLFT ;to the left
1580 CMP #13 ;vert scroll
1590 BEQ SCDWN ;going down
1600 CMP #14 ;vert scroll
1610 BEQ SCUP ;going up
1620 JMP XITVB
1630 ;*******************************
1640 ; do the fine scrolling first
1650 ;*******************************
1660 ;
1670 SCLRT
1680 LDX #7 ;8 bits per char
1690 LP2 ; STX HSCROL ;scroll the lst
1700 DEX ;set up for next scroll
1710 BCC LP2 ;loop until 8 are
1720 ; LDX #7 ;reset scroll reg
1730 ; STX HSCROL ;to beginning

1740 ;********************************
1750 ; now we’ll coarse scroll one
1760 ;********************************
1770 LDX #0 ;counter
1780 LOOP2 LDA DLIST+4,X ;get disp mem
1790 CLC ;before addition
1800 ADC #1 ;raise it by 1
1810 STA DLIST+4,X ;in disp list
1820 LDA DLIST+5,X ;get hi byte
1830 ADC #0 ;add carry in
1840 STA DLIST+5,X ;in disp list
1850 INX ;move forward in
1860 INX ; display list
1870 INX ; 3 bytes
1880 CPX #72 ;24*3=72
1890 BCC LOOP2 ;not finished
1900 ; JSR DELAY
1910 ;
1920 JMP XITVB ;exit from VB
1930 SCLFT
1940 LDX #7
1950 LP3 STX HSCROL
1960 DEX
1970 BPL LP3
1980 LDX #7
1990 ; STX HSCROL
2000 ;
2010 LDX #72
2020 LP4 LDA DLIST+4,X
2030 SEC
2040 SBC #1
2050 STA DLIST+4,X
2060 LDA DLIST+5,X
2070 SBC #0
2080 STA DLIST+5,X
2090 DEX
2100 DEX
2110 DEX
2120 BNE LP4
2130 ; JSR DELAY
2140 JMP XITVB ;safe escape

2150 SCDWN
2160 LDX #7
2170 LP5 STX 54277
2180 DEX
2190 BPL LP5
2200 LDX #7
2210 STA 54277
2220 ;
2230 ;coarse scroll
2240 ;
2250 LDX #0
2260 LP6 LDA DLIST+5,X
2270 CLC
2280 ADC #250
2290 STA DLIST+5,X
2300 LDA DLIST+5,X
2310 ADC #0
2320 STA DLIST+6,X
2330 INX
2340 INX
2350 INX
2360 CPX #72
2370 BCC LP6
2380 JMP XITVB
2390 SCUP
2400 LDX #0
2410 LP7 STX 54277
2420 INX
2430 CPX #7
2440 BPL LP7
2450 LDX #7
2460 STX 54277

2470 ;coarse
2480 LDX #72
2490 LP8 LDA DLIST+5,X
2500 CLC
2510 ADC #250
2520 STA DLIST+5,X
2530 LDA DLIST+6,X
2540 ADC #0
2550 DEX
2560 DEX
2570 DEX
2580 BNE LP8
2590 XITVB
2600 PLA
2610 TAX
2620 PLA
2630 ; TAY
2640 ; PLA
2650 JMP XITVBV
2660 WAIT
2670 LDA #0
2680 STA 20
2690 WW1 LDA 20
2700 CMP #1
2710 BNE WW1
2720 RTS

2730 MOVDAT
2740 LDA #0
2750 STA MVSRCE ;low byte
2760 LDA CHBASE ;hi byte
2770 STA MVSRCE+1 ;hi byte
2780 ;
2790 LDA #NEWADR&255 ; loc. 1024
2800 STA MVDEST ; loc. 178
2810 LDA #NEWADR/256
2820 STA MVDEST+1
2830 ;
2840 LDA #TABLEN&255
2850 STA LENPTR
2860 LDA #TABLEN/256
2870 STA LENPTR+1
2880 ;
2890 ;start the move
2900 ;
2910 LDY #0
2920 LDX LENPTR+1
2930 BEQ MVPART
2940 MVPAGE
2950 LDA (MVSRCE),Y
2960 STA (MVDEST),Y
2970 INY
2980 BNE MVPAGE
2990 INC MVSRCE+1
3000 INC MVDEST+1
3010 DEX
3020 BNE MVPAGE
3030 MVPART
3040 LDX LENPTR
3050 BEQ MVEXIT
3060 MVLAST
3070 LDA (MVSRCE),Y
3080 STA (MVDEST),Y
3090 INY
3100 DEX
3110 BNE MVLAST

3120 MVEXIT
3130 ;
3140 LDA #1
3150 STA RAMCHR ;24578
3160 ;
3170 ;calculate RAMCHR’S address
3180 ;
3190 LDA #0
3200 STA RAMCHR+1 ;clearing it
3210 LDA RAMCHR
3220 CLC
3230 ASL A
3240 ROL RAMCHR+1 ;get carry
3250 ASL A
3260 ROL RAMCHR+1
3270 ASL A
3280 ROL RAMCHR+1
3290 STA RAMCHR ;mult by 8
3300 FNDADR CLC
3310 LDA RAMCHR
3320 ADC #NEWADR&255
3330 STA CHRADR
3340 LDA RAMCHR+1
3350 ADC #NEWADR/256
3360 STA CHRADR+1
3370 ;

3380 ;change characters
3390 ;
3400 NEWCHR LDY #0
3410 DOSHAPE LDA SHAPE,Y
3420 STA (CHRADR),Y
3430 INY
3440 CPY #24
3450 BCC DOSHAPE
3460 ;
3470 LDA #NEWADR/256 ;hi byte
3480 STA CHBASE ;756
3490 RTS
3500 DELAY
3510 LDY #120
3520 LDX #2
3530 CNTD1 DEX
3540 BNE CNTD1
3550 INY
3560 BNE CNTD1
3570 RTS
3580 ;
3590 SHAPE
3600 .BYTE 0,251,251,251,251,0,223,223
3610 .BYTE 0,239,239,239,239,0,125,125
3620 .BYTE 252,19