How a Memories demo fits in 256 bytes


Introduction


Hello! My name is HellMood, and this article is about a small MS DOS program called Memories. This program has a size of 256 bytes, it won in the category of «PC 256 byte» competition demoscene «Revision» in 2020, and also received the Audience Award. You can watch the video of the program’s output here , and the video with the reaction of the online audience and moderators here . Download the release and leave comments here. This article will present an in-depth analysis of the program, talk about historical references and development stages. The article is posted in the sizecoding wiki. It will not only allow you to understand the internal structure of Memories, but will also help you create something similar. Explore it! If you are new to sizecoding (writing programs within the desired size) or in x86 assembler, it is recommended that you start with the basics of this wiki . The principles are easy to understand, but it’s not so easy to figure out implementation details.

Short review


In this article we will talk about the version sent to the contest for DosBox (256 bytes). The archive also contains versions for FreeDos and Windows XP DOS, which at the time of writing the post did not work on all computers. These alternative versions were included in the archive as proof of concept to show that the program not only works in the emulator. In the “PC 256 bytes” category of the “Revision” competition of 2020, it was possible to indicate “FreeDos” or “DosBox” as the platform (the latter in a specific configuration). As alternative versions prove, in fact, you can modify the version for DosBox so that it works in FreeDos, MS DOS, WinXP and Win98, but the article will not be about that.

Be that as it may, reliable versions for all platforms and computers are under development. As for possible further optimizations, I will only talk about the version sent to the contest, although I have already found several places where the code can be optimized. Since this is a demonstration of the history of small effects, almost none of the code is perfect, and it can be further reduced. In order not to get confused in different versions, I will talk only about the competition.

History of small effects



Dimension categories at http://www.pouet.net

We, sizcoders, reason in size categories. For MS DOS, these categories are 256b, 128b, 64b, and 32b. These are the standards of one of the largest archives of the demo scene www.pouet.net. There is no 16b category, however many small effects can be implemented in 16 bytes. Almost all the effects from “Memories” were written and optimized by me earlier, and basically their implementation was an attempt to reduce the existing size of the effect, or to create something similar, but smaller. By size reduction here is meant its reduction to one of the following smaller categories 2 ^ N. For example, if the effect was implemented in 33-64 bytes, then it is reduced to 32 bytes or less. Almost every time I managed to “lower” the effect to a lower category, I sent the resulting tiny program to an event dedicated to the demoscene, in which remote participants were allowed to participate in category 256b, and / or published the result on www.pouet.net. In this section, I will introduce you to the effects, as well as talk about their origin and authors.

Array of chessboards



kasparov, 16 bytes. The

source of this effect was my own “Kasparov 16b” of 2018 ( link ). It seems (quote from the release notes), I "just made this board, fit it into 17 bytes, but it was not very beautiful until I came up with a trick ...". Previously, there was already a similar effect implemented in 32 bytes: 2003 ew from the developer headcrash. ( link ) In this case, I tried to implement “real” chessboards with an 8x8 square and recognizable black and white squares, as well as the correct orientation of individual chessboards, that is, the lower right corner (h1) should have been white. In order for this effect to work with the global framework, in “Memories” it had to be re-implemented using another technique: recording on the screen; In addition, the direction of scrolling has been changed so that it differs from the “scrolling tilted plane” effect.

Zooming circles


Scalable circles (zooming circles) were supposed to participate in demopati as an intro of 32 bytes, but I never did. This effect does not have a 64 byte predecessor, because in the 64b category much more complex effects are possible. Zooming circles were the result of my desperate attempt to get into category 32b with the effect of a round “tunnel”, for which my personal record was still 52 bytes (“Neontube” - 2016) ( link ), which, in turn, became an optimization of the classic 64 -byte effect "constant evolution" developers ryg / Farbrausch (2003) ( link ). In the zooming circles procedure, the distance and angle are eliminated / ignored, due to which it was possible to fall into category 32b.

Scrolling tilted plane



Floorcast, a 32-byte version, a variation of the

