138 lines
3.4 KiB
ArmAsm
138 lines
3.4 KiB
ArmAsm
; lenser -- Atari 2600 (VCS) image viewer kernel (6502, "racing the beam").
|
|
;
|
|
; No framebuffer -- per visible scanline the kernel feeds the TIA a 40-pixel
|
|
; asymmetric playfield (left 20 + right 20, rewritten mid-line) plus a shared
|
|
; playfield colour (COLUPF) and two backgrounds -- COLUBK is set for the left
|
|
; half during HBLANK then rewritten mid-line for the right half, so each
|
|
; scanline shows 3 colours (left bg + right bg + foreground). The nine 192-byte
|
|
; data tables are page-aligned (set by the cartridge builder) so LDA tab,Y never
|
|
; crosses a page and the kernel stays cycle-exact.
|
|
;
|
|
; #defines from the wrapper -- PF0L,PF1L,PF2L,PF0R,PF1R,PF2R,BKL,BKR,PFT (table
|
|
; bases), WAITMODE (0 forever / 1 fire / 2 seconds), WAITSECS.
|
|
;
|
|
; assembled by a2600/viewer/assemble.py via xa
|
|
|
|
VSYNC = $00
|
|
VBLANK = $01
|
|
WSYNC = $02
|
|
NUSIZ0 = $04
|
|
COLUPF = $08
|
|
COLUBK = $09
|
|
CTRLPF = $0A
|
|
PF0 = $0D
|
|
PF1 = $0E
|
|
PF2 = $0F
|
|
INPT4 = $3C
|
|
FRLO = $80 ; frame counter (seconds mode)
|
|
FRHI = $81
|
|
PARITY = $82 ; interlace frame parity (IL mode)
|
|
|
|
* = $f000
|
|
start:
|
|
sei
|
|
cld
|
|
ldx #0
|
|
txa
|
|
clr:
|
|
sta $00,x
|
|
inx
|
|
bne clr ; clear $00-$FF (RAM + TIA)
|
|
ldx #$ff
|
|
txs
|
|
|
|
frame:
|
|
lda #2
|
|
sta VSYNC
|
|
sta WSYNC
|
|
sta WSYNC
|
|
sta WSYNC ; 3 VSYNC lines
|
|
lda #0
|
|
sta VSYNC
|
|
lda #2
|
|
sta VBLANK
|
|
sta CTRLPF ; reflect off (we draw both halves explicitly)
|
|
lda #0
|
|
sta CTRLPF
|
|
#if IL
|
|
; temporal interlace -- alternate the two 4K banks (frame A / frame B)
|
|
; each frame; the kernel is identical in both banks so execution
|
|
; continues seamlessly and only the data tables differ.
|
|
lda PARITY
|
|
eor #1
|
|
sta PARITY
|
|
beq selbank0
|
|
lda $1ff9 ; F8 hotspot -> select bank 1 (AD F9 1F)
|
|
jmp bankdone
|
|
selbank0:
|
|
lda $1ff8 ; F8 hotspot -> select bank 0 (AD F8 1F)
|
|
bankdone:
|
|
#endif
|
|
ldx #36
|
|
vbl:
|
|
sta WSYNC
|
|
dex
|
|
bne vbl
|
|
lda #0
|
|
sta VBLANK
|
|
|
|
; ---- visible image, 192 cycle-exact scanlines ----
|
|
ldy #0
|
|
kloop:
|
|
sta WSYNC
|
|
lda BKL,y ; left background (HBLANK)
|
|
sta COLUBK
|
|
lda PFT,y ; shared foreground
|
|
sta COLUPF
|
|
lda PF0L,y
|
|
sta PF0
|
|
lda PF1L,y
|
|
sta PF1
|
|
lda PF2L,y
|
|
sta PF2
|
|
lda PF0R,y ; right playfield PF0 (early, before mid-line)
|
|
sta PF0
|
|
lda BKR,y ; right background (lands at the half boundary)
|
|
sta COLUBK
|
|
lda PF1R,y
|
|
sta PF1
|
|
lda PF2R,y
|
|
sta PF2
|
|
iny
|
|
cpy #192
|
|
bne kloop
|
|
|
|
lda #0
|
|
sta PF0
|
|
sta PF1
|
|
sta PF2
|
|
sta COLUBK
|
|
|
|
; ---- hold / exit ----
|
|
#if WAITMODE == 1
|
|
lda INPT4
|
|
bmi over ; bit7 set = fire not pressed
|
|
jmp start ; pressed -> reset (re-display)
|
|
#endif
|
|
#if WAITMODE == 2
|
|
inc FRLO
|
|
bne fr_ok
|
|
inc FRHI
|
|
fr_ok:
|
|
lda FRHI
|
|
cmp #>(WAITSECS*60)
|
|
bcc over
|
|
lda FRLO
|
|
cmp #<(WAITSECS*60)
|
|
bcc over
|
|
jmp start
|
|
#endif
|
|
over:
|
|
lda #2
|
|
sta VBLANK
|
|
ldx #30
|
|
ovl:
|
|
sta WSYNC
|
|
dex
|
|
bne ovl
|
|
jmp frame
|