; delta.asm ; void decode_delta_fli(UBYTE *data) case on mcopy table.macros decode_delta_fli start using yoffset using shiftcolor ; using grey_color using odd_pixel using even_pixel ; yoffset is a lookup table for the start of each line on the GS ; shiftcolor is a lookup table of values all the same from '0000 to FFFF' ; grey_color is a lookup table for the 256 different possible colors reduced ; to sixteen for gs display GS_screen equ $012000 VGA_X equ 1 ; width across (0 - 319) current_line equ VGA_X+2 ; height of current line (0 - 199) lines_left equ current_line+2 ; number of lines left packets equ lines_left+2 ; number of packets per line packet_type equ packets+2 ; type and length of packet color equ packet_type+2 ; color (0 - 15) color1 equ color+2 ; color1 (aaaa) same in all positions temp_X equ color1+2 ; temporary x save GS_offset equ temp_X+2 ; (current_line * 160) for current line packet_size equ GS_offset+2 quotient equ packet_size+2 ; called from orca c csub (4:data),24 phb phk plb ; use local addressing lda [data] ; word sta current_line ; starting line ldy #2 ; init ptr lda [data],y ; word iny iny ; next position sta lines_left ; number of lines that change loop1 dec lines_left ; any more lines bpl cont ; >= 0 done plb ; fix bank ret cont stz VGA_X ; start x = 0 lda [data],y ; byte iny and #$00FF ; mask off high byte sta packets ; number of packets in this line loop2 lda packets ; number of packets bne cont2 ; any left to do inc current_line ; next line bra loop1 ; go try next line ; lookup starting offset by (current_line * 160) and save in GS_offset cont2 lda current_line ; current line asl a ; x2 tax lda yoffset,x sta GS_offset ; current (current_line * 160) lda [data],y ; word iny ; next position iny pha and #$00FF ; mask off high byte clc adc VGA_X ; VGA_X = data + VGA_X sta VGA_X ; offset in x direction lsr a clc adc GS_offset ; byte offset from start sta temp_X pla ; next byte xba and #$00FF ; mask off high byte sta packet_type ; length and type of packet bit #$0080 ; byte oriented (bit 7 set ?) bne screen_repeat ; true jmp screen_copy ; false ; screen_repeat copies 1 color packet_type times to the screen ; color = data[current y] (byte) ; packet_type = (-packet_type) bit 7 set means its a repeat packet screen_repeat lda [data],y ; byte iny and #$00FF ; mask off high byte asl a ; x2 tax lda odd_pixel,x ; ( 0 - 15 ) sta color ; (000a) asl a ; x2 tax lda shiftcolor,x sta color1 ; (aaaa) ; from here on down X is offset into current line ldx temp_X ; temp_X is byte offset into screen ; fix packet_type ; packet_type = (-packet_type) lda #256 sec sbc packet_type sta packet_type ; save it sta packet_size ; variable to use ok lda VGA_X ; starting on odd x bit #1 beq even ; nope ; starting on odd pixel. try to see how many to draw lda packet_size cmp #2 beq odd2pix ; = 2 bcs odd3pix ; > 2 pixels ; ; < 2 ; draw just one pixel in odd location ; so draw 1 first short m lda GS_screen,x ; from screen and #$F0 ; mask (AAA0) ora color ; add color sta GS_screen,x ; to screen ************ long m jmp done_repeat ; done odd2pix lda color1 and #$F00F ; 2 pixels sta color1 lda GS_screen,x ; from screen and #$0FF0 ; mask (0AA0) ora color1 ; add color sta GS_screen,x ; to screen ************ jmp done_repeat ; done odd3pix pha ; save packet_size lda color1 and #$FF0F ; mask (AA0A) sta temp_X lda GS_screen,x ; from screen and #$00F0 ; mask (A0AA) ora temp_X ; add color sta GS_screen,x ; to screen ************ pla ; get packet_size back sec sbc #3 beq done_repeat ; any left? sta packet_size inx ; fix offset on screen inx ; number of words to write is packet_size / 4 ; getting here means we start on an even byte boundry ; and packet_size >= 1 even lda packet_size ; cmp #4 bcc re5 ; < 4? lsr a ; /2 lsr a ; /4 phy ; save y value tay ; quotient value ; loop to write words to screen as fast as possible lda color1 ; color to write GS_loop sta GS_screen,x ;*************** inx inx ; 4 pixels / word dey ; any words left to write? bne GS_loop ply ; get y back ; lower 2 bits re4 lda packet_size and #$3 ; only want lower 3 pixels ; are there any pixels to draw? beq done_repeat ; done re5 cmp #2 ; 2 pixels beq draw_two ; = 2 bcs draw_3 ; >= 2 ; default draw 1 ; draw one pixel on an even byte boundry draw_one short m lda color1 ; default 1 pixel (aaaa) and #$F0 ; (00a0) sta color1 ; save it lda GS_screen,x ; from screen and #$0F ; mask ora color1 ; add color sta GS_screen,x ; to screen ************** long m bra done_repeat ; done ; two pixels = 1 byte draw_two short m ; 8 bits wide lda color1 ; just store directly to screen sta GS_screen,x long m bra done_repeat ; done ; 3 pixels aligned on an even byte boundry draw_3 lda color1 ; (aaaa) and #$F0FF ; (a0aa) sta color1 lda GS_screen,x ; from screen and #$0F00 ; mask ora color1 ; add color sta GS_screen,x ; to screen **************** ;here is joint end for both repeat and copy done_repeat dec packets ; one less to do lda VGA_X clc adc packet_type sta VGA_X ; fix x jmp loop2 ; go do next packet ; screen_copy copies multiple colors (packet_type) times to the screen ; packet_type = positive ; on entry Accum has the value of packet_type screen_copy sta packet_size ; init lda VGA_X ; check for odd x bit #1 bne doOdd ; yep jmp even1 doOdd lda packet_size cmp #2 beq Codd2pix ; = 2 bcc odd1 ; < 2 jmp Codd3pix ; > 2 pixels ; draw just one pixel in odd location ; so draw 1 first odd1 lda [data],y ; byte iny and #$00FF asl a ; x2 tax lda odd_pixel,x ; (0 - 15) sta color ldx temp_X lda GS_screen,x ; from screen and #$FFF0 ; mask ora color ; add color sta GS_screen,x ; to screen ******************** jmp done_repeat ; done Codd2pix lda [data],y ; word iny iny pha and #$00FF asl a tax lda odd_pixel,x ; (000a) ; pixel 1 sta color ; (00a0) pla xba and #$00FF asl a tax lda even_pixel,x ; (000b) xba ora color ; pixel 2 sta color ; (00ab) ldx temp_X ; ; 2 pixels starting from odd pixel lda GS_screen,x and #$0FF0 ora color sta GS_screen,x ;**************************** jmp done_repeat Codd3pix lda [data],y ; word iny iny pha and #$00FF asl a tax lda odd_pixel,x ; (000a) ; pixel 1 sta color ; (0001) pla xba and #$00FF asl a tax lda even_pixel,x ; (000b) ; pixel 2 sta color1 ; (0020) lda [data],y ; byte iny and #$00FF asl a tax lda odd_pixel,x ; (000a) ora color1 xba ; (0023) ora color ; pixel 3 sta color ; (2301) ldx temp_X lda GS_screen,x ; from screen and #$00F0 ; mask ora color ; add color sta GS_screen,x ; to screen ******************** lda packet_size sec sbc #3 bne re6 jmp done_repeat ; save packet_size re6 sta packet_size ; fix x inx inx stx temp_X ; fix x offset even1 lda packet_size ; here means starting on an even byte ok1 cmp #4 ; >= 4? bcs tt1 ; no so see how many pixels left jmp cont10 tt1 lsr a ; /2 lsr a ; /4 ; quotient is number of words to write to screen sc2 sta quotient ; multiple of 4 pixels to write sc3 lda [data],y ; word iny iny pha ; save it for later and #$00FF asl a tax lda even_pixel,x ; (000a) sta color ; (00a0) pla xba ; swap a and b and #$00FF asl a tax lda odd_pixel,x ; (000b) ora color sta color ; (00ab) lda [data],y ; word iny iny pha and #$00FF asl a tax lda even_pixel,x ; (000c) sta color1 ; (c0ab) pla xba and #$00FF asl a tax ; the reason for storing different parts in color and color1 ; is that there is only one 'xba ora color1' lda odd_pixel,x ; (000d) ora color1 ; (cdab) xba ora color ldx temp_X ; temp_X = (VGA_X /2) + GS_offset sta GS_screen,x ;************************* inx inx stx temp_X ; temp_X = temp_X + 2 ; are we done? dec quotient beq cont9 jmp sc3 ; see what is left to draw cont9 lda packet_size and #3 ; ; check for any pixels to draw cont9a bne cont10 jmp done_repeat ; done cont10 cmp #2 beq Ido2 ; = 2 bcs Ido3 ; > 2 pixels? bra Ido1 ; < 2 ; default draw 2 pixels Ido2 lda [data],y ; word iny iny pha and #$00FF asl a tax lda even_pixel,x ; (000a) sta color ; (00a0) pla xba and #$00FF asl a tax lda odd_pixel,x ; (000b) ora color ldx temp_X ; short m sta GS_screen,x long m jmp done_repeat Ido3 lda [data],y ; word iny iny pha ; save it for later and #$00FF asl a tax lda even_pixel,x ; (000a) sta color pla ; get it back and #$00FF asl a tax lda odd_pixel,x ; (000b) ora color sta color ; (00ab) lda [data],y ; byte iny and #$00FF asl a tax lda even_pixel,x ; (000c) xba ; swap a and b ora color sta color ; (c0ab) ldx temp_X ; lda GS_screen,x and #$0F00 ora color sta GS_screen,x ;*********************** jmp done_repeat Ido1 lda [data],y ; byte iny and #$00FF asl a tax lda even_pixel,x ; (000a) sta color ; (00a0) ldx temp_X lda GS_screen,x and #$FF0F ora color sta GS_screen,x ;********************* jmp done_repeat end append task.asm