英特尔8086/8087组件 180 144 142 138字节
这将对所有trig和浮点运算使用8087数学协处理器。所有计算均在具有80位浮点精度的硬件中完成。
df06 b101 d8c8 df06 af01 d8c8 dec1 d9fa df1e b301 8b16 b301
33c0 81fa aa00 7c03 eb53 9083 fa06 7d05 b032 eb49 9083 fa10
7d05 b019 eb3f 90df 06b7 01df 06b5 01d9 f3df 06b1 01dd d2d9
ebde f9de c9de c1df 1eb3 01a1 b301 bb9c 01d7 83fa 6b7d 0a83
fa63 7c05 b303 eb09 9081 faa2 007c 04b3 02f6 e30b 0810 0713
0311 020f 0a06 0d04 1201 1405 0c09 0e0b 0a00
以MASM MACRO(基本上是函数)形式编写,以X和Y为坐标,并以AX返回计算出的分数。领带是顺时针方向折断的。
MAX_BULL EQU 6
MAX_25 EQU 16
MIN_3X EQU 99
MAX_3X EQU 107
MIN_2X EQU 162
MAX_2X EQU 170
; cartesian coordinates to radius
; ST = sqrt( X^2 + Y^2 )
; input: X,Y (mem16,mem16)
; output: Radius (mem16)
FCRAD MACRO X, Y, R
FILD Y ; ST[] = Y
FMUL ST,ST ; ST = y^2
FILD X ; ST[] = X
FMUL ST,ST ; ST = x^2
FADD ; ST = ST + ST1
FSQRT ; ST = SQRT(ST)
FISTP R ; R = ROUND(ST)
ENDM
; cartesian coordinates to sector #
; input: X,Y (mem16,mem16)
; output: Sector (mem16)
FCSEC MACRO X, Y, S
FILD Y ; ST[] = Y
FILD X ; ST[] = X
FPATAN ; ST = atan2(Y,X)
FILD CTEN ; ST[] = 10
FST ST(2) ; ST(2) = 10
FLDPI ; ST[] = pi
FDIV ; ST = 10 / pi
FMUL ; ST = A * ST
FADD ; ST = ST + 10
FISTP S ; S = ROUND(ST)
ENDM
; score the dart throw
; input: X / Y coordinates (mem16)
; output: Score (AX)
SCORE MACRO X, Y
LOCAL IS_BULL, IS_25, IS_3X, IS_2X, MUL_SCORE, DONE
FCRAD X, Y, FDW ; FDW = radius(X,Y)
MOV DX, FDW ; DX = FDW = radius
XOR AX, AX ; score is initially 0
CMP DX, MAX_2X ; >= 170 (miss)
JL IS_BULL ; if not, check for bullseye
JMP DONE
IS_BULL:
CMP DX, MAX_BULL ; < 6 (inner bullseye)
JGE IS_25 ; if not, check for 25
MOV AL, 50 ; score is 50
JMP DONE
IS_25:
CMP DX, MAX_25 ; < 16 (outer bullseye)
JGE IS_3X ; if not, check for triple
MOV AL, 25 ; score is 25
JMP DONE
IS_3X:
FCSEC X, Y, FDW ; FDW = sector(X,Y)
MOV AX, FDW ; load sector # into AX
MOV BX, OFFSET SCR ; load base score table
XLAT ; put base score into AL
CMP DX, MAX_3X ; < 107 (triple upper bounds)
JGE IS_2X ; if not, check for double
CMP DX, MIN_3X ; >= 99 (triple lower bounds)
JL IS_2X ; if not, check for double
MOV BL, 3 ; this is triple score
JMP MUL_SCORE ; go forth and multiply
IS_2X:
CMP DX, MIN_2X ; >= 162 (double lower bounds) (> 170 already checked)
JL DONE ; if not, single score
MOV BL, 2 ; this is double score
MUL_SCORE:
MUL BL ; multiply score either 2x or 3x
DONE:
ENDM
; DATA (place in appropriate segment)
SCR DB 11,8,16,7,19,3,17,2,15,10,6 ; score table
DB 13,4,18,1,20,5,12,9,14,11
CTEN DW 10 ; constant 10 to load into FPU
FDW DW ? ; temp DW variable for CPU/FPU data transfer
PC DOS的示例测试程序。在DARTTEST.COM上下载。
INCLUDE DART.ASM ; the above file
INCLUDE INDEC.ASM ; generic I/O routines - input int
INCLUDE OUTDEC.ASM ; generic I/O routines - output int
FINIT ; reset 8087
MOV AH, 2 ; display "X" prompt
MOV DL, 'X'
INT 21H
CALL INDEC ; read decimal for X into AX
MOV X, AX
MOV AH, 2 ; display "Y" prompt
MOV DL, 'Y'
INT 21H
CALL INDEC ; read decimal for Y into AX
MOV Y, AX
SCORE X, Y ; AX = SCORE( X, Y )
CALL OUTDEC ; display score
X DW ?
Y DW ?
输出量
上述测试程序的示例用法。具有8087,DOSBox或您喜欢的仿真器的实际IBM PC。
A>DARTTEST.COM
X: 0
Y: 0
50
A>DARTTEST.COM
X: 2
Y: 101
60
A>DARTTEST.COM
X: -163
Y: -1
22
A>DARTTEST.COM
X: 6
Y: 18
1
A>DARTTEST.COM
X: -6
Y: 18
5
A>DARTTEST.COM
X: 45
Y: -169
0
A>DARTTEST.COM
X: 22
Y: 22
4
A>DARTTEST.COM
X: -150
Y: 0
11
A>DARTTEST.COM
X: -150
Y: 0
11
A>DARTTEST.COM
X: -150
Y: -1
11
A>DARTTEST.COM
X: -7
Y: -6
25
A>DARTTEST.COM
X: -90
Y: 138
24
*编辑:
- 通过删除truncate-rounding语句和10.5常量,可得到-36字节。领带现在按顺时针方向断开。
- 通过删除不再需要的FRNDINT -2字节
- -4个字节,FMUL使用相同的源/目标