2017-05-22 115 views
1

我正在使用dosbox与tasm。我不知道为什么分数系统不工作

这是用汇编语言编写的代码的主要部分。

IDEAL 
MODEL small 
STACK 100h 
P186 

include 'GL1.asm' 

DATASEG 

ballX DW 160 
ballY DW 100 
ballColor DB 4 
BALL_SIZE EQU 20 
ballDeltaX DW ? 
ballDeltaY DW ? 
scorr db 0 

randChangeCounter DW ? 

CODESEG 

start: 
mov ax, @data 
mov ds, ax 
mov ax, 13h 
int 10h 
mov al,[ballColor] 
call glBall 
mov CX,60 
mov [ballDeltaX],-2 
mov [ballDeltaY],-1 
mov cx,300 
call SetCursor 
Gameloop: 
mov BH ,00h 
call TickDelay 

call mouse 

call Score 

cmp [scorr] , 20 
je exit 
call randChange 


call changeOnborder 
call renderBall 

call mouse 
call Score 
cmp [scorr] , 20 
je exit 


jmp Gameloop 
exit: 

mov ah, 0 
mov al, 2 
int 10h 

mov ax, 4c00h 
int 21h 

proc renderBall 
PUSHA 

xor al,al ; balck 
call glBall 

mov cx,[ballDeltaX] 
add [ballX],cx 
mov cx,[ballDeltaY] 
add [ballY],cx 

mov al,[ballColor] 
call glBall 
POPA  
ret 
endp renderBall 

proc waitKey 
PUSHA 
mov ah,00h 
int 16h 
POPA 
ret 
endp waitKey  

proc glBall 
PUSHA 
mov cx,[ballX] 
mov dx,[ballY] 
mov ah,BALL_SIZE 
mov bl,BALL_SIZE 

call glBox 
POPA 
ret 
endp glBall 

proc glBox 
PUSHA 
@@ONE_LINE : 
call glVLine 
inc dx 
dec bl 
jnz @@ONE_LINE 
POPA 
ret 
endp 

proc glVLine 
PUSHA 
mov bl,ah 
mov bh,0 
mov ah,0ch 
@@ONE_PIXEL : 
int 10h 
inc cx 
dec bl 
jnz @@ONE_PIXEL 
POPA 
ret 
endp 

proc randChange 
push ax 
inc [randChangeCounter] 
cmp [randChangeCounter],20 
jne @@skip 
    mov [randChangeCounter],0 

    mov ax,13 ; +-6 
    call rand_max 
    sub ax,6 
    mov [ballDeltaX],ax 

    mov ax,13 ; +-4 
    call rand_max 
    sub ax,6 
    mov [ballDeltaY],ax 

    mov ax,6 
    call rand_max 
    add ax,2 
    mov [ballColor],al 

@@skip: 
pop ax 
ret 
endp randChange 
proc SetCursor 

mov ax, 0h 
int 33h 
mov ax, 1h 
int 33h 
mov ax, 3h 
int 33h 
ret 
endp SetCursor 
proc mouse 
mov ax, 3h 
int 33h 
ret 
endp mouse 
proc Score 

mov ax,3h 
int 33h 
cmp bl,1 
je Check_X1_Cords 
ret 
Check_X1_Cords: 
cmp cx, [ballX] 
jg Check_X2_Cords 
ret 
Check_X2_Cords: 
cmp cx,[ballX+20] 
jl Check_Y1_Cords 
ret 
Check_Y1_Cords: 
cmp dx, [ballY] 
jg ScoreLabel 
ret 
Check_Y2_Cords: 
cmp dx, [ballY+20] 
jl ScoreLabel 
ret 
ScoreLabel: 
inc [scorr] 
ret 
endp Score 

proc changeOnborder 
push ax 

mov ax,[ballX] 
add ax,[ballDeltaX] 
cmp ax,320-BALL_SIZE 
jg X_FIX 
cmp ax,0 
jge X_OK 
X_FIX: 
mov [ballColor],1 
neg [ballDeltaX] 
X_OK: 

mov ax,[ballY] 
add ax,[ballDeltaY] 
cmp ax,200- BALL_SIZE 
jg Y_FIX 
cmp ax,0 
jge Y_OK 
Y_FIX: 
mov [ballColor],1 
neg [ballDeltaY] 
Y_OK: 

pop ax 
ret 
endp changeOnborder 

END start 

,这是GL1.asm

RANDPRIME equ 401 

segment biosdata at 40h 
org 6ch 
timer  dw ? ; clock ticks 
ends 

DATASEG 
lastrand dw 0 


FastCounter DW 0 ; 
SlowCounter DW 0 ; 

CODESEG 

; 
; timeticks - get time ticks from bios data segment. 
; 
; Register Arguments: 
; None. 
; 
; Returns: 
; ax - current ticks 
; 

proc timeticks 
push es 

mov ax, biosdata 
mov es, ax 
assume es:biosdata 
mov ax, [timer] 
assume es:nothing 
pop es 
ret 
endp 

; 
; random - pseudo generate random number 
; 
; Register Arguments: 
; None. 
; 
; Returns: 
; ax - random number. 
; 
codeseg 
proc random 
push dx 
push bx 
mov bx, [lastrand] 
mov ax, bx 
mov dx, RANDPRIME 
mul dx 
mov dx, ax 
call timeticks 
xor ax, dx 
xchg dh, dl 
xor ax, dx 
xchg bh, bl 
xor ax, bx 
mov [lastrand], ax 
pop bx 
pop dx 
ret 
endp 

proc rand_max 
push dx 
push bx 
mov bx,ax ; store max 
call random ; -> ax 
xor dx,dx 
div bx 
mov ax,dx ; the reminder [0..max] 

pop bx 
pop dx 
ret 
endp rand_max 
;===================== Delay ===================== 
Proc delay 

push ax 
push cx 
push dx 
push es 

mov dx,0 
mov cx , 55 
div cx 

mov cx, ax 
cmp cx,0 
je Finish 
DelayLoop: 

call timeticks 
mov dx,ax 
Tick: 
call timeticks 
cmp dx,ax 
je Tick 

loop DelayLoop 
Finish: 

pop es 
pop dx 
pop cx 
pop ax 
ret 
endp Delay 

proc TickDelay 
pusha 

mov cx, 4 
each_sync: 
    call wait_for_vsync 
loop each_sync 

popa 
ret 
endp TickDelay 

proc wait_for_vsync 
pusha 

mov dx, 03dah 
@@previous_not_ended: 
in al, dx 
test al, 08h 
jnz @@previous_not_ended 

@@next_not_started: 
in al, dx 
test al, 08h 
jz @@next_not_started 

@@exit: 
popa 
ret 
endp 

我不知道该怎么办,我认为这个问题是在GL1但林不知道。

根据问题或代码风格的任何帮助将真正appreaciated。

非常感谢。

+0

你期望你的代码呢?是什么代码做呢?请提供这方面的信息。 – fuz

回答

0

很难说,什么“不起作用”的意思,以及你的代码应该做什么,但我会尝试猜测,下面的部分没有做什么打算(也许,你没有评论任何东西) 。

... 
    ; cx = 0..639 mouse.x position 
Check_X1_Cords: 
    cmp cx, [ballX] 
    jg Check_X2_Cords 
    ret 
Check_X2_Cords: 
    cmp cx,[ballX+20] 
    jl Check_Y1_Cords 
    ret 
    ... 

的事情是,即ballX符号是存储器地址DW(两个字节)的保留空间。例如地址0x1234。并且地址0x1234处的存储器包含例如两个字节:0x88 0x01(0x0188 = 392)。而假设鼠标在x位置550

然后第一cmp将比较cx(550),在地址0x1234(0x0188 = 392)值,并做jg跳转到Check_X2_Cords

第二cmp将在地址0x1234+20 = 0x1248,这是任何值是存在于内存值进行比较cx(550),但很可能不会有用的东西(可能是零,因为它看起来超出了你的你还有其他变数在数据段中)。

你大概没希望编写第二次测试为:

... 
Check_X2_Cords: 
    add cx,20 
    cmp cx,[ballX] 
    jl Check_Y1_Cords 
    ... 

cmp cx,[ballX+20]不会增加20到内存中的价值,但它会增加20到ballX,这是象征性的标签(地址在内存),而不是值/变量。

虽然某些汇编(MASM)的支持语法像mov ax,ballX,这使得它看起来ballX变量(如在高级语言),这是IMO只是混乱的谬论,因为该指令的真正本质是mov ax,[offset_of_some_address] ,并且ballX是地址,而不是值。

可能还有其他的错误,我没有做全面的代码审查,刚刚停止在我看到的第一个可疑的事情(在大约10秒钟)。


另一个快速捕获,在random您使用一些时间数据与每个随机数生成?不要那样做,那也是错误。使用时间滴答只计算一些初始的“种子”值,然后随机发生器将工作。将时间数据混入每次通话都会使其非随机。你RANDPRIME太小,只是谷歌的一些非常简单和快速(和不够好出于安全目的,但对于游戏会做的非常好)RNGR算法,经典的一个是几乎无处不在肯定描述。

1

只是一个快速浏览的说明如下:

timeticks程序不读取BIOS计时器在所有!
你已经设置了一切为了ES段寄存器,但mov ax, [timer]指令完全只依赖于DS段寄存器。

这破坏了你的rand_max延迟程序。
难怪它不工作

以另一种方式,以下将成为无限循环(因为timeticks最有可能总是返回相同的值!):

call timeticks 
    mov dx, ax 
Tick: 
    call timeticks 
    cmp dx, ax 
    je Tick 
相关问题