Код:
PROCEDURE PutSpr (x, y: INTEGER; PROCEDURE spr);
BEGIN /*$C
.TITLE CG008
MOV R2, -(SP)
MOV R3, -(SP)
MOV R4, -(SP)
MOV R5, -(SP)
MOV 16(SP), R4 ; X
MOV 14(SP), R3 ; Y
MOV 10(SP), R5 ; R5 - pointer to sprite
mov (R5), -(SP) ; DX
mov (R5)+, -(SP) ; DX
mov (R5)+, -(SP) ; DY
mov R5, -(SP) ; spraddr w/o dx, dy
tst -(SP) ; reserving for vaddr
;----------------------------------------------
mov R3, R1 ; R0 = DY*80
ash #3, R1 ; ^_^
mov R1, R0 ; change to mul
mov R3, R1 ; it's just for fun
ash #1, R1 ; dunno will it be faster
add R1, R0 ;
ash #3, R0 ;
mov R4, R1 ;
ash #-3, R1 ;
add R1, R0 ; R0 += DX/8
add #^O100000, R0
mov R0, @#^O176640 ; vaddr
mov R0, (SP) ; vaddr -> (SP)
mov R4, R0 ; shift value
bic #^B1111111111111000, R0 ; if it = 0 - use simple sprite out
bne 10$
; // sprite out with X aligned to 8 pix //
mov #^O176642, R0
mov #^O176640, R1
mov #80., R3
sub 6(SP), R3
2$: mov 6(SP), R2 ; DX
4$: mov (R5)+, (R0)
inc (R1)
sob R2, 4$ ; cycle by DX
add R3, (R1)
dec 4(SP) ; cycle by DY
bne 2$
jmp 99$
; // sprite out with arbitrary X //
10$: mov R0, R3 ; R3 = shift value
asl R0 ;
mov MASK(R0), R4 ; R4 = mask value
asl 6(SP) ; DX = DX * 2
20$:
; // draw first DY part //
mov (SP), @#^O176640 ; vaddr
mov 2(SP), R5 ; spraddr
mov 4(SP), R2 ; DY
30$: mov (R5), R1
ash R3, R1
bic R4, R1
com R4
mov @#^O176642, R0
bic R4, R0
com R4
bis R1, R0
mov R0, @#^O176642
add #80, @#^O176640
add 6(SP), R5 ; R5 = R5+DX2
sob R2, 30$
inc (SP) ; inc vaddr
; // draw second DY part //
mov (SP), @#^O176640 ; vaddr
mov 2(SP), R5 ; spraddr
mov 4(SP), R2 ; DY
com R4 ; invert mask
40$: mov (R5), R1
swab R1
movb R1, R0
ashc R3, R0 ; R0:R1 << R3
bic R4, R0 ; apply mask
com R4
mov @#^O176642, R1
bic R4, R1
com R4
bis R0, R1
mov R1, @#^O176642
add #80, @#^O176640
add 6(SP), R5
sob R2, 40$
com R4 ; invert mask
add #2, 2(SP) ; spraddr += 2
dec 8(SP) ; cycle by DX
bne 20$
;----------------------------------------------
99$: tst (SP)+
tst (SP)+
tst (SP)+
tst (SP)+
tst (SP)+
MOV (SP)+, R5
MOV (SP)+, R4
MOV (SP)+, R3
MOV (SP)+, R2
*/
END {PutSpr};