diff --git a/graphics/hgr/flood_fill/Makefile b/graphics/hgr/flood_fill/Makefile new file mode 100644 index 00000000..5525bed1 --- /dev/null +++ b/graphics/hgr/flood_fill/Makefile @@ -0,0 +1,32 @@ +include ../../../Makefile.inc + +DOS33 = ../../../utils/dos33fs-utils/dos33 +TOKENIZE = ../../../utils/asoft_basic-utils/tokenize_asoft +LINKER_SCRIPTS = ../../../linker_scripts +EMPTY_DISK = ../../../empty_disk + +all: flood.dsk + +flood.dsk: HELLO FLOOD + cp $(EMPTY_DISK)/empty.dsk flood.dsk + $(DOS33) -y flood.dsk SAVE A HELLO + $(DOS33) -y flood.dsk BSAVE -a 0x6800 FLOOD + + +### + +HELLO: hello.bas + $(TOKENIZE) < hello.bas > HELLO + + +#### + +FLOOD: flood.o + ld65 -o FLOOD flood.o -C $(LINKER_SCRIPTS)/apple2_6800.inc + +flood.o: flood.s + ca65 -o flood.o flood.s -l flood.lst + +#### +clean: + rm -f *~ *.o *.lst HELLO FLOOD diff --git a/graphics/hgr/flood_fill/flood.s b/graphics/hgr/flood_fill/flood.s new file mode 100644 index 00000000..377c0fdc --- /dev/null +++ b/graphics/hgr/flood_fill/flood.s @@ -0,0 +1,883 @@ +;******************************************************************************* +;* Micro-Painter, by Bob Bishop * +;* Copyright 1980 Datasoft, Inc. All Rights Reserved. * +;* * +;* Disassembly of "PAINT" routines. * +;******************************************************************************* +;* Disassembly by Andy McFadden, using 6502bench SourceGen v1.4. * +;* Last updated 2019/10/25. * +;******************************************************************************* + +color_black = 0 +color_purple = 1 +color_green = 2 +color_blue = 3 +color_orange = 4 +color_white = 5 +work_buffer = $7000 ; work data area,$ from $7000-7fff +TXTCLR = $c050 +MIXCLR = $c052 +TXTPAGE1 = $c054 +LORES = $c056 + +;******************************************************************************* +;* FILL - flood fill with dither pattern. * +;* * +;* Uses a circular buffer at $7000-7fff to hold X/Y coordinates. The color of * +;* the pixel at the initial X/Y is used as the to-fill color. * +;* * +;* Start by adding the initial X/Y to the work buffer. We then loop, removing * +;* the first coordinate from the buffer and testing the color at that location.* +;* If it matches, we draw the pixel, and then add the four adjacent pixels to * +;* the list. Repeat until the list is empty. * +;* * +;* Warning: filling with the same color, e.g. filling a white area with white,* +;* will likely hang. * +;* * +;* On entry: * +;* $01 - X-coord * +;* $02 - Y-coord * +;* $04 - even color (0-5) * +;* $05 - odd color (0-5) * +;* * +;* Preserves X/Y registers. * +;******************************************************************************* + +xc = $01 +yc = $02 +back = $03 +evenc = $04 +oddc = $05 +match_color = $10 +add_coord_lo = $12 +plot_coord_lo = $13 +add_coord_ptr = $14 ; new coords are added at this point +plot_coord_ptr = $16 ; coords are read from this pointer and plotted +tmp = $18 + +FILL: + txa + pha + tya + pha + lda #$80 + sta back + jsr PLT ; get current color at X,Y + lda back + sta match_color ; this is the color we're replacing + lda #work_buffer + sta add_coord_ptr+1 + sta plot_coord_ptr+1 + lda xc ; put first point into work buffer + sta work_buffer + lda yc + sta work_buffer+1 + ldy #$02 ; point next output past the X,Y we just added + sty add_coord_lo + ldy #$00 + sty plot_coord_lo + + ; Get the next candidate coordinate. + +FillLoop: + lda (plot_coord_ptr),Y + sta xc + iny + lda (plot_coord_ptr),Y + sta yc + iny + bne L6845 ; still on same page, branch + inc plot_coord_ptr+1 ; move to next page + lda plot_coord_ptr+1 + cmp #$80 ;did we reach the end of the buffer? + bne L6845 ; no, keep going + lda #>work_buffer ; yes, reset it + sta plot_coord_ptr+1 +L6845: + sty plot_coord_lo + lda #$80 + sta back + jsr PLT ; get screen pixel color + lda back + cmp match_color ; matching color? + bne L6873 ; no, don't plot + +; The current pixel matches the color we want to replace. Plot a pixel and add +; the four adjacent pixels to the work list. + + jsr DITHER ; plot pixel with dither colors + inc xc + jsr AddCoord ; X+1,Y + dec xc + inc yc + jsr AddCoord ; X,Y+1 + dec xc + dec yc + jsr AddCoord ; X-1,Y + inc xc + dec yc + jsr AddCoord ; X-1,Y-1 + inc yc +L6873: + ldy plot_coord_lo ; have we reached the end? + cpy add_coord_lo + bne FillLoop ; low part differs, continue + lda plot_coord_ptr+1 + cmp add_coord_ptr+1 + bne FillLoop ; high part differs, continue + pla ; done! + tay + pla + tax + rts + +AddCoord: + lda yc ; check Y-coord + cmp #255 ; off top of screen? + beq L68CA ; yes, ignore + cmp #192 ; off bottom of screen? + beq L68CA ; yes, ignore + lda xc ; check X-coord + cmp #$ff ; off left of screen? + beq L68CA ; yes, ignore + cmp #140 ; off right of screen? + beq L68CA ; yes, ignore + +; Looks good, add X,Y to list. +; Note add_coord_ptr is always $xx00; the low byte is in add_coord_lo. + + ldy add_coord_lo + sta (add_coord_ptr),Y + iny + lda yc + sta (add_coord_ptr),Y + iny + sty add_coord_lo + lda add_coord_ptr+1 + sta tmp + cpy #$00 ; did we advance to next page? + bne L68B8 ; no, continue + inc add_coord_ptr+1 ; yes, advance + lda add_coord_ptr+1 + cmp #(>work_buffer)+16 ; did we reach end of work area? + bne L68B8 ; no, still good + lda #>work_buffer ; yes, wrap around + sta add_coord_ptr+1 +L68B8: + cpy plot_coord_lo ; did we run into the "write" ptr? + bne L68CA ; no + lda plot_coord_ptr+1 ; check the high byte + cmp add_coord_ptr+1 + bne L68CA ;still no + dec add_coord_lo ; whoops; back up, discarding what we just added + dec add_coord_lo + lda tmp ; restore previous high byte + sta add_coord_ptr+1 +L68CA: + rts + +.align $100 + +DITHER: + jmp DITHER1 + +PLT: + jmp PLT1 ; external entry point + +;******************************************************************************* +;* DITHER - plot a point with dithered colors. * +;* * +;* On entry: * +;* * +;* $00 - hi-res page (zero for page 1, nonzero for page 2) * +;* $01 - X coordinate [0,139] * +;* $02 - Y coordinate [0,191] * +;* $04 - even color value * +;* $05 - odd color value * +;* * +;* Preserves X/Y registers. * +;******************************************************************************* +;Clear variables +pageflg = $00 +;xc = $01 +;yc = $02 +;back = $03 +;evenc = $04 +;oddc = $05 +hptr = $07 + +DITHER1: + txa + pha + lda yc ; start with the Y-coord + ldx evenc ; check the even color + beq L691A ; black, use checkerboard + cpx #color_white ; white + beq L691A ; yes, use checkerboard pattern + ldx oddc ; check the odd color + beq L691A ; black, use checkerboard + cpx #color_white ; white? + bne L691C ; yes, use checkerboard +L691A: + eor xc ; factor in the X coord to get checkerboard +L691C: + and #$01 ; only low bit matters + tax ; X=0 or 1 + lda evenc,X ; load evenc or oddc + sta back ; set as color to draw + jmp Plt2 + +;******************************************************************************* +;* PLT - plot a point and return the current color. * +;* * +;* On entry: * +;* * +;* $00 = hi-res page (zero for page 1, nonzero for page 2) * +;* $01 = X-coord [0,139] * +;* $02 = Y-coord [0,191] * +;* $03 = $80=no plot, 0-5=color to draw * +;* * +;* On exit: * +;* $03 = screen color (0-5) (will be the new color if we're in draw mode) * +;* * +;* Preserves X/Y registers. * +;******************************************************************************* +screen_bit = $06 +cflag = $09 + +PLT1: + txa + pha +Plt2: + tya + pha + jsr SetRowBase ; set $07-08 as hi-res pointer + ldx back ; get color + bmi L693B ; not drawing, branch + lda color_flag_0,X ; get color flags for the two bits + sta cflag + lda color_flag_1,X + sta cflag+1 +L693B: + ldx xc + ldy div7_tab,X ; get byte offset + lda bit_tab,X ; get bit offset (low bit of pair) + sta screen_bit + +; We want to read/write two hi-res bits, so we loop through here twice. + + ldx #$00 ; first bit +BitLoop: + lda screen_bit + bit back ; are we writing? + bpl PlotWrite ; yes, branch + +; Just reading the screen. + + and (hptr),Y ; test screen bit + beq BitLoopBottom ; not set + txa ; 0 or 1 + sec ; will add +1 or +2 + adc back ; so this sets bit 0 or bit 1 + sta back + lda (hptr),Y ; check hi bit + bpl BitLoopBottom ; not set, branch + lda back ; set bit 2 if the hi-res pixel's high bit was set + ora #$04 + sta back + bne BitLoopBottom + + +; Draw the pixel. + +PlotWrite: + eor #$ff ; reverse screen bit to form mask + and (hptr),Y ; AND with screen data + sta (hptr),Y ; store, clearing previous value at that bit + lda cflag,X ; get color flag 0 or 1 + beq BitLoopBottom ; zero, don't need to set pixel or high bit + lda screen_bit ; nonzero, set the appropriate bit in the pixel + ora (hptr),Y + sta (hptr),Y + lda cflag ; is it black or white? + cmp cflag+1 ; (want black/white to match hi bit of adjacent color) + beq BitLoopBottom ; yes, leave high bit alone + lda (hptr),Y ; not black or white, so we need to set high bit + and #$7f ; clear whatever's there now + sta (hptr),Y + lda cflag,X ; get high bit from color flag + and #$80 + ora (hptr),Y + sta (hptr),Y ; set that on the screen +BitLoopBottom: + inx + cpx #$02 ; have we done it twice? + beq BitLoopDone ; yes, bail + asl screen_bit ; no, shift screen bit to next position + bpl BitLoop ; didn't shift into high bit, loop + iny ; shifted into high bit, move on to next byte + lda #$01 ; and reset bit to low bit + sta screen_bit + bne BitLoop ; (always) + +BitLoopDone: + lda back ; were we writing? + bpl L69A3 ; yes, bail + and #$07 ; no, do a color lookup + tax + lda bits_to_color,X ; convert 00000HBA to 0-5 + sta back +L69A3: + pla + tay + pla + tax + rts + +;.junk 29 +.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +.byte 0,0,0,0,0,0,0,0,0,0,0,0,0 + +; +; Sets $07-08 as the hi-res base pointer for the row in "yc". +; + +SetRowBase: + ldy yc + lda ytable_lo,Y + sta hptr + lda pageflg ; 0 for page 1, nonzero for page 2 + beq L69D2 + lda #$60 ; configure for page 2 +L69D2: + eor ytable_hi,Y + sta hptr+1 + rts + +; These bytes have three possible values. They're used by PLT to figure out +; which bits to set on the hi-res screen for a given color (0-5). +; +; $00 = don't set this bit +; $7f = set this bit, clear high bit of byte +; $ff = set this bit, set high bit of byte +; +; Each hi-res color (in our 140x192 screen) requires two bits per pixel. One +; bit comes from each table. + +color_flag_0: + .byte $00,$7f,$00,$ff,$00,$ff + +color_flag_1: + .byte $00,$00,$7f,$00,$ff,$ff +; +; Converts a bit pattern to a color, 0-5. +; +; Index is a 3-bit value 00000HBA, where A is set if the first bit of the hi-res +; pixel was set, B is set if the second bit of the hi-res pixel was set, and H +; is set if the high bit of at least one of the bytes with a pixel was set. +; (Remember that we're treating the screen as being 140 pixels across, so it's +; two bits per pixel.) + +bits_to_color: + .byte color_black + .byte color_purple + .byte color_green + .byte color_white + .byte color_black + .byte color_blue + .byte color_orange + .byte color_white + +.align $100 + +SCOPE: + jmp SCOPE1 ; entry point from Applesoft + +;******************************************************************************* +;* INIT - initialize "micro" / "scope" mode * +;* * +;* Clears the lo-res screen and enables lo-res graphics mode. * +;* * +;* Preserves X/Y registers. * +;******************************************************************************* +; Clear variables +ptr = $0e + +INIT: + txa + pha + tya + pha + + ; Clear lo-res screen to black. + + ldx #23 ; X = row +ClearLoLoop: + lda lr_ytable_lo,X + sta ptr + lda lr_ytable_hi,X + sta ptr+1 + lda #$00 + ldy #39 ; Y = column +L6A17: + sta (ptr),Y + dey + bpl L6A17 + dex + bpl ClearLoLoop + + ; Configure soft-switches for lo-res. + sta TXTCLR + sta MIXCLR + sta TXTPAGE1 + sta LORES + pla + tay + pla + tax + rts + +;******************************************************************************* +;* SCOPE - display part of the hi-res screen magnified on the lo-res screen. * +;* * +;* On entry: * +;* $00 = X position [0,139] * +;* $01 = Y position [0,191] * +;* * +;* Preserves X/Y registers. * +;******************************************************************************* +;Clear variables +;xc = $00 +;yc = $01 +col_ctr = $02 +row_ctr = $03 +saved_byte_off = $04 +work_ptr_lo = $05 +first_bit = $06 +hr_byte = $07 +hi_in_lo = $08 +start_x = $09 +;hptr = $0c +work_ptr = $0e + +SCOPE1: + txa + pha + tya + pha + sec ; left edge is XC - 9 + lda xc + sbc #9 + sta xc + sta start_x + sec + lda yc ; top edge is YC - 11 + sbc #11 + sta yc + lda #$00 + sta work_ptr_lo + sta work_ptr + lda #>work_buffer + sta work_ptr+1 ; out_ptr = work buffer + +; +; Phase 1: convert hi-res pixels to values in the work buffer. +; +; Each hi-res pixel in our window gets two adjacent values in the work buffer, +; one per bit. The value is from 0-3, and reflects the state of one bit on the +; pixel plus the high bit of the byte. +; +; Note: there's a 1-pixel black border on the left and right of the lo-res +; display, presumably to allow the central 2x2 block to be centered on the +; screen. There's also a 2-pixel black border on the bottom of the screen. +; + + lda #23 + sta row_ctr +RowLoop: + lda #38 + sta col_ctr + ldx yc ; get the Y-coord + cpx #192 ; did we wrap off the top? + bcs OffEdge ; yes, bail + lda ytable_lo,X ; get the hi-res row base + sta hptr + lda ytable_hi,X + sta hptr+1 + ldx xc ; get the X-coord + cpx #140 ; did we wrap around to the left when subtracting? + bcc ScanPixel ; no, scan it + +; We're off the left edge, so just fill in black until we get on the screen. + + ldy work_ptr_lo + lda #$00 +OffLeftLoop: + sta (work_ptr),Y + iny + sta (work_ptr),Y + iny + bne L6A7A + inc work_ptr+1 +L6A7A: + dec col_ctr + dec col_ctr + inx + bne OffLeftLoop + sty work_ptr_lo + clc + +; Get the color of a pixel. X coordinate in X-reg, carry flag is clear. + +ScanPixel: + lda bit_tab,X ; get first hi-res pixel bit + sta first_bit + ldy div7_tab,X ; get byte offset + ldx col_ctr ; lo-res column counter +L6A8E: + lda (hptr),Y ; get hi-res byte + sta hr_byte + and #$80 ; clear everything but the hi bit + rol ; roll it into the low bit + rol ; (note carry was clear) + sta hi_in_lo + iny + sty saved_byte_off + ldy work_ptr_lo +L6A9D: + lda hr_byte ; get pixel byte + and first_bit ; mask off everything but interesting bit + beq L6AA5 ; bit not set, branch + lda #$02 ; bit set, use $02 regardless of bit position +L6AA5: + ora hi_in_lo ; add high bit (so now value is 0-3) + sta (work_ptr),Y ; save that off + iny ; advance work ptr + bne L6AAE + inc work_ptr+1 +L6AAE: + dex ; decrement column counter + beq L6AD2 ; bail when we reach column 0 + asl first_bit ; shift to the next bit in the pixel + bpl L6A9D ; still in same byte, repeat + sty work_ptr_lo + lda #$01 ; move to next byte, reset mask to bit 0 + sta first_bit + ldy saved_byte_off + cpy #40 ; off right edge of hi-res screen? + bcc L6A8E ; nope, keep going + stx col_ctr ; yes, go into "off edge" code + +; We're off the edge, to the right or the bottom. Fill out the row with black +; pixels. + +OffEdge: + ldy work_ptr_lo + lda #$00 +L6AC7: + sta (work_ptr),Y + iny + bne L6ACE + inc work_ptr+1 +L6ACE: + dec col_ctr ; decrement the column counter + bne L6AC7 ; not end of row yet, branch +L6AD2: + sty work_ptr_lo + lda start_x ; reset X-coord + sta xc + inc yc ; advance to next row + dec row_ctr ; are we done? + beq Scope2 ; yes, move to rendering + jmp RowLoop ; no, loop + +.align $100 + +; Phase 2: render the contents of the work buffer on the lo-res screen. +; +; The values in the work buffer are from 0-3. 0/2 indicates that the +; corresponding hi-res bit was set, +1 if the high bit in the byte was set. + +;work_ptr = $0c +lr_ptr = $0e + +Scope2: + lda #$01 ; left edge; 1-pixel boundary at sides + sta xc + lda #$00 ; no border at top + sta yc + sta saved_byte_off + sta work_ptr + lda #>work_buffer + sta work_ptr+1 + ldx yc ; get lo-res screen row base +L6B12: + lda lr_ytable_lo,X + sta lr_ptr + lda lr_ytable_hi,X + sta lr_ptr+1 +DrawLoLoop: + ldy saved_byte_off + lda (work_ptr),Y ; get the first value + iny + asl ; shift it over + asl + ora (work_ptr),Y ; add in the second value + iny ; advance work ptr + bne L6B2A + inc work_ptr+1 +L6B2A: + sty saved_byte_off + tax ; put color value (0-15) in X + lda lr_color_map,X ; convert it to a lo-res color + ldy xc + sta (lr_ptr),Y ; plot 2x2 pixel (two bytes wide) + iny + sta (lr_ptr),Y + iny + sty xc + cpy #39 ; end of row? + bne DrawLoLoop ; not yet, loop + lda #$01 ; reset X-coord + sta xc + inc yc ; advance to next row + ldx yc + cpx #23 ; done? (leaves 1-pixel boundary at bottom) + bne L6B12 ; no, loop + +; Draw crosshairs. It flickers a little because, on each loop, we draw the hi- +; res colors and then slam the crosshairs down. + + lda #$dd ; two pixels, color=13 (yellow) + ldx #$04 +L6B4E: + sta $05b5,X ; hard-wired screen positions + sta $05be,X + dex + bpl L6B4E + ldx #$01 +L6B59: + sta $043b,X + sta $04bb,X + sta $06bb,X + sta $073b,X + dex + bpl L6B59 + +; Add "half-pixel" crosshair gap. The hi-res pixel at the center is a 2x2 lo- +; res block. We create a gap of 1 lo-res block between it and the crosshair. +; For the vertical line, that means we're not writing a full byte, because each +; text byte holds two lo-res blocks. + + ldx #$01 +L6B6A: + lda $053b,X ; draw one pixel with color=13 + and #$f0 ; leave other pixel alone + ora #$0d + sta $053b,X + lda $063b,X + and #$0f + ora #$d0 + sta $063b,X + dex + bpl L6B6A + pla + tay + pla + tax + rts + +; Low-res row address, low byte. + +lr_ytable_lo: +.byte $00,$80,$00,$80,$00,$80,$00,$80 +.byte $28,$a8,$28,$a8,$28,$a8,$28,$a8 +.byte $50,$d0,$50,$d0,$50,$d0,$50,$d0 + +; Low-res row address,$ high byte. + +lr_ytable_hi: +.byte $04,$04,$05,$05,$06,$06,$07,$07 +.byte $04,$04,$05,$05,$06,$06,$07,$07 +.byte $04,$04,$05,$05,$06,$06,$07,$07 + +; +; Map hi-res pixel values to lo-res colors. +; +; Index is AHBH, where A and B are the hi-res pixel values, and H is the high +; bit of the hi-res byte. For example, green is 0010, purple is 1010, orange is +; 0111, blue is 1101. +; +; Some pixels straddle two bytes and potentially have different values for the +; high bit in each. Each color thus has two entries. +; +lr_color_map: +.byte $00 ; 0000 lo-res color 0 = black +.byte $00 ; 0001 +.byte $cc ; 0010 12 = light green +.byte $99 ; 0011 9 = orange +.byte $00 ; 0100 +.byte $00 ; 0101 +.byte $cc ; 0110 +.byte $99 ; 0111 +.byte $33 ; 1000 3 = purple +.byte $33 ; 1001 +.byte $ff ; 1010 15 = white +.byte $ff ; 1011 +.byte $66 ; 1100 6 = medium blue +.byte $66 ; 1101 +.byte $ff ; 1110 +.byte $ff ; 1111 + +.align $100 + +; Hi-res row base address, low byte. +ytable_lo: +.byte $00,$00,$00,$00,$00,$00,$00,$00,$80,$80,$80,$80,$80,$80,$80,$80 +.byte $00,$00,$00,$00,$00,$00,$00,$00,$80,$80,$80,$80,$80,$80,$80,$80 +.byte $00,$00,$00,$00,$00,$00,$00,$00,$80,$80,$80,$80,$80,$80,$80,$80 +.byte $00,$00,$00,$00,$00,$00,$00,$00,$80,$80,$80,$80,$80,$80,$80,$80 +.byte $28,$28,$28,$28,$28,$28,$28,$28,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8 +.byte $28,$28,$28,$28,$28,$28,$28,$28,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8 +.byte $28,$28,$28,$28,$28,$28,$28,$28,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8 +.byte $28,$28,$28,$28,$28,$28,$28,$28,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8 +.byte $50,$50,$50,$50,$50,$50,$50,$50,$d0,$d0,$d0,$d0,$d0,$d0,$d0,$d0 +.byte $50,$50,$50,$50,$50,$50,$50,$50,$d0,$d0,$d0,$d0,$d0,$d0,$d0,$d0 +.byte $50,$50,$50,$50,$50,$50,$50,$50,$d0,$d0,$d0,$d0,$d0,$d0,$d0,$d0 +.byte $50,$50,$50,$50,$50,$50,$50,$50,$d0,$d0,$d0,$d0,$d0,$d0,$d0,$d0 + +;******************************************************************************* +;* CLEAN -- set all non-white pixels to black. * +;* * +;* Preserves X/Y registers. * +;******************************************************************************* + +; Clear variables + +;xc = $01 +;yc = $02 +;back = $03 + +CLEAN: + txa + pha + tya + pha + ldy #$00 +L6CC6: + ldx #$00 +L6CC8: + stx xc + sty yc + lda #$80 ; read only + sta back + jsr PLT ; get current pixel color + lda back + cmp #color_white ; is it a white pixel? + beq L6CE0 ; yes, leave it alone + lda #color_black ; no, clear it + sta back + jsr PLT ; draw black pixel +L6CE0: + inx + cpx #140 ; end of line? + bne L6CC8 ; no, continue + iny + cpy #192 ; end of screen? + bne L6CC6 ; no, continue + pla + tay + pla + tax + rts + +.align $100 + +; Hi-res row base address, high byte. + +ytable_hi: +.byte $20,$24,$28,$2c,$30,$34,$38,$3c,$20,$24,$28,$2c,$30,$34,$38,$3c +.byte $21,$25,$29,$2d,$31,$35,$39,$3d,$21,$25,$29,$2d,$31,$35,$39,$3d +.byte $22,$26,$2a,$2e,$32,$36,$3a,$3e,$22,$26,$2a,$2e,$32,$36,$3a,$3e +.byte $23,$27,$2b,$2f,$33,$37,$3b,$3f,$23,$27,$2b,$2f,$33,$37,$3b,$3f +.byte $20,$24,$28,$2c,$30,$34,$38,$3c,$20,$24,$28,$2c,$30,$34,$38,$3c +.byte $21,$25,$29,$2d,$31,$35,$39,$3d,$21,$25,$29,$2d,$31,$35,$39,$3d +.byte $22,$26,$2a,$2e,$32,$36,$3a,$3e,$22,$26,$2a,$2e,$32,$36,$3a,$3e +.byte $23,$27,$2b,$2f,$33,$37,$3b,$3f,$23,$27,$2b,$2f,$33,$37,$3b,$3f +.byte $20,$24,$28,$2c,$30,$34,$38,$3c,$20,$24,$28,$2c,$30,$34,$38,$3c +.byte $21,$25,$29,$2d,$31,$35,$39,$3d,$21,$25,$29,$2d,$31,$35,$39,$3d +.byte $22,$26,$2a,$2e,$32,$36,$3a,$3e,$22,$26,$2a,$2e,$32,$36,$3a,$3e +.byte $23,$27,$2b,$2f,$33,$37,$3b,$3f,$23,$27,$2b,$2f,$33,$37,$3b,$3f + +;******************************************************************************* +;* NEG -- reverse colors on entire hi-res screen * +;* * +;* Does a top-to-bottom operation to avoid the Venetian-blind look. * +;******************************************************************************* + +; Clear variables + +;xc = $01 +;yc = $02 +;hptr = $07 +;hptr_h = $08 + +NEG: + txa + pha + tya + pha + ldx #$00 ; start at the top +L6DC6: + stx yc + jsr SetRowBase ; get address in hptr + ldy #39 ; for each byte in the row +L6DCD: + lda (hptr),Y + eor #$ff ; reverse colors + sta (hptr),Y + dey + bpl L6DCD + inx ; next row + cpx #192 ; done? + bne L6DC6 + pla + tay + pla + tax + rts + + + +.align $100 + +; Maps X coordinate [0,139] to bit. + +bit_tab: +.byte $01,$04,$10,$40,$02,$08,$20,$01,$04,$10,$40,$02,$08,$20,$01,$04 +.byte $10,$40,$02,$08,$20,$01,$04,$10,$40,$02,$08,$20,$01,$04,$10,$40 +.byte $02,$08,$20,$01,$04,$10,$40,$02,$08,$20,$01,$04,$10,$40,$02,$08 +.byte $20,$01,$04,$10,$40,$02,$08,$20,$01,$04,$10,$40,$02,$08,$20,$01 +.byte $04,$10,$40,$02,$08,$20,$01,$04,$10,$40,$02,$08,$20,$01,$04,$10 +.byte $40,$02,$08,$20,$01,$04,$10,$40,$02,$08,$20,$01,$04,$10,$40,$02 +.byte $08,$20,$01,$04,$10,$40,$02,$08,$20,$01,$04,$10,$40,$02,$08,$20 +.byte $01,$04,$10,$40,$02,$08,$20,$01,$04,$10,$40,$02,$08,$20,$01,$04 +.byte $10,$40,$02,$08,$20,$01,$04,$10,$40,$02,$08,$20 + +.align $100 + +; Maps X coordinate [0,$139] to byte [0,$39]. + +div7_tab: +.byte $00,$00,$00,$00,$01,$01,$01,$02,$02,$02,$02,$03,$03,$03,$04,$04 +.byte $04,$04,$05,$05,$05,$06,$06,$06,$06,$07,$07,$07,$08,$08,$08,$08 +.byte $09,$09,$09,$0a,$0a,$0a,$0a,$0b,$0b,$0b,$0c,$0c,$0c,$0c,$0d,$0d +.byte $0d,$0e,$0e,$0e,$0e,$0f,$0f,$0f,$10,$10,$10,$10,$11,$11,$11,$12 +.byte $12,$12,$12,$13,$13,$13,$14,$14,$14,$14,$15,$15,$15,$16,$16,$16 +.byte $16,$17,$17,$17,$18,$18,$18,$18,$19,$19,$19,$1a,$1a,$1a,$1a,$1b +.byte $1b,$1b,$1c,$1c,$1c,$1c,$1d,$1d,$1d,$1e,$1e,$1e,$1e,$1f,$1f,$1f +.byte $20,$20,$20,$20,$21,$21,$21,$22,$22,$22,$22,$23,$23,$23,$24,$24 +.byte $24,$24,$25,$25,$25,$26,$26,$26,$26,$27,$27,$27 diff --git a/graphics/hgr/flood_fill/hello.bas b/graphics/hgr/flood_fill/hello.bas new file mode 100644 index 00000000..53cd3e2a --- /dev/null +++ b/graphics/hgr/flood_fill/hello.bas @@ -0,0 +1,2 @@ +10 PRINT CHR$ (4)"BRUN FLOOD" + diff --git a/linker_scripts/apple2_6700.inc b/linker_scripts/apple2_6700.inc new file mode 100644 index 00000000..d399991f --- /dev/null +++ b/linker_scripts/apple2_6700.inc @@ -0,0 +1,12 @@ +MEMORY { + ZP: start = $00, size = $1A, type = rw; + RAM: start = $6700, size = $6000, file = %O; +} + +SEGMENTS { +CODE: load = RAM, type = ro, align=$100; +RODATA: load = RAM, type = ro; +DATA: load = RAM, type = rw; +BSS: load = RAM, type = bss, define = yes; +ZEROPAGE: load = ZP, type = zp; +} diff --git a/linker_scripts/apple2_6800.inc b/linker_scripts/apple2_6800.inc new file mode 100644 index 00000000..8f076dcd --- /dev/null +++ b/linker_scripts/apple2_6800.inc @@ -0,0 +1,12 @@ +MEMORY { + ZP: start = $00, size = $1A, type = rw; + RAM: start = $6800, size = $6000, file = %O; +} + +SEGMENTS { +CODE: load = RAM, type = ro, align=$100; +RODATA: load = RAM, type = ro; +DATA: load = RAM, type = rw; +BSS: load = RAM, type = bss, define = yes; +ZEROPAGE: load = ZP, type = zp; +}