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.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment