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: