; 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