Tested on WinXP, DosBox, Oracle Virtual Box (MSDos 6.22)

On WinXP, start a console first, since this is self exiting
When an immediate error occurs (like on my strange old
notebook), try "debug" leave debug with "q", and rerun
"texture".

The "DIV" version looks crazy on my notebook in fullscreen!
See "winxp full.jpg" =)

On a real MSDos, everything should work as intended.

On DosBox, the exit tech seems not to work (see comments
in the asm file), it's fine otherwise.

Watch a video of me, executing texture on MSDos 6.22
https://www.youtube.com/watch?v=t4IMZFtaakk

If there's anything you want to know, feel free to 
contact me : storrryteller@hotmail.com

Reading the comments is highly recommended!


; ---------------------------------------------------
;                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 =)
