I'm cleaning up the video controller code and preparing to check it into SVN. While I'm doing that, I'd like people to take a look at the programming model. There is room for a variety of improvements and critiques. We also need an assembler written, we need C code to auto-generate code from standard X.org timing numbers, and when I finish the basic test harness, I'd like others to help augment that.
Some improvements we should work on: - Find good uses for bit 24 and opcode 4. - Consider running vertical and horizontal programs in separate state machines Regarding the last comment, while it's a simplification of the hardware to have a single state machine, it can get tedious to account for every instruction in the vertical program in the horizontal subroutines. We have a dual-ported program file, so we could make the vertical code and horizontal code overlap in time (by putting them at different stages of a pipeline), simplifying the programming. As for the logic area, this would increase the control logic considerably but remove some of the code associated with subroutines. Here's a draft of some of the programming guide: This video controller works somewhat like a general-purpose programmable device. Every video word (time period corresponding to 4 pixels) is controlled by the execution of an instruction in program memory. To make programming reasonable and to cope with limited program memory (512 words), looping mechanisms are provided. Note: Memory words are 256 bits, while video words vary based on the bitdepth. Each instruction word is 32 bits, and there are 7 valid instructions. The fixed fields (common to all instructions) are as follows: [31] video data enable [30] vertical sync [29] horizontal sync [28:27] cursor control: 00 = do nothing 01 = increment cursor_y and reset cursor_x 10 = reset cursor_y 11 = reset cursor_x and cursor_y [cursor_x is incremented implictly when transmitting video words] [26] return from subroutine [25] raise video interrupt signal [24] unassigned [23:21] instruction opcode Valid opcodes: 0: JUMP (unconditional) [8:0] = instruction address 1: CALL (subroutine) [20:9] = 2049-count [8:0] = instruction address 2: NOOP (sync signals only) [20:9] = 2049-count 3: SEND (video words) [20:9] = 2049-count 4: (unassigned) 5: FETCH (video words from memory) [20:9] = number of 256-bit memory words memory word address is auto-incremented 6: ADDR (set memory word address) [20:0] = Upper bits of memory word address This number is shifted left by 7 to make a memory word address 7: INC (increment memory word address) [20:0] = Memory word address offset This number is sign-extended and added to the video word address. This is useful for panning and other cases where the physical display is not as wide as the memory buffer. Note: Incrementing the memory word address has 2 delay slots. That is, the sum is not valid for two instruction cycles after an INC instruction. FETCH instructions should fetch one scanline of memory words one scanline in advance of when they are needed. They tie up the memory address counter for about half a scanline. Counter values are encoded as (2049-count). Thus, a value of 2048 indicates a count of 1, and a value of 0 indicates a count of 2049. For longer counts, use more instructions. Assembly mnemonics look like this: OPCODE [syncs and flags] #count addr Sample video program: ; Simple 640x480 program ; hfp = 8 ; hsync = 8 ; hbp = 8 ; vfp = 3 ; vsync = 3 ; vbp = 3 ; vsync,hsync negative-assertion, data-enable positive assertion ; Entry point .addr = 0 ; Vertical program ADDR [-v,-h,-d] 0 ; vid addr = start of framebuffer CALL [-v,-h,-d] #1 vsync+1 CALL [-v,-h,-d] #2 vsync CALL [+v,-h,-d] #2 vblank ; back porch FETCH [+v,-h,-d] #640 ; Fetch for first scanline CALL [+v,-h,-d] #1 vbp+1 CALL [+v,-h,-d] #1 vbp CALL [+v,-h,-d] #479 vactive NOOP [+v,-h,-d] ; Already fetched last scanline CALL [+v,-h,-d] #1 vactive+1 CALL [+v,-h,-d] #2 vblank ; front porch CALL [+v,-h,-d] #1 vblank_short JUMP [+v,+h,-d] 0 vsync: NOOP [-v,-h,-d] #1 ; last 4 pixels of hsync NOOP [-v,+h,-d] #2 ; back porch NOOP [-v,+h,-d] #640 ; active period, but vblank NOOP [-v,+h,-d,ret] #2 ; front porch vblank: NOOP [+v,-h,-d] #1 ; last 4 pixels of hsync NOOP [+v,+h,-d] #2 ; back porch NOOP [+v,+h,-d] #640 ; active period, but vblank NOOP [+v,+h,-d,ret] #2 ; front porch vblank_short: NOOP [+v,-h,-d] #1 ; last 4 pixels of hsync NOOP [+v,+h,-d] #2 ; back porch NOOP [+v,+h,-d] #640 ; active period, but vblank NOOP [+v,+h,-d,ret] #1 ; front porch vactive: FETCH [+v,-h,-d] #1 ; last 4 pixels of hsync NOOP [+v,+h,-d] #2 ; back porch SEND [+v,+h,-d] #640 ; active period, but vblank NOOP [+v,+h,-d,ret] #2 ; front porch .end _______________________________________________ Open-graphics mailing list [email protected] http://lists.duskglow.com/mailman/listinfo/open-graphics List service provided by Duskglow Consulting, LLC (www.duskglow.com)
