Hi.

So I've not got my bochs code into a form that I can easily distribute, so that will have to wait for a bit. In the mean time (Actually why I was bored at work) I've been playing with hq, hqasm and hqsim. Quite a nice set of programs, good work there.

First a bug report ;-) The assembler doesn't support '%' so It's hard to load 32-bit constants. Or am I missing something? I came up with this, but it also relies on me knowing that the low half is greater than 32767.

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

        ; (We cant use 'or' because the constant is sign extended)

I guess that for the very few occasions when this is needed it won't be a problem.

So, what have I been doing? Well I had a go at converting draw_glyph into HQ assembler. There were a couple of changes that I made - firstly the bitmap was stored the wrong way around in the C version - the MSB of each octet is the left most pixel. Secondly I converted it to one Y loop instead of a loop of 4 and a loop of height / 4. I think this makes smaller and quicker code.

Anyway I've attached my code as I'm not sure if it's ready to be checked in or not. Feel free to do so if you like it. (The test section should be moved somewhere else).


I think, from my reading of the other code mainly, that there is a delay when we read from an external port? Is there also a delay when we read from local memory?

For instance, if we assume that G_VID_SCREEN_WIDTH is local memory, I think that this will fail because r0 does not have the value read from memory until after the add.

        move    [G_VID_SCREEN_WIDTH], r0
        add     q0, r0, q0

So this could be re-written:

        move    [G_VID_SCREEN_WIDTH], r0
        noop
        add     q0, r0, q0

Is this correct?


MM

PS.
I probably won't be converting the rest of the VGA converter into HQ just yet, this was just to see how it all hung together.
;;; Copyright (c) 2008 Traversal Technology
;;; 
;;; Permission is hereby granted, free of charge, to any person obtaining a
;;; copy of this software and associated documentation files (the "Software"),
;;; to deal in the Software without restriction, including without limitation
;;; the rights to use, copy, modify, merge, publish, distribute, sublicense,
;;; and/or sell copies of the Software, and to permit persons to whom the
;;; Software is furnished to do so, subject to the following conditions:
;;; 
;;; The above copyright notice and this permission notice shall be included in
;;; all copies or substantial portions of the Software.
;;; 
;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
;;; DEALINGS IN THE SOFTWARE.
;;;
;;; Author: Mark Marshall

include hqio

; HERE!
let G_VID_SCREEN_WIDTH = 0x100
let G_VID_GLYPH_HEIGHT_M1 = 0x101

  frame test
        alias p0 = r31
        protect r10..r30

        move 640, r1
        move r1, [G_VID_SCREEN_WIDTH]
        move 15, r1
        move r1, [G_VID_GLYPH_HEIGHT_M1]

        move    ((123000000)/65536)+1, r6
        shiftu  r6, 16, r6
        add     r6, -11072, r6 ; ((123000000)%65536)
        move    0x12, r7
        move    0x34, r8
        noop
        jump draw_glyph, r9
          noop
        noop
        jump 510
          noop
  endframe

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

    frame draw_glyph
        alias q0..q2 = r6..r8
        alias p0 = r9
        protect r4..r5
        protect r10..r31

;  r6/q0 = pixel address
;  r7/q1 = fg color
;  r8/q2 = bg color
;  r9/p0 = return address
;
;  r0 = general scratch register
;  r1 = y counter
;  r2 = mask (and x counter) / second scratch
;  r3 = 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?).

draw_glyph:

        ; We use R1 as our height counter, starting from 0
        move    0, r1
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     r1, 3, r0
        jnzero  r0, glyph_no_get
          noop
        move    [MEM_READQ_DATA], r3
glyph_no_get:

        ; 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.
        ;
        ; 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.

glyph_loop_cmd:
        move    [MEM_CMDQ_FREE], r0
        move    0x80, r2
        sub     r0, 9, r0
        jneg    r0, glyph_loop_cmd
          noop

        ; Set the current pixel address.
        move    q0, [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     r3, r2, r0
        jzero   r0, glyph_bg
          move    q2, r0
        move    q1, r0
glyph_bg:
        ; Shift the mask and loop if non-zero.  The sotre to video
        ; mem is done in the delay slot.
        shiftu  r2, -1, r2
        jnzero  r2, glyph_loop_x
          move    r0, [MEM_SEND_DATA_1111]

        ; Read the screen width and the glyph height
        move    [G_VID_SCREEN_WIDTH], r0
        move    [G_VID_GLYPH_HEIGHT_M1], r2
        ; Shift the glyph data.
        shiftu  r3, -8, r3
        ; Move pixel addr to the next line down
        add     q0, r0, q0

        ; If our height counter is equal to the glyph height then 
        ; we are done
        sub     r1, r2, r0
        jnzero  r0, glyph_loop
          add     r1, 1, r1
        jump    p0
          noop

    endframe
MEM_READQ_DATA 0xaa55aa55
MEM_CMDQ_FREE 7
MEM_CMDQ_FREE 9
MEM_CMDQ_FREE 9
MEM_CMDQ_FREE 9
MEM_CMDQ_FREE 9

MEM_READQ_DATA 0xaa55aa55
MEM_CMDQ_FREE 9
MEM_CMDQ_FREE 9
MEM_CMDQ_FREE 9
MEM_CMDQ_FREE 9

MEM_READQ_DATA 0xaa55aa55
MEM_CMDQ_FREE 9
MEM_CMDQ_FREE 9
MEM_CMDQ_FREE 9
MEM_CMDQ_FREE 9

MEM_READQ_DATA 0xaa55aa55
MEM_CMDQ_FREE 9
MEM_CMDQ_FREE 9
MEM_CMDQ_FREE 9
MEM_CMDQ_FREE 9
_______________________________________________
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