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!
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.
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
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.
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.
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:
Use biggest register you can use rep movsw, movsd, fp register
Tile engine otherwise?
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.
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!
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