News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

No flickering in mode 13h

Started by popcalent, June 10, 2021, 10:27:08 AM

Previous topic - Next topic

popcalent

Hi all,

I'm working on some code to prevent flickering in mode 13h caused by drawing the screen out of sync with the vertical retrace. The idea is to creare a 320x200 buffer and draw everything there. Then wait for the end of the vertical retrace and dump the buffer into the video memory. I have done this before in C, but I'm having some problems in assembly.

The first problem, I can't create a 320x200 buffer because it exceeds 64K. Actually it doesn't, but since I have other variables, the total size of the data segment exceeds 64K.
SCREEN_BUFFER   DB      64000   DUP(?)

I made these macros that put pixels on the buffer, and dump the buffer into the video memory. I wasn't unable to see if they work because the aforementioned problem. I intend to turn them into subroutines, eventually.

; PUTS A PIXEL IN THE BUFFER
; EX. MODE13H_PIXEL 160, 100, 15
;---------------------------------------------------
MODE13H_PIXEL  MACRO XCOORD, YCOORD, COLOR
        PUSH    AX
        PUSH    BX
        PUSH    ES
        PUSH    DI
        LEA     AX, SCREEN_BUFFER
        MOV     ES, AX
        MOV     AX, YCOORD
        MOV     BX, YCOORD
        SHL     AX, 8
        SHL     BX, 6
        ADD     AX, BX
        ADD     AX, XCOORD
        MOV     DI, AX
        MOV     AL, COLOR
        MOV     ES:[DI], AL
        POP     DI
        POP     ES
        POP     BX
        POP     AX
        ENDM

; DUMPS THE BUFFER
;---------------------------------------------------
MODE13H_BUFFER_DUMP     MACRO
        PUSH    AX
        PUSH    BX
        PUSH    DS
        PUSH    ES
        PUSH    SI
        PUSH    DI
        ;=============
        MOV     AX, 0A000H
        MOV     ES, AX
        LEA     AX, SCREEN_BUFFER1
        MOV     DS, AX
        MOV     DI, 0
        MOV     SI, 0
        ;=============
        BUFFER_DUMP:
                MOV     AL, DS:[SI]
                MOV     ES:[DI], AL
                INC     SI
                INC     DI
                CMP     DI, 0FA00H    ;DI<64000?
                JMP_L   BUFFER_DUMP
        ;=============
        POP     DI
        POP     SI
        POP     ES
        POP     DS
        POP     BX
        POP     AX
        ENDM


How do I make a buffer the size of the screen? Thanks!










avcaballero

The best way to avoid flickering is using double buffering, but you may also wait for vertical and horizontal retrace. Nevertheless, if your frames animation don't join well you will see flickering no matter what you do to trying to avoid it. For example, when your image calculation is not sincronized with your painting routine (you calculate faster than you paint) or when your routines don't actually join well your succesive frames animation.

daydreamer

check memory thread
,I use separate segments CS,SS for the usual variables and arrays,which can be used either by [bp],[sp] or segment override CS:adress while I use several segments below 0A000h to draw to ,starting with 9000,and going down 8000,7000... with DS and ES as backbuffers
while .com program gets near start of memory,after some data
but I dont have a real 286 computer,so it might occcupy something memory space on real computer
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

FORTRANS

Hi,

   You can define a segment to hold your screen buffer
that is separate from your normal data segment.


SBUFFER SEGMENT

SCREEN_BUFFER    DB       64000 DUP(?)

SBUFFER ENDS

...

        MOV     AX,SEG SBUFFER
        MOV     ES,AX
        ASSUME  ES:SBUFFER
        MOV     DI,OFFSET SCREEN_BUFFER


    If you are using the simplified directives (.CODE, .DATA),
there is the .FARDATA directive.

Regsrds,

Steve N.

popcalent

Quote from: caballero on June 10, 2021, 06:33:02 PM
The best way to avoid flickering is using double buffering, but you may also wait for vertical and horizontal retrace. Nevertheless, if your frames animation don't join well you will see flickering no matter what you do to trying to avoid it. For example, when your image calculation is not sincronized with your painting routine (you calculate faster than you paint) or when your routines don't actually join well your succesive frames animation.

Hi, caballero.
Yes, I'm doing double buffering, and I intend to wait for the retrace. But I'm doing one thing at a time. First, I'm figuring out the double buffering, and when that works I'll focus my attention to the retrace.

popcalent

Quote from: FORTRANS on June 10, 2021, 08:33:25 PM
Hi,

   You can define a segment to hold your screen buffer
that is separate from your normal data segment.

Thanks, FORTRANS. I did it, and it works... works as in it does what I wanted it to do. The problem is it's so slow that the game is unplayable!  :sad:

daydreamer

Use biggest register you can use rep movsw, movsd, fp register
Tile engine otherwise?

my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

avcaballero

#7
I wonder what kind of game are you making to waste so many resources. Here's an tiny rotozoomer example that only uses retrace waiting and it seems to go quite smooth, at least in my dosbox

Oh, wait, I have commented the wait retracing calling and it seems to goes fine. Well, you may uncomment this line too and see what happens.

Edited: same program a bit optimized.

popcalent

Quote from: daydreamer on June 10, 2021, 06:42:26 PM
check memory thread
Thanks, I will!  :thumbsup:

Quote from: caballero on June 11, 2021, 07:23:17 AM
I wonder what kind of game are you making to waste so many resources.
I'm more inclined to think the game wastes so many resources because of my inexperience with assembly. Thanks for the code!

daydreamer

Thanks Steve,never used. Fardata before :thumbsup:
Access without Change segment all the time is faster
.fardata
Buffer Db 64000 dup(0)
;1536 bytes space for variables
Sintab Db 256 dup(0)
Xpos DW 16 dup(160)
Ypos dw 16 dup (100)

also prevents bugs that broke my code earlier,after I changed DS from original CS,DS,SS,ES,I forgot CS: override to access my variables and arrays



my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding