Sunday, October 26, 2008

ASM: Revised Chekerboard program, now with flashing squares

I revised by checkerboard ASM program to have the white colored squares fade in and out. I wanted to do this for a few reasons. It shows a palette shift, which I have demonstrated previously, but it also shows how to do a time delay in ASM. The time delay turned out to be a little trickier than I thought. I tried using the DOS Get Time interrupt, but if you don’t test all the registers it returns and try to get away with just the DX register, you end up with unacceptably long delays when minutes change or hours change. I ended up using the system BIOS call to get the system clock ticks. The same problem will arise after midnight, but that can easily be overcome by testing the appropriate flag which gets set when midnight occurs. Again, I have included comments, and I also included the addresses that DOS Debug displays. If I do anymore ASM programs, I thing I will use an assembler going forward. Its easier than having to specify jumps by address, which change when I add something new to a program.

--initialize video mode to 320x200x256
13F2:0100 B81300 MOV AX,0013
13F2:0103 CD10 INT 10
point data segment and extra segment to video memory
13F2:0105 B800A0 MOV AX,A000
13F2:0108 8ED8 MOV DS,AX
13F2:010A 8EC0 MOV ES,AX
13F2:010C 31FF XOR DI,DI
--initialize registers with values of palette to use
--use word instead of bytes for the stosw instruction
13F2:010E B80F0F MOV AX,0F0F
13F2:0111 BB0000 MOV BX,0000
--initialize to the number of veritical squares
13F2:0114 B90800 MOV CX,0008
13F2:0117 51 PUSH CX
--start execution, logic is explained in previous post
13F2:0118 B9C800 MOV CX,00C8
13F2:011B 51 PUSH CX
13F2:011C B91400 MOV CX,0014
13F2:011F F3 REPZ
13F2:0120 AB STOSW
13F2:0121 50 PUSH AX
13F2:0122 89D8 MOV AX,BX
13F2:0124 5B POP BX
13F2:0125 59 POP CX
13F2:0126 E2F3 LOOP 011B
13F2:0128 50 PUSH AX
13F2:0129 89D8 MOV AX,BX
13F2:012B 5B POP BX
13F2:012C 59 POP CX
13F2:012D E2E8 LOOP 0117
--get ready to ramp down the white palette entry
--do this 3fh times
13F2:012F B93F00 MOV CX,003F
13F2:0132 B3FF MOV BL,FF
13F2:0134 FECB DEC BL
--initialize with the port to tell video card we are changing
--a pallete entry. This should be changed at some point to
--actually retrieve the pallete entry to change
13F2:0136 BAC803 MOV DX,03C8
13F2:0139 B00F MOV AL,0F
13F2:013B EE OUT DX,AL
--increment dx by 1, to point to the port to actually
--set a pallette entry
13F2:013C 42 INC DX
13F2:013D 88D8 MOV AL,BL
--output the new pallette entries
13F2:013F EE OUT DX,AL
13F2:0140 EE OUT DX,AL
13F2:0141 EE OUT DX,AL
--we need a slight pause so this is effect is visible, otherwise it
--just looks like ugly staticy squares, so save our registers
13F2:0142 50 PUSH AX
13F2:0143 53 PUSH BX
13F2:0144 51 PUSH CX
13F2:0145 52 PUSH DX
--we want to test this by a single clock tick, 1/18 of a second, which
--we will use DI to compare against
13F2:0146 BF0100 MOV DI,0001
--call int 1ah, function 00, which will get a clock tick, to initialize
--out testing value and set in BX
13F2:0149 B400 MOV AH,00
13F2:014B CD1A INT 1A
13F2:014D 89D3 MOV BX,DX
--cal again to get current value
13F2:014F CD1A INT 1A
--subtract stored value from current value. If it is greater, than we have
--surpassed our delay time, and we need to keep moving, otherwise, test again
13F2:0151 29DA SUB DX,BX
13F2:0153 39D7 CMP DI,DX
13F2:0155 77F8 JA 014F
--restore registers
13F2:0157 5A POP DX
13F2:0158 59 POP CX
13F2:0159 5B POP BX
13F2:015A 58 POP AX
--loop back to palette shift beginning
13F2:015B E2D7 LOOP 0134
--do the same thing as the palette shift above, but in reverse order, ramping
--the values up
13F2:015D B93F00 MOV CX,003F
13F2:0160 FEC3 INC BL
13F2:0162 BAC803 MOV DX,03C8
13F2:0165 B00F MOV AL,0F
13F2:0167 EE OUT DX,AL
13F2:0168 42 INC DX
13F2:0169 88D8 MOV AL,BL
13F2:016B EE OUT DX,AL
13F2:016C EE OUT DX,AL
13F2:016D EE OUT DX,AL
13F2:016E 50 PUSH AX
13F2:016F 53 PUSH BX
13F2:0170 51 PUSH CX
13F2:0171 52 PUSH DX
13F2:0172 BF0100 MOV DI,0001
13F2:0175 B400 MOV AH,00
13F2:0177 CD1A INT 1A
13F2:0179 89D3 MOV BX,DX
13F2:017B CD1A INT 1A
13F2:017D 29DA SUB DX,BX
13F2:017F 39D7 CMP DI,DX
13F2:0181 77F8 JA 017B
13F2:0183 5A POP DX
13F2:0184 59 POP CX
13F2:0185 5B POP BX
13F2:0186 58 POP AX
13F2:0187 E2D7 LOOP 0160
--check if there is a key press. If not, keep going, otherwise, stop
--running the program.
13F2:0189 B406 MOV AH,06
13F2:018B B2FF MOV DL,FF
13F2:018D CD21 INT 21
13F2:018F 749E JZ 012F
--reset video mode
13F2:0191 B80300 MOV AX,0003
13F2:0194 CD10 INT 10
--return to DOS
13F2:0196 B8004C MOV AX,4C00
13F2:0199 CD21 INT 21

No comments: