8bitlenser/lenser/bbc/viewer/slideshow.s
2026-07-03 19:35:35 -07:00

174 lines
3.8 KiB
ArmAsm

; lenser -- BBC Micro slideshow loader (6502), loaded at PAGE (&1900) and *RUN.
;
; Sets the screen MODE once, then steps through NIMAGES pictures stored as DFS
; files "00".."NN". For each slide it programmes that image's logical->physical
; palette (from the ss_pal table), *LOADs the file straight into screen memory,
; and waits (key / seconds / both) before advancing.
;
; #defines from the build wrapper --
; WAITMODE 1 key / 2 seconds / 3 both WAITSECS timeout RATE 50/60 fps
; NIMAGES image count LOOPFLAG 1 wrap / 0 stop MODE screen mode NCOL colours
; The packager patches the screen-base hex into the OSCLI string and appends the
; ss_pal table (NCOL physical-colour bytes per image).
OSWRCH = $FFEE
OSRDCH = $FFE0
OSBYTE = $FFF4
OSCLI = $FFF7
palptr = $70
cnt = $72
* = $1900
start:
; ---- VDU 22, mode (once) ----
lda #22
jsr OSWRCH
lda #MODE
jsr OSWRCH
; ---- hide the text cursor (VDU 23,1,0;0;0;0;) ----
lda #23
jsr OSWRCH
lda #1
jsr OSWRCH
ldx #8
curz:
lda #0
jsr OSWRCH
dex
bne curz
lda #0
sta ssidx
ssmain:
; ---- palptr = ss_pal + ssidx*NCOL ----
lda #<ss_pal
sta palptr
lda #>ss_pal
sta palptr+1
ldx ssidx
beq setpal
pmul:
clc
lda palptr
adc #NCOL
sta palptr
bcc pm1
inc palptr+1
pm1:
dex
bne pmul
setpal:
; ---- VDU 19, logical, physical, 0,0,0 for each logical colour ----
ldx #0
pl:
cpx #NCOL
beq pldone
lda #19
jsr OSWRCH
txa
jsr OSWRCH ; logical colour = X
txa
tay
lda (palptr),y
jsr OSWRCH ; physical colour
lda #0
jsr OSWRCH
jsr OSWRCH
jsr OSWRCH
inx
bne pl
pldone:
; ---- build the filename digits "NN" into the OSCLI string ----
lda ssidx
ldx #$2f
sec
nten:
inx
sbc #10
bcs nten
adc #10
ora #$30
sta cmd+6 ; ones digit
txa
sta cmd+5 ; tens digit
; ---- *LOAD NN <base> straight into screen memory ----
ldx #<cmd
ldy #>cmd
jsr OSCLI
jsr sswait
inc ssidx
lda ssidx
cmp #NIMAGES
bcc ssmain
#if LOOPFLAG == 1
lda #0
sta ssidx
jmp ssmain
#else
rts ; back to BASIC
#endif
; ---- wait (returns), flushing the keyboard buffer first ----
sswait:
lda #15
ldx #1
jsr OSBYTE ; flush input buffers
#if WAITMODE == 1
jsr OSRDCH ; block until a key
rts
#endif
#if WAITMODE == 2
lda #<(WAITSECS*RATE)
sta cnt
lda #>(WAITSECS*RATE)
sta cnt+1
sw2:
lda #19
jsr OSBYTE ; wait for vertical sync (1 frame)
lda cnt
bne sd2
dec cnt+1
sd2:
dec cnt
lda cnt
ora cnt+1
bne sw2
rts
#endif
#if WAITMODE == 3
lda #<(WAITSECS*RATE)
sta cnt
lda #>(WAITSECS*RATE)
sta cnt+1
sw3:
lda #129
ldx #0
ldy #0
jsr OSBYTE ; INKEY(0) -- poll keyboard, no wait
cpy #$ff
bne sw3d ; Y != $FF -> a key was pressed
lda #19
jsr OSBYTE ; wait one frame
lda cnt
bne sd3
dec cnt+1
sd3:
dec cnt
lda cnt
ora cnt+1
bne sw3
sw3d:
rts
#endif
ssidx: .byte 0
; OSCLI string -- packager patches the 4-hex screen base; loader patches "NN"
cmd: .byte "LOAD 00 0000", 13
; ss_pal table (NCOL bytes per image) appended by the build wrapper