## 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 ..........).....