272 lines
7.4 KiB
ArmAsm
272 lines
7.4 KiB
ArmAsm
; lenser -- Atari static-playfield slideshow viewer (GR.15 / GR.9 / GR.8).
|
|
;
|
|
; Self-booting (OS loads this to $2000, JSRs $2006). Steps through NIMAGES
|
|
; pictures stored as raw sectors -- image i at sectors BASESEC + i*SPI -- SIO-
|
|
; reading SPI sectors and showing each before advancing (key / seconds / both).
|
|
;
|
|
; DOUBLE BUFFERED so the previous slide stays on screen while the next loads (no
|
|
; blank between slides). Two RAM buffers alternate as front/back --
|
|
; buffer 0 -- bitmap $4000/$5000, colour bytes $6000
|
|
; buffer 1 -- bitmap $7000/$8000, colour bytes $9000
|
|
; both kept below $A000 so they are RAM even when the BASIC ROM is enabled. The
|
|
; display list's two LMS addresses point at the front buffer; each slide is SIO-
|
|
; read into the *back* buffer while the front (the previous picture) keeps
|
|
; displaying, then -- during a vertical blank so the change isn't torn -- the LMS
|
|
; addresses and colour registers are switched to it. ss_hi = ssbuf*$30 is the
|
|
; high-byte offset ($00 buffer 0, $30 buffer 1) added to every buffer address.
|
|
;
|
|
; The mode is fixed for the whole slideshow, chosen by build-time #defines --
|
|
; DLMODE ANTIC mode byte ($0e GR.15, $0f GR.9/GR.8)
|
|
; GPRIOR GTIA priority/mode ($00, or $40 for GR.9)
|
|
; COLORMODE colour-register layout (0 GR.15 / 1 GR.9 / 2 GR.8)
|
|
; plus WAITMODE/WAITSECS/RATE, NIMAGES, LOOPFLAG, BASESEC, SPI (see assemble.py).
|
|
|
|
colptr = $cb ; zero-page pointer to the back buffer's colours
|
|
|
|
* = $2000
|
|
boot:
|
|
.byte 0 ; flags
|
|
.byte 0 ; sector count (patched by the ATR writer)
|
|
.word $2000 ; load address
|
|
.word binit ; init address (DOSINI)
|
|
|
|
cont: ; $2006 -- OS JSRs here after loading the stub
|
|
lda #<dlist
|
|
sta $230 ; SDLSTL
|
|
lda #>dlist
|
|
sta $231 ; SDLSTH
|
|
lda #GPRIOR
|
|
sta $26f ; GPRIOR
|
|
lda #$00
|
|
sta $22f ; SDMCTL = 0 (blank before the first image only)
|
|
sta ssidx
|
|
sta ssbuf ; first slide loads into buffer 0
|
|
|
|
ssmain:
|
|
jsr sethi ; ss_hi = ssbuf * $30
|
|
jsr readimg ; SIO-load image ssidx into the back buffer
|
|
|
|
; ---- wait for a vertical blank, then flip to the back buffer ----
|
|
; (the front buffer -- the previous slide -- has stayed on screen)
|
|
lda $14
|
|
vbwait:
|
|
cmp $14
|
|
beq vbwait ; RTCLOK ticked -> we are in the vertical blank
|
|
|
|
; display-list LMS -- region 1 = base, region 2 = base + $1000
|
|
lda #$00
|
|
sta lms1
|
|
sta lms2
|
|
lda #$40
|
|
clc
|
|
adc ss_hi
|
|
sta lms1+1 ; $40 / $70
|
|
lda #$50
|
|
clc
|
|
adc ss_hi
|
|
sta lms2+1 ; $50 / $80
|
|
|
|
; colour bytes are at base + $2000
|
|
lda #$00
|
|
sta colptr
|
|
lda #$60
|
|
clc
|
|
adc ss_hi
|
|
sta colptr+1 ; $60 / $90
|
|
#if COLORMODE == 0
|
|
ldy #$00
|
|
lda (colptr),y
|
|
sta $2c8 ; COLBAK (value 0)
|
|
ldy #$01
|
|
lda (colptr),y
|
|
sta $2c4 ; COLPF0 (value 1)
|
|
ldy #$02
|
|
lda (colptr),y
|
|
sta $2c5 ; COLPF1 (value 2)
|
|
ldy #$03
|
|
lda (colptr),y
|
|
sta $2c6 ; COLPF2 (value 3)
|
|
#endif
|
|
#if COLORMODE == 1
|
|
ldy #$00
|
|
lda (colptr),y
|
|
sta $2c8 ; COLBAK = hue (GR.9)
|
|
#endif
|
|
#if COLORMODE == 2
|
|
ldy #$00
|
|
lda (colptr),y
|
|
sta $2c6 ; COLPF2 background
|
|
sta $2c8 ; COLBAK border = background
|
|
ldy #$01
|
|
lda (colptr),y
|
|
sta $2c5 ; COLPF1 foreground
|
|
#endif
|
|
lda #$22
|
|
sta $22f ; SDMCTL on (a no-op after the first slide)
|
|
|
|
jsr sswait
|
|
lda ssbuf
|
|
eor #$01
|
|
sta ssbuf ; next slide loads into the other buffer
|
|
inc ssidx
|
|
lda ssidx
|
|
cmp #NIMAGES
|
|
bcc ssmain
|
|
#if LOOPFLAG == 1
|
|
lda #$00
|
|
sta ssidx
|
|
jmp ssmain
|
|
#else
|
|
lda #$00
|
|
sta $09 ; clear BOOT? so warmstart enters BASIC
|
|
jmp $e474 ; warm-start (exit)
|
|
#endif
|
|
|
|
binit:
|
|
rts
|
|
|
|
; ss_hi = ssbuf * $30 (back-buffer high-byte offset -- $00 buffer 0, $30 buffer 1)
|
|
sethi:
|
|
ldx #$00
|
|
lda ssbuf
|
|
beq sh0
|
|
ldx #$30
|
|
sh0:
|
|
stx ss_hi
|
|
rts
|
|
|
|
; ---- SIO read SPI sectors of image ssidx into the back buffer (base+$0000) ----
|
|
readimg:
|
|
lda #<BASESEC
|
|
sta secn
|
|
lda #>BASESEC
|
|
sta secn+1
|
|
ldx ssidx
|
|
beq rsbuf
|
|
radd:
|
|
clc
|
|
lda secn
|
|
adc #SPI
|
|
sta secn
|
|
bcc ra1
|
|
inc secn+1
|
|
ra1:
|
|
dex
|
|
bne radd
|
|
rsbuf:
|
|
lda #$00
|
|
sta $0304 ; DBUFLO = $00
|
|
lda #$40
|
|
clc
|
|
adc ss_hi
|
|
sta $0305 ; DBUFHI = $40 / $70 (back buffer base)
|
|
lda #SPI
|
|
sta cnt
|
|
rloop:
|
|
lda #$31
|
|
sta $0300 ; DDEVIC = disk
|
|
lda #$01
|
|
sta $0301 ; DUNIT 1
|
|
lda #$52
|
|
sta $0302 ; DCOMND R (read)
|
|
lda #$40
|
|
sta $0303 ; DSTATS = read direction
|
|
lda #$1f
|
|
sta $0306 ; DTIMLO
|
|
lda #$80
|
|
sta $0308 ; DBYTLO = 128
|
|
lda #$00
|
|
sta $0309 ; DBYTHI
|
|
lda secn
|
|
sta $030a ; DAUX1 sector low
|
|
lda secn+1
|
|
sta $030b ; DAUX2 sector high
|
|
jsr $e459 ; SIOV
|
|
clc
|
|
lda $0304
|
|
adc #$80
|
|
sta $0304 ; buffer += 128
|
|
bcc rb1
|
|
inc $0305
|
|
rb1:
|
|
inc secn
|
|
bne rb2
|
|
inc secn+1
|
|
rb2:
|
|
dec cnt
|
|
bne rloop
|
|
rts
|
|
|
|
; ---- wait (returns; defeats attract mode via $4d) ----
|
|
sswait:
|
|
#if WAITMODE == 1
|
|
lda #$ff
|
|
sta $2fc ; clear CH
|
|
sw1:
|
|
lda #$00
|
|
sta $4d
|
|
lda $2fc
|
|
cmp #$ff
|
|
beq sw1
|
|
rts
|
|
#endif
|
|
#if WAITMODE == 2
|
|
lda #$00
|
|
sta $12
|
|
sta $13
|
|
sta $14 ; reset RTCLOK
|
|
sw2:
|
|
lda #$00
|
|
sta $4d
|
|
lda $13
|
|
cmp #>(WAITSECS*RATE)
|
|
bcc sw2
|
|
bne sw2d
|
|
lda $14
|
|
cmp #<(WAITSECS*RATE)
|
|
bcc sw2
|
|
sw2d:
|
|
rts
|
|
#endif
|
|
#if WAITMODE == 3
|
|
lda #$ff
|
|
sta $2fc
|
|
lda #$00
|
|
sta $12
|
|
sta $13
|
|
sta $14
|
|
sw3:
|
|
lda #$00
|
|
sta $4d
|
|
lda $2fc
|
|
cmp #$ff
|
|
bne sw3d ; any key ends the slide
|
|
lda $13
|
|
cmp #>(WAITSECS*RATE)
|
|
bcc sw3
|
|
bne sw3d
|
|
lda $14
|
|
cmp #<(WAITSECS*RATE)
|
|
bcc sw3
|
|
sw3d:
|
|
rts
|
|
#endif
|
|
|
|
ssidx: .byte 0
|
|
ssbuf: .byte 0 ; 0 or 1 -- which buffer the next slide loads into
|
|
ss_hi: .byte 0 ; ssbuf * $30 (back-buffer high-byte offset)
|
|
secn: .word 0
|
|
cnt: .byte 0
|
|
|
|
dlist:
|
|
.byte $70,$70,$70 ; 24 blank scan lines
|
|
.byte DLMODE+$40 ; LMS + mode
|
|
lms1:
|
|
.word $4000 ; region 1 base (patched to the front buffer)
|
|
.dsb 101,DLMODE
|
|
.byte DLMODE+$40 ; LMS + mode
|
|
lms2:
|
|
.word $5000 ; region 2 base (patched to the front buffer)
|
|
.dsb 89,DLMODE
|
|
.byte $41 ; JVB
|
|
.word dlist
|