million-perfect-letters/src/ui.common.a

263 lines
6.8 KiB
Plaintext

;license:MIT
;(c) 2020 by 4am
;
; common graphics functions
;
; Public functions:
; - Home
; - WaitForKeyWithTimeout
; - LongWaitForKeyWithTimeout
; - ScrollDown
; - ScrollDownBy
; - ScrollUp
; - ScrollUpBy
; - LogicalColumnToPhysicalColumn
; - ToASCIIString
;
; Public variables:
; - GlobalLeftMargin
;
GlobalLeftMargin
!byte $0A
;------------------------------------------------------------------------------
; Home
; clear graphics page 1 without flicker
;
; in: none, but assumes text screen 1 is clear (this is done at program startup)
; out: hi-res page 1 cleared and displayed
; X preserved
; A/Y clobbered
; flags clobbered
;------------------------------------------------------------------------------
Home
bit PAGE1
bit FULLGFX
bit HIRES
bit TEXTMODE
ldy #$00
tya
- sta $2000, y
sta $2100, y
sta $2200, y
sta $2300, y
sta $2400, y
sta $2500, y
sta $2600, y
sta $2700, y
sta $2800, y
sta $2900, y
sta $2A00, y
sta $2B00, y
sta $2C00, y
sta $2D00, y
sta $2E00, y
sta $2F00, y
sta $3000, y
sta $3100, y
sta $3200, y
sta $3300, y
sta $3400, y
sta $3500, y
sta $3600, y
sta $3700, y
sta $3800, y
sta $3900, y
sta $3A00, y
sta $3B00, y
sta $3C00, y
sta $3D00, y
sta $3E00, y
sta $3F00, y
iny
bne -
bit GFXMODE
rts
;------------------------------------------------------------------------------
; WaitForKeyWithTimeout
; just what it says on the tin
;
; in: A = timeout length (like standard $FCA8 wait routine)
; out: A = 0
; X/Y preserved
; N = 1 if key was pressed to exit early
; N = 0 if time ran out
;------------------------------------------------------------------------------
WaitForKeyWithTimeout
sec
@wait1 pha
@wait2 sbc #1
bne @wait2
pla
bit $C000
bmi @exit
sbc #1
bne @wait1
@exit rts
;------------------------------------------------------------------------------
; LongWaitForKeyWithTimeout
; just what it says on the tin
;
; in: X = number of iterations for an A=0 wait loop
; out: A,X = 0
; Y preserved
; N = 1 if key was pressed to exit early
; N = 0 if time ran out
;------------------------------------------------------------------------------
LongWaitForKeyWithTimeout
lda #0
- jsr WaitForKeyWithTimeout
bmi +
dex
bne -
+ rts
;------------------------------------------------------------------------------
; ScrollDown
; scroll a single puzzle column down 16 HGR rows
;
; in: Y = logical column to scroll
; out: X/Y preserved
;------------------------------------------------------------------------------
ScrollDown
lda #$16
; /!\ execution falls through to ScrollDownBy
;------------------------------------------------------------------------------
; ScrollDownBy
; scroll a single puzzle column down a specified number of HGR rows
;
; in: Y = logical column to scroll
; A = number of HGR rows to scroll
; out: X/Y preserved
;------------------------------------------------------------------------------
ScrollDownBy
stx @x+1
sty @y+1
tax
jsr LogicalColumnToPhysicalColumn
jsr InitScrollStorage
jsr GENSCROLLDOWN
@x ldx #$FD ; SMC
@y ldy #$FD ; SMC
rts
;------------------------------------------------------------------------------
; ScrollUp
; scroll a single puzzle column up 16 HGR rows
;
; in: Y = logical column to scroll
; out: X/Y preserved
;------------------------------------------------------------------------------
ScrollUp
lda #$16
; /!\ execution falls through to ScrollUpBy
;------------------------------------------------------------------------------
; ScrollUpBy
; scroll a single puzzle column up a specified number of HGR rows
;
; in: Y = logical column to scroll
; A = number of HGR rows to scroll
; out: X/Y preserved
;------------------------------------------------------------------------------
ScrollUpBy
stx @x+1
sty @y+1
tax
jsr LogicalColumnToPhysicalColumn
jsr InitScrollStorage
jsr GENSCROLLUP
@x ldx #$FD ; SMC
@y ldy #$FD ; SMC
rts
;------------------------------------------------------------------------------
; LogicalColumnToPhysicalColumn
;
; in: Y contains logical column number
; out: Y contains physical byte offset to use against an HGR base address
; A clobbered
; X preserved
;------------------------------------------------------------------------------
LogicalColumnToPhysicalColumn
lda GlobalLeftMargin
clc
bcc +
- adc #$03
+ dey
bpl -
tay
rts
nonZeroDigits = $EE
paddingCharacter = $EF
;------------------------------------------------------------------------------
; ToASCIIString
; convert byte value to length-prefixed 3-digit decimal number as ASCII string
; with given padding character
;
; in: X = any number (0..255 obviously)
; A = padding character (e.g. '0' or ' ')
; out: $F1 = 0x03
; $F2..$F4 = ASCII digits of decimal representation
; clobbers $EE,$EF,$F0
; all flags & registers clobbered
;------------------------------------------------------------------------------
ToASCIIString
sta paddingCharacter
stx $F0
ldx #0
stx nonZeroDigits
stx $F1
@outer lda #0
pha
@inner lda $F0
cmp @kPowersOfTen, x
bcc @digitDone
sbc @kPowersOfTen, x
sta $F0
lda $F1
sbc #0
sta $F1
pla
adc #0
pha
jmp @inner
@digitDone
pla
beq @maybeUsePaddingChar
inc nonZeroDigits
- ora #$30
bne + ; always branches
@maybeUsePaddingChar
cpx #2
beq -
ldy nonZeroDigits
bne -
lda paddingCharacter
+ sta $F2, x
inx
cpx #$03
bcc @outer
lda #3 ; length byte
sta $F1
rts
@kPowersOfTen
!byte 100
!byte 10
!byte 1
InitScrollStorage
; [private]
; out: preserves X/Y
lda #$00
sta $FC
sta $FD
sta $FE
sta $FF
rts