; --------------------------------------------------- ; T e x t u r e 16 b ; --------------------------------------------------- ; 16 byte MSDOS procedural text mode graphic effect ; by HellMood / DESiRE ; Release : January 2015 ; Greetings to every sizecoder out there! ; Let's make 16byters a thing again ♥ org 0x100 bits 16 ; assembler information. i use NASM ; "nasm texture.asm -fbin -o texture.com" push ax ; equals "0x50" which is the number of columns ; in the standard text mode (80x25), this way ; [si] = [0x100] = 0x50, which allows an optimized ; row/column generation later. Also, this is a one ; byte instruction, which does no harm to the rest ; of the code flow, and needs no further jumping ; into the middle of instructions ;) push 0xB670 pop es ; Let ES point to the start of the text memory. ; There are several ways to save a byte here, with ; the usage of "LES ??,[(bx+)si(+n)]" like "m8trix", ; reusing code as segment data, but i am already ; at 16bytes, and the segment alignment is crucial ; to the visual effect : First, you will want a ; segment in the form "0xB800 - n * 10", to have ; horizontal alignment (incrementing segments shift ; 16 bytes, 160 = 80 * 2 = 80 colored chars /w 2byte) ; Second, you will want to make that 0xB800 - n * 80 ; to have good vertical alignment, like, having the ; pattern start at the top left corner. That is ; of course strongly bound to the pattern itself. ; Third, you can now shift through several segments ; by changing the segment value yourself. This offers ; a little design space for tuning the effect. Personally ; i don't like the original 0xB800, but maybe it's ; just me :D. Fourth, a neat little thing you might ; have noticed with this value: The first three bytes ; of the code now spell "Php" ^^ Values you might try ; here : 0xB800, 0xB7B0, 0xB760, 0xB710, 0xB6C0 etc. L: stosw ; Finally, write a colored char to the screen and ; increment the memory pointer DI. It is important ; to increment DI before doing using DIV, so that ; division overflow does not occur right at the start. ; DI is "0xFFFE" at start on almost every DOS environment ; and plain "0x0000" after the first "stosw". mov ax,di idiv byte [si] ; Compose row and column number from the memory pointer ; so they end up in AL and AH. This saves one byte ; over moving "0x50" to any register and then DIV. ; ATTENTION : this can, and will(!) overflow, and it is ; totally intended. When DI reaches 0x5000, division by ; "0x50" would result in 0x100, which doesn't fit into ; on byte, therefore, division overflow is triggered, and ; exits the program. But at this point, 255 rows have been ; written already, which is enough even for a backshifted ; segment start. By changing the segment (described above) ; you can chose which 25 of the 255 lines you want to see. ; If you use IDIV instead of DIV, it is reduced to 128 ; possible lines. With the special segment i chose, it ; also suppresses the unwanted 25th row, resulting in a ; well aligned texture (10*8 x 3*8 chars) ; NOTE : DOSBOX seems to trigger the overflow, but does ; not exit the program. ; NOTE : On my old WinXP Laptop, the overflow occurs right ; at the start. However, if you start "debug", then quit ; it the run "texture", it shows the desired effect. xor ah,al mov al,0xB1 ; Now, that column and row are available in AL and AH, just ; XOR them to get a color combination of foreground ; background from it. Using "0xB1" as the char beeing ; written, which is a XOR pattern itself, creates the ; effect of up to 256 colors combinations via dithering. ; On systems using the high bit of the color byte to ; indicate blinking, it is 128 colors combinations. Many ; combinations map to same/similar colors, so the true ; and perceived number of colors is lower of course ;) ; The segment i chose above, is located in an area which ; should be free of blinking on any system. The 25th row ; which would blink on some systems, is supressed by using ; IDIV instead of DIV. If you have fun with blinking effects, ; switch back to DIV and lower the segment value even more ;) jmp short L ; rinse and repeat =)