mirror of
https://github.com/cc65/cc65.git
synced 2024-08-18 10:29:06 +00:00
296 lines
5.9 KiB
ArmAsm
296 lines
5.9 KiB
ArmAsm
;
|
|
; Ullrich von Bassewitz, 2009-11-02
|
|
;
|
|
; void __fastcall__ tgi_vectorchar (const unsigned char* Ops);
|
|
; /* Draw one character of the vector font at the current graphics cursor
|
|
; * position using the current font magnification.
|
|
; */
|
|
;
|
|
|
|
.import imul16x16r32, umul16x16r32, negax, negeax
|
|
|
|
.include "tgi-kernel.inc"
|
|
.include "tgi-vectorfont.inc"
|
|
.include "zeropage.inc"
|
|
|
|
.macpack longbranch
|
|
|
|
;----------------------------------------------------------------------------
|
|
; Data
|
|
|
|
Ops = regbank
|
|
Flag = regbank+2
|
|
|
|
.bss
|
|
X1: .res 2
|
|
Y1: .res 2
|
|
X2: .res 2
|
|
Y2: .res 2
|
|
|
|
;----------------------------------------------------------------------------
|
|
; Get the next operation from the Ops pointer, remove the flag bit and sign
|
|
; extend the 8 bit value to 16 bits.
|
|
|
|
.code
|
|
.proc GetOp
|
|
|
|
; Load delta value
|
|
|
|
ldy #0
|
|
lda (Ops),y
|
|
inc Ops
|
|
bne :+
|
|
inc Ops+1
|
|
|
|
; Move bit 7 into Flag, then sign extend the value in A and extend the sign
|
|
; into X.
|
|
|
|
: asl a ; Flag into carry
|
|
ror Flag
|
|
ldx #0
|
|
cmp #$80 ; Sign bit into carry
|
|
ror a ; Sign extend the value
|
|
bpl :+
|
|
dex ; Value is negative
|
|
|
|
; Done
|
|
|
|
: rts
|
|
|
|
.endproc
|
|
|
|
|
|
;----------------------------------------------------------------------------
|
|
; Get and process one coordinate value. The scale factor is passed in a/x
|
|
|
|
.code
|
|
GetProcessedYCoord:
|
|
lda _tgi_textscaleh+0
|
|
ldx _tgi_textscaleh+1
|
|
|
|
GetProcessedCoord:
|
|
|
|
; Save scale factor as left operand for multiplication
|
|
|
|
sta ptr1
|
|
stx ptr1+1
|
|
|
|
; Load next operation value.
|
|
|
|
jsr GetOp
|
|
|
|
; Multiplicate with the scale factor.
|
|
|
|
jmp tgi_imulround ; Multiplicate, round and scale
|
|
|
|
;----------------------------------------------------------------------------
|
|
; Add the base coordinate with offset in Y to the value in A/X
|
|
|
|
.code
|
|
.proc AddBaseCoord
|
|
|
|
clc
|
|
adc _tgi_curx+0,y
|
|
pha
|
|
txa
|
|
adc _tgi_curx+1,y
|
|
tax
|
|
pla
|
|
rts
|
|
|
|
.endproc
|
|
|
|
;----------------------------------------------------------------------------
|
|
; Subtract the value in a/x from the base coordinate with offset in Y
|
|
; This is
|
|
;
|
|
; ax = _tgi_cur[xy] - ax
|
|
;
|
|
; which can be transformed to
|
|
;
|
|
; ax = _tgi_cur[xy] + (~ax + 1);
|
|
|
|
|
|
.code
|
|
.proc SubBaseCoord
|
|
|
|
eor #$FF
|
|
sec ; + 1
|
|
adc _tgi_curx+0,y
|
|
pha
|
|
txa
|
|
eor #$FF
|
|
adc _tgi_curx+1,y
|
|
tax
|
|
pla
|
|
rts
|
|
|
|
.endproc
|
|
|
|
;----------------------------------------------------------------------------
|
|
;
|
|
|
|
.code
|
|
.proc _tgi_vectorchar
|
|
|
|
; Multiplicate the char value by two and save into Y
|
|
|
|
asl a
|
|
tay
|
|
|
|
; Since we will call tgi_lineto, which uses the zero page, and we do also
|
|
; need the zero page, make room in the register bank.
|
|
|
|
lda Ops
|
|
pha
|
|
lda Ops+1
|
|
pha
|
|
lda Flag
|
|
pha
|
|
|
|
; Calculate a pointer to the vector ops for the given char (now in Y). We
|
|
; definitely expect a font here, that has to be checked by the caller.
|
|
|
|
lda _tgi_vectorfont
|
|
clc
|
|
adc #<(TGI_VECTORFONT::CHARS - 2*TGI_VF_FIRSTCHAR)
|
|
sta Ops
|
|
lda _tgi_vectorfont+1
|
|
adc #>(TGI_VECTORFONT::CHARS - 2*TGI_VF_FIRSTCHAR)
|
|
sta Ops+1
|
|
|
|
iny
|
|
lda (Ops),y
|
|
tax
|
|
dey
|
|
lda (Ops),y
|
|
sta Ops
|
|
stx Ops+1
|
|
|
|
; Main loop executing vector operations
|
|
|
|
Loop: lda _tgi_textscalew+0
|
|
ldx _tgi_textscalew+1
|
|
jsr GetProcessedCoord ; Get X vector
|
|
|
|
; Depending on the text direction, the X vector is either applied to X as
|
|
;
|
|
; X2 = _tgi_curx + XMag * XDelta
|
|
;
|
|
; or applied to Y as
|
|
;
|
|
; Y2 = _tgi_cury - XMag * XDelta
|
|
;
|
|
; which can be transformed to
|
|
;
|
|
; Y2 = _tgi_cury + (~(XMag * XDelta) + 1);
|
|
;
|
|
;
|
|
; For the Y component we have
|
|
;
|
|
; Y2 = _tgi_cury - YMag * YDelta
|
|
;
|
|
; which can be transformed to
|
|
;
|
|
; Y2 = _tgi_cury + (~(YMag * YDelta) + 1);
|
|
;
|
|
; or applied to X as
|
|
;
|
|
; X2 = _tgi_curx - YMag * YDelta
|
|
;
|
|
; which can be transformed to
|
|
;
|
|
; X2 = _tgi_curx + (~(YMag * YDelta) + 1);
|
|
;
|
|
|
|
ldy _tgi_textdir ; Horizontal or vertical text?
|
|
bne @Vertical ; Jump if vertical
|
|
|
|
; Process horizontal text
|
|
|
|
ldy #0
|
|
jsr AddBaseCoord
|
|
sta X2
|
|
stx X2+1
|
|
|
|
; Get Y vector
|
|
|
|
jsr GetProcessedYCoord
|
|
|
|
; Apply to Y
|
|
|
|
ldy #2
|
|
jsr SubBaseCoord
|
|
sta Y2
|
|
stx Y2+1
|
|
jmp @DrawMove
|
|
|
|
; Process vertical text
|
|
|
|
@Vertical:
|
|
ldy #2
|
|
jsr SubBaseCoord
|
|
sta Y2
|
|
stx Y2+1
|
|
|
|
; Get Y vector
|
|
|
|
jsr GetProcessedYCoord
|
|
|
|
; Apply to X
|
|
|
|
ldy #0
|
|
jsr SubBaseCoord
|
|
sta X2
|
|
stx X2+1
|
|
|
|
; Draw, then move - or just move
|
|
|
|
@DrawMove:
|
|
bit Flag
|
|
bpl @Move ; Jump if move only
|
|
|
|
.if 0
|
|
ldy #7 ; Copy start coords into zp
|
|
: lda X1,y
|
|
sta ptr1,y
|
|
dey
|
|
bpl :-
|
|
|
|
jsr tgi_line ; Call the driver
|
|
.else
|
|
ldy #7 ; Copy start coords
|
|
: lda X1,y
|
|
sta tgi_clip_x1,y
|
|
dey
|
|
bpl :-
|
|
|
|
jsr tgi_clippedline ; Call line clipper
|
|
.endif
|
|
|
|
; Move the start position
|
|
|
|
@Move: ldy #3
|
|
: lda X2,y
|
|
sta X1,y
|
|
dey
|
|
bpl :-
|
|
|
|
; Loop if not done
|
|
|
|
bit Flag
|
|
bvc Loop
|
|
|
|
; Done. Restore zp and return.
|
|
|
|
pla
|
|
sta Flag
|
|
pla
|
|
sta Ops+1
|
|
pla
|
|
sta Ops
|
|
rts
|
|
|
|
.endproc
|
|
|