Dark Bit Factory & Gravity
PROGRAMMING => Other languages => ASM => Topic started by: rain_storm on February 12, 2007
-
This is really slow you can notice the screen being updated, How can I speed this up? I have seen tutorials talking about writing directly to the screen buffer but I have never seen a tutorial that allowed the colour to be changed. Also I have gotten this down to 57 bytes is this too big for the effect that Im going for? This is a little test run in preparation for a plasma effect but I thought that if I couldnt get this runnin fast than plasma would be far too slow...
org 100h
mov al,13h
int 10h
xor cx,cx
main:
mov al,cl
add al,dl
add al,bl
shr al,01h
mov ah,0Ch
int 10h
inc cx
cmp cx,320
jb main
xor cx,cx
inc dx
cmp dx,200
jb main
xor cx,cx
xor dx,dx
inc bx
cmp bx,0FFH
jbe exit
xor bx,bx
exit:
mov ah, 01h
int 16h
jz main
mov ah, 4Ch
int 21h
-
Using int 10h to draw pixels is very, very slow.
Try making a pointer to
a000:0000
this is where the screen memory is located
ie.
mov ax,0a000h
mov ds,ax
Then to draw a pixel
mov si,pixel offset (0-63999)
mov al,colour
mov [si],al
That should get you somewhere!
Jim
-
Thanks Jim thats was miles faster, I'm gonna avoid int 10h from now on
-
heres a much faster version its up to 85 bytes but its much faster so its worth it -
org 100h
mov al,13h
int 10h
mov ax,0a000h
mov ds,ax
xor cx,cx
main:
mov [si],al
inc si
inc al
inc cx
cmp cx, 320
jb main
mov si, dx
mov cx, dx
shl cx, 06h
shl si, 08h
add si, cx
xor cx, cx
inc bx
mov al, bl
inc dx
cmp dx, 200
jbe main
xor dx, dx
sub bx,200
mov ah,01h
int 16h
jz main
mov ah, 4Ch
int 21h
-
You'll get it much smaller when you realise that all the pixels are next to each other in memory.
So there's no need to do x+320*y every pixel, you just need to add 1 to si.
Jim
-
You are right I got it down to 52 bytes thats smaller than the first version I posted man this has really been worthwhile I cant believe the increase in speed. Now I really have to get some sleep. Thanks alot Jim :cheers:
org 100h
mov al,13h
int 10h
mov ax, 0a000h
mov ds, ax
main:
xor si, si
xor dl, dl
mov al, bl
inc bl
plot:
xor cx, cx
mov al, dl
add al, bl
draw:
mov [si],al
inc si
inc al
inc cx
cmp cx, 140h
jb draw
inc dl
cmp dl, 0C8h
jb plot
mov ah,01h
int 16h
jz main
mov ah, 4Ch
int 21h
-
This will go smaller again when you spot that now you're not using x and y in your calculation, you only need one loop. It's not necessary to count up cx and dl separately, just count cx from 0 to 64000 (320*200). :)
Have fun!
Jim
-
How do you do that? Whats you're secret, Jim? Are you an Illuminati or a Freemason or something :kewl: +karma for the insights, Iv picked up more assembler today than a month of reading Art of Assembly
-
http://dbfinteractive.com/index.php?topic=407.msg5603#msg5603 (http://dbfinteractive.com/index.php?topic=407.msg5603#msg5603)
Actually, it's quicker to count cx down from 64000 to 0.
Jim
-
thats because an addition in hardware is a pyrabid of 'xor gates' and 'and gates' that tapers upwards whilst subtraction is mearly a xor (thats why xor ax,ax clears the value in ax). since a 16 bit number requires 16 xors+ands to add them thats 15 more steps than it takes to subtract. I've got a logic simulator, a good one, I work in electrics too and I've built full adders and multipliers out of 7400's logic chips I'm really more a hardware guy that has a thing for graphics than an all out programmer. Heres a thing I put together to subtract and add two values you need an emulator to check the results in the variables 'value' and 'carry' but this is a true software emulation of how basic math is done in hardware it was written for emu8086 so it might not work as is in fasm but everything is done with boolean logic so the math will be universal
mins_oper:
mov ah, a_reg
mov value, ah
mov bh, b_reg
xor ah, bh
mov value, ah
plus_oper:
mov ah, a_reg
mov value, ah
mov bh, b_reg
mov ch, a_reg
mov dh, b_reg
mov carry, dh
xor ah, bh
mov value, ah
and ch, dh
mov carry, ch
shl ch, 0001h
mov carry, ch
plus_loop:
mov ah, value
mov bh, carry
mov ch, value
mov dh, carry
mov value, ah
xor ah, bh
mov value, ah
and ch, dh
mov carry, ch
shl ch, 0001h
mov carry, ch
cmp ch, 0000_0000b
jne plus_loop
ret
a_reg db 0111_1111b
b_reg db 0001_0001b
value db 0000_0000b
carry db 0000_0000b
end
-
:D I was thinking it's because there's an instruction jcxz which doesn't need a cmp cx,64000 to check for the end. It's easier to check for cx=0 than cx=value.
Isn't a-b implemented as a+(-b) in hardware? Last time I worked at that level was with 8bit PALs and PALASM about 17 years ago now!
Jim
-
you mean twos compliment? the way I was shown was with logic chips and xor works to return the difference between two values. its not capable of handling negative values but at least at a hobbyist level its very adaptable ie obstacle avoidence for gettin a robot to turn away from the closest wall this is a cheap way to calculate without a microcontroller since a xor chip only costs about 50p micros range from 8 pounds to 80 pounds
Got it down to 39 bytes Iv never coded anything this small before
org 100h
mov al,13h
int 10h
mov ax, 0A000h
mov ds, ax
draw:
mov [si], dl
inc si
sub dl, 02h
cmp si, 0FFFFh
jb draw
inc bl
mov dl, bl
mov ah, 01h
int 16h
jz draw
mov ax, 0003h
int 10h
mov ah, 4Ch
int 21h
-
I think si=0 at the start of a com file, so you're getting away with not setting that. Also, there are 64000 pixels on the screen, not 65536, but it won't matter if you go over the end, since there is really a 64Kb segment there anyway.
Nice work on shrinking it! I'm pretty sure the keytest can be made smaller.
Were you looking for code to change the palette too?
Jim
-
Ive been playing around with the pallet offset (3C8h) and sending values to the vga card to replace the default values but I am finding it very hard to generate a pallet that the monitor can display. Any body got any pointers just so you can see what I am attempting it looks something like this ...
mov dx,3c8h ; pallet offset
xor al,al ; set al to zero
out dx,al ; send the offset to the vga card
inc dx ; increase dx now we start sending RGB values ranging from 0 - 63 (up to 256 colours)
but its very difficult to create a pallet that actually works most wotnt display and the ones that do are as difficult to work with as mode 13h default pallet which is a joke imho
-
Try working with values from 32-63 to start with. Or try some colour ramps, black->red, black->green, black->blue etc.
What do you mean "most won't display"? Anything with values 0-63 in there should display.
Jim
-
This tutorial (http://fly.srk.fer.hr/GDM/articles/vgamodex/vgamx1.html) states that it is possible to create pallets that will not display and its correct I have made ones that only display black for all colours ??? but also have created ones with mixed results not happy with anything so far
values of 32 and up I will see what I can do with that (I was starting with 0 and up)
whats a ramp? a transition from black to colour?
-
A ramp is just a gradient between two colours. Since you know that red (63,0,0) is a good colour and blue (0,0,63) is a good colour, then any colours in between them in a gradient are also good colours.
I couldn't find anything on that page about invalid palettes (because I skimmed it too quickly) - can you point it out?
Jim
-
I dont really know how to link to parts of a webpage but its about half way down. there are two sections headed with quotes with really big text
first quote is -
"Apparently, it IS
possible to cause damage
to monitors if incorrect
values are used!"
and the second one is right below that -
"A little knowledge
can be dangerous,
so be careful!"
-
OK, at that point he's not talking about the palette, he's talking about the display controller in general.
In theory, it's possible to set the frequency of the display to something ludicrous, and have a monitor blow due to that. In new monitors that will never happen - they all spot out of range signals and ignore them. Last time I heard of this happening was in a Commodore PET from the 1980s.
So, putting in duff palette values isn't going to make a non-displayable screen. Are you actually trying to follow that Mode-X tutorial or are you still in 13h?
Jim
-
Ah I see. I figured out why things went going right with the black screen I forgot to increas the colour value and it was always set to zero :whack: stupid mistake I am still in mode 13h I want to get the pallet working before I even think about different resolutions and paging I got one to work it was exactly how you explained it before keep values below 63 and it worked perfectly but it doesnt look I used all 256 collours thats because the screen is 320 pixels long so I had to use an increment of 4 for colours or it wouldnt look right
org 100h
mov al, 13h ; enter graphics mode
int 10h
mov ax, 0A000h ; get screen buffer offset
mov ds, ax ; and put it in ds
mov dx,03C8h ; get colour pallet offset
xor al,al ; clear al
out dx,al ; send zero to vga card
inc dx ; now dx points to pallet
reds:
mov al, bl ; get brightness
out dx, al ; red
xor al, al ; only red
out dx, al ; green
out dx, al ; blue
mov al, bl ; get brightness
out dx, al ; red
xor al, al ; only red
out dx, al ; green
out dx, al ; blue
mov al, bl ; get brightness
out dx, al ; red
xor al, al ; only red
out dx, al ; green
out dx, al ; blue
mov al, bl ; get brightness
out dx, al ; red
xor al, al ; only red
out dx, al ; green
out dx, al ; blue
inc bl ; make it a bit brighter
cmp bl, 64 ; check for max brightness
jb reds ; loop if not max brightness
draw:
mov [si], dl ; put colour on screen
add dx, 04h ; next colour
inc si ; next pixel
cmp si, 0FFFFh ; compare against screen buffer limit
jb draw ; loop
add dx, 01h ; scroll one colour for next frame
mov ah, 01h ; check for key press
int 16h
jz draw ; loop
mov ax, 0003h ; enter text mode
int 10h
mov ah, 4Ch ; exit to o/s
int 21h
-
That's right, under VGA/MCGA you only have 6bit colour guns, so 262144 colours instead of the present day 16.7million. Means there are only 64 shades of red.
Jim
-
Wow! What's ASM!?
Seem's like an impossible language eeeeee ???
Don't think I'll be starting this one! lol
-
Assembler - mostly the code posted here is Intel x86 assembler, which is written in mnemonics (assembler instructions) and assembled directly to machine code. There's no high level language stuff, just the basic instructions for moving data around, processing it, and access directly to the CPU registers. It's a lot of fun, and every CPU from every manufacturer is different!
Jim
-
Clanky, if you want to see what can be done in asm, go over to intro-inferno and search for productions from a group called wamma
There's a guy called Yobi who codes some of the most amazing low byte stuff you've ever seen! Honestly, you would not believe the effects you can do in 256 bytes!!
Typically asm instruction sets are not so bad to learn, for a start, there are far fewer commands to worry about and on the pc, you just use them to do the stuff that jim says.. You can also invoke interrupts to open screens etc..
mov al,13h <-- That just puts the desired gfx mode into the register al
int 10h <-- Initialise the video mode
There are several registers, you can think of them like variables, and you can store memory addresses in them or data and perform operations on that data exactly the same as you would in basic, only the command set is different.
Assembly language was developed a long time ago to help programmers write programs for the first computers.. Originally all programs were written in binary on punch cards, assembly language (because of it's limited command list and simple commands) is very easily translatable into machine code that the computer understands. It's cool to use, very powerful and produces extremely efficient programs!
-
Out of curiosity, why do you guys still use 16-bit real mode (with BIOS interrupts etc) for your assembly language stuff? ???
Is it just because it's easier, or because of like the 'retro' appeal?
-
Because mode 13 is the best mode for 256 colour tiny intros. You can make intros that are even smaller than 256 bytes, sometimes there are even 64 byte or 32 byte intros released.
-
Also 16-bit x86 (DOS) assembler is the most documented form of assembler so its a good variant to cut your teeth on MASM32 and other 32 bit assemblers expect that the programmer is not new to the language and so the basics are not covered in a way that suits learnin the stuff with no experience. And you can thank Ralf Brown for making 16-bit DOS so accessable to the masses
-
Thanks. I see, so it's all about optimizing for size over speed. I'd never actually heard of Ralf Brown until I just googled :-\
But is there an actual requirement for such micro-sized executables, or is it just about the hacker kudos to see who can shave off maximum bytes?
I mean, I could understand it if the target platform had only a couple of k of RAM installed, but for a modern PC with a couple of G's and a 32/64-bit OS? ???
Please forgive my ignorance about the demo/intro scene - and don't get me wrong, I'm not trying to knock it or anything. I really admire what you guys do, just tryin' to understand the motivation behind it.
-
Here's some research for you :)
WAMMA (http://www.intro-inferno.com/search.php)
These are all 256b dos intros in pure assembler using 13h. (some of them you may have to quit using alt and tab as the coder tries to squeeze as much into 256b as possible), this is a demo making forum, not a games place so it's understandable that games coders can have some trouble understanding the motivation.. But if you check out those intros by Wamma you will either get it or not.
For me, and most of the people here they are art.
-
Whoops.
Just type wamma into the search box on the page that comes up :)
-
Thanks for the link, and also for taking the time to enlighten this ignorant peasant - yes, the penny has dropped and I can certainly relate to the 'minimalist art' thing. In one sense this is programming in it's purest form.
I have to confess that I previously visited here solely out of interest in the general applicability of the programming techniques discussed, but you may have made a convert out of me ;)
Time to dust off my old DOS-era assembly skills and have a crack at some of this good stuff myself! :)
-
Thats a mighty fine collection of tiny code there here is also a good site they deal exclusively in 256b and some 32b/64b
http://www.256b.com/home.php