Scrolling tilted plane, is one of my own releases, the 2018 floorcast 32b. The effect of “flooring” has its own history in sizecoding and has gradually decreased from 256 bytes to 32 bytes. Different versions differ in the number of planes, in some two planes are displayed, in others - only one. In the “floorcast 32b” release, I specifically decided to abandon the “XOR” texture, and in “Memories” I used it again, masking it with the final touch in the form of “AND”.

  • 2008 rain_storm version - 256 bytes - link
  • 2008 version of org_100h - 128 bytes - link
  • 2013 Baudsurfer version - 86 bytes - link
  • 2014 Baudsurfer version - 64 bytes - link
  • 2018 HellMood Version - 32 bytes - Link

Parallax checkerboards



Projektbeschreibung, 32 bytes

I released parallax chessboards in 2018 as a 32-byte Projektbeschreibung effect. In it, I tried to reduce the size of “Follow the light” ( link ) from “Digimind” (2006) or my own “Lucy” (2014) ( link ) to 32 bytes. Very useful sources of inspiration were Paralaxa by Rrrolas (32 bytes, 2007, link ) and Byteropolis by Sensenstahl (2013) ( link) The Rrrolas rendering technique was very close to my final decision, the code was changed to correct the location of the planes, replace the triangles with chessboards, and improve the colors. Memories used the color scheme of the Digimind version. In addition, the effect was maximally modified to reduce deformations.

Sierpinski rotozoomer



colpinski, 16 bytes


rotastic, 32 bytes

It consists of two effects: rotozoomer and Sierpinski effect as a texture. The Sierpinski effect is based on my own 2013 Colpinski 16b effect ( link ), where I managed to get the maximum possible with the frag function fsqrt. This effect has no predecessor, because it can be implemented directly by combining X and Y, rather than using an Iterated Function System or cellular automata. “Rotation and scaling” (rotozoomer) was released by me in 2017 as the 32b intro “rotastic” ( link ), it is based on the ideas of “ryg” by the developer Farbrausch (51 bytes, 2002, link ) and “Gargaj” of the group “Conspiracy” "(49 bytes, 2002, link ).

Raycast bent tunnel



Into a new era, 64-bit version The

raycast bent tunnel has become a modified version of my own 64-byte release, “Into a new era” (2018, link ). The original colors were replaced with the colors of the standard palette, the geometry and the corresponding calculations were slightly changed so that the depth effect was not used to calculate texture values. A separate version of this effect is 50 bytes in size. The main sources of inspiration for creating the 64-byte version were two 128-byte intros: “Spongy” from “TBC” (2009, link ) and “Wolf128” by Baudsurfer (2014, link ), and I developed the algorithm myself.

Ocean night to day



Ocean, version 64b

The ocean effect is based on my own 64-byte release of “Ocean” 2016 ( link ). A separate generation of the colors and music of the original was cut out, both generators were not compatible with the main Memories framework without using heaps of extra bytes. The special effect of "dawn" is due to the overall implementation of the framework structure. I will talk about this in the next chapter.

Fading effect


The transition between the two effects is in itself an effect that has no predecessors. Rather, it is an idea that has evolved over several years, and perhaps it was similarly implemented by many others. In short, when calculating the frame, the position of each pixel is randomized, and the time that determines which effect should be used is shifted by this randomization value, which was previously reduced. This allows you to use a standard VGA palette (image, source), rather than create your own colors for smooth mixing, which saves space.

The framework of my "tiny megademo"


To combine several small effects into one “megademo”, they should use the same technique and at most they should not apply assumptions (regarding the contents of memory and registers). They are also required to use the same timing values ​​and work in accordance with the total time. It took quite a long time to prepare individual effects suitable for the framework, and at first a lot of extra space. It should be noted that some of the most impressive effects (judging by the reaction of viewers and views on social networks) could not be included in the demo due to the HUGE excessive use of memory. After all the effects had been fixed, I could start thinking about “bracketing” frequently repeated calculations, which would save a few more bytes.The framework performs the following actions:

  • 320 x 200 256


  • 35 FPS
  • ESC
    • ESC,


