Difference between revisions of "Snippet:Blit"
m (1 revision) |
|
(No difference)
|
Latest revision as of 23:23, 16 November 2012
The blit subroutine reads a two-color (1 bit per pixel) block of graphics data from ROM and displays it on the screen, using several parameters. It works much in the same way as the drawchar routine except for arbitrarily sized data. The code was originally taken from Videocart 26 and adapted to be more flexible and reusable.
The routine is separated into two parts, blitGraphic and blit. blit takes parameters in registers r1-r6, and retrieves graphics data from the location DC0 points to. It can be called independently of blitGraphic. blitGraphic takes hard-coded parameters from ROM at the address pointed at by DC0 and then calls the blit routine. When the parameters do not need to be dynamic, storing the parameters in ROM and calling the blitGraphic routine directly can be more efficient than writing them to the registers and calling blit.
;===========; ; Blit Code ; ;===========; ;--------------; ; Blit Graphic ; ;--------------; ; takes graphic parameters from ROM, stores them in r1-r6, ; changes the DC and calls the blit function with the parameters ; ; modifies: r1-r6, Q, DC blitGraphic: ; load six bytes from the parameters into r0-r5 lisu 0 lisl 1 .blitGraphicGetParms: lm lr I, A ; store byte and increase ISAR br7 .blitGraphicGetParms ; not finished with the registers, loop ; load the graphics address lm lr Qu, A ; into Q lm lr Ql, A lr DC, Q ; load it into the DC ; call the blit function jmp blit ;---------------; ; Blit Function ; ;---------------; ; this function blits a graphic based on parameters set in r1-r6, ; and the graphic data pointed to by DC0, onto the screen ; originally from cart 26, modified and annotated ; ; modifies: r1-r9, DC ; register reference: ; ------------------- ; r1 = color 1 (off) ; r2 = color 2 (on) ; r3 = x position ; r4 = y position ; r5 = width ; r6 = height (and vertical counter) ; ; r7 = horizontal counter ; r8 = graphics byte ; r9 = bit counter ; ; DC = pointer to graphics blit: ; fix the x coordinate lis 4 as 3 lr 3, A ; fix the y coordinate lis 4 as 4 lr 4, A lis 1 lr 9, A ; load #1 into r9 so it'll be reset when we start lr A, 4 ; load the y offset com ; invert it .blitRow: outs 5 ; load accumulator into port 5 (row) ; check vertical counter ds 6 ; decrease r6 (vertical counter) bnc .blitExit ; if it rolls over exit ; load the width into the horizontal counter lr A, 5 lr 7, A lr A, 3 ; load the x position com ; complement it .blitColumn: outs 4 ; use the accumulator as our initial column ; check to see if this byte is finished ds 9 ; decrease r9 (bit counter) bnz .blitDrawBit ; if we aren't done with this byte, branch .blitGetByte: ; get the next graphics byte and set related registers lis 8 lr 9, A ; load #8 into r9 (bit counter) lm lr 8, A ; load a graphics byte into r8 .blitDrawBit: ; shift graphics byte lr A, 8 ; load r8 (graphics byte) as 8 ; shift left one (with carry) lr 8, A ; save it ; check color to use lr A, 2 ; load color 1 bc .blitSavePixel ; if this bit is on, draw the color lr A, 1 ; load color 2 .blitSavePixel: inc bc .blitCheckColumn ; branch if the color is "clear" outs 1 ; output A in p1 (color) .blitTransferData: ; transfer the pixel data li $60 outs 0 li $c0 outs 0 ; and delay a little bit .blitSavePixelDelay: ai $60 ; add 96 bnz .blitSavePixelDelay ; loop if not 0 (small delay) .blitCheckColumn: ds 7 ; decrease r7 (horizontal counter) bz .blitCheckRow ; if it's 0, branch ins 4 ; get p4 (column) ai $ff ; add 1 (complemented) br .blitColumn ; branch .blitCheckRow: ins 5 ; get p5 (row) ai $ff ; add 1 (complemented) br .blitRow ; branch .blitExit: ; return from the subroutine pop
Note: the adjustment of x and y in blit are to allow the coodinates 0, 0 to access the upper left pixel visible to the screen, not to VRAM, which expands four pixels above and to the left of that pixel.
To call the above functions, you should use:
dci graphic.parameters ; address of parameters pi blitGraphic
for blitGraphic, and:
; parameters have been loaded into r1-r6 beforehand dci graphic.data ; address of graphic data pi blit
for blit. If you're using parameters stored in ROM, they should be in this order:
graphic.parameters: .byte bkg ; color 1 .byte blue ; color 2 .byte 4 ; x position .byte 18 ; y position .byte $60 ; width .byte $13 ; height .word graphic.data ; address for the graphics