Announcement

Collapse
No announcement yet.

VESA Problem

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • G Grant
    replied
    Here are a couple of subs that will transfer any size virtual array
    to and from the video segment. I had to make a few assumptions about
    the way your code works. The following code assumes that your virtual
    array is a 0 based BYTE array (1 byte per pixel), and that the virtual
    array is the exact same size as the VESA video memory array (given
    the current video resolution). It also assumes that your VESA video
    banking code is switching the video memory into the conventional memory
    video segment 64k at a time. If any of these assumptions are wrong,
    you should be able to alter the code to work the way you want it.

    When you call the code, just include the name of the virtual array
    with an empty set of parentheses:
    CALL Scr2VMem(VirtualBuffer?())


    Code:
    DECLARE FUNCTION ARRAYINFO(BYVAL INTEGER, ANY) AS LONG
    Code:
    SUB VESA_Scr2VMem(BUFFER?())
     DIM ELEMENT AS DWORD, VESA_BANK AS INTEGER, EMS_PAGE_COUNT AS INTEGER
     TOTALBYTES&       = ARRAYINFO(1, BUFFER?())
     FULL_EMS_PAGES%   = TOTALBYTES& \ 16384         'TOTAL FULL 16k EMS PAGES
     LAST_EMS_PAGE%    = TOTALBYTES& MOD 16384       'BYTES IN LAST EMS PAGE
     EMS_PAGE_FRAME??? = VARPTR32(BUFFER?(0))
     VIDEO??           = &H0A000  '**Or use: VIDEO?? = DPBVX_INTERNAL_WIN_A_SEG
     asm_WFP???        = DPBVX_INTERNAL_WIN_FUNC_PTR 
     ! PUSH SI
     ! PUSH DI
     ! CLD
    NEXT_64k_VIDEO_PAGE:
     ! PUSH DS
     ! DB &H60                        ;VESA
     ! MOV DX, VESA_BANK              ;VIDEO
     ! XOR BX, BX                     ;BANKING
     ! LDS DI, asm_WFP???             ;CODE
     ! CALL DWORD PTR DS:[DI]         ;GOES
     ! DB &H61                        ;HERE 
     ! POP  DS
     ! MOV EMS_PAGE_COUNT, 4          ;FOUR 16k EMS PAGES PER 64k VIDEO SEGMENT
     ! XOR SI, SI                     ;START AT OFFSET 0 OF VIDEO SEGMENT
    NEXT_16k_EMS_PAGE:
     ! DEC FULL_EMS_PAGES%
     ! JS PARTIAL_16k_EMS_PAGE        ;NO MORE FULL 16k EMS PAGES LEFT
     ! PUSH SI                        ;DESTROYED BY THE VIRTUAL ARRAY REFERENCE
     DUMMY? = BUFFER?(ELEMENT)        'LET POWERBASIC FILL THE PAGE FRAME
     ! POP  SI
     ! MOV AX, DS                     ;SAVE DS FOR ACCESS TO VIRTUAL ARRAY
     ! LES DI, EMS_PAGE_FRAME???
     ! MOV DS, VIDEO??
     ! MOV CX, 4096
     ! DB 102
     ! REP MOVSW
     ! MOV DS, AX
     ! DB 102
     ! ADD ELEMENT, 16384             ;ELEMENT AT NEXT EMS PAGE
     ! DW 00
     ! DEC EMS_PAGE_COUNT
     ! JNZ NEXT_16k_EMS_PAGE
     ! INC VESA_BANK
     ! JMP NEXT_64k_VIDEO_PAGE
    PARTIAL_16k_EMS_PAGE:
     ! CMP LAST_EMS_PAGE%, 0
     ! JZ FINISHED
     ! PUSH SI
     DUMMY? = BUFFER?(ELEMENT)
     ! POP  SI
     ! MOV AX, DS
     ! LES DI, EMS_PAGE_FRAME???
     ! MOV DS, VIDEO??
     ! MOV BX, LAST_EMS_PAGE%
     ! MOV CX, BX
     ! SHR CX, 1
     ! SHR CX, 1
     ! DB 102
     ! REP MOVSW
     ! MOV CX, BX
     ! AND CX, 3
     ! REP MOVSB
     ! MOV DS, AX
    FINISHED:
     ! POP DI
     ! POP SI
    END SUB
    Code:
    SUB VESA_VMem2Scr(BUFFER?())
     DIM ELEMENT AS DWORD, VESA_BANK AS INTEGER, EMS_PAGE_COUNT AS INTEGER
     TOTALBYTES&       = ARRAYINFO(1, BUFFER?())
     FULL_EMS_PAGES%   = TOTALBYTES& \ 16384         'TOTAL FULL 16k EMS PAGES
     LAST_EMS_PAGE%    = TOTALBYTES& MOD 16384       'BYTES IN LAST EMS PAGE
     EMS_PAGE_FRAME??? = VARPTR32(BUFFER?(0))
     VIDEO??           = &H0A000  '**Or use: VIDEO?? = DPBVX_INTERNAL_WIN_A_SEG
     asm_WFP???        = DPBVX_INTERNAL_WIN_FUNC_PTR 
     ! PUSH SI
     ! PUSH DI
     ! CLD
    NEXT_VIDEO_PAGE:
     ! PUSH DS
     ! DB &H60                        ;VESA
     ! MOV DX, VESA_BANK              ;VIDEO
     ! XOR BX, BX                     ;BANKING
     ! LDS DI, asm_WFP???             ;CODE
     ! CALL DWORD PTR DS:[DI]         ;GOES
     ! DB &H61                        ;HERE
     ! POP DS
     ! MOV EMS_PAGE_COUNT, 4          ;FOUR 16k EMS PAGES PER 64k VIDEO PAGE
     ! XOR DI, DI                     ;START AT OFFSET 0 OF VIDEO SEGMENT
    NEXT_EMS_PAGE:
     ! DEC FULL_EMS_PAGES%
     ! JS PARTIAL_EMS_PAGE            ;NO MORE FULL 16k EMS PAGES LEFT
     ! PUSH DI                        ;DESTROYED BY THE VIRTUAL ARRAY REFERENCE
     DUMMY? = BUFFER?(ELEMENT)        'LET POWERBASIC FILL THE PAGE FRAME
     ! POP DI
     ! MOV AX,DS                      ;SAVE DS FOR ACCESS TO THE VIRTUAL ARRAY
     ! LDS SI, EMS_PAGE_FRAME???
     ! MOV ES, VIDEO??
     ! MOV CX, 4096
     ! DB 102
     ! REP MOVSW
     ! MOV DS, AX
     ! DB 102
     ! ADD ELEMENT, 16384             ;ELEMENT AT NEXT EMS PAGE
     ! DW 00
     ! DEC EMS_PAGE_COUNT
     ! JNZ NEXT_EMS_PAGE
     ! INC VESA_BANK
     ! JMP NEXT_VIDEO_PAGE
    PARTIAL_EMS_PAGE:
     ! CMP LAST_EMS_PAGE%, 0
     ! JZ DONE
     ! PUSH DI
     DUMMY? = BUFFER?(ELEMENT)
     ! POP DI
     ! MOV AX, DS
     ! LDS SI, EMS_PAGE_FRAME???
     ! MOV ES, VIDEO??
     ! MOV BX, LAST_EMS_PAGE%
     ! MOV CX, BX
     ! SHR CX, 1
     ! SHR CX, 1
     ! DB 102
     ! REP MOVSW
     ! MOV CX, BX
     ! AND CX, 3
     ! REP MOVSB
     ! MOV DS, AX
    DONE:
     ! POP DI
     ! POP SI
    END SUB

    ------------------

    Leave a comment:


  • G Grant
    replied
    Hello Walt. Been a while since my last post here. How has everyone
    been? Anyway I'll try to help what little I can here.

    First of all, when you use the MOVS instructions, data is moved
    from DS:SI (Source) to ESI (Destination). Not DSI to ES:SI,
    which, unless I'm reading it wrong (and I might be), is what you
    seem to be doing. Also, when you use REP MOVS instructions, be
    sure to set the direction flag with CLD to make sure the registers
    are being incremented after each data move.

    Second, adding 1 to a segment register is equivalent to adding 16
    to the 32 bit segmentffset address, NOT 16K. So to add 16K to a
    segmentffset address, just add 1024 to the segment register (not
    1).

    Lastly, when referencing a virtual array element through the EMS
    page frame, you must be sure the correct 16K portion of the virtual
    array is currently switched into the page frame. Simply reading from
    or writing to the EMS page frame itself will not automatically update
    the page frame. PowerBASIC will automatically update the EMS page
    frame simply by making reference to the correct element of the virtual
    array (such as: A? = v_array?(16385). So, to fill the page frame with
    the first 16K of a virtual array, just read any element (into a dummy
    variable) within the first 16K of the virtual array. To fill it with
    the second 16K of the virtual array, read any element within the second
    16K of the array, and so on.
    Be sure to take into account the size of the array elements when
    referencing an element, since its the number of BYTES of the offset
    of the element that determines which portion of the array gets switched
    into the page frame. Also, as long as the correct portion of the virtual
    array is currently switched into the page frame, you can write to the
    virtual array by writing directly to the EMS page frame. But be careful
    not to write beyond the end of the page frame, or disasterous results may
    occur.

    I hope that helps, (and that I'm even on the right track).


    [This message has been edited by G Grant (edited August 02, 2001).]

    Leave a comment:


  • Lance Edmonds
    replied
    When you reference one virtual array subscript, PowerBASIC will page switch, say, up to one 16k EMS page into the EMS page frame so that the subscript can be read or written. The size of the EMS page may be lower - I'm not that familar with the internal operation of the Virtual array engine to be 100% sure (without checking with R&D).

    While you have not shown the code that calls this SUB, it seems logical that your may be arbitarily writing beyond the scope of the loaded (valid) EMS page, where there may or may not be virtual array pages loaded.

    You may need to reference more of the array in Basic code before this SUB executes, or maybe create 4 separate 16K virtual arrays and reference each before caalling the Sub.

    In this case, it may be easier to manaage the EMS page frame yourself (and matybe overlaying a conventional array with DIM..AT), rather than anticipating the operation of the virtual array engine.



    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Walt Decker
    started a topic VESA Problem

    VESA Problem

    For double buffering in SVGA you have to make a virtual array with the size of the screen, no probem. But the memcopy routine which has to blit the whole buffer to the video segment does not work properly. Some things get messed up and only 1/4 part of each bank is filled. Perhaps you could take a look at the code and tell where it's wrong.

    Here are the routines that are giving the headache.

    sub VESA_Scr2Mem(seg_buf as word) ' seg_buf: Segment
    ' of Virtual Array
    ' Direct Bank Switch Pointer
    asm_WFP???=DPBVX_INTERNAL_WIN_FUNC_PTR
    ' Number of Banks
    asm_NOB??=DPBVX_INTERNAL_NUMBER_OF_BANKS
    ' Video Segment
    asm_SEG??=DPBVX_INTERNAL_WIN_A_SEG
    '
    ' dx : current bank
    ' es:[si] : pointer to target memory (buffer)
    ' ds:[di] : pointer to source memory (screen)
    '
    dim bank as word
    startseg??=seg_buf

    for bank=0 to asm_NOB??
    p1??=startseg??
    p2??=startseg??+1
    p3??=startseg??+2
    p4??=startseg??+3

    ! push ds

    ! db &h60 ; -------------
    ! mov dx,bank ; Direct Bank
    ! xor bx,bx ; Switch
    ! lds di,asm_WFP??? ; Routine
    ! call dword ptr ds:[di] ;
    ! db &h61 ; -------------

    ! mov ax,asm_SEG??
    ! mov ds,ax

    ! mov ax,p1?? ; This should copy
    ! mov es,ax ; the first 16k
    ! xor si,si ; from each bank
    ! xor di,di ; to the buffer
    ! mov cx,&h1000 ;
    ! db &h66 ;
    ! rep movsw ;

    ! mov ax,p2?? ; This should copy
    ! mov es,ax ; the second 16k
    ! xor si,si ; from each bank
    ! mov di,&h4000 ; to the buffer
    ! mov cx,&h1000 ;
    ! db &h66 ;
    ! rep movsw ;

    ! mov ax,p3?? ; This should copy
    ! mov es,ax ; the third 16k
    ! xor si,si ; from each bank
    ! mov di,&h8000 ; to the buffer
    ! mov cx,&h1000 ;
    ! db &h66 ;
    ! rep movsw ;

    ! mov ax,p4?? ; This should copy
    ! mov es,ax ; the fourth 16k
    ! xor si,si ; from each bank
    ! mov di,&hc000 ; to the buffer
    ! mov cx,&h1000 ;
    ! db &h66 ; Together the whole bank (64k)
    ! rep movsw ;

    ! pop ds

    incr startseg??,4 ' jump over 4 segs ( good way? )
    next bank
    end sub

    sub VESA_Mem2Scr(seg_buf as word) ' seg_buf: Segment
    ' of Virtual Array
    ' Direct Bank Switch Pointer
    asm_WFP???=DPBVX_INTERNAL_WIN_FUNC_PTR
    ' Number of Banks
    asm_NOB??=DPBVX_INTERNAL_NUMBER_OF_BANKS
    ' Video Segment
    asm_SEG??=DPBVX_INTERNAL_WIN_A_SEG
    '
    ' dx : current bank
    ' es:[si] : pointer to target memory (screen)
    ' ds:[di] : pointer to source memory (buffer)
    '
    dim bank as word
    startseg??=seg_buf

    for bank=0 to asm_NOB??
    p1??=startseg??
    p2??=startseg??+1
    p3??=startseg??+2
    p4??=startseg??+3

    ! push ds

    ! db &h60 ; -------------
    ! mov dx,bank ; Direct Bank
    ! xor bx,bx ; Switch
    ! lds di,asm_WFP??? ; Routine
    ! call dword ptr ds:[di] ;
    ! db &h61 ; -------------

    ! mov ax,asm_SEG??
    ! mov es,ax

    ! mov ax,p1?? ; This should copy
    ! mov ds,ax ; the first 16k
    ! xor di,di ; back to the screen
    ! xor si,si ; for each bank
    ! mov cx,&h1000 ;
    ! db &h66 ;
    ! rep movsw ;

    ! mov ax,p2?? ; etc...
    ! mov ds,ax
    ! xor di,di
    ! mov si,&h4000
    ! mov cx,&h1000
    ! db &h66
    ! rep movsw

    ! mov ax,p3??
    ! mov ds,ax
    ! xor di,di
    ! mov si,&h8000
    ! mov cx,&h1000
    ! db &h66
    ! rep movsw

    ! mov ax,p4??
    ! mov ds,ax
    ! xor di,di
    ! mov si,&hc000
    ! mov cx,&h1000
    ! db &h66
    ! rep movsw

    ! pop ds

    incr startseg??,4
    next bank
    end sub


    ------------------
Working...
X