Assembler in DOS.
category: code [glöplog]
okay, i just wrapped up my turbo assembler and started to code after all these years..
and then generating .com files with the tiny model, org100h, but then i tried to write some procedures with the 'proc' method and then calling the procedure with 'call' in the main-code, i got this error message: "Fatal: cannot generate com file. data below initial CS:IP defined". maybe there are some directives i am missing? i dont know. i basically know what segments are, but i dont know why it wont link.
and then generating .com files with the tiny model, org100h, but then i tried to write some procedures with the 'proc' method and then calling the procedure with 'call' in the main-code, i got this error message: "Fatal: cannot generate com file. data below initial CS:IP defined". maybe there are some directives i am missing? i dont know. i basically know what segments are, but i dont know why it wont link.
In .COM files, the initial entry point *must* be at 100h (i.e. the first thing in your program must be code).
If you want to define data at the top, to something like
If you want to define data at the top, to something like
Code:
org 100h
start:
jmp real_start
var1 dw 0
var2 dw 0
; ...
real_start:
; program starts here
thanks ryg. it worked. unbelieveable! :b
"unbelieveable"
...
lol. :)
...
lol. :)
hah.
now im stuck again.
i define an array as this: screen db 64000 dup(0); and when i try mov ax,screen it wont work either mov ax,screen[0]. to get to change the byte(s) of that array?
now im stuck again.
i define an array as this: screen db 64000 dup(0); and when i try mov ax,screen it wont work either mov ax,screen[0]. to get to change the byte(s) of that array?
mov di,screen
stosb
stosb
Gargaj: i get error under compilation for mov di,screen => "operand types do not match"
oh, i forgot to change db to dw.
lea dx,screen
mov di, dx
if you use dw instead of db, you are actually allocating 64000 words (not bytes)
mov di, dx
if you use dw instead of db, you are actually allocating 64000 words (not bytes)
still stuck.
i'll just post the important code here anyway...
basically, i just want the flip procedure to work..
i'll just post the important code here anyway...
Code:
.model tiny
.code
org 100h
main:
jmp real_start
mode dw 0013h ;default video mode
video dw 0A000h
screen dw 32000 dup(0) ;our backbuffer
flip proc
push ds
;push ax
;push cx
mov ax,video
mov es,ax
mov di, screen
stosb
mov ds,ax
xor si,si
xor di,di
mov cx,32000
rep movsw
;pop cx
;pop ax
pop ds
endp
real_start:
mov mode, 0011h
call SetMode
; call clearScreen
; call readTicks
; call charOut
; call waitKeyPress
; call Exit
;*********************************
;get a seed from the runtime clock
;*********************************
call readTicks
mov seed, dl
;**********
;start loop
;**********
mov cx,65535;1000; 2000;65535;80*40 ;init loop counter (80*25)(40*25)
again:
call rndfunc ;changes to bl
mov seed, bl
push ax
;mov ax,screen ;0a000h
;mov es,ax ;es = address of video
;add ax,cx
;mov al, bl ;color
;stosb
; mov dl,seed ;puts ascii char in dl
; call charout ;30h=0, 31h=1
pop ax
;mov ax,0
mov ah,01h
int 16h
jz again
mov ah,00h
int 16h
cmp al, 1bh ;check escape character
je quit
call flip
jmp again ;increments cx (counter)
quit:
; call waitKeyPress
call Exit
end main
basically, i just want the flip procedure to work..
This is off my mind but...
Code:
flip proc
push si
push di
push ds
les di,[video]
lds si,[screen]
mov cx,32000
rep movsw
pop ds
pop di
pop si
endp
actually, that'd fail...
More like:
If my mind serves well...
More like:
Code:
flip proc
push si
push di
push ds
mov ax,video
mov es,ax
xor di, di
lds si,[screen]
mov cx,32000
rep movsw
pop ds
pop di
pop si
endp
If my mind serves well...
You do know that mov is mov dest, src, right? :)
You could just put the screen buffer in the next segment if you create a COM file.
So the flip would become:
Code:
mov ax,cs
add ah,10h
mov es,ax
So the flip would become:
Code:
push ds
push es
mov ax,cs
add ah,10h
mov ds,ax
push 0a000h
pop es
xor si,si
xor di,di
mov cx,16000
rep movsd
pop es
pop ds
AAAArhrAaaaaRHRHRRRGRGRHGGGHGHHHHHHHH!!!!
first things first:
don't use dw for constants! That's what EQU (or just "=") is there for.
second, don't put 64000 bytes of *initialized* data into a .COM file! because congratulations, minus that and the 256 byte PSP you now have exactly 1280 bytes left for all your remaining code+initialized data+stack. allocate the 64k separately (either from DOS or manage your own memory) and use that. anyway, moving on.
i don't know what the "stosb" in flip is supposed to accomplish, but it's bullshit. di should be zero - video memory starts at 0a000h:0.
changing screen to a "dw 32000 dup (0)" from a "db 64000 dup (0)" is BS too. that's only necessary because of another bug in that code: "mov di, screen" won't work (even ignoring the fact that you should be loading it to si not di). this is TASM not NASM; "mov di, screen" is exactly equivalent to "mov di, [screen]" (which is why it wouldn't let you do it for the "db" version). but that's not what you want. what you want is either "mov si, offset screen" or "lea si, screen" or "lea si, [screen]" (all three accomplish the same thing).
jcl: "lds si, [blah]" will interpret blah as a *far pointer* (i.e. 16-bit offset followed by 16-bit segment) and load that into ds:si. that's how the "les bp, [bx]" trick i used in some of my <=64b-intros works (bx is 0 on startup, and if you look at the PSP layout, you'll find that this will result in bp=020cdh, es=size of available memory in paragraphs. normally this is 9fffh which is just 16b off 0a000h.
mics code will work though and mentions the right approach (allocating the screen backbuffer in a different segment). listen to the man, he knows what he's doing!
first things first:
Code:
mode dw 0013h ;default video mode
video dw 0A000h
screen dw 32000 dup(0) ;our backbuffer
don't use dw for constants! That's what EQU (or just "=") is there for.
second, don't put 64000 bytes of *initialized* data into a .COM file! because congratulations, minus that and the 256 byte PSP you now have exactly 1280 bytes left for all your remaining code+initialized data+stack. allocate the 64k separately (either from DOS or manage your own memory) and use that. anyway, moving on.
i don't know what the "stosb" in flip is supposed to accomplish, but it's bullshit. di should be zero - video memory starts at 0a000h:0.
changing screen to a "dw 32000 dup (0)" from a "db 64000 dup (0)" is BS too. that's only necessary because of another bug in that code: "mov di, screen" won't work (even ignoring the fact that you should be loading it to si not di). this is TASM not NASM; "mov di, screen" is exactly equivalent to "mov di, [screen]" (which is why it wouldn't let you do it for the "db" version). but that's not what you want. what you want is either "mov si, offset screen" or "lea si, screen" or "lea si, [screen]" (all three accomplish the same thing).
jcl: "lds si, [blah]" will interpret blah as a *far pointer* (i.e. 16-bit offset followed by 16-bit segment) and load that into ds:si. that's how the "les bp, [bx]" trick i used in some of my <=64b-intros works (bx is 0 on startup, and if you look at the PSP layout, you'll find that this will result in bp=020cdh, es=size of available memory in paragraphs. normally this is 9fffh which is just 16b off 0a000h.
mics code will work though and mentions the right approach (allocating the screen backbuffer in a different segment). listen to the man, he knows what he's doing!
ok thanks for all the great help so far. i used mic's approach at the end.
so it works good. i'll be post the code so if you can see other weird things that are not supposed to be there. let me know.
so it works good. i'll be post the code so if you can see other weird things that are not supposed to be there. let me know.
Code:
waitKeyPress proc
mov ah,0
int 16h
ret
endp
flip proc
push ds ;push ds on stack
push es
mov ax,0a000h
mov es,ax ;move dest into ax
mov ax,0a000h;
add ah,10h
mov ds,ax ;move src into ds
xor si,si ;src clear
xor di,di ;dst clear
mov cx,19200
rep movsw ;copy src to dst (ds:si -> es:di)
pop es
pop ds
ret
endp
;*********************************
;get a seed from the runtime clock
;*********************************
call readTicks
mov seed, dl
;**********
;start loop
;**********
again:
mov ax,0a000h ;move video mem into ax
add ah,10h ;jump to backbuffer
mov es,ax ;backbuffer[ES:DI] = bl
xor di,di
fillrnd:
call rndfunc ;changes to bl
mov seed, bl ;iterated rand: output->input
mov al,bl ;mov randcol into al
stosb ;store al at ES:DI
cmp di,38400
jne fillrnd
call flip
;******************
;check for keypress
;******************
mov ah,01h
int 16h
jz again
mov ah,00h
int 16h
cmp al, 1bh ;check escape character
je quit
jmp again ;increments cx (counter)
quit:
call Exit
end main
Quote:
jcl: "lds si, [blah]" will interpret blah as a *far pointer* (i.e. 16-bit offset followed by 16-bit segment) and load that into ds:si.
That's totally right... but hey, it's been like 10/12 years since I last used any x86 assembler! :D
I have coded the cartoon fish during the years of 1996 and finish it in 2004, but it runs only on msdos with vesa, and I do not want anymore to port it on windows. the sources are available on my web site : http://laurent.horus.free.fr/
what's the code to open a windows window in assembler and draw into ?
where I can find tasm.exe and tlink.exe ?
tasm. don't go there. there be dragons.
also it is not free. use MASM32 or NASM.
This uses MASM32 that btw has lots of examples for this kind of shit.
also it is not free. use MASM32 or NASM.
This uses MASM32 that btw has lots of examples for this kind of shit.
Is there a Service Pack ASM ... SPASM ;)
i have tasm 3.2
Gasm
What about FASM? Dunno if it does .com but sure does 64 if you wanna go for that.
@Ferris you forgot the "or" before "gasm". ;)
@Ferris you forgot the "or" before "gasm". ;)