;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; PICDRAWH (standard hi-res picture painter) from ;
; The Graphics Magician for the Apple II, 1984 edition ;
; ;
; Copyright Penguin Software ;
; Binary obtained from http://graphicsmagician.com/polarware/ ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Disassembly by Andy McFadden, using 6502bench SourceGen v1.9.2. ;
; Last updated 2025/07/16 ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Public interface: ;
; ;
; A pointer to the picture data is passed in $00/01. When the drawing code ;
; finishes, the pointer will be set past the last byte processed. ;
; ;
; $8d00 (36096): clears the hi-res screen to white1 (white with high bit ;
; set), then draws the picture. ;
; $8d03 (36099): draws the picture without clearing the screen first. Useful ;
; when drawing on top of a background image or a previous picture. ;
; $8d06 (36102): skips the screen clear, draws the picture with the top-left ;
; moved to the coordinates specified in $8d09-8d0b (36105-16107). This is ;
; used for "objects", so the first command in the file must be a dummy "start ;
; line" that specifies the object's top-left origin. ;
; $8d72 (36210): draws one step only. Set $8d1c (36124) to 1, call the ;
; standard entry point once, then call this repeatedly. ;
; ;
; Additional variables and calls used by PICEDIT tool: ;
; $8d0d (SP+13): current pattern index (0-107) ;
; $8d0e (SP+14): current brush or glyph index (0-127) ;
; $8d0f/10 (SP+15/16): current X coordinate lo/hi ;
; $8d11 (SP+17): reverse text flag ;
; $0a (10): current Y coordinate ;
; $9043 (SP+835): draws current brush or glyph with the current pattern at ;
; the current coordinates. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pic_ptr .eq $00 {addr/2} ;pointer to picture data, set by caller
pat_subindex_even .eq $02
pat_subindex_odd .eq $03
pixel_mask .eq $04
cmd_yc .eq $0a ;current Y coordinate
BAS_HPAG .eq $e6 ;hi-res page to draw on ($20 or $40)
pat_subindex_x4 .eq $ff ;pattern subindex for current row, x4
HCLEAR .eq $f3f4 ;clear hi-res screen, color in A-reg
BAS_HPOSN .eq $f411 ;set hi-res position; horiz=(Y,X) vert=A
BAS_HGLIN .eq $f53a ;draw line from last point to (A,X),Y
HCOLOR1 .eq $f6ec ;HCOLOR= with color in X-reg
;
; Public entry points.
;
.addrs $8d00
8d00: 4c 3a 8d ClearAndDraw jmp DoClearAndDraw
8d03: 4c 3f 8d DrawNoClear jmp DoDrawNoClear
8d06: 4c 1d 8d DrawAtCoord jmp DoDrawAtCoord
;
; Variables. Some are public, some are used by the editor, some are internal.
;
8d09: 00 arg_xoff_lo .dd1 $00 ;(36105) top-left X coord, low part
8d0a: 00 arg_xoff_hi .dd1 $00 ;(36106) top-left X coord, high part
8d0b: 00 arg_yoff .dd1 $00 ;(36107) top-left Y coord
8d0c: 00 cur_cmd .dd1 $00 ;current command (written but not read)
8d0d: 00 pat_color_idx .dd1 $00 ;color index for brushes and fill
8d0e: 00 brush_index .dd1 $00 ;selected brush (0-7)
8d0f: 00 cmd_xh .dd1 $00 ;X coord for current command, high part
8d10: 00 cmd_xl .dd1 $00 ;X coord for current command, low part
8d11: 00 rev_text_flag .dd1 $00 ;bool (0/1): xdraw text instead of pattern?
8d12: 00 text_xl .dd1 $00 ;text cursor position, X lo
8d13: 00 text_xh .dd1 $00 ;text cursor position, X hi
8d14: 00 text_yc .dd1 $00 ;text cursor position, Y
8d15: 00 bitmap_index .dd1 $00 ;index into brush / font glyph tables (0-127)
8d16: 00 obj_origin_xl .dd1 $00 ;object origin, X lo
8d17: 00 obj_origin_xh .dd1 $00 ;object origin, X hi
8d18: 00 obj_origin_yc .dd1 $00 ;object origin, Y
8d19: 00 at_coord_flag .dd1 $00 ;bool (0/1): draw at coords, instead of (0,0)?
8d1a: 00 bitmap_addr_hi .dd1 $00 ;high byte of bitmap address
8d1b: 00 bitmap_tmp .dd1 $00 ;temporary storage
single_step_flag
8d1c: 00 .dd1 $00 ;bool (0/1): stop after drawing one element?
;
; Prepares to draw an object at a specific coordinate.
;
; This is expected to be used for an "object", which begins with a dummy "set
; line start" command that specifies the coordinates of the object's origin.
;
8d1d: a9 01 DoDrawAtCoord lda #$01
8d1f: 8d 19 8d sta at_coord_flag ;set flag indicating at-coord mode
8d22: a0 00 ldy #$00 ;first command in an "object" is a dummy line start
8d24: b1 00 lda (pic_ptr),y ; command
8d26: 29 01 and #$01 ;get the high byte of XC from the command arg
8d28: 8d 17 8d sta obj_origin_xh ;save as object origin
8d2b: c8 iny
8d2c: b1 00 lda (pic_ptr),y ;get low byte of XC
8d2e: 8d 16 8d sta obj_origin_xl ;save
8d31: c8 iny
8d32: b1 00 lda (pic_ptr),y ;get YC
8d34: 8d 18 8d sta obj_origin_yc ;save
8d37: 4c 44 8d jmp DrawStart ;jump to the main draw routine
8d3a: a9 ff DoClearAndDraw lda #$ff ;use color=white1 (high bit set)
8d3c: 20 f4 f3 jsr HCLEAR ;clear the screen with Applesoft routine
8d3f: a9 00 DoDrawNoClear lda #$00
8d41: 8d 19 8d sta at_coord_flag ;clear at-coord flag
8d44: a2 04 DrawStart ldx #4
8d46: 20 ec f6 jsr HCOLOR1 ;set hi-res color to black1 (hi bit set)
8d49: a0 00 ldy #0 ;xh=0
8d4b: a2 8c ldx #140 ;xl=140 (center of screen)
8d4d: a9 06 lda #6 ;yc=6
8d4f: 20 11 f4 jsr BAS_HPOSN ;set hi-res position
8d52: a9 00 lda #0
8d54: 8d 0d 8d sta pat_color_idx ;default to pattern color 0
8d57: 8d 12 8d sta text_xl ;initialize text cursor position to top-left
8d5a: 8d 13 8d sta text_xh
8d5d: 8d 14 8d sta text_yc
8d60: a9 05 lda #5 ;default to brush #5
8d62: 8d 0e 8d sta brush_index
8d65: a9 95 lda #>brush_bitmaps ;set bitmap address hi to brush bitmap page
8d67: 8d 1a 8d sta bitmap_addr_hi
8d6a: ad 19 8d lda at_coord_flag ;are are we using the "draw at" feature?
8d6d: f0 03 beq ProcessCommand ;no, go process commands
8d6f: 4c 75 8e jmp @Advance3 ;yes, skip over the object origin before starting
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; Main command processing loop. ;
; ;
; This is also the public entry point for single-stepping. ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
]cmd_code .var $08 {addr/1} ;high 4 bits
]cmd_arg .var $09 {addr/1} ;low 4 bits
8d72: a0 00 ProcessCommand ldy #$00
8d74: b1 00 lda (pic_ptr),y ;get the command byte
8d76: 29 f0 and #$f0 ;code in upper 4 bits
8d78: 85 08 sta ]cmd_code
8d7a: b1 00 lda (pic_ptr),y
8d7c: 29 0f and #$0f ;arg in lower 4 bits
8d7e: 85 09 sta ]cmd_arg
; Handle the command.
8d80: a5 08 lda ]cmd_code ;code $0x?
8d82: d0 04 bne @Try2x ;no, branch
8d84: 20 89 8e jsr IncPicPtr ;advance past command
8d87: 60 rts ;picture done, exit
8d88: 8d 0c 8d @Try2x sta cur_cmd ;save cmd code
8d8b: c9 20 cmp #$20 ;is it "set line color"?
8d8d: d0 0b bne @Try4x
8d8f: a6 09 ldx ]cmd_arg ;line color (0-7) is in cmd byte
8d91: 20 ec f6 jsr HCOLOR1 ;set line color
8d94: 20 89 8e jsr IncPicPtr ;advance past command
8d97: 4c 80 8e jmp @NextCmd
8d9a: c9 40 @Try4x cmp #$40 ;is it "set brush"?
8d9c: d0 0b bne @Try6x
8d9e: a5 09 lda ]cmd_arg ;brush index (0-7) is in cmd byte
8da0: 8d 0e 8d sta brush_index
8da3: 20 89 8e jsr IncPicPtr ;advance past command
8da6: 4c 80 8e jmp @NextCmd
8da9: c9 60 @Try6x cmp #$60 ;is it "set brush/fill color"?
8dab: d0 0f bne @Try3x
8dad: c8 iny
8dae: b1 00 lda (pic_ptr),y ;get next byte in command
8db0: 8d 0d 8d sta pat_color_idx ;save as fill color
8db3: 20 89 8e jsr IncPicPtr ;advance past command
8db6: 20 89 8e jsr IncPicPtr
8db9: 4c 80 8e jmp @NextCmd
8dbc: c9 30 @Try3x cmp #$30 ;is it "reverse text"?
8dbe: d0 08 bne @Try5x
8dc0: a9 01 lda #$01
8dc2: 8d 11 8d sta rev_text_flag ;set the "reverse text" flag
8dc5: 4c cc 8d jmp @DrawText
8dc8: c9 50 @Try5x cmp #$50 ;is it "normal text"?
8dca: d0 17 bne @Not5x
8dcc: c8 @DrawText iny
8dcd: b1 00 lda (pic_ptr),y ;get character
8dcf: 8d 15 8d sta bitmap_index
8dd2: 20 90 8e jsr DrawChar ;draw it
8dd5: a9 00 lda #$00
8dd7: 8d 11 8d sta rev_text_flag ;clear the "reverse text" flag
8dda: 20 89 8e jsr IncPicPtr ;advance past command
8ddd: 20 89 8e jsr IncPicPtr
8de0: 4c 80 8e jmp @NextCmd
; Not command 0/2/3/4/5/6. 7/9/B/D/F are unused, leaving 1/8/A/C/E, which all
; take X,Y arguments. Process those now.
8de3: a5 09 @Not5x lda ]cmd_arg ;high part of XC is in the low bits of the cmd byte
8de5: 8d 0f 8d sta cmd_xh
8de8: c8 iny
8de9: b1 00 lda (pic_ptr),y ;get the low part of XC
8deb: 8d 10 8d sta cmd_xl
8dee: c8 iny
8def: b1 00 lda (pic_ptr),y ;get the Y coord
8df1: 85 0a sta cmd_yc ;store this in ZP
; If we're drawing an object at a specific position, we need to adjust the X,Y
; in the command. We do this by applying two translations: subtract the object
; origin from the command coordinates to get a relative position, then add the
; relative position to the draw-at position. (This would be simpler if the
; object were stored with coordinates relative to (0,0), instead of defined with
; absolute coordinates at the default position.)
;
; The result is stored back into the command position variables, so that nothing
; else in the code needs to know that we're doing a draw-at.
8df3: ad 19 8d lda at_coord_flag ;are we drawing at a specific location?
8df6: f0 32 beq @NotAt ;no, branch
8df8: 38 sec ;compute cmd_x - origin_x
8df9: ad 10 8d lda cmd_xl
8dfc: ed 16 8d sbc obj_origin_xl
8dff: 8d 10 8d sta cmd_xl
8e02: ad 0f 8d lda cmd_xh
8e05: ed 17 8d sbc obj_origin_xh
8e08: 8d 0f 8d sta cmd_xh
8e0b: 18 clc ;now add draw_at_x
8e0c: ad 10 8d lda cmd_xl
8e0f: 6d 09 8d adc arg_xoff_lo
8e12: 8d 10 8d sta cmd_xl
8e15: ad 0f 8d lda cmd_xh
8e18: 6d 0a 8d adc arg_xoff_hi
8e1b: 8d 0f 8d sta cmd_xh
8e1e: 38 sec ;compute cmd_y - origin_y
8e1f: a5 0a lda cmd_yc
8e21: ed 18 8d sbc obj_origin_yc
8e24: 18 clc ;now add draw_at_y
8e25: 6d 0b 8d adc arg_yoff
8e28: 85 0a sta cmd_yc
; X,Y coordinates parsed, back to command code switch.
8e2a: a5 08 @NotAt lda ]cmd_code
8e2c: c9 80 cmp #$80 ;is it "set line start"?
8e2e: d0 0e bne @TryAx
8e30: ae 10 8d ldx cmd_xl ;load coords into registers
8e33: a5 0a lda cmd_yc
8e35: ac 0f 8d ldy cmd_xh
8e38: 20 11 f4 jsr BAS_HPOSN ;set hi-res position
8e3b: 4c 75 8e jmp @Advance3
8e3e: c9 a0 @TryAx cmp #$a0 ;is it "draw line to"?
8e40: d0 0e bne @TryCx
8e42: a4 0a ldy cmd_yc ;load coords into registers
8e44: ad 10 8d lda cmd_xl
8e47: ae 0f 8d ldx cmd_xh
8e4a: 20 3a f5 jsr BAS_HGLIN ;do Applesoft HPLOT TO
8e4d: 4c 75 8e jmp @Advance3
8e50: c9 c0 @TryCx cmp #$c0 ;is it "draw brush at"?
8e52: d0 06 bne @TryEx
8e54: 20 43 90 jsr DrawBrush ;draw the brush bitmap
8e57: 4c 75 8e jmp @Advance3
8e5a: c9 e0 @TryEx cmp #$e0 ;is it "fill at"?
8e5c: d0 06 bne @MustBe1x
8e5e: 20 7e 8f jsr Fill ;do the fill operation
8e61: 4c 75 8e jmp @Advance3
8e64: ad 10 8d @MustBe1x lda cmd_xl ;must be "set text cursor"
8e67: 8d 12 8d sta text_xl ;(undefined commands will end up here)
8e6a: ad 0f 8d lda cmd_xh
8e6d: 8d 13 8d sta text_xh
8e70: a5 0a lda cmd_yc
8e72: 8d 14 8d sta text_yc
; Advance the picture pointer by 3 bytes.
8e75: 18 @Advance3 clc
8e76: a5 00 lda pic_ptr
8e78: 69 03 adc #3
8e7a: 85 00 sta pic_ptr
8e7c: 90 02 bcc @NextCmd
8e7e: e6 01 inc pic_ptr+1
; Loop to process next command, or stop here.
8e80: ad 1c 8d @NextCmd lda single_step_flag ;are we in single-step mode?
8e83: d0 03 bne @Return ;yes, return to caller
8e85: 4c 72 8d jmp ProcessCommand ;no, loop
8e88: 60 @Return rts
;
; Increments the picture pointer by 1.
;
8e89: e6 00 IncPicPtr inc pic_ptr
8e8b: d0 02 bne @Return
8e8d: e6 01 inc pic_ptr+1
8e8f: 60 @Return rts
;
; Draws a character glyph at the current text cursor position.
;
; Unlike most HRCGs, glyphs can be drawn at arbitrary pixel locations.
;
; On entry:
; $8d12-8d14: cursor position
; $8d15: character index
;
; On exit:
; $8d12-8d13: X coordinate advanced by 8 pixels
;
8e90: ad 12 8d DrawChar lda text_xl ;copy text cursor position
8e93: 8d 10 8d sta cmd_xl
8e96: ad 13 8d lda text_xh
8e99: 8d 0f 8d sta cmd_xh
8e9c: ad 14 8d lda text_yc
8e9f: 85 0a sta cmd_yc
8ea1: ad 15 8d lda bitmap_index ;want character value << 3, which
8ea4: 4a lsr A ; means high byte includes value >> 5
8ea5: 4a lsr A
8ea6: 4a lsr A
8ea7: 4a lsr A
8ea8: 4a lsr A
8ea9: 18 clc
8eaa: 6d 1a 8d adc bitmap_addr_hi
8ead: 8d 1a 8d sta bitmap_addr_hi ;set high
8eb0: ad 15 8d lda bitmap_index ;get char value again
8eb3: 0a asl A ;left shift 3x for low byte
8eb4: 0a asl A
8eb5: 0a asl A
8eb6: 8d 15 8d sta bitmap_index ;replace index with low part of pointer
8eb9: 20 f3 8e jsr DivideXBy7 ;split X coord into col/pixel
8ebc: 20 93 90 jsr DrawBitmap ;draw the bitmap
8ebf: a9 95 lda #>brush_bitmaps ;reset bitmap high address
8ec1: 8d 1a 8d sta bitmap_addr_hi
; Advance text cursor by 8 pixels. (Most HRCGs advance by 7 to get 40 cols.)
8ec4: 18 clc
8ec5: ad 12 8d lda text_xl
8ec8: 69 08 adc #8
8eca: 8d 12 8d sta text_xl
8ecd: 90 03 bcc @Return
8ecf: ee 13 8d inc text_xh
8ed2: 60 @Return rts
;
; Calculates the hi-res row address for the specified Y coordinate, and
; configures the brush pattern sub-index based on whether the row is odd or
; even.
;
; On entry:
; $02: pattern sub-index for even rows
; $03: pattern sub-index for odd rows
; $0a: Y coordinate
;
; On exit:
; $08-09: pointer to row
; $ff: value from $02 or $03, multiplied x4
;
]hires_ptr .var $08 {addr/2}
8ed3: a4 0a CalcRowAddr ldy cmd_yc ;get Y coord
8ed5: b9 3c 91 lda row_addr_hi,y ;get the high byte of the address
8ed8: 18 clc
8ed9: 65 e6 adc BAS_HPAG ;combine with current page ($20 or $40)
8edb: 85 09 sta ]hires_ptr+1
8edd: b9 fc 91 lda row_addr_lo,y ;get the low byte of the address
8ee0: 85 08 sta ]hires_ptr
;
8ee2: a5 0a lda cmd_yc ;get Y coord
8ee4: 4a lsr A ;check odd/even
8ee5: b0 05 bcs @WasOdd ;if odd, branch
8ee7: a5 02 lda pat_subindex_even ;use the even-row subindex
8ee9: 4c ee 8e jmp @WasEven
8eec: a5 03 @WasOdd lda pat_subindex_odd ;use the odd-row subindex
8eee: 0a @WasEven asl A ;multiply by 4
8eef: 0a asl A
8ef0: 85 ff sta pat_subindex_x4
8ef2: 60 rts
;
; Divides the 16-bit X coordinate by 7. Produces an 8-bit quotient and an 8-bit
; remainder. Used to convert an X coordinate into a column number and pixel
; offset.
;
; On entry:
; $8d0f/8d10: X coordinate low/hi (0-279)
;
; On exit:
; $0b: quotient / column (0-39)
; $0c: remainder / pixel (0-6)
;
]xcoord .var $08 {addr/2} ;0-279
]hires_byte_off .var $0b {addr/1} ;0-39
]hires_pix_num .var $0c {addr/1} ;0-6
8ef3: a0 ff DivideXBy7 ldy #-1 ;init quotient counter to -1
8ef5: ad 10 8d lda cmd_xl ;copy X coord to zero page
8ef8: 85 08 sta ]xcoord
8efa: ad 0f 8d lda cmd_xh
8efd: 85 09 sta ]xcoord+1
8eff: a5 08 lda ]xcoord ;(could skip this by reversing order of above)
8f01: 38 sec
8f02: e9 07 @Loop sbc #7 ;divide by subtracting 7 repeatedly
8f04: c8 iny
8f05: b0 fb bcs @Loop ;loop if we didn't borrow
8f07: 38 sec
8f08: c6 09 dec ]xcoord+1 ;update high byte
8f0a: 10 f6 bpl @Loop ;if still > 0, loop
8f0c: 84 0b sty ]hires_byte_off ;save result
8f0e: 18 clc
8f0f: 69 07 adc #7 ;make the remainder positive
8f11: 85 0c sta ]hires_pix_num
8f13: 60 rts
;
; Double-bit masks for the hi-res screen.
;
; This is a little off - the first two entries are identical - because we only
; want to examine a single byte. The high bit is excluded, because we're just
; testing visible pixels.
;
8f14: 03 two_bits .dd1 %00000011
8f15: 03 .dd1 %00000011
8f16: 06 .dd1 %00000110
8f17: 0c .dd1 %00001100
8f18: 18 .dd1 %00011000
8f19: 30 .dd1 %00110000
8f1a: 60 .dd1 %01100000
;
; Tests the contents of the hi-res screen to see if a specific pixel is white.
; Used by the fill code.
;
; Pixels appear white when two adjacent bits are set. This code does not check
; for set bits in adjacent bytes, which makes the code faster but slightly less
; precise.
;
; On entry:
; $08-09: pointer to current row on hi-res screen
; $0b: hi-res byte offset (0-39)
; $0c: hi-res pixel offset (0-6)
;
; On exit:
; Z-flag: set if white pixel found (two adjacent bits are set to 1)
;
]hires_ptr .var $08 {addr/2}
8f1b: a6 0c TestForWhite ldx ]hires_pix_num ;get the X coordinate pixel number (0-6)
8f1d: bd 14 8f lda two_bits,x ;get a mask with two bits set
8f20: a4 0b ldy ]hires_byte_off ;get the X coordinate byte offset (0-39)
8f22: 31 08 and (]hires_ptr),y ;AND it with the contents of the hi-res screen
8f24: dd 14 8f cmp two_bits,x ;set Z-flag if both bits are set
8f27: 60 rts
;
; Draws pattern pixels on the hi-res screen. Used by fill code.
;
; If everything is going correctly, we're drawing pixels on white areas of the
; screen only. So screen_pixels & pixel_mask = pixel_mask.
;
; On entry:
; $08-09: pointer to hi-res row
; A-reg: mask, with 1 bits where pixels should be drawn
; Y-reg: hi-res byte position (0-39)
; $fc: byte from hi-res screen
;
]screen_pixels .var $fc {addr/1}
DrawPatternPixels
8f28: 85 04 sta pixel_mask ;save the mask
8f2a: 45 fc eor ]screen_pixels ;clear the white pixels we're drawing over
8f2c: 29 7f and #$7f ;clear the high bit (get it from pattern)
8f2e: 85 fc sta ]screen_pixels ;stash it
;
8f30: 98 tya ;get the byte position
8f31: 29 03 and #$03 ;mod it (0-3)
8f33: 05 ff ora pat_subindex_x4 ;combine with subindex * 4 to get pattern data index
8f35: aa tax
8f36: bd 2f 94 lda pattern_data,x ;get the pattern for this byte
8f39: 25 04 and pixel_mask ;exclude the bits we can't touch
8f3b: 05 fc ora ]screen_pixels ;combine with modified screen byte
8f3d: 91 08 sta (]hires_ptr),y ;write to screen
8f3f: 60 rts
;
; Gets the pattern color sub-indices.
;
; On entry:
; $8d0d: pattern color index
;
; On exit:
; $02: sub-index for even rows
; $03: sub-index for odd rows
;
GetPatSubIndices
8f40: ad 0d 8d lda pat_color_idx ;get pattern color index (0-107)
8f43: 0a asl A ;double it
8f44: a8 tay
8f45: b9 57 93 lda pat_color_subidxs,y ;get value for even rows
8f48: 85 02 sta pat_subindex_even
8f4a: c8 iny
8f4b: b9 57 93 lda pat_color_subidxs,y ;get value for odd rows
8f4e: 85 03 sta pat_subindex_odd
8f50: 60 rts
;
; Finds rightmost (highest) black pixel, and returns a mask that can be used to
; draw to the right of it.
;
; Suppose the hi-res screen has pixels set like this ('#'=set):
; # - # - # # # (high bit clear)
; The goal is to get a mask in which the 1 bits represent pixels we can
; overwrite with the pattern. The fill is moving leftward, so the mask would
; be:
; - - - - # # # (high bit ignored)
;
; The pixels are displayed in reverse order, so the screen byte corresponding to
; the above would be:
; 0 1 1 1 0 1 0 1
; The index of the rightmost black pixel is the index of the leftmost (highest)
; zero bit, ignoring the high bit. In this case, it's bit 3. Table entry #3
; holds:
; 1 1 1 1 0 0 0 0
;
; On entry:
; A-reg: byte value from hi-res screen
; $fd: -1
;
; On exit:
; A-reg: pixel mask, with 1s indicating bits we want to draw on
; $fd: index of highest 0 bit, 0-6 (not set if all bits are 1)
;
]left_pixel_idx .var $fd {addr/1}
]right_pixel_idx .var $fe {addr/1}
CalcLeftEdgeMask
8f51: 29 7f and #$7f ;mask off the high bit
8f53: c9 7f cmp #$7f ;are all other bits set (all white)?
8f55: d0 04 bne @FindZero ;no, branch
8f57: a9 ff lda #$ff ;yes, return a mask with all bits set
8f59: 30 0c bmi @Return ;(always)
8f5b: a2 07 @FindZero ldx #7 ;init position to 7
8f5d: 0a asl A ;shift to ignore the high bit
8f5e: ca @Loop dex ;dec posn
8f5f: 0a asl A ;shift high bit into carry
8f60: b0 fc bcs @Loop ;loop until we find a zero bit
8f62: 86 fd stx ]left_pixel_idx ;save for later (0-6)
8f64: bd 35 91 lda mask_left,x ;get bit mask
8f67: 60 @Return rts
;
; Finds leftmost (lowest) black pixel, and returns a mask that can be used to
; draw to the left of it.
;
; On entry:
; A-reg: value from hi-res screen
; $fe: 7
;
; On exit:
; A-reg: pixel mask, with 1s indicating bits we want to draw on
; $fe: index of lowest 0 bit, 0-6 (not set if all bits are 1)
;
CalcRightEdgeMask
8f68: 29 7f and #$7f ;mask off the high bit
8f6a: c9 7f cmp #$7f ;are all other bits set?
8f6c: d0 04 bne @FindZero ;no, branch
8f6e: a9 ff lda #$ff ;yes, return a mask with all bits set
8f70: 30 0b bmi @Return ;(always)
8f72: a2 ff @FindZero ldx #-1 ;init position to -1
8f74: e8 @Loop inx ;inc posn
8f75: 4a lsr A ;shift low bit into carry
8f76: b0 fc bcs @Loop ;loop until we find a zero bit
8f78: 86 fe stx ]right_pixel_idx ;save for later (0-6)
8f7a: bd 2e 91 lda mask_right,x ;get bit mask
8f7d: 60 @Return rts
;
; Fills a region of the hi-res screen with a pattern.
;
; Algorithm description, from the manual:
; 1) Scan directly up from the selected point until a border is found.
; 2) Move down one line, filling to the left and right borders.
; 3) Average the left and right borders to find the midpoint, and move down one
; line from there.
; 4) Check to see if the point moved down to is a border. If not, go back to
; step 2.
;
; The midpoint adjustment provides better handling of concave shapes.
;
; On entry:
; $8d0f/8d10: starting X coordinate low/hi (0-279)
; $0a: starting Y coordinate (0-191)
;
8f7e: 20 40 8f Fill jsr GetPatSubIndices ;configure pattern colors
8f81: 20 f3 8e jsr DivideXBy7 ;get col/pixel for this X position
; Move straight up until we find a non-white pixel or the edge of the screen.
8f84: 20 d3 8e @Loop jsr CalcRowAddr ;calculate row address
8f87: 20 1b 8f jsr TestForWhite ;see if the pixel is white
8f8a: d0 09 bne @NotWhite ;if not, branch
8f8c: a5 0a lda cmd_yc ;get the Y coord
8f8e: f0 0a beq @FoundTop ;if we're at the top of the screen, branch
8f90: c6 0a dec cmd_yc ;move up one row
8f92: 4c 84 8f jmp @Loop
8f95: e6 0a @NotWhite inc cmd_yc ;move back down to the last white pixel we saw
8f97: 20 d3 8e jsr CalcRowAddr ;calculate the hi-res row address
; Now we have the starting position.
8f9a: a4 0b @FoundTop ldy ]hires_byte_off
8f9c: a9 ff @FillLoop lda #-1 ;init bit index to -1 (past start of byte)
8f9e: 85 fd sta ]left_pixel_idx
8fa0: a9 07 lda #7 ;init bit index to 7 (past end of byte)
8fa2: 85 fe sta ]right_pixel_idx
; Process the first byte. We need to determine if the byte has set bits to the
; left edge and/or right edge, and draw the pattern pixels here.
8fa4: b1 08 lda (]hires_ptr),y ;get byte from hi-res screen
8fa6: 85 fc sta ]screen_pixels ;save for pattern draw code
8fa8: a6 0c ldx ]hires_pix_num ;get pixel offset from X coord
8faa: 1d 35 91 ora mask_left,x ;set all bits to the right, so we ignore them
8fad: 20 51 8f jsr CalcLeftEdgeMask ;find the left edge
8fb0: 85 04 sta pixel_mask ;save the mask
8fb2: a6 0c ldx ]hires_pix_num
8fb4: bd 2e 91 lda mask_right,x ;now get the mask with the bits set to our left
8fb7: 05 fc ora ]screen_pixels ;combine it with screen pixels
8fb9: 20 68 8f jsr CalcRightEdgeMask ;find the right edge; mask in A-reg
8fbc: 25 04 and pixel_mask ;combine the masks
8fbe: 20 28 8f jsr DrawPatternPixels ;draw the pattern in the remaining space
;
8fc1: a5 fd @Leftward lda ]left_pixel_idx ;check the leftmost pixel
8fc3: c9 ff cmp #-1 ;did we draw to the left edge of the byte?
8fc5: d0 13 bne @LeftNonWhite ;no, branch
8fc7: 88 dey ;yes, move one byte left
8fc8: 30 0d bmi @LeftEdge ;if we're past the left edge, branch
8fca: b1 08 lda (]hires_ptr),y ;get pixel data from screen
8fcc: 85 fc sta ]screen_pixels ;save for pattern draw
8fce: 20 51 8f jsr CalcLeftEdgeMask ;find the left edge; mask in A-reg
8fd1: 20 28 8f jsr DrawPatternPixels ;draw the pattern
8fd4: 4c c1 8f jmp @Leftward ;loop
]left_col .var $05 {addr/1}
8fd7: c8 @LeftEdge iny ;Y=0
8fd8: 84 fd sty ]left_pixel_idx ;set to zero
8fda: 84 05 @LeftNonWhite sty ]left_col ;save leftmost byte column
8fdc: a4 0b ldy ]hires_byte_off ;get initial byte column
;
8fde: a5 fe @Rightward lda ]right_pixel_idx ;check the rightmost pixel
8fe0: c9 07 cmp #7 ;did we draw to the right edge of the byte?
8fe2: d0 15 bne @RightNonWhite ;yes, branch
8fe4: c8 iny
8fe5: c0 28 cpy #40 ;have we reached the right edge?
8fe7: f0 0d beq @RightEdge ;yes, branch
8fe9: b1 08 lda (]hires_ptr),y ;get pixel data from screen
8feb: 85 fc sta ]screen_pixels ;save for pattern draw
8fed: 20 68 8f jsr CalcRightEdgeMask ;find the right edge; mask in A-reg
8ff0: 20 28 8f jsr DrawPatternPixels ;draw the pattern
8ff3: 4c de 8f jmp @Rightward ;loop
8ff6: 88 @RightEdge dey ;Y=39
8ff7: c6 fe dec ]right_pixel_idx ;set to 6
; Line is filled. Compute a new center X coord, by adding the left/right column
; numbers, multiplying by 7 to get a pixel column, then dividing by two.
8ff9: 98 @RightNonWhite tya
8ffa: 18 clc
8ffb: 65 05 adc ]left_col ;add the left and right byte columns
8ffd: 85 05 sta ]left_col ;save the result
8fff: a0 00 ldy #$00
9001: 8c 0f 8d sty cmd_xh
9004: 0a asl A ;multiply sum by 8
9005: 0a asl A
9006: 2e 0f 8d rol cmd_xh
9009: 0a asl A
900a: 2e 0f 8d rol cmd_xh
900d: 38 sec
900e: e5 05 sbc ]left_col ;subtract to get sum * 7
9010: b0 03 bcs @NotBig
9012: ce 0f 8d dec cmd_xh ;had to borrow, no longer > 256, update high byte
9015: 18 @NotBig clc
9016: 65 fe adc ]right_pixel_idx ;add in the right pixel index
9018: 90 04 bcc @NoInc
901a: ee 0f 8d inc cmd_xh ;update high byte
901d: 18 clc
901e: 65 fd @NoInc adc ]left_pixel_idx ;add in the left pixel index
9020: 90 03 bcc @NoInc
9022: ee 0f 8d inc cmd_xh ;update high byte
;
9025: 4e 0f 8d @NoInc lsr cmd_xh ;divide sum by 2
9028: 6a ror A
9029: 8d 10 8d sta cmd_xl ;save new center X coord
902c: 20 f3 8e jsr DivideXBy7 ;calculate new byte/pixel indices
;
902f: e6 0a inc cmd_yc ;move down one line
9031: a5 0a lda cmd_yc
9033: c9 c0 cmp #192 ;have we reached the bottom of the screen?
9035: f0 0b beq @Return ;yes, bail
9037: 20 d3 8e jsr CalcRowAddr ;no, calculate new row address
903a: 20 1b 8f jsr TestForWhite ;test the initial pixel
903d: d0 03 bne @Return ;not white, bail
903f: 4c 9c 8f jmp @FillLoop ;keep going
9042: 60 @Return rts
;
; Draws a brush as a series of four bitmaps.
;
; Bitmaps are stored in the same format as font glyphs. The four parts of the
; brush appear in the order top-left, top-right, bottom-left, bottom-right. The
; current X,Y position determines the top-left corner, not the center.
;
; On entry:
; $8d0f/8d10: starting X coordinate low/hi (0-279)
; $0a: starting Y coordinate (0-191)
;
9043: 20 f3 8e DrawBrush jsr DivideXBy7 ;split X coordinate into byte/pixel
9046: ad 0e 8d lda brush_index ;compute brush index (0-7) * 32
9049: 0a asl A
904a: 0a asl A
904b: 0a asl A
904c: 0a asl A
904d: 0a asl A
904e: 8d 15 8d sta bitmap_index ;save as bitmap index (0-127)
9051: 20 93 90 jsr DrawBitmap ;draw top-left bitmap
;
9054: ad 15 8d lda bitmap_index ;advance to the next bitmap
9057: 18 clc
9058: 69 08 adc #8
905a: 8d 15 8d sta bitmap_index
905d: a5 0b lda ]hires_byte_off ;save a copy of the current byte offset
905f: 48 pha
9060: e6 0b inc ]hires_byte_off ;move one byte to the right
9062: a5 0a lda cmd_yc ;restore original Y coordinate
9064: 38 sec
9065: e9 07 sbc #7
9067: 85 0a sta cmd_yc
9069: 20 93 90 jsr DrawBitmap ;draw top-right bitmap
;
906c: ad 15 8d lda bitmap_index ;advance to the next bitmap
906f: 18 clc
9070: 69 08 adc #8
9072: 8d 15 8d sta bitmap_index
9075: 68 pla ;restore left X coordinate
9076: 85 0b sta ]hires_byte_off
9078: e6 0a inc cmd_yc ;move down one more line (total of 8)
907a: 20 93 90 jsr DrawBitmap ;draw bottom-left bitmap
;
907d: ad 15 8d lda bitmap_index ;advance to the next bitmap
9080: 18 clc
9081: 69 08 adc #8
9083: 8d 15 8d sta bitmap_index
9086: e6 0b inc ]hires_byte_off ;advance to next byte column
9088: a5 0a lda cmd_yc ;restore original Y coordinate
908a: 38 sec
908b: e9 07 sbc #7
908d: 85 0a sta cmd_yc
908f: 20 93 90 jsr DrawBitmap ;draw bottom-right bitmap
9092: 60 rts
;
; Draws a bitmap. Bitmaps are 1 byte wide and 8 bytes high.
;
; Call DivideXBy7 before calling here, to split the X coordinate into byte and
; pixel indices.
;
; This does not test for screen edges.
;
; On entry:
; $8d15: bitmap pointer, lo
; $8d1a: bitmap pointer, hi
; $0a: hi-res top row (0-183)
; $0b: hi-res column (0-39)
; $0c: hi-res pixel (0-6)
;
; On exit:
; $0a: increased by 7
;
]shifted_lo .var $04 {addr/1}
]shifted_hi .var $05 {addr/1}
]bitmap_ptr .var $06 {addr/2} ;pointer to bitmap data
]data_idx .var $fc {addr/1} ;index into bitmap data (0-7)
]pixel_tmp .var $fd {addr/1}
9093: 20 40 8f DrawBitmap jsr GetPatSubIndices ;initialize color pattern sub-indices
9096: a9 00 lda #$00
9098: 85 fc sta ]data_idx ;init counter
909a: 20 d3 8e @BigLoop jsr CalcRowAddr ;calculate row base address
909d: a5 08 lda ]hires_ptr ;add byte offset to address, so now the pointer
909f: 18 clc ; is to the first byte we want to change
90a0: 65 0b adc ]hires_byte_off
90a2: 85 08 sta ]hires_ptr
;
90a4: ad 15 8d lda bitmap_index ;copy bitmap pointer to ZP
90a7: 85 06 sta ]bitmap_ptr
90a9: ad 1a 8d lda bitmap_addr_hi
90ac: 85 07 sta ]bitmap_ptr+1
90ae: a4 fc ldy ]data_idx
90b0: b1 06 lda (]bitmap_ptr),y ;get a byte from the bitmap
90b2: 8d 1b 8d sta bitmap_tmp ;save the value (this could be avoided)
90b5: e6 fc inc ]data_idx ;increment bitmap data index
; Shift the bitmap data 0-6 times to get the right pixel position.
90b7: a9 00 lda #$00
90b9: 85 05 sta ]shifted_hi
90bb: ad 1b 8d lda bitmap_tmp ;restore the value
90be: 0a asl A ;shift once to get hi bit out of the way
90bf: a4 0c ldy ]hires_pix_num ;pixel position is number of times to shift
90c1: f0 07 @Loop beq @ShiftDone ;if done, branch
90c3: 0a asl A ;shift as 16-bit value
90c4: 26 05 rol ]shifted_hi
90c6: 88 dey
90c7: 4c c1 90 jmp @Loop
90ca: 4a @ShiftDone lsr A ;shift low byte back one (because of hi bit)
90cb: 85 04 sta ]shifted_lo ;stash low byte
;
90cd: ad 11 8d lda rev_text_flag ;are we in reverse-text mode?
90d0: d0 41 bne @DrawRev ;yes, branch
;
90d2: a0 00 ldy #$00 ;for later
90d4: a5 0b lda ]hires_byte_off ;get the byte offset
90d6: 29 03 and #$03 ;reduce to 0-3
90d8: 05 ff ora pat_subindex_x4 ;combine with subindex * 4 to get pattern data index
90da: aa tax
90db: a5 04 lda ]shifted_lo ;get the shifted bitmap data, low byte
90dd: 09 80 ora #$80 ;set the high bit
90df: 3d 2f 94 and pattern_data,x ;mask off whatever isn't in the color pattern
90e2: 85 fd sta ]pixel_tmp ;stash it
90e4: a5 04 lda ]shifted_lo ;are any pixels set?
90e6: f0 08 beq @NoLow ;no, branch (could have checked this earlier?)
90e8: 49 7f eor #$7f ;invert bits
90ea: 31 08 and (]hires_ptr),y ;clear pixels that are set in the bitmap
90ec: 05 fd ora ]pixel_tmp ;merge in the (shifted AND pattern) bits
90ee: 91 08 sta (]hires_ptr),y ;store it
;
90f0: c8 @NoLow iny ;Y=1
90f1: a5 0b lda ]hires_byte_off ;get the byte offset
90f3: 18 clc
90f4: 69 01 adc #$01 ;add one, because we're drawing one column over
90f6: 29 03 and #$03 ;reduce to 0-3
90f8: 05 ff ora pat_subindex_x4 ;combine with subindex * 4 to get pattern data index
90fa: aa tax
90fb: a5 05 lda ]shifted_hi ;get the shifted bitmap data, high byte
90fd: 09 80 ora #$80 ;set the high bit
90ff: 3d 2f 94 and pattern_data,x ;mask off whatever isn't in the color pattern
9102: 85 fd sta ]pixel_tmp ;stash it
9104: a5 05 lda ]shifted_hi ;are any pixels set?
9106: f0 1a beq @NextLine ;no, branch
9108: 49 7f eor #$7f ;invert bits
910a: 31 08 and (]hires_ptr),y ;clear pixels that are set in the bitmap
910c: 05 fd ora ]pixel_tmp ;merge in the (shifted AND pattern) bits
910e: 91 08 sta (]hires_ptr),y ;store it
9110: 4c 22 91 jmp @NextLine
; Reverse-text mode ignores the current pattern, and just inverts pixels
; ("XDRAW" mode).
9113: a0 00 @DrawRev ldy #$00
9115: a5 04 lda ]shifted_lo ;get low part
9117: 51 08 eor (]hires_ptr),y ;XOR with screen contents
9119: 91 08 sta (]hires_ptr),y ;store it
911b: c8 iny
911c: a5 05 lda ]shifted_hi ;get high part
911e: 51 08 eor (]hires_ptr),y ;XOR with screen contents
9120: 91 08 sta (]hires_ptr),y ;store it
;
9122: a5 fc @NextLine lda ]data_idx ;get index into bitmap data
9124: c9 08 cmp #8 ;reached last line?
9126: f0 05 beq @Return ;yes, bail
9128: e6 0a inc cmd_yc ;no, move down a row
912a: 4c 9a 90 jmp @BigLoop ; and loop
912d: 60 @Return rts
;
; Edge masks for flood fill. 1s indicate the bits we're allowed to fill with
; the pattern. (Remember that hi-res pixels appear in reverse order.)
;
912e: 80 mask_right .dd1 %10000000
912f: 81 .dd1 %10000001
9130: 83 .dd1 %10000011
9131: 87 .dd1 %10000111
9132: 8f .dd1 %10001111
9133: 9f .dd1 %10011111
9134: bf .dd1 %10111111
9135: fe mask_left .dd1 %11111110
9136: fc .dd1 %11111100
9137: f8 .dd1 %11111000
9138: f0 .dd1 %11110000
9139: e0 .dd1 %11100000
913a: c0 .dd1 %11000000
913b: 80 .dd1 %10000000
;
; Hi-res row address, high part. This value should be ORed with $20 or $40.
;
913c: 00 04 08 0c+ row_addr_hi .bulk $00,$04,$08,$0c,$10,$14,$18,$1c,$00,$04,$08,$0c,$10,$14,$18,$1c
+ $01,$05,$09,$0d,$11,$15,$19,$1d,$01,$05,$09,$0d,$11,$15,$19,$1d
+ $02,$06,$0a,$0e,$12,$16,$1a,$1e,$02,$06,$0a,$0e,$12,$16,$1a,$1e
+ $03,$07,$0b,$0f,$13,$17,$1b,$1f,$03,$07,$0b,$0f,$13,$17,$1b,$1f
+ $00,$04,$08,$0c,$10,$14,$18,$1c,$00,$04,$08,$0c,$10,$14,$18,$1c
+ $01,$05,$09,$0d,$11,$15,$19,$1d,$01,$05,$09,$0d,$11,$15,$19,$1d
+ $02,$06,$0a,$0e,$12,$16,$1a,$1e,$02,$06,$0a,$0e,$12,$16,$1a,$1e
+ $03,$07,$0b,$0f,$13,$17,$1b,$1f,$03,$07,$0b,$0f,$13,$17,$1b,$1f
+ $00,$04,$08,$0c,$10,$14,$18,$1c,$00,$04,$08,$0c,$10,$14,$18,$1c
+ $01,$05,$09,$0d,$11,$15,$19,$1d,$01,$05,$09,$0d,$11,$15,$19,$1d
+ $02,$06,$0a,$0e,$12,$16,$1a,$1e,$02,$06,$0a,$0e,$12,$16,$1a,$1e
+ $03,$07,$0b,$0f,$13,$17,$1b,$1f,$03,$07,$0b,$0f,$13,$17,$1b,$1f
;
; Hi-res row address, low part.
;
91fc: 00 00 00 00+ row_addr_lo .bulk $00,$00,$00,$00,$00,$00,$00,$00,$80,$80,$80,$80,$80,$80,$80,$80
+ $00,$00,$00,$00,$00,$00,$00,$00,$80,$80,$80,$80,$80,$80,$80,$80
+ $00,$00,$00,$00,$00,$00,$00,$00,$80,$80,$80,$80,$80,$80,$80,$80
+ $00,$00,$00,$00,$00,$00,$00,$00,$80,$80,$80,$80,$80,$80,$80,$80
+ $28,$28,$28,$28,$28,$28,$28,$28,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8
+ $28,$28,$28,$28,$28,$28,$28,$28,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8
+ $28,$28,$28,$28,$28,$28,$28,$28,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8
+ $28,$28,$28,$28,$28,$28,$28,$28,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8
+ $50,$50,$50,$50,$50,$50,$50,$50,$d0,$d0,$d0,$d0,$d0,$d0,$d0,$d0
+ $50,$50,$50,$50,$50,$50,$50,$50,$d0,$d0,$d0,$d0,$d0,$d0,$d0,$d0
+ $50,$50,$50,$50,$50,$50,$50,$50,$d0,$d0,$d0,$d0,$d0,$d0,$d0,$d0
+ $50,$50,$50,$50,$50,$50,$50,$50,$d0,$d0,$d0,$d0,$d0,$d0,$d0,$d0
;
92bc: 20 24 28 2c+ .junk 155
;
; Sub-indexes for 108 patterns. Each entry is adjacent two bytes, holding the
; sub-indices into the color pattern data table for even and odd rows. Values
; are in the range [0,29].
;
; For example, color pattern 8 uses sub-index $03 for even rows and $06 for odd.
; In the pattern table, $03 is white0, $06 is orange. The pattern drawn will
; have alternating rows of white and orange.
;
pat_color_subidxs
9357: 03 07 16 07+ .bulk $03,$07,$16,$07,$1a,$1d,$1c,$17,$08,$0b,$00,$1b,$00,$04,$03,$1b
+ $03,$06,$1a,$06,$00,$06,$00,$11,$02,$06,$1c,$13,$10,$13,$10,$07
+ $02,$1b,$02,$07,$02,$17,$02,$09,$1a,$04,$10,$04,$02,$05,$12,$17
+ $1a,$07,$03,$17,$16,$19,$03,$05,$03,$0d,$1a,$0d,$1a,$05,$10,$05
+ $00,$0d,$00,$17,$08,$05,$16,$05,$01,$05,$16,$0b,$01,$07,$01,$17
+ $01,$09,$01,$04,$16,$04,$0c,$0f,$01,$1b,$01,$11,$0c,$17,$0c,$04
+ $16,$13,$01,$06,$16,$06,$0c,$11,$07,$07,$04,$04,$07,$1b,$1b,$1d
+ $07,$11,$06,$07,$17,$06,$06,$1b,$06,$06,$04,$06,$11,$13,$04,$11
+ $17,$07,$17,$0b,$17,$19,$05,$07,$17,$05,$07,$0d,$05,$05,$05,$0d
+ $0d,$0f,$04,$0d,$17,$04,$05,$1b,$05,$06,$03,$03,$16,$03,$03,$0c
+ $00,$00,$08,$1a,$02,$16,$1a,$1c,$03,$10,$02,$03,$02,$1a,$02,$02
+ $12,$1c,$00,$1a,$12,$1a,$10,$12,$00,$10,$03,$1a,$16,$1a,$16,$12
+ $01,$02,$16,$18,$01,$03,$01,$1a,$01,$16,$01,$01,$01,$00,$16,$00
+ $16,$0c,$16,$0e,$0c,$0e,$00,$0c
;
; Single-line color patterns. There are 30 patterns, 4 bytes each.
;
; When written to the hi-res screen, the 4-byte alignment is maintained so that
; overlapping areas drawn with the same pattern don't clash.
;
942f: 00 00 00 00 pattern_data .bulk $00,$00,$00,$00 ;$00
9433: 55 2a 55 2a .bulk $55,$2a,$55,$2a ;$01
9437: 2a 55 2a 55 .bulk $2a,$55,$2a,$55 ;$02
943b: 7f 7f 7f 7f .bulk $7f,$7f,$7f,$7f ;$03
943f: 80 80 80 80 .bulk $80,$80,$80,$80 ;$04
9443: d5 aa d5 aa .bulk $d5,$aa,$d5,$aa ;$05
9447: aa d5 aa d5 .bulk $aa,$d5,$aa,$d5 ;$06
944b: ff ff ff ff .bulk $ff,$ff,$ff,$ff ;$07
944f: 33 66 4c 19 .bulk $33,$66,$4c,$19 ;$08
9453: b3 e6 cc 99 .bulk $b3,$e6,$cc,$99 ;$09
9457: 4c 19 33 66 .bulk $4c,$19,$33,$66 ;$0a
945b: cc 99 b3 e6 .bulk $cc,$99,$b3,$e6 ;$0b
945f: 11 22 44 08 .bulk $11,$22,$44,$08 ;$0c
9463: 91 a2 c4 88 .bulk $91,$a2,$c4,$88 ;$0d
9467: 44 08 11 22 .bulk $44,$08,$11,$22 ;$0e
946b: c4 88 91 a2 .bulk $c4,$88,$91,$a2 ;$0f
946f: 22 44 08 11 .bulk $22,$44,$08,$11 ;$10
9473: a2 c4 88 91 .bulk $a2,$c4,$88,$91 ;$11
9477: 08 11 22 44 .bulk $08,$11,$22,$44 ;$12
947b: 88 91 a2 c4 .bulk $88,$91,$a2,$c4 ;$13
947f: c9 a4 92 89 .bulk $c9,$a4,$92,$89 ;$14
9483: 24 12 49 24 .bulk $24,$12,$49,$24 ;$15
9487: 77 6e 5d 3b .bulk $77,$6e,$5d,$3b ;$16
948b: f7 ee dd bb .bulk $f7,$ee,$dd,$bb ;$17
948f: 5d 3b 77 6e .bulk $5d,$3b,$77,$6e ;$18
9493: dd bb f7 ee .bulk $dd,$bb,$f7,$ee ;$19
9497: 6e 5d 3b 77 .bulk $6e,$5d,$3b,$77 ;$1a
949b: ee dd bb f7 .bulk $ee,$dd,$bb,$f7 ;$1b
949f: 3b 77 6e 5d .bulk $3b,$77,$6e,$5d ;$1c
94a3: bb f7 ee dd .bulk $bb,$f7,$ee,$dd ;$1d
94a7: 00 00 00 00+ .align $0100 (89 bytes)
;
; Brush bitmaps. Each bitmap has four 8-byte pieces, arranged the same way that
; the font glyphs are.
;
; Must be page-aligned.
;
9500: 00 00 00 00+ brush_bitmaps .bulk $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$40,$00,$00,$00,$00,$00,$00,$00,$01
+ $40,$00,$00,$00,$00,$00,$00,$00,$01,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$40,$60,$00,$00,$00,$00,$00,$00,$01,$03
+ $60,$40,$00,$00,$00,$00,$00,$00,$03,$01,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$60,$70,$70,$00,$00,$00,$00,$00,$03,$07,$07
+ $70,$70,$60,$00,$00,$00,$00,$00,$07,$07,$03,$00,$00,$00,$00,$00
+ $00,$00,$00,$60,$78,$78,$7c,$7c,$00,$00,$00,$03,$0f,$0f,$1f,$1f
+ $7c,$7c,$78,$78,$60,$00,$00,$00,$1f,$1f,$0f,$0f,$03,$00,$00,$00
+ $00,$60,$7c,$7e,$7e,$7e,$7f,$7f,$00,$03,$1f,$3f,$3f,$3f,$7f,$7f
+ $7f,$7f,$7e,$7e,$7e,$7c,$60,$00,$7f,$7f,$3f,$3f,$3f,$1f,$03,$00
+ $00,$00,$00,$00,$40,$08,$20,$00,$00,$00,$00,$00,$00,$04,$00,$09
+ $28,$00,$10,$00,$00,$00,$00,$00,$00,$05,$00,$01,$00,$00,$00,$00
+ $00,$20,$08,$24,$40,$12,$68,$60,$00,$04,$01,$14,$00,$2b,$03,$27
+ $62,$48,$22,$28,$00,$10,$40,$00,$17,$09,$22,$15,$00,$0a,$00,$00
;
; Hi-res font glyphs. This is a 96-character font (no control chars), stored in
; standard hi-res font format.
;
; The glyphs generally use lines that are two pixels wide, so that the text is
; visible when drawn in color.
;
; This must start on the page following the brush bitmaps. We don't include
; glyphs for the control characters, but by indexing from $9500 we can multiply
; the char value by 8 without adjusting the start address.
;
9600: 00 00 00 00+ font_glyphs .bulk $00,$00,$00,$00,$00,$00,$00,$00,$1c,$1c,$1c,$1c,$00,$1c,$1c,$00
+ $36,$36,$24,$36,$00,$00,$00,$00,$12,$3f,$3f,$12,$3f,$3f,$12,$00
+ $0c,$3f,$03,$3f,$30,$3f,$0c,$00,$00,$27,$17,$0f,$3c,$3a,$39,$00
+ $06,$09,$02,$04,$2a,$11,$2e,$00,$0c,$0c,$08,$0c,$00,$00,$00,$00
+ $38,$1c,$0e,$0e,$0e,$1c,$38,$00,$0e,$1c,$38,$38,$38,$1c,$0e,$00
+ $08,$2a,$1c,$3e,$1c,$2a,$08,$00,$0c,$0c,$3f,$3f,$0c,$0c,$00,$00
+ $00,$00,$00,$00,$00,$1c,$18,$0c,$00,$00,$3e,$3e,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$1c,$1c,$00,$60,$70,$38,$1c,$0e,$07,$03,$00
+ $1e,$33,$33,$33,$33,$33,$1e,$00,$3c,$36,$33,$30,$30,$30,$30,$00
+ $1e,$3f,$33,$38,$0e,$3f,$3f,$00,$1e,$3f,$30,$3e,$30,$3f,$1e,$00
+ $38,$3c,$36,$33,$3f,$30,$30,$00,$3f,$3f,$03,$1f,$30,$3f,$1e,$00
+ $1c,$06,$03,$1f,$33,$33,$1e,$00,$3f,$3f,$30,$18,$0c,$0c,$0c,$00
+ $1e,$3f,$33,$1e,$33,$3f,$1e,$00,$1e,$3f,$33,$3e,$30,$3e,$1e,$00
+ $00,$1c,$1c,$00,$00,$1c,$1c,$00,$00,$1c,$1c,$00,$00,$1c,$18,$0c
+ $70,$38,$1c,$0e,$1c,$38,$70,$00,$00,$3e,$3e,$00,$3e,$3e,$00,$00
+ $07,$0e,$1c,$38,$1c,$0e,$07,$00,$1e,$3f,$33,$18,$0c,$00,$0c,$00
+ $7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$1e,$3f,$33,$3f,$3f,$33,$33,$00
+ $1f,$3f,$33,$1f,$33,$3f,$1f,$00,$1e,$3f,$33,$03,$33,$3f,$1e,$00
+ $1f,$3f,$33,$33,$33,$3f,$1f,$00,$3f,$3f,$03,$1f,$03,$3f,$3f,$00
+ $3f,$3f,$03,$1f,$1f,$03,$03,$00,$1e,$3f,$03,$3b,$33,$3f,$1e,$00
+ $33,$33,$33,$3f,$3f,$33,$33,$00,$3f,$3f,$0c,$0c,$0c,$3f,$3f,$00
+ $b0,$b0,$b0,$b0,$b3,$bf,$9e,$80,$33,$3b,$1f,$0f,$1f,$3b,$33,$00
+ $03,$03,$03,$03,$03,$3f,$3f,$00,$63,$77,$6b,$63,$63,$63,$63,$00
+ $33,$33,$37,$3f,$3b,$33,$33,$00,$1e,$3f,$33,$33,$33,$3f,$1e,$00
+ $1f,$3f,$33,$3f,$1f,$03,$03,$00,$1e,$3f,$23,$23,$2b,$13,$2e,$00
+ $1f,$3f,$33,$3f,$1f,$3b,$33,$00,$1e,$3f,$03,$1e,$30,$3f,$1e,$00
+ $3f,$3f,$0c,$0c,$0c,$0c,$0c,$00,$33,$33,$33,$33,$33,$3f,$1e,$00
+ $33,$33,$33,$33,$33,$1e,$0c,$00,$63,$63,$63,$6b,$6b,$77,$63,$00
+ $33,$33,$1e,$0c,$1e,$33,$33,$00,$33,$33,$33,$1e,$0c,$0c,$0c,$00
+ $3f,$3f,$18,$0c,$06,$3f,$3f,$00,$1f,$1f,$03,$03,$03,$1f,$1f,$00
+ $03,$07,$0e,$1c,$38,$70,$60,$00,$1f,$1f,$18,$18,$18,$1f,$1f,$00
+ $0c,$1e,$3f,$00,$00,$00,$00,$00,$80,$80,$80,$80,$80,$80,$ff,$ff
+ $06,$0c,$18,$30,$00,$00,$00,$00,$00,$00,$1e,$30,$3e,$33,$3e,$00
+ $03,$03,$1f,$33,$33,$33,$1f,$00,$00,$00,$1e,$33,$03,$33,$1e,$00
+ $30,$30,$3e,$33,$33,$33,$3e,$00,$00,$00,$1e,$33,$1f,$03,$1e,$00
+ $1c,$36,$06,$1f,$06,$06,$06,$00,$00,$00,$1e,$33,$33,$3e,$30,$1e
+ $03,$03,$1f,$33,$33,$33,$33,$00,$00,$0c,$00,$0c,$0c,$0c,$0c,$00
+ $30,$00,$30,$30,$30,$33,$33,$1e,$03,$03,$33,$1b,$0f,$1b,$33,$00
+ $0e,$0c,$0c,$0c,$0c,$0c,$1e,$00,$00,$00,$3f,$5b,$5b,$5b,$5b,$00
+ $00,$00,$1f,$33,$33,$33,$33,$00,$00,$00,$1e,$33,$33,$33,$1e,$00
+ $00,$00,$1f,$33,$33,$1f,$03,$03,$00,$00,$3e,$33,$33,$3e,$30,$30
+ $00,$00,$1f,$33,$03,$03,$03,$00,$00,$00,$1e,$03,$1e,$30,$1e,$00
+ $06,$06,$1f,$06,$06,$36,$1c,$00,$00,$00,$33,$33,$33,$33,$3e,$00
+ $00,$00,$33,$33,$33,$1e,$0c,$00,$00,$00,$6d,$6d,$6d,$6d,$7e,$00
+ $00,$00,$33,$1e,$0c,$1e,$33,$00,$00,$00,$33,$33,$33,$3e,$30,$1e
+ $00,$00,$3f,$18,$0c,$06,$3f,$00,$1c,$1e,$06,$07,$06,$1e,$1c,$00
+ $0c,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$0e,$1e,$18,$38,$18,$1e,$0e,$00
+ $00,$00,$28,$14,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
.adrend ↑ $8d00