Friday, March 03, 2006

ASM: Sprawling Palette across the Screen

I was reading today’s Penny Arcade, and Tycho makes an interesting statement about “loving the … savage and untamed qualities” and “being drawn to the stark brutalities” of the PC. I think that about sums up my fascination with Assembly as of late. Maybe I am a glutton for punishment. I couldn’t imagine trying to write an entire operating system in this, and I probably would flock to the nearest high level language available, but it is fun to digress to the primitive, low level lands of the microprocessor architecture every now and then. But it would be nice to work with a “polished” interface such as OS X and escape PC hell for a while, but that still a ways away for me. Once I find my old Turbo C disks, I intend on salvaging a few of the old PC boxes I have in my closet to work on some basic DOS based projects, going almost completely in the opposite direction. I am thinking of trying to simulate a basic parallel port communications session from the ground up with a program written in mixed C/Inline ASM. Not real exciting by today’s standards, but still, I haven’t worked on projects like that since I was studying electronics at the local community college. Well, continuing with my adventures in Asm land, I wrote this little program that will simply sprawl out the existing palette across the screen.

0BD0:0100 B81300        MOV     AX,0013
0BD0:0103 CD10          INT     10
0BD0:0105 B800A0        MOV     AX,A000
0BD0:0108 8EC0          MOV     ES,AX
0BD0:010A 31FF          XOR     DI,DI
0BD0:010C B9C800        MOV     CX,00C8
0BD0:010F 51            PUSH    CX
0BD0:0110 31C0          XOR     AX,AX
0BD0:0112 B94001        MOV     CX,0140
0BD0:0115 AA            STOSB
0BD0:0116 FEC0          INC     AL
0BD0:0118 E2FB          LOOP    0115
0BD0:011A 59            POP     CX
0BD0:011B E2F2          LOOP    010F
0BD0:011D B410          MOV     AH,10
0BD0:011F CD16          INT     16
0BD0:0121 B80300        MOV     AX,0003
0BD0:0124 CD10          INT     10
0BD0:0126 B8004C        MOV     AX,4C00
0BD0:0129 CD21          INT     21

Lets break it apart.

MOV     AX,0013
INT     10

This will change the video resolution into 320x240x256.

MOV     AX,A000
MOV     ES,AX
XOR     DI,DI

Setting up ES:DI for quick access to video memory.

0BD0:010C B9C800        MOV     CX,00C8
0BD0:010F 51            PUSH    CX

This is setting up my “outer loop”. What I am going to do it loop through the each color in the pallete 200 times. C8 is the hex value for 200. I push it onto the stack so that I do not mess up the count with anything in the inner loop.

0BD0:0110 31C0          XOR     AX,AX
0BD0:0112 B94001        MOV     CX,0140
Here I am setting up my inner loop. First, I zero out AX, so I can start with the first position in the pallete. Then I set the counter in the inner loop to 140, which is hex for 320. I will rollover since the pallete only contains 256 colors, but that’s OK for what I am trying to do here.

0BD0:0115 AA            STOSB
0BD0:0116 FEC0          INC     AL
0BD0:0118 E2FB          LOOP    0115

Now, I take the value in AX, which is indicating which pallete array element to use, and store that into ES:DI, and DI is automatically incremented by 1 with the STOSB instruction. I increase AL so I can use the next value in the pallete on the next pass, and loop back to the STOSB instruction all 320 times as stored in register CX.

0BD0:011A 59            POP     CX
0BD0:011B E2F2          LOOP    010F

Now, since I am done with the inner loop, I get my outer loop counter value back from the stack, and loop back to the outer loops PUSH CX statement. The loop statement will decrement CX by 1 automatically.

0BD0:011D B410          MOV     AH,10
0BD0:011F CD16          INT     16

I will wait for a key press from the user so they can see the sprawled pallete.

0BD0:0121 B80300        MOV     AX,0003
0BD0:0124 CD10          INT     10
0BD0:0126 B8004C        MOV     AX,4C00
0BD0:0129 CD21          INT     21


Set the video mode back to mode 3, and return to DOS. Pretty cool little program for only 43 bytes. Next I am going to try to do a pallete rotation on the colors, but I will leave that for a future article.

No comments: