passport/src/print.a
2021-07-07 12:01:15 -04:00

603 lines
15 KiB
Plaintext
Executable File

;-------------------------------
; PrintByID
; Print a string from the string table
;
; Handles string substitutions and
; auto-uppercases on older machines
;
; fully re-entrant to support nested
; string substitutions (see strings/en.a)
;
; in: string ID (byte) on stack
; out: all registers preserved
; oVerflow bit clear
; all other flags clobbered
; stack set to after params
;-------------------------------
PrintByID
sta @tmpa+1
sty @tmpy+1
; get pointer to stack-based params then move the stack beyond them
pla
sta $00
clc
adc #$01
tay
pla
sta $01
adc #$00
pha
tya
pha
; save all registers and this routine's internal pointers
; (can't use SaveAXY because this routine needs to be re-entrant)
@tmpa lda #$FD ; SMC
pha
@tmpy lda #$FD ; SMC
pha
txa
pha
lda @print+1
pha
lda @print+2
pha
ldy #1
lda ($00), y ; get ID of string to print
tax
lda StringTableLow, x
sta @print+1
lda StringTableHigh, x
sta @print+2
dey ; Y=0
@print
lda $FFFF ; modified at runtime
beq @done
cpy #0 ; are we in substitution mode or include mode?
bmi @include ; yes, include mode
beq @nosub ; no -> branch
ldy #0
cmp #"t" ; "%t" = current track
bne @sub1
lda gTrack
bpl @printbyte ; unconditional branch
@sub1
cmp #"s" ; "%s" = current sector
bne @sub2
lda gSector
bpl @printbyte ; unconditional branch
@sub2
cmp #"S" ; write slot
bne @sub3
lda SLOT
bne @printsd ; unconditional branch
@sub3
cmp #"D" ; write drive
bne @sub4
lda DRIVE
@printsd
ora #$80
jsr PrintA
bvc @next ; unconditional branch
@sub4
cmp #"0" ; "%0" through "%9"
bcc @nosub
cmp #":"
bcs @nosub
sec
sbc #"0"
tax
lda gDisplayBytes, x
@printbyte
jsr PrintByte
bvc @next ; unconditional branch
@nosub
cmp #"%"
bne @stillnosub
iny ; Y=#$01 (substitution mode, next character will be interpreted)
bne @next ; unconditional branch
@stillnosub
cmp #"@"
bne +
dey ; Y=#$FF (include mode, next character will be interpreted)
bne @next ; unconditional branch
+ cmp #$E1
bcc @noforce
and kForceLower
@noforce
jsr COUT
@next
inc @print+1
bne @print
inc @print+2
bne @print ; unconditional branch
@done
pla
sta @print+2
pla
sta @print+1
pla
tax
pla
tay
pla
clv
rts
@include
sta @id
jsr PrintByID
@id !byte $FD ; SMC
ldy #0
beq @next ; unconditional branch
;-------------------------------
; PrintByte
; print a hexadecimal byte
; in: A contains byte to print
; out: all registers preserved
; all flags clobbered
; @tmpa clobbered
; @tmpx clobbered
; @tmpy clobbered
;-------------------------------
PrintByte
jsr SaveAXY
jsr PRBYTE
jmp LoadAXY
;-------------------------------
; PrintA
; print a single character through COUT
; in: A contains character to print
; out: all registers preserved
; all flags clobbered
; @tmpa clobbered
; @tmpx clobbered
; @tmpy clobbered
;-------------------------------
PrintA
jsr SaveAXY
jsr COUT
; /!\ execution falls through here
LoadAXY
lda tmpa
ldx tmpx
ldy tmpy
clv
rts
SaveAXY
sta tmpa
stx tmpx
sty tmpy
rts
;-------------------------------
; ClearScreen
;-------------------------------
ClearScreen
jsr TEXT
lda $C061
bmi +
lda $C062
bpl @home
+ inc gMode
@home jmp HOME
;-------------------------------
; CheckCache
; Intercept text about to be scrolled off the screen
; Cache it in spare LC space for viewing later
;-------------------------------
CheckCache
ldx $25
cpx #$17
bne .nocache
ldx $24
cpx #$27
beq .docache
cmp #$8D
bne .nocache
.docache
pha
cmp #$8D
beq .skipcr
sta $7F7
.skipcr
bit $C081
bit $C081
ldx #$27
cachesrc
lda $700, x
CacheDst
sta $D400, x
dex
bpl cachesrc
lda CacheDst+1
adc #$27
sta CacheDst+1
bcc .skiphi
inc CacheDst+2
.skiphi
pla
.nocache
jmp $FDF0
;-------------------------------
; CheckLogKeys
; Enable scrolling of log, if more than once screen worth
; Left/Right (all)
; Up/Down (not II or II+)
;-------------------------------
CheckLogKeys
ldx CacheDst+1
ldy CacheDst+2
stx .startline1+1
sty .startline1+2
stx .startline2+1
sty .startline2+2
cpy #$D4
bne .skipkey
cpx #0
bne .skipkey
.nolog
rts
.checkkey
jsr WaitForKey
.skipkey
cmp #k_up
beq .checkup
cmp #k_right
beq .checkdown
cmp #k_down
beq .checkdown
cmp #k_left
bne .nolog
.checkup
lda .startline1+2
cmp #$D4
bne .scrollup
lda .startline1+1
beq .checkkey
.scrollup
jsr .substart
bit $C081
bit $C081
ldx #$27
.copyend1
lda $7D0,x
.endline1
sta $D428,x
dex
bpl .copyend1
ldx #22
.scrollscreen
txa
jsr $FBC1 ;BASCALC
lda $28
sta $2A
lda $29
sta $2B
inx
txa
jsr $FBC1 ;BASCALC
ldy #$27
.copyline
lda ($2A),y
sta ($28),y
dey
bpl .copyline
dex
dex
cpx #5
bne .scrollscreen
bit $C083
ldx #$27
.copystart1
.startline1
lda $D400,x
sta $700,x
dex
bpl .copystart1
bit $C081
jmp .checkkey
.checkdown
lda .startline1+2
cmp CacheDst+2
bne .scrolldown
lda .startline1+1
cmp CacheDst+1
beq .checkkey
.scrolldown
bit $C081
bit $C081
ldx #$27
.copystart2
lda $700,x
.startline2
sta $D400,x
dex
bpl .copystart2
lda #$8D
jsr $FDF0
bit $C083
bit $C083
ldx #$27
.copyend2
.endline2
lda $D428,x
sta $7D0,x
dex
bpl .copyend2
bit $C081
jsr .addstart
jmp .checkkey
.substart
sec
lda .startline1+1
sta .endline1+1
sta .endline2+1
sbc #$28
sta .startline1+1
sta .startline2+1
lda .startline1+2
sta .endline1+2
sta .endline2+2
sbc #0
sta .startline1+2
sta .startline2+2
rts
.addstart
clc
lda .endline1+1
sta .startline1+1
sta .startline2+1
adc #$28
sta .endline1+1
sta .endline2+1
lda .endline1+2
sta .startline1+2
sta .startline2+2
adc #0
sta .endline1+2
sta .endline2+2
rts
;-------------------------------
; Print Shop style animation
; by Vince `deater` Weaver <vince@deater.net>
; https://github.com/deater/dos33fsprogs/blob/master/graphics/gr/thinking/cracking.s
; SPDX-License-Identifier: MIT
GBASL = $26
GBASH = $27
COL = $E0
CURRENT_BITMAP = $E1
BITMAP_PTR = $E2
XSAVE = $E3
SAVED_YY = $E3
YSAVE = $E4
SAVED_XX = $E4
ADJUSTED_YY = $E5
GBASCALC = $F847 ; take Y-coord/2 in A, put address in GBASL/H ( A trashed, C clear)
SETGR = $FB40 ; Init graphics, clear screen, A is $D0 after
WAIT = $FCA8 ; delay 1/2(26+27A+5A^2) us
thinking:
jsr SETGR ; set lo-res 40x40 mode
; A=$D0 afterward
lda #0
sta COL ; consistent starting color
; not technically needed
;=============================
;=============================
; print thinking frame
;=============================
;=============================
print_thinking_frame:
ldx #0 ; reset YY to 0
stx BITMAP_PTR ; also reset bitmap pointer to 0
yloop:
txa ; load YY
jsr GBASCALC ; take Y-coord/2 in A, put address in GBASL/H
;=======================
ldy #0 ; reset XX to 0
xloop:
; this is only jumped to every 8th XX
inc_pointer:
inc BITMAP_PTR
; load current bitmap ptr into CURRENT_BITMAP
; is a don't care if not between 7 and 14
stx XSAVE
ldx BITMAP_PTR
lda thinking_data-1-30,X
sta CURRENT_BITMAP
ldx XSAVE
thinking_xloop:
; this is called every XX
stx XSAVE ; save X (YY)
sty YSAVE ; save Y (XX)
; if YY <6 or YY > 13 then don't draw bitmap
cpx #6
bcc do_plot
cpx #13
bcs do_plot
handle_bitmap:
ror CURRENT_BITMAP ; rotate next bit from bitmap in
bcs skip_plot ; skip plotting (assume BG is black)
do_plot:
lda COL ; set starting color
and #$7
tay
lda color_lookup,Y ; lookup color in table
ldy YSAVE ; restore Y (XX)
sta (GBASL),Y
skip_plot:
;==================================
; adjust colors to make boxes
; 0000000000000000
; 0111111111111110
; 0122222222222210
; XX is in Y (currently also in YSAVE)
; YY is in X (currently also in XSAVE)
ldx SAVED_YY ; YY
ldy SAVED_XX ; XX
; if YY is < 10 do following, otherwise reverse
txa ; put YY in A (saved bytes later)
cmp #10
bcc counting_up
counting_down:
; now doing the reverse
lda #19
sec
sbc SAVED_YY
; YY (in A) now going from 10..0
counting_up:
sta ADJUSTED_YY
detect_adjust_dir:
; if YY is < 10 do following, otherwise reverse
; if XX is < 10, check for inc
; if XX is > 30 check for dex
; else, no adjust
cpy #10 ; is XX < 10
bcc color_adjust_up ; then potentially adjust UP
cpy #30 ; is XX > 30
bcs color_adjust_down ; then potentially adjust down
bcc color_adjust_none ; else, do nothing
color_adjust_up:
; if XX < YY then inc color
; if XX >= YY then do nothing
cpy ADJUSTED_YY ; compare XX to YY
bcs col_same ; bge do nothing
col_inc:
inc COL
col_same:
jmp color_adjust_none
color_adjust_down:
lda #39
sec
sbc ADJUSTED_YY
sta ADJUSTED_YY
cpy ADJUSTED_YY ; compare XX to YY
; if XX > 39-YY then inc color
bcc col_down_same
col_dec:
dec COL
col_down_same:
; fallthrough
color_adjust_none:
;============================
; inc XX for next pixel
iny ; inc XX
cpy #40 ; if we hit 40, done line
beq done_done
tya ; if we are multiple of 8
and #$7 ; then need to increment bitmap ptr
beq inc_pointer
bne thinking_xloop
done_done:
;=============================================
; adjust color for next line
inc COL
;=======================
; move to next line
inx
cpx #20
bne yloop
;============================================
; done frame, increment color for next round
;============================================
inc COL
rts
;0 1 2 3 3
;01234567|89012345|67890123|45678901|23456789
; ** ***| *** | ** * |* * * |* ***
; * * |* * * |* * *| * ** |* * *
; * * |* * * |* * * | * ** |* *
; * ***| ***** |* ** | * * * |* *
; * * *| * * |* * * | * * *|* * **
; * * |* * * |* * *| * * *|* * *
; ** * |* * * | ** * |* * * |* ****
; 7*5 bytes = 35 bytes
thinking_data:
!byte $EC,$38,$16,$15,$39
!byte $22,$45,$91,$34,$45
!byte $22,$45,$51,$34,$05
!byte $E2,$7C,$31,$54,$05
!byte $A2,$44,$51,$94,$65
!byte $22,$45,$91,$94,$45
!byte $2C,$45,$16,$15,$79
color_lookup:
; magenta, pink, orange, yellow, lgreen, aqua, mblue, lblue
!byte $33,$BB,$99,$DD,$CC,$EE,$66,$77