Skip to navigation

Revs on the BBC Micro

Screen buffer: DRAW_BYTE

Name: DRAW_BYTE [Show more] Type: Macro Category: Screen buffer Summary: Draw a pixel byte as part of a horizontal line when drawing the track view
Context: See this macro in context in the source code References: This macro is used as follows: * DrawTrackBytes (Part 1 of 3) uses DRAW_BYTE * DrawTrackBytes (Part 2 of 3) uses DRAW_BYTE

This routine draws a row of four pixels (i.e. one byte) as part of the track view. The track view is drawn one line at a time, with each line being one pixel high. Each of these lines is drawn as a sequence of bytes, with each byte containing four pixels. Each macro instance draws one pixel byte into screen memory, so that's one four-pixel block within the horizontal line. So the full sequence of macros, from DRAW_BYTE 0 through DRAW_BYTE 39, draws a one-pixel high line across the full width of the screen. In other words, each DRAW_BYTE macro draws a character block's worth of line, as the screen is 40 character blocks wide. Each macro instance draws one pixel byte, from offset X within dash data block I%, into screen memory. The offset X is decremented for each run through the sequence of macros, as data is stored at the end of each dash data block. So as each pixel line is drawn, moving down the screen, X decrements down from 79 (the start of each dash data block) as we work our way through the data. The destination address in screen memory for the data is governed by (Q P), which points to the address of the pixel byte to update in the first byte (i.e. the address of the first pixel in the line across the screen). If the dash data byte is zero, then the current value of A is stored in screen memory (i.e. the same value that was stored in the previous byte). If the dash data byte is non-zero, then this is stored in A and screen memory, unless it is &55, in which a zero is stored in A and screen memory. As it is copied, the source dash data byte is zeroed, so the macro effectively moves a byte into screen memory, clearing it in the process.
Arguments: I% The pixel byte number (0 to 39) X The offset within the dash data of the data to be drawn on the screen (from &7F down, as the dash data lives at the end of each dash data block) A The value stored in screen memory in the previous pixel byte (or the starting value if this is pixel byte 0) (Q P) The screen address of the leftmost character block to update (i.e. the screen address of the pixel byte to draw in the first character block on the line, so this is the address of the start of the horizontal line that the sequential macros draw) (S R) Contains (Q P) + &100, to be used instead of (Q P) for pixel bytes 32 to 39
MACRO DRAW_BYTE I% LDY dashData+&80*I%,X \ Set Y to the X-th byte of dash data block I% BEQ P%+10 \ If Y = 0, skip the next three instructions (i.e. jump \ to the LDY #LO(8*I%) instruction to leave the value of \ A alone) \ Otherwise Y is non-zero, and we do the following in \ the next three instructions: \ \ * Zero the location in code block I% from which we \ just read a byte \ \ * Set A to the byte we just read from code block I%, \ unless the value is &55, in which case set A = 0 LDA #0 \ Zero the X-th byte of dash data block I% STA dashData+&80*I%,X LDA zeroIfYIs55,Y \ Set A to the Y-th byte from zeroIfYIs55 \ \ This sets A = Y, unless Y = &55, in which case it sets \ Y = 0, so that's: \ \ If Y = &55, set A = 0, otherwise set A = Y \ \ The zeroIfYIs55 table exists just to enable us to do \ this logic in one instruction \ If Y = 0 above, this is where we jump to LDY #LO(8*I%) \ Store A in character block I% in screen memory, as an IF I% < 32 \ offset from (Q P) STA (P),Y \ ELSE \ (S R) is used instead of (Q P) for pixel bytes 32 to STA (R),Y \ 39, which saves us from having to increment Q to cross ENDIF \ the page boundary, as (S R) = (Q P) + &100 \ Fall through into the next DRAW_BYTE macro to draw \ the next pixel byte along to the right, continuing the \ horizontal line of pixels ENDMACRO