## simple illustration of the circle-drawing trick from HAKMEM
## in the form of a 64-byte MS-DOS .COM file
## by Kragen Javier Sitaker, 2008, public domain
## don't expect too much --- this is not going to win any prizes.
## it's not in the same league visually as dirojed or klappquadrat.
## but hey, it's my first 64-byte intro, I don't know what I'm doing.
## compile with gas as follows:
## as -R morecircles.s -o morecircles.o
## objcopy -O binary morecircles.o morecircles.com.0
## dd if=morecircles.com.0 of=morecircles.com bs=256 skip=1
## I've only tested it in DOSBox and in QEMU with FreeDOS;
## hope it works elsewhere!
## registers are used as follows:
## %ax: X-coordinate from center of circle, sin theta
## %bx: scratch space
## %cx: loop counter
## %dx: Y-coordinate from center of circle, cos theta
## %di: scratch space used to compute address of pixel
## %si: center of circle (as pixel address)
## %bp: PRNG state
## %cs, %ds, %ss, %sp, %ip: the usual
## %es: the video RAM segment
## the top stack item: the current color and a counter
.code16
.org 0x100
## set video mode 13h
start: mov $0x13, %al
int $0x10
## load video segment into %es
#mov $seg-2, %bx # if we leave this out, it actually still mostly works
les (%bx), %bp # we don't care what goes into %bp as long as it's not 0
init: ## change radius and position pseudorandomly
mov %bp, %ax # random seed is in %bp
imulw (start+1) # 0xcd13**n % 65536 has period 16384
mov %ax, %bp
xor %ax, %si # get some "randomness" into the position
xor %dx, %dx # set angle to 90 degrees
mov %ax, %cx # number of iterations: (scaled) radius
loop: ## turn coordinates in %ax, %dx into offset in %di
## first, put %dx/256 * 320 into %di
## sin and cos are scaled by 16 so the circle is round, not octagonal
xor %bx, %bx
mov %dh, %bh
mov %bx, %di
sar $2, %bx
add %bx, %di
## now add x-coordinate, %ax/256
mov %ax, %bx
sar $8, %bx
add %bx, %di
## now offset them both by the center of circle
add %si, %di
#mov %si, %di # to see the centers only, to see how bad the RNG is
## now set a pixel
pop %bx # we're using whatever was on the stack...
movb %bh, %es:(%di) # change color every 256 pixels by using %bh
inc %bx
push %bx
## this is the circle-drawing trick from HAKMEM
## to update sin and cos:
## cos += sin * scale
mov %ax, %bx
sar $4, %bx
add %bx, %dx
## sin -= cos * scale
mov %dx, %bx
sar $4, %bx
sub %bx, %ax
loop loop
## now that we've drawn a circle, let's go to the next one
jmp init
#seg: .short 0xa000 # (see above about "it actually still mostly works")
## In case you have trouble compiling it:
## [EMAIL PROTECTED]:~/devel/circles$ xxd < morecircles.com
## 0000000: b013 cd10 c42f 89e8 f72e 0101 89c5 31c6 ...../........1.
## 0000010: 31d2 89c1 31db 88f7 89df c1fb 0201 df89 1...1...........
## 0000020: c3c1 fb08 01df 01f7 5b26 883d 4353 89c3 ........[&.=CS..
## 0000030: c1fb 0401 da89 d3c1 fb04 29d8 e2d6 ebc6 ..........).....