X86 Kod maszynowy - 150 146 149 133 127 127 bajtów
Wersja golfowa:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
--------------------------------------------------------------------
0000 B0 13 CD 10 BA C9 03 88 F1 BE 76 01 F3 6E B0 0F - °.Í.ºÉ.ˆñ¾v.ón°.
0010 49 68 00 A0 07 F3 AA 64 66 A1 6C 04 66 A3 80 01 - Ih. .óªdf¡l.f£€.
0020 64 66 A1 6C 04 66 2B 06 80 01 66 50 89 E5 D9 EB - df¡l.f+.€.fP‰åÙë
0030 D8 C0 DA 4E 00 DE 34 D9 FB BB 7D 01 DE 0F DE 47 - ØÀÚN.Þ4Ùû»}.Þ.ÞG
0040 FE DF 5E 02 DE 0F DE 47 FE DF 5E 00 5F 69 FF 40 - þß^.Þ.ÞGþß^._iÿ@
0050 01 58 01 C7 BB 88 01 8B 0F 39 CF 74 C3 30 C0 AA - .X.Ç»ˆ.‹.9ÏtÃ0Àª
0060 4F 89 3F 89 CF B0 0F AA 31 C0 FE C4 CD 16 74 B0 - O‰?‰Ï°.ª1ÀþÄÍ.t°
0070 B8 03 00 CD 10 C3 20 00 20 44 04 64 00 4B 00 - ¸..Í.Ã . D.d.K.
„Ungolfed”, wersja źródłowa:
; golfCrcl.asm
;
; - 16 bit implementation of an animated pixel that circumscribes a circle.
; - 127 bytes .COM file
;
; - enhzflep -
; 31 Oct 2015 - initial
; - set closest colour to desired #800080
; 2/3 Nov 2015 - removed unnecessary instuctions, used BX register to index mem by fpu
; - removed .data section alignment, better register use in curPixel/lastPixel compares and calcs, reusing value of si after palette setting
[section .text]
[bits 16]
[org 0x100]
EntryPoint:
; mov fs, bx ; bx is 0 on entry. Set fs seg register to this
; set graphics mode 320x200
mov al, 0x13
int 0x10
; set colour #0 to be as close to the desired one as possible
; the vga palette registers are 6 bits by default (some models allow switching to 8 bits)
; therefore, we cant represent all of the 16.7m colours that we can in 24bit modes
; we're limited to 'just' 64*64*64 = 262,144 (256k) colours. Unfortunately, #800080 is not
; a colour we can represent exactly in mode13 or any other mode with 6 bit regs.
mov dx, 0x3c9
mov cl, dh
mov si, desiredCol
rep outsb ; cx now=0 and si now points to totalTicksNeeded
; clear the screen to white
mov al, 0x0f ; index of a colour thats already FF,FF,FF
; xor cx, cx ; cx = 0 - its zeroed by the rep outsb instruction above.
dec cx ; cx = FFFF
push word 0xA000 ; segment of video memory
pop es ; pop it into es
rep stosb ; es:[di] = 0F, inc di, dec cx. If cx != 0 then repeat.
; setup the timing stuff
mov eax, [fs:0x046C] ; 32 bit value updated at 18.2Hz by bios
mov [initialTicks], eax
.drawLoop:
mov eax, [fs:0x046C] ; 32 bit value updated at 18.2Hz by bios
sub eax, [initialTicks] ; eax = curTime-startTime (in increments of 1/18.2 of a second --- 182 = 10 seconds)
push eax ; number of elapsed clock ticks - ready to be loaded by fpu. Also stack space for calc result
mov bp, sp ; get pointer to last element pushed onto the stack
fldpi ; st0 = pi
fadd st0 ; st0 = 2pi
fimul long [bp] ; (currentTick/requiredTicks) * 2pi
; fidiv word [totalTicksNeeded]
fidiv word [si] ; si still points to totalTicksNeeded after setting the palette earlier
fsincos ; st0 = cos(old_st0), st1 = sin(old_st0)
mov bx, radius
fimul word [bx] ; fimul word [radius] - cos(angle)*radius
fiadd word [bx-2] ; fiadd word [origin] - origin + cos(angle)*radius
fistp word [bp+2] ; ---- X-coord -------
fimul word [bx] ; fimul word [radius]
fiadd word [bx-2] ; fiadd word [origin]
fistp word [bp+0] ; ---- Y-coord -------
;---------------
pop di ; calculated Y-coord
imul di, 320 ; multiply it by the screen width
pop ax ; calculated X-coord
add di, ax ; di = x + (pixels_per_row * y_coord)
mov bx, lastIndex
mov cx, [bx] ; get the mem index for the last pixel
cmp di, cx ; check if we're indexing the same pixel as last time through the loop
je .drawLoop ; if so, return to start of loop - no need to delete and redraw the pixel in the same spot.
xor al, al ; col index 0
stosb ; draw our purple pixel
dec di ; stosb advanced di to the next pixel, undo this (stosb followed by dec di is still shorter than mov es:[di], al)
mov [bx], di ; save the pixel's mem address
mov di, cx ; restore index of pixel drawn last time through the loop
mov al, 0x0f ; pal index of white
stosb ; erase the last pixel
; check for a keystroke
xor ax, ax
inc ah
int 0x16
jz .drawLoop ; loop if no keys pressed
.drawingDone:
; set text mode 80x25
mov ax, 0x3
int 0x10
; program exit
ret ; Dos pushes a 0000 onto the stack and copies CD 20 to offset 0 of our code-seg
; before it invokes our program. ret jumps back to that CD 20 (int 0x20) instruction
; Since this is a .COM file, all program, data and stack exist in the same segment.
; Using .text and .data sections only improves program readability - doing so only has minor effects on the binary produced.
;
; In this case, the assembler word aligns anything in the data section. This may have the effect of adding a padding byte,
; which we really dont need/want here. Data is machine-word aligned to improve the speed of access for the hardware. Machine-word
; is used to refer to the size of an int. In the case of 16 bit code, this will generally be 16 bits, 32 bit code has 32 bit words
; and so on. This code is 16 bit, so things should be aligned to word boundaries for maximum execution speed
;
;[section .data]
desiredCol db 0x80/4, 0x00, 0x80/4 ; palette registers are only 6 bit.
totalTicksNeeded dw 1092
origin dw 100
radius dw 75
; ticks/second = 18.2
; totalTime = 60 seconds
; totalTicks = 1092 (18.2 * 60)
; degreesPerTick = 360 / 1092 = 0.3296703
; timerTicksAddr = 0040:006C (0000:046C) dword
[section .bss]
initialTicks resd 1
lastTickValue resd 1
lastIndex resw 1
Do pobrania, wersja zakodowana w standardzie base64
data:application/octet-stream;base64,sBPNELrJA4jxvnYB826wD0loAKAH86pkZqFsBGajgAFkZqFsBGYrBoABZlCJ5dnr2MDaTgDeNNn7u30B3g/eR/7fXgLeD95H/t9eAF9p/0ABWAHHu4gBiw85z3TDMMCqT4k/ic+wD6oxwP7EzRZ0sLgDAM0QwyAAIEQEZABLAA==
Skopiuj i wklej ten adres do przeglądarki. Zmień nazwę pliku wynikowego golfcrcl.com
i uruchom w środowisku DOS, tj. DosBox.