org 100h
s:
	mov al,0x13				; set AL to mode 320*200 in 256 colors
	int 0x10	 			; call BIOS to set mode
	xchg bp,ax				; set timing value to 0x13 
	push 0xa000-10			; write the screen adress to register ES
	pop es					; works in conjunction with Rrrola trick
	mov ax,0x251c			; parameter for changing timer interrupt
	mov dl,timer			; adress of timer routine, assume DH=1
	int 0x21				; install timer routine
top:
	mov ax,0xcccd			; load magic Rrrola constant
	mul di					; transform screen pointer to X, Y
	add al,ah				; use transformation garbage as
	xor ah,ah				; pseudorandom value and clear AH
	add ax,bp				; add time value to random value
	shr ax,9				; divide by 512 (basically the speed)
	and al,15				; filter effect number
	xchg bx,ax				; move effect number to BX
	mov bh,1				; reset BH to align with start of code
	mov bl,[byte bx+table]	; read the effect address from the table
	call bx					; call the effect
	stosb					; write the return value and advance
	inc di					; triple interlace trick for after
	inc di					; effect and smoothing the animation
	jnz top					; repeat until the frame is complete
	mov al,tempo			; set AL to divider for timer
	out 40h,al				; set timing (dual pass)
	in al,0x60				; read keyboard
	dec al					; quit on ESC
	jnz top					; otherwise repeat loop
sounds: db 0xc3, 11, 0x93; 0xc3 is MIDI/RET; fx2-s is used as volume
table: 	db fx2-s,fx1-s,fx0-s,fx3-s,fx4-s,fx5-s,fx6-s,sounds-s,stop-s


Array of chessboards



array of chessboards

The easiest effect to start with. After shifting the string temporarily, the classic XOR pattern is applied. To create the impression of a chessboard grid, all but two bits are set in color. The real trick is to shift to the “good” place of the palette. The part of the frame that is perceived as black is actually not black, but is the dark part of the standard VGA palette . This shift allows you to give the dark and light cells the feeling of an ancient chessboard.

	xchg dx,ax		; get XY into AX
	sub ax,bp		; subtract time from row
	xor al,ah		; XOR pattern (x xor y)
	or al,0xDB		; pattern for array of boards
	add al,13h		; shift to good palette spot

Zooming circles



zooming circles

The distance D from the point (X, Y) to the center (0,0) is sqrt (XÂČ + YÂČ). The framework previously makes DL contain the centered coordinate X, and DH = Y needs to be centered in the code. To perform the square root calculation operation in x86, quite a lot of code is required, but in fact it can be omitted. With a careful choice of colors, the feeling of converging circles without a square root seems quite convincing.

	mov al,dh		; get Y in AL
	sub al,100		; align Y vertically
	imul al			; AL = YÂČ
	xchg dx,ax		; YÂČ/256 in DH, X in AL
	imul al			; AL = XÂČ
	add dh,ah		; DH = (XÂČ + YÂČ)/256
	mov al,dh		; AL = (XÂČ + YÂČ)/256
	add ax,bp		; offset color by time
	and al,8+16		; select special rings

Scrolling tilted plane



scrolling tilted plane

This effect is implemented as follows: first, to simulate the distance, a large constant is divided by line number Y. Then the obtained value is used twice: a) multiplied by the centered value of X and b) as offset by the current time. Then these results are combined using the XOR pattern, from which a special pattern is selected.

	mov ax,0x1329	; initialize with constant
	add dh,al		; preventing divide overflow
	div dh			; reverse divide AL = C/Y'
	xchg dx,ax		; DL = C/Y', AL = X
	imul dl			; AH = CX/Y'
	sub dx,bp		; DL = C/Y'-T 	
	xor ah,dl		; AH = (CX/Y') ^ (C/Y'-T)
	mov al,ah		; move to AL
	and al,4+8+16	; select special pattern

Parallax checkerboards



parallax checker boards

This is a kind of reykasting (emitting rays) with dynamic geometry. Each plane of the objects is divided horizontally due to 16-bit multiplication with a sign and vertically due to the operation of implicit logic with the column number. Additionally, indirect distortion is applied to connect the edges of the resulting mesh (4 “solid” areas, 4 “transparent” areas alternately). If the beam crosses one of the solid areas, the color becomes the iteration number (+ the palette offset in shades of gray), and if not, the plane moves to the screen pointer, after which the process repeats until the maximum number of iterations is reached.

	mov cx,bp		; set inital point to time
	mov bx,-16		; limit to 16 iterations
fx3L:
	add cx,di		; offset point by screenpointer
	mov ax,819		; magic, related to Rrrola constant
	imul cx			; get X',Y' in DX
	ror dx,1		; set carry flag on "hit"
	inc bx			; increment iteration count
	ja fx3L			; loop until "hit" or "iter=max"
	lea ax,[bx+31]	; map value to standard gray scale

Sierpinski rotozoomer



sierpinski rotozoomer


Graph 1 / cos (atan (x)), created using www.google.com

To rotate with scaling, trigonometric functions or their good approximate values ​​are usually required. Let's take a look at the usual 2D rotation equation and interpret it in a special way to get rid of trigonometry in calculations:

x' = x*cos(a) - y*sin(a)
y' = x*sin(a) + y*cos(a)

If we add scaling, it will look like this:

x' = z * (x*cos(a) - y*sin(a))
y' = z * (x*sin(a) + y*cos(a))

Now let's say that we do not define z ourselves, and put 1 / cos (a) out of brackets:

x' = 1/cos(a) * (x - y*tan(a))
y' = 1/cos(a) * (x*tan(a) + y)

Now we replace tan (a) with a time variable, because the tangent function tends to infinity as it approaches 180 °:

x' = 1/cos(atan(T)) * (x - y*T)
y' = 1/cos(atan(T)) * (x*T + y)

If we don’t care about the lack of the ability to set the scaling factor and we don’t control the angle directly, now we can rotate from -180 ° to + 180 ° without using trigonometric functions. As a result of this, the scaling factor turns out to be tied to time T. The function for the coefficient is shown in the image, due to which scaling occurs from an infinitesimal number to one (the original size) and back to infinitesimal. A fair amount of bytes were spent decorating this effect, fixing time offsets, speeding up animations, increasing the pixels of Sierpinski’s triangles and creating beautiful colors, but I think it was worth it.

	lea cx,[bp-2048]; center time to pass zero
	sal cx,3		; speed up by factor 8!
	movzx ax,dh		; get X into AL
	movsx dx,dl		; get Y int DL
	mov bx,ax		; save X in BX
	imul bx,cx		; BX = X*T
	add bh,dl		; BH = X*T/256+Y
	imul dx,cx		; DX = Y*T
	sub al,dh		; AL = X-Y*T/256
	and al,bh		; AL = (X-Y*T/256)&(X*T/256+Y)
	and al,252		; thicker sierpinski
	salc			; set pixel value to black
	jnz fx4q		; leave black if not sierpinski
	mov al,0x2A		; otherwise: a nice orange
	fx4q:

Raycast bent tunnel



raycast bent tunnel

This is a type of tunnel with rakasting from "into a new era" (see above). A detailed description of this effect for a similar Essence program has been published on reddit. I got rid of unique colors, changed the direction of the tilt, and the geometry became more closed to improve performance on older computers and in DosBox.

	mov cl,-9		; start with depth 9 (moves backwards)
	fx5L: 
	push dx			; save DX, destroyed inside the loop
		mov al,dh	; Get Y into AL
		sub al,100	; Centering Y has to be done "manually".
		imul cl		; Multiply AL=Y by the current distance, to get a projection(1)
		xchg ax,dx	; Get X into AL, while saving the result in DX (DH)
		add al,cl	; add distance to projection, (bend to the right)
		imul cl		; Multiply AL=X by the current distance, to get a projection(2)
		mov al,dh	; Get projection(1) in AL
		xor al,ah	; combine with projection(2)
		add al,4	; center the walls around 0
		test al,-8	; check if the wall is hit
	pop dx			; restore DX
	loopz fx5L		; repeat until "hit" or "iter=max"
	sub cx,bp		; offset depth by time
	xor al,cl		; XOR pattern for texture 
	aam 6			; irregular pattern with MOD 6
	add al,20		; offset into grayscale palette

Ocean night to day



oceannight


oceanday

The Ocean Effect is an excellent example of “fluke”. If we load the value into the FPU as an integer and store it as a floating point, and then interpret it again as an integer, then we get a great pattern. If you combine this with the inverse division, you get a beautiful wave effect. It works closely with the DX register, which has a sign reversal in the position we need, so we can easily separate the sky from the sea. However, the final touch is the color. In accordance with the structure of the global framework, the value of AL is determined at the input of the function, it contains the address of the effect. By shuffling the code a bit, you can get the sky color "free" without using instructions, just like the color of the "transition to day", which is also the effect address. And this is not a happy coincidence. In other versions than the DosBox version,the color of the sky for this reason may vary.

	sub dh,120			; check if pixel is in the sky
	js fx6q				; quit if that's the case
	mov [bx+si],dx		; move XY to a memory location
	fild word [bx+si]	; read memory location as integer
	fidivr dword [bx+si]; reverse divide by constant
	fstp dword [bx+si-1]; store result as floating point
	mov ax,[bx+si]		; get the result into AX
	add ax,bp			; modify color by time
	and al,128			; threshold into two bands
	dec ax				; beautify colors to blue/black

Fading effect


For convenience, the effect is isolated from the global framework. In fact, it generates a pseudo-random number from the screen pointer, and then performs a time offset by its scaled value, after which it causes the desired effect.

	mov ax,0xcccd			; load magic Rrrola constant
	mul di					; transform screen pointer to X, Y
	add al,ah				; use transformation garbage as
	xor ah,ah				; pseudorandom value and clear AH
	add ax,bp				; add time value to random value
	shr ax,9				; divide by 512 (basically the speed)
	and al,15				; filter effect number
	xchg bx,ax				; move effect number to BX
	mov bh,1				; reset BH to align with start of code
	mov bl,[byte bx+table]	; read the effect address from the table

MIDI music


This section of code increments the time value and creates a sound. By selecting channel 3, we can reuse the “change tool channel” instruction as “RET”. By shifting the effect code, you can create a suitable value for the volume, which saves another byte. It is worth considering that this part of the code only works if the MIDI device is already in UART mode, otherwise you will need to spend another three bytes. Many of the spectators and organizers told me that the tune is a bit like Mike Oldfield's Incantations , but it was created with a very simple technique. Since Hypnoteye 2015, I experimented with procedural MIDI and eventually released a small MIDI framework (64 bytes). The main principle of his work is to jump with a fixed pitch in the tone space and convert high values ​​to lower ones (by division modulo). Simple combinations of stepwidth and modvalue can achieve interesting effects. For example, stepwidth = 3 allows you to get a continuously lasting reduced minor chord, and stepwidth = 4 or stepwidth = 6 - tritonal effects. With a well-chosen modvalue, these patterns can create sequences. I have not carried out a proper theoretical analysis, but simply explored the space of tones and noted interesting sounds.

sounds: db 0xc3, 11, 0x93, fx2-s
...
		inc bp				; increment timing value
		test bp, 7			; play a note every 8th step
		jnz nomuse			; quit if in between
		mov dx,0x330		; port number for MIDI
		mov si,sounds		; adress for sound data
		outsb				; change instrument of channel 3
		outsb				; to vibraphone
		outsb				; play a note on channel 3
		imul ax,bp,-19*32*4	; the magic melody constant
		shr ax,10			; scale down and implicit "and 63"
		add al,22			; pitch base is 22
		out dx,al			; play THIS note on channel 3
		outsb				; play it with THIS volume

Full release code


; "memories" by HellMood/DESiRE
; the tiny megademo, 256 byte msdos intro
; shown in April 2020 @ REVISION
;
;   (= WILL BE COMMENTED IN DETAIL LATER =)
;
; create : nasm.exe memories.asm -fbin -o memories.com
; CHOOSE YOUR TARGET PLATFORM (compo version is dosbox)
; be sure to use the dosbox.conf from this archive!
; only ONE of the defines should be active!
%define dosbox			; size : 256 bytes
;%define freedos		; size : 230 bytes
;%define winxpdos		; size : 263 bytes

; DON'T TOUCH THESE UNLESS YOU KNOW WHAT YOU'RE DOING
%ifdef winxpdos
	%define music
	%define switch_uart
	%define safe_dx
	%define safe_segment
%endif
%ifdef freedos
	%define safe_dx
%endif
%ifdef dosbox
	%define music
	;%define safe_dx ; sometimes needed
%endif

; GLOBAL PARAMETERS, TUNE WITH CARE!
%define volume 127	; not used on dosbox (optimization)
%define instrument 11
%define scale_mod -19*32*4; 
%define time_mask 7
%define targetFPS 35
%define tempo 1193182/256/targetFPS		
%define sierp_color 0x2A
%define tunnel_base_color 20
%define tunnel_pattern 6
%define tilt_plate_pattern 4+8+16
%define circles_pattern 8+16

org 100h
s:
%ifdef freedos
	mov fs,ax
	mov [fs:0x46c],ax
%endif
	mov al,0x13
	int 0x10	 
	xchg bp,ax
	push 0xa000-10
	pop es
%ifndef freedos
	mov ax,0x251c
	%ifdef safe_dx	
		mov dx,timer	
	%else ; assume DH=1, mostly true on DosBox
		mov dl,timer
	%endif
	int 0x21
%endif
top:
%ifdef freedos
	mov bp,[fs:0x46c]
%endif	
	mov ax,0xcccd
	mul di
	add al,ah
	xor ah,ah
	add ax,bp
	shr ax,9
	and al,15
	xchg bx,ax
	mov bh,1
	mov bl,[byte bx+table]
	call bx
	stosb
	inc di
	inc di
	jnz top
	mov al,tempo
	out 40h,al
	in al,0x60
	dec al
	jnz top
sounds:
	db 0xc3	; is MIDI/RET
%ifdef music
	db instrument,0x93
	%ifdef switch_uart
		db volume		; without switch, volume is in table
		db 0x3f 
	%endif
%endif
table: ; first index is volume, change order with care!		    					
	db fx2-s,fx1-s,fx0-s,fx3-s,fx4-s,fx5-s,fx6-s,sounds-s,stop-s
stop:
	pop ax
	ret
timer:
%ifndef freedos
	%ifdef safe_segment
		push cs
		pop ds
	%endif
		inc bp
	%ifdef music	
		test bp, time_mask
		jnz nomuse
		mov dx,0x330
		mov si,sounds
		outsb
		outsb
		outsb
		imul ax,bp,scale_mod
		shr ax,10
		add al,22
		out dx,al
		outsb
		%ifdef switch_uart
			inc dx
			outsb
		%endif
	%endif
nomuse:
	iret
%endif	
fx0: ; tilted plane, scrolling
	mov ax,0x1329
	add dh,al
	div dh
	xchg dx,ax
	imul dl
	sub dx,bp
	xor ah,dl
	mov al,ah
	and al,tilt_plate_pattern
ret
fx2: ; board of chessboards
	xchg dx,ax
	sub ax,bp
	xor al,ah
	or al,0xDB
	add al,13h
ret
fx1: ; circles, zooming
	mov al,dh
	sub al,100
	imul al
	xchg dx,ax
	imul al
	add dh,ah
	mov al,dh
	add ax,bp
	and al,circles_pattern
ret
fx3: ; parallax checkerboards
	mov cx,bp
	mov bx,-16
