Click to See Complete Forum and Search --> : Assembler


prince_kenshi
01-18-2001, 10:21 PM
Do we have any good assembler programmers here? I'm having a little problem with this program I've been working on for quite a while now. This particular part of the program is supposed to load all of the palette registers into a 768 byte array, change one of them according to user response, and put it back in the registers. Whenever I run it on the debugger, it seems to load the registers just fine and edit them correctly and when it's saving them to the registers, it's the correct data. But for some reason it's showing the same colors when I display the palette. I'm running mode 13h when displaying the palette, a regular text mode for everything else. Here are my procs for loading and saving the palette registers:

load_pal proc
xor al,al
mov dx,03C7h
out dx,al
mov di,offset temp_pal
mov dx,03C9h
mov cx,0300h
rep ins byte ptr [si],dx
ret
endp

save_pal proc
xor al,al
mov dx,03C8h
out dx,al
mov si,offset temp_pal
mov dx,03C9h
mov cx,0300h
rep outs dx,byte ptr [si]
ret
endp

I hope someone can tell me what's wrong with this. I hope I've provided enough information for you.

------------------
Prince Kenshi
Son of Bahamut

miller
01-19-2001, 03:00 AM
I'm assuming this is on a DOS/Win9x box, because you can't do 16bit programming on Linux.

The code looks fine, as long as that's where the palette info is located, which you said you already confirmed. I have only ever done 32bit assembly on Linux, so I don't know how the palette stuff is supposed to work.

If you give a quick explanation of how the pallette is supposed to work, then maybe I can help.

prince_kenshi
01-19-2001, 05:05 AM
This is a Dos program since I don't know protected mode programming very well yet. (By the way, if you know some good tutorials for protected mode programming, either Windows or Linux, I'd appreciate their addresses.) But here's how the palettes are supposed to work. Port 3C7 and 3C8 are for declaring which register you want to mess with first. In load_pal, I outputted 0 to 3C7 because I wanted to read from register 0 first. Same thing with save_pal and 3C8. After you send the value to one of these registers, it sets 3C9 for read or write depending on which port it was. The first load or save to 3C9 is color red, then green, and then blue. Then it automatically increments to the next palette register. I watch in debugger what values are being outputted to 3C9 and they all seem correct. But when I go back and view the palette, none of the colors have changed. I've been working on and off of this program for months now and I just can't figure out what's wrong with it. I hope somebody can figure it out because I'm about to die trying.

------------------
Prince Kenshi
Son of Bahamut

miller
01-19-2001, 12:31 PM
I don't know. Going by your explanation, this "should" work. My only thought is that running it in the debugger is resetting the palette somehow, but that's just a shot in the dark. I found this (http://www.digibel.org/~staf/topic.php?lang=eng&top=vga) page, which shows how to change the palette using int 10h, but changing the video memory directly would probably be faster.

------------------------------

As for the protected mode programming, it's easier than real mode because you don't have to mess with segment registers. Your program can see the whole 4G(if you have that much) of memory at once. You can check out linuxassembly.org (http://www.linuxassembly.org) for some good stuff to get you started programming assembly in linux. The thing is, it isn't as much fun as with DOS, because with DOS you got to access your hardware directly, whereas with linux the hardware is protected, so you have to go through the system calls. It's still interesting though.

But, the best documentation I've seen are the Intel i386 manuals. HERE. (http://developer.intel.com) I don't kow exact URLs, but you should be able to find them in there somewhere. Let me know if you can't find them. Anyway, there are three of them. They are long and boring, but there's some good stuff there if you want to skim. Volume 1 gives an overview of the whole architecture, with some pretty technical stuff. Volume two is just a HUGE list of the instruction set and how each one works. There is enough information in that one to write your own assembler. Volume three is a systems programming guide. It goes down and dirty into the architecture. From how the machine boots, to how to manage memory. There are some great pieces of code in there. It also includes stuff about how protected mode programming works. How to boot into protected mode, etc. When I get some free time I'm going to mess with this a lot more.

prince_kenshi
01-19-2001, 04:05 PM
Thanks for the links. I had read some document about protected mode programming but it didn't really talk about any operating system, it was more about the processor. I'm going to take a look at that linuxassembly site sometime. I mainly need some exampled of the system calls and such. I don't supposed there's an equivalent to Ralf Brown's interrupt list for Linux. As for the Intel manuals, I already have the first two saved on my hard drive. The second one can be a life saver at times. I haven't checked out the third though, and I don't know why. That might be another thing for me to read.

As for my program, I don't know what I'm going to do about it. I've started making another program, a hex editor, at the suggestion of one of my friends. It's a good way to practice the skill. But maybe that site will help me start on a Unix program. Hopefully it's about Unix in general because I have BSD rather than Linux. They probably have the same system calls anyway though. But again, thanks for the help.

------------------
Prince Kenshi
Son of Bahamut

miller
01-19-2001, 05:35 PM
In Linux, all system calls are through int 81h(?not sure..brain fart) BSD system calls use a different interrupt vector, I think. But, on Linux...not sure about BSD, the system call numbers may be changed, so you are supposed to go through the C library to make the calls. So, you just stick your args on the stack and do a call read, for example. No interrupts neccesary.

As far as the linuxassembly site, you should be fine if you do your syscalls through the C library, but if you use the interrupts, then I'll bet the way syscalls are done in BSD are different than Linux. Try a google search (http://www.google.com/search?sourceid=navclient&q=freebsd+assembly) for freebsd assembly.