Thanks for the comments.

Timothy Normand Miller wrote:
Readdressing the little-endian thing, were you saying that the way
glyph bits are stored in the VGA font is big-endian?  If so, then that
was my mistake.

Yes, from my reading of several different books on the VGA, the fonts are stored with the MSB of each octet as the left most pixel. I change my mind every day about whether this is the right way around or not, but that is only a philosophical issue now.


Read on...

>> ; HERE!
>> > let G_VID_SCREEN_WIDTH = 0x100
>> > let G_VID_GLYPH_HEIGHT_M1 = 0x101
>
> Are these addresses in scratch memory?

Yes, it was my intention that these would be in scratch memory. I'm not sure how we're going to allocate things there yet. They could also be passed in registers, but I can see no advantage in that.


       move    ((123000000)/65536)+1, r6
       shiftu  r6, 16, r6
       add     r6, -11072, r6 ; ((123000000)%65536)

We're going to have to get help from Petter about how to do this
properly.  Also, what is the meaning of the 123000000 that you're
trying to store in r6?

Petter's a new feature to make this easier, thanks Petter. I'm loading a large number with zeros on the left into the pixel address so that in the simulator I can see easily that I am incrementing the pixel address by the amount I thought I should be. This 'frame' is only for testing.


       move    0x12, r7
       move    0x34, r8
       noop
       jump draw_glyph, r9
         noop
       noop
       jump 510

What code is going to be fixed at 510?

In the simulator, jumping to address 510 stops the simulation.


         noop
 endframe

;;; ------------------------------------------------------------------------
;;; draw_glyph(r6: pixel_addr, r7: fg_color, r8: bg_color, r9: continuation)

   frame draw_glyph
       alias p0..p3 = r6..r9
       alias q0..q3 = r0..r3
       protect r4..r5
       protect r10..r31

;  p0 = pixel address
;  p1 = fg color
;  p2 = bg color
;  p3 = return address
;
;  q0 = general scratch register
;  q1 = y counter
;  q2 = mask (and x counter) / second scratch
;  q3 = font data
;
; Global data:
;
; G_VID_SCREEN_WIDTH
;    The offset to add to the pixel_address to move down one line
; G_VID_GLYPH_HEIGHT_M1
;    The height of a font character (minus 1)
;
; It is assumed that the glyph data is contained in consecutive
; 8-bit chunks of the data being read from memory.  The least
; signifigant 8-bits are the first (top) line.  For each line,
; the most significant bit is assumed to be the left-most bit.
; This matches the VGA (and common sense?).

Good comments!  :)

If the bytes are little-endian relative to each other, then it makes
sense for the bits in the bytes to also be little-endian.  That's
common sense to me.  But it would not surprise me at all if they
didn't do it that way.  On x86, X11 stores bitmaps internally in a
truly little-endian manner, whereas GDI in Windows stores the bytes
little-endian but the bits big-endian.  To a large degree, it's all
purely arbitrary, although some combinations are easier to remember
and therefore less bug-prone.

draw_glyph:

       ; We use Q1 as our height counter, starting from 0
       move    0, q1
glyph_loop:

       ; Every fourth scan line we need to read a new uint32 of
       ; glyph data.  The code is smaller if I only have one loop,
       ; as opposed to the two in Tims original C version.

       and     q1, 3, q0
       jnzero  q0, glyph_no_get
         ; Shift the glyph data.
         shiftu  q3, -8, q3
       move    [MEM_READQ_DATA], q3
glyph_no_get:

What you did is just fine.  We'll revisit this when we run this in the
real hardware.  If the framerate is less than 10fps, we'll look into
making optimizations that add more code to make it faster.  Unrolled
loops and such.  I can't really judge the difference here, and since
you're the one doing the hard work to hand-code the assembly, I'm not
going to argue with you.  :)

       ; We now check to see if thre are at least 9 free spaces
       ; in the command Q.  If there are fewer than 9 we loop.

One for the address, 8 for the data.

       ;
       ; R2 is the mask that we will use below, we might as well
       ; load that up now in the delay slot after the memory read.

q2?

One of the biggest crimes in software is when the comments get out of step with the code. I'm sorry, I'll try to not let it happen again. ;-).


glyph_loop_cmd:
       move    [MEM_CMDQ_FREE], q0
       move    0x80, q2
       sub     q0, 9, q0
       jneg    q0, glyph_loop_cmd
         noop

       ; Set the current pixel address.
       move    p0, [MEM_SEND_ADDR_MEM]

       ; We now loop over the eight horizontal pixels of the
       ; glyph data.  To count this loop we are using the mask
       ; that has been initialised to 0x80.  Once we have shifted
       ; it right until it is zero we are done.

glyph_loop_x:
       ; And the mask with the glyph data, and load R0 with either
       ; the foreground color or the background color.
       and     q3, q2, q0
       jzero   q0, glyph_bg
         move    p2, q0
       move    p1, q0
glyph_bg:
       ; Shift the mask and loop if non-zero.  The store to video
       ; mem is done in the delay slot.
       shiftu  q2, -1, q2
       jnzero  q2, glyph_loop_x
         move    q0, [MEM_SEND_DATA_1111]

       ; Read the screen width and the glyph height
       move    [G_VID_SCREEN_WIDTH], q0
       move    [G_VID_GLYPH_HEIGHT_M1], q2
       ; Move pixel addr to the next line down
       add     p0, q0, p0

       ; If our height counter is equal to the glyph height then
       ; we are done
       sub     q1, q2, q0
       jnzero  q0, glyph_loop
         add     q1, 1, q1
       jump    p3
         noop

   endframe

Very sweet!

Thanks, I really enjoy this sort of coding, and there's very little need for it any more. At work, I'm quite against anyone ever checking in any assembler, it can be very hard for the non-author to debug.

_______________________________________________
Open-graphics mailing list
[email protected]
http://lists.duskglow.com/mailman/listinfo/open-graphics
List service provided by Duskglow Consulting, LLC (www.duskglow.com)

Reply via email to