fx3L:
	add cx,di
	mov ax,819
	imul cx	 
	ror dx,1	 
	inc bx	 
	ja fx3L
	lea ax,[bx+31]	 
ret
fx4: ; sierpinski rotozoomer	
	lea cx,[bp-2048]
	sal cx,3
	movzx ax,dh
	movsx dx,dl
	mov bx,ax
	imul bx,cx
	add bh,dl
	imul dx,cx
	sub al,dh
	and al,bh
	and al,0b11111100
	salc				; VERY slow on dosbox, but ok
	jnz fx4q
	mov al,sierp_color
	fx4q:
ret
fx5: ; raycast bent tunnel
	mov cl,-9
	fx5L: 
	push dx
		mov al,dh
		sub al,100
		imul cl
		xchg ax,dx	
		add al,cl
		imul cl
		mov al,dh
		xor al,ah
		add al,4
		test al,-8
	pop dx
	loopz fx5L
	sub cx,bp
	xor al,cl
	aam tunnel_pattern; VERY slow on dosbox, but ok
	add al,tunnel_base_color
ret
fx6: ; ocean night / to day sky
	sub dh,120
	js fx6q
	mov [bx+si],dx
	fild word [bx+si]
	fidivr dword [bx+si]
	fstp dword [bx+si-1]
	mov ax,[bx+si]
	add ax,bp
	and al,128
	dec ax
fx6q:
ret

Bonus - NFO / ASCII
                                                             art : hammerfist
         ∂#MW%e                              _d$Ng,
         'B,  ∂b                   _jM@$QZb,cQ"  )@
  ,edRB$b,l@   Wk,yGR$KM&$b,     ,dP"     Wl ]bsd%UR8BG6&$@DSyG#ZKM&$b,
,dP      "T%L  'MGF      "*∂R_   Tg    "*4Zk,#I  YP   W"    7P      "*∂R
4M   gd@    ^   ∂@   d@b   dQ$#@Z@R3L_    "*GMj  'W      ,gd$   d@b   9Q$#%b
W#,  `M          Wb  `*  _4P   `Qk  *#N8L   `H5   @b   'QR7YK   `*  _4F"   Qk
`6@L             dML            '@          ,BK   'M    ∂B  *b,            '#L
  ^QBb,_     _,4&M∞∂@=,_       _dGL       _gQKM    GL    @k  'Mg,_         _dG,
    "*BN5W$2#MNP"   "*G3WRM8&B5P"`Y@QNW3Z5P" ∂#$W8BRM3XZN87    "*GW38M%EBDW5P"`


                              p r e s e n t s

            4
           d@,
         _& `Wl
      _,aP   "#baedM$#@@K JP*"?ML
 ,ad@$#P"         ,d@NEWVB"     X,aQPYb,_
V@Mm,_          ,d@MW#BW'      EMP"   '¶R ,ngBP^fML
 ¶M@N@y        Y#BNW#M"       J9"      `MQ9"      "MgRBq  ,QBMg,
  VN#P` ,d@@    `WM@^                   7f         ¶F` 7kY"   ^G  _.eQNE1.
   ]B _G@MWN$,   `P                     '     4b       QP      ¶w@F*^  ^Qb
   ]O@NRM#W@MNB,         ;                    ^`      j        JP^       Yl
  J#NRNWM@#BcT"^        ,A  _J                     _q@                   `X
 '¶WM#B@WdY`,7        _G#YN#PM                 _,gG"                      M,
  *BN#WP"  dK       ,Q@NRMB"]9       ,      _,M@Q*                        #A
   "U^      V@h,   iNBW#NT  J'      J9     s@QN"         _;               'D,
             ¶RMBv&NMQR@9  .W      .K'     "9`         ,6BA   _JL          ]l
              Y#NE@W#NRP   #[      `¶8               _d@MW#B_jW#W          BN
               "GQ@MR#W    QL_      *B            _,p#NBW#NQMG@WY          3Q
                  "Y@F     ,XW@M%im,_Yb_     _,g5@#MW@QMNE@E@NRMB         ,WM
                    `  _,gP*"#REM#GB@N#MQbnd@N#M@MW#R8QSB^'WQERM@        ;4NB,
                     ,GYKL    ¶E#B8R8QSB@M@#BM#W@MNB"`_  ,  "^` N       ,dW@Ql
                   _Q`'W`*t    '¶@GS#MBQ#E@W#NQBW[     'LvQ_   ,K    _dNABGM#N
                  ,F   '          `^WAB@QGE9*"9^*@L    jP7FY,  ¶h,_.jWM#BR#GBM,
                 J;    ,   _                  '       '   "LL  YxE#B8R8QSBNW@W;
                AP   _,Ag6^          _   J                  ¶A  `"Q#M@MW#R8E#P
               j@   `"XQW[            'LvK,_      'L_,/      @t    Y#NE@WNR"
              :M/     9^*@L           jP7F"       _PYKL     _,A;     ¶RSNQ"
              dKL     '     `        '   "L      "`'W`*t   `"XQb      `W^
              Q`8t            'L_,/         ,   _   '        9^Q
             ,W               _PYKL       _,Ag6^             ' W,     _ ,#N&
             !N  _   J       "`'W`*t     `"XQW[       _  J     N!_JG9^RwQ' *t
             `W,  'LvK,_        '        _gGB8@L   _   'LvK,_ ,WgB'    V    7L
         _.,gm&@B&wBZF"                j@'`  "WL _gML  jZd7Yb lN"          dBWl
      ,g&QB*"^`    `"*G@g, .gR&k,_   ,N"      '@QF  ¶k;gMF  *QvQ     jQ, ,@N@B#,
   .eQF*`              `Yb@"  "*6Qg,gF     ,   7     XMN"    'MNB,    ^¶QWSER@N;
 ,gP"           qy,      W'       ^Q'     &L      ,g@W'       `QMEL     `"WBNWP
g7              ¶9      ,X         M?     9"   _q8MSK           ¶EMt       *@K
Vh   _,m#L             _AH        le         ,GBDNE9^A,          *@F        NMg
 ¶L,qQ@ND           _.m@Bl        We      ,gM@B8#Q'   ¶h_                   lWE,
  W9NHW@`          JWM#B@]        @e     4WR@NGF^      'QL                  dRWl
   VMd*            "@BE@PM        'N      *UP"           VW,               JRSB;
  ,@F       j       `¶WK W,        ¶t                     XNt            _A@E#N
_JP       ,6&         "GLdM         XD,               _.g8NMA@k,_    _,gG#NMGR;
"Z      .JRER           'VMi     _jNB#W&_         _,j@E@W#Nl ¶MBGMNQGNQMG@QBW9
 ¶h   ,G@NRMBl            `"   ,d#R@M$F ¶Mg,_.gp&@@NEWVBWBMG  *QMN8R8SBN$E@WF
  Vb dW#R8QSRb,                 *YM@EQ,_ 'MENBW#NQMG#B@R@MW#l   "BM@QNENRQG'
   *WGS#MBMNEYL                    `^"*8M@Q@NRM#W@BWSNW@QBF"`     `^*@QBF^ [HFT]
    ^M@MW#Q9 ^Wt                           `^¶RQ@W8NQGP*`
     ¶Q#@P     Vk                            lA `"^`
      Y"       `MA                           J#,
                *R@,                        ,MQl
                 Y#Wk,                      GWM8L
                  W8RQSt,_                 AQ@MR#,
                  `@M@#SB@Mbm.,_          QNBW#NW
                    ¶QB8R8SBN$WNRM@#GNtwg@NMQR@B'
                     *MBQ#8R8QS@NE@WNBW#NQMG@NR;
                      `WGS#MBQ#R8QSB@NE@W#NQBW9
                        *OMW@QMNE@E@NRMW@QMB@*
                          `^"YQW@Q#SB#NE@EGP
                               `^"*8R@GBQF`


All Articles