Sie sind auf Seite 1von 20

.model medium .stack 20 .

data currentValue dw 0 a equ 0b97dh c equ 137h memory db 25 dup(0) userin db 25 dup(0) startmin db 1 dup(0) startsec db 1 dup(0) stopsec db 1 dup(0) stopmin db 1 dup(0) timemin db 1 dup(0) timesec db 1 dup(0) skor db 1 dup(0) data01 data02 data03 data04 data05 data06 data07 data08 data09 data10 data11 data12 data13 data14 data15 data16 data17 data18 data19 data20 data21 data22 data23 data24 data25 data26 data27 data28 data29 data30 data31 data32 data33 data34 data35 data36 data37 data38 data39 data40 data41 data42 data43 db db db db db db db db db db db db db db db db db db db db db db db db db db db db db db db db db db db db db db db db db db db "car", '$' "can", '$' "tin", '$' "toe", '$' "fat", '$' "van", '$' "fan", '$' "eye", '$' "car", '$' "pot", '$' "keg", '$' "hot", '$' "red", '$' "tar", '$' "dot", '$' "damp", '$' "dumb", '$' "butt", '$' "read", '$' "lame", '$' "hall", '$' "pine", '$' "line", '$' "dove", '$' "spit", '$' "fire", '$' "hunt", '$' "slam", '$' "bomb", '$' "yard", '$' "width", '$' "sauce", '$' "youth", '$' "press", '$' "smoke", '$' "flame", '$' "video", '$' "audio", '$' "cable", '$' "power", '$' "level", '$' "prank", '$' "blaze", '$'

data44 data45 data46 data47 data48 data49 data50 data51 data52 data53 data54 data55 data56 data57 data58 data59 data60 data61 data62 data63 data64 data65 data66 data67 data68 data69 data70 data71 data72 data73 data74 data75

db db db db db db db db db db db db db db db db db db db db db db db db db db db db db db db db

"sound", '$' "speak", '$' "knight", '$' "hunter", '$' "squire", '$' "wizard", '$' "bottom", '$' "random", '$' "typing", '$' "maniac", '$' "fridge", '$' "access", '$' "laptop", '$' "portal", '$' "attack", '$' "sorbet", '$' "studio", '$' "windows", '$' "dungeon", '$' "moaning", '$' "adapter", '$' "records", '$' "cracker", '$' "capture", '$' "program", '$' "process", '$' "circuit", '$' "product", '$' "designs", '$' "gadgets", '$' "visions", '$' "healing", '$'

randmin dw 1 randmax dw 15 same db 0 .code ;MACRO beep macro freq push ax push dx push bx speakeron mov al, 182 out 43h, al mov dx, 12h mov ax, 34dch mov bx, freq div bx out 42h, al mov al, ah out 42h, al pop bx pop dx pop ax

endm ; turn on speaker speakeron macro in al, 61h or al, 03h out 61h, al endm ; turn off speaker speakeroff macro in al, 61h and al, 0fch out 61h, al endm delay macro ms ;untuk buat waktu selama 2s push ax push cx push dx mov dx, 00h mov ax, 03e8h mov cx, ms mul cx mov cx, dx mov dx, ax mov ah, 86h int 15h pop dx pop cx pop ax endm putc macro char push ax mov al, char mov ah, 0eh int 10h pop ax endm write macro string local next, message, finished, skipdcl push ax push si jmp skipdcl message db string, 0 skipdcl: lea si, message next: mov al, cs:[si] cmp al, 00h jz finished inc si mov ah, 0eh int 10h jmp next

finished: pop si pop ax endm writeln macro string local next, message, finished, skipdcl push ax push si jmp skipdcl message db string, 13, 10, 0 skipdcl: lea si, message next: mov al, cs:[si] cmp al, 00h jz finished inc si mov ah, 0eh int 10h jmp next finished: pop si pop ax endm linefeed macro push ax mov al, 0dh mov ah, 0eh int 10h mov al, 0ah int 10h pop ax endm writeA macro MessageAddress local writeloop push ax push dx push ds push si mov ax, seg MessageAddress mov ds, ax lea si, MessageAddress mov ah, 02h mov dl, [si] writeloop: int 21h inc si mov dl, [si] cmp dl, 0h

jne writeloop pop pop pop pop endm writelnA macro MessageAddress writeA MessageAddress push ax push dx mov ah, 02h mov dl, 0ah int 21h mov dl, 0dh int 21h pop dx pop ax endm clrscr macro push ax mov ax, 03h int 10h pop ax endm waitForEnter macro local readnext push ax mov ah, 07h readnext: int 21h cmp al, 0dh jne readnext pop ax endm si ds dx ax

;read from stdin without echo

printInt macro val local not_zero, printed, positive push dx push ax push cx mov cmp jnz putc jmp ax, val ax, 0 not_zero '0' printed

not_zero: ; the check SIGN of AX, ; make absolute if it's negative: cmp ax, 0 jns positive ; jump if no sign (=positive) neg ax putc '-' positive:

printUInt ax printed: pop cx pop ax pop dx endm printUInt macro val local begin_print, end_print, skip, calc, print_zero push ax push bx push cx push dx mov ax, val ; flag to prevent printing zeros before number: mov cx, 1 mov ; (result of "/ 10000" is always less or equal to 9). bx, 10000 ; 2710h - divider.

; AX is zero? cmp ax, 0 jz print_zero begin_print: ; check divider (if zero go to end_print): cmp bx, 0 jz end_print ; avoid printing zeros before number: cmp cx, 0 je calc ; if AX<BX then result of DIV will be zero: cmp ax, bx jb skip calc: mov cx, 0 mov div dx, 0 bx ; set flag. ; AX = DX:AX / BX (DX=remainder).

; print last digit ; AH is always ZERO, so it's ignored add al, 30h ; convert to ASCII code. putc al mov ax, dx ; get remainder from last div. skip: ; calculate BX=BX/10 push ax mov dx, 0 mov ax, bx push cx mov cx, 10 div cx ; AX = DX:AX / 10 pop cx mov bx, ax

(DX=remainder).

pop jmp

ax begin_print

print_zero: putc '0' end_print: pop dx pop pop pop endm ; result in cx readInt macro local make_minus, next_digit, not_cr, ok_digit local backspace_checked, remove_not_digit, ok_AE_0 local too_big, too_big2, set_minus, stop_input, not_minus local cancel_minus, cancel_backspace, remove_minus local cancel_zero, is_zero, count, examine make_minus push push push push mov mov mov db 0 ; used as a flag.

cx bx ax

bx dx ax si cx, 0 bx, 0 make_minus, 0

next_digit: ; get char from keyboard ; into AL: mov ah, 00h int 16h ; and print it: mov ah, 0Eh int 10h ; check for MINUS: cmp al, '-' je set_minus ; check for ENTER key: cmp al, 0Dh ; carriage return? jne not_cr jmp stop_input set_minus: cmp bx, 0 ja cancel_minus mov cs:make_minus, 1 inc bx jmp next_digit cancel_minus: putc 8 putc ' ' putc 8

; clear position. ; backspace.

jmp

next_digit

not_cr: cmp al, 8 ; 'BACKSPACE' pressed? jne backspace_checked cmp bx, 0 jz cancel_backspace ; cancel backspace mov dx, 0 ; remove last digit by mov ax, cx ; division: push bx mov bx, 10 div bx ; AX = DX:AX / 10 (DX-rem). pop bx mov cx, ax putc ' ' ; clear position. putc 8 ; backspace again. dec bx cmp bx, 0 je remove_minus jmp next_digit remove_minus: mov cs:make_minus, 0 jmp next_digit cancel_backspace: mov al, 20h mov ah, 0Eh int 10h jmp next_digit backspace_checked: ; allow only digits: cmp al, '0' jae ok_ae_0 jmp remove_not_digit ok_ae_0: cmp al, '9' jbe ok_digit remove_not_digit: putc 8 ; backspace. putc ' ' ; clear last entered not digit. putc 8 ; backspace again. jmp next_digit ; wait for next input. examine: cmp jnz jmp is_zero: cmp je cmp je jmp cancel_zero: bx, 0 cancel_zero bx, 1 examine count cs:make_minus, 0 cancel_zero count

putc putc ' ' putc 8 jmp ok_digit: cmp je count: inc ; multiply cx push ax mov ax, cx push mov mul bx pop mov cx, ax pop ax

8 ; backspace. ; clear last entered digit. ; backspace again. next_digit al, '0' is_zero bx by 10 (first time the result is zero) bx bx, 10 ; dx:ax = ax*10 bx

; check if the number is too big ; (result should be 16 bits) cmp dx, 0 jne too_big ; convert from ascii code: sub al, 30h ; add mov mov add jc jmp al to cx: ah, 0 dx, cx cx, ax too_big2 next_digit ; restore the backuped value before add. ; dx was zero before backup!

; backup, in case the result will be too big. ; jump if the number is too big.

too_big2: mov cx, dx mov dx, 0

too_big: mov ax, cx push bx mov bx, 10 div bx ; reverse last dx:ax = ax*10, make ax = dx:ax / 10 pop bx mov cx, ax putc 8 ; backspace. putc ' ' ; clear last entered digit. putc 8 ; backspace again. dec bx jmp next_digit ; wait for enter/backspace. stop_input: ; check flag: cmp cs:make_minus, 0 je not_minus neg cx

not_minus: linefeed pop si pop ax pop dx pop bx endm ; result in cx readUInt macro local next_digit, not_cr, ok_digit local backspace_checked, remove_not_digit, ok_AE_0 local too_big, too_big2, stop_input local cancel_backspace local cancel_zero, is_zero, count push push push push mov mov bx dx ax si cx, 0 bx, 0

next_digit: ; get char from keyboard ; into AL: mov ah, 00h int 16h ; and print it: mov ah, 0Eh int 10h ; check for ENTER key: cmp al, 0Dh ; carriage return? jne not_cr jmp stop_input not_cr: cmp al, 8 ; 'BACKSPACE' pressed? jne backspace_checked cmp bx, 0 jz cancel_backspace ; cancel backspace mov dx, 0 ; remove last digit by mov ax, cx ; division: push bx mov bx, 10 div bx ; AX = DX:AX / 10 (DX-rem). pop bx mov cx, ax putc ' ' ; clear position. putc 8 ; backspace again. dec bx jmp next_digit cancel_backspace: mov al, 20h mov ah, 0Eh int 10h jmp next_digit

backspace_checked: ; allow only digits: cmp al, '0' jae ok_ae_0 jmp remove_not_digit ok_ae_0: cmp al, '9' jbe ok_digit remove_not_digit: putc 8 ; backspace. putc ' ' ; clear last entered not digit. putc 8 ; backspace again. jmp next_digit ; wait for next input. is_zero: cmp je jmp cancel_zero: putc putc ' ' putc 8 jmp ok_digit: cmp je count: inc ; multiply cx push ax mov ax, cx push mov mul bx pop mov cx, ax pop ax bx by 10 (first time the result is zero) bx bx, 10 ; dx:ax = ax*10 bx bx, 0 cancel_zero count 8 ; backspace. ; clear last entered digit. ; backspace again. next_digit al, '0' is_zero

; check if the number is too big ; (result should be 16 bits) cmp dx, 0 jne too_big ; convert from ascii code: sub al, 30h ; add mov mov add jc jmp al to cx: ah, 0 dx, cx cx, ax too_big2 next_digit

; backup, in case the result will be too big. ; jump if the number is too big.

too_big2:

mov mov

cx, dx dx, 0

; restore the backuped value before add. ; dx was zero before backup!

too_big: mov ax, cx push bx mov bx, 10 div bx ; reverse last dx:ax = ax*10, make ax = dx:ax / 10 pop bx mov cx, ax putc 8 ; backspace. putc ' ' ; clear last entered digit. putc 8 ; backspace again. dec bx jmp next_digit ; wait for enter/backspace. stop_input: linefeed pop si pop ax pop dx pop bx endm ;return in dx nextRandom macro min, max call rand push ax push bx push cx mov ax, currentValue mov bx, max sub bx, min inc bx xor dx, dx div bx add dx, min pop cx pop bx pop ax endm readline macro inputBuffer push ax push ds push bx push cx mov ax, seg inputBuffer mov ds, ax lea dx, inputBuffer mov bx, 0h ;stdin mov ah, 3fh ;readline mov cx, 50 ;buffer length int 21h pop cx pop bx pop ds pop ax endm

;END-MACRO ;PROCEDURE rand proc near push ax push bx push cx push mov push bp bp, sp bx mov ax, currentValue mov cx, a mov bx, c mul add mov ror s. pop pop bx bp pop cx pop bx pop ax cx ax, bx currentValue, ax ax, 2 ; set base pointer to stack pointer ;initialize with previous value ; We will be using the formula: ; bx*ax + bx and for mod we will just ;ignore the value in dx.

;Using rotate to mask hifrequency pattern

ret rand endp randomize proc near push ax push cx mov ah, 2ch int 21h mov byte ptr currentValue, dl pop cx pop ax call rand ret randomize endp ;ENDPROCEDURE .startup clrscr writeln "Typing Maniac" writeln "--------------------------------" writeln "press any key to start" linefeed push ax push cx push dx mov ah,01h int 21h mov ah,02ch int 21h mov al,0h mov skor,al mov startmin,cl mov startsec,dh

;get system clock ;get seconds

pop ax pop cx pop dx char3: ;3 characters word call randomize nextRandom 01h, 0fh ; get random data based on data 1 mov si, offset data01 push ax push cx mov ah, 0 mov al, dl sub al, 1h mov cl, 4h ; string length 4byte mul cl add si, ax ; save to memory mov di, offset memory save3: mov al, [si] mov [di], al cmp al, '$' je printstr3 inc si inc di jmp save3 printstr3: clrscr ; print string mov dx, offset memory mov ah, 09h int 21h linefeed pop cx pop ax ; readline input from user readline userin ; check score mov si, offset memory mov di, offset userin mov cx,3h ; 3 char length check3: mov bh, [si] mov bl, [di] cmp bh, bl je next3 beep 0440h delay 064h speakeroff jmp char3 next3: inc si inc di loop check3 mov al,skor

inc al mov skor,al mov al,skor mov ah,05h cmp al,ah jne ulang3 jmp gaulang3 ulang3: jmp char3 gaulang3: char4: ;4 characters word call randomize nextRandom 01h, 0fh ; get random data based on data 16 mov si, offset data16 push ax push cx mov ah, 0h mov al, dl sub al, 1h mov cl, 5h ; string length 5byte mul cl add si, ax ; save to memory mov di, offset memory save4: mov al, [si] mov [di], al cmp al, '$' je printstr4 inc si inc di jmp save4 printstr4: clrscr ; print string mov dx, offset memory mov ah, 09h int 21h linefeed pop cx pop ax ; readline input from user readline userin ; check score mov si, offset memory mov di, offset userin mov cx,4h ; 4 char length check4: mov bh, [si] mov bl, [di] cmp bh, bl je next4 beep 0440h delay 064h

speakeroff jmp char4 next4: inc si inc di loop check4 mov al,skor inc al mov skor,al mov al,skor mov ah,0ah cmp al,ah jne ulang4 jmp gaulang4 ulang4: jmp char4 gaulang4: char5: ;4 characters word call randomize nextRandom 01h, 0fh ; get random data based on data 1 mov si, offset data31 push ax push cx mov ah, 0 mov al, dl sub al, 1h mov cl, 6h ; string length 5byte mul cl add si, ax ; save to memory mov di, offset memory save5: mov al, [si] mov [di], al cmp al, '$' je printstr5 inc si inc di jmp save5 printstr5: clrscr ; print string mov dx, offset memory mov ah, 09h int 21h linefeed pop cx pop ax ; readline input from user readline userin ; check score mov si, offset memory mov di, offset userin mov cx,5h ; 5 char length

check5: mov bh, [si] mov bl, [di] cmp bh, bl je next5 beep 0440h delay 064h speakeroff jmp char5 next5: inc si inc di loop check5 mov al,skor inc al mov skor,al mov al,skor mov ah,0fh cmp al,ah jne ulang5 jmp gaulang5 ulang5: jmp char5 gaulang5: char6: ;6 characters word call randomize nextRandom 01h, 0fh ; get random data based on data 1 mov si, offset data46 push ax push cx mov ah, 0 mov al, dl sub al, 1h mov cl, 7h ; string length 5byte mul cl add si, ax ; save to memory mov di, offset memory save6: mov al, [si] mov [di], al cmp al, '$' je printstr6 inc si inc di jmp save6 printstr6: clrscr ; print string mov dx, offset memory mov ah, 09h int 21h linefeed pop cx pop ax

; readline input from user readline userin ; check score mov si, offset memory mov di, offset userin mov cx,6h ; 6 char length check6: mov bh, [si] mov bl, [di] cmp bh, bl je next6 beep 0440h delay 064h speakeroff jmp char6 next6: inc si inc di loop check6 mov al,skor inc al mov skor,al mov al,skor mov ah,014h cmp al,ah jne ulang6 jmp gaulang6 ulang6: jmp char6 gaulang6: char7: ;4 characters word call randomize nextRandom 01h, 0fh ; get random data based on data 1 mov si, offset data61 push ax push cx mov ah, 0 mov al, dl sub al, 1h mov cl, 8h ; string length 5byte mul cl add si, ax ; save to memory mov di, offset memory save7: mov al, [si] mov [di], al cmp al, '$' je printstr7 inc si inc di jmp save7 printstr7: clrscr ; print string

mov dx, offset memory mov ah, 09h int 21h linefeed pop cx pop ax ; readline input from user readline userin ; check score mov si, offset memory mov di, offset userin mov cx,7h ; 7 char length check7: mov bh, [si] mov bl, [di] cmp bh, bl je next7 beep 0440h delay 064h speakeroff jmp char7 next7: inc si inc di loop check7 mov al,skor inc al mov skor,al mov al,skor mov ah,019h cmp al,ah jne ulang7 jmp gaulang7 ulang7: jmp char7 gaulang7: mov ah,02ch int 21h mov stopmin,cl mov stopsec,dh clrscr writeln "your time: " mov al,stopmin mov ah,startmin cmp al,ah je seccond jmp minute seccond: mov al,stopsec mov ah,startsec sub al,ah mov timesec,al mov ah,0h printint ax jmp finish minute: sub al,ah

dec al mov ah,03ch mul ah mov timemin,al mov ah,startsec mov al,03ch sub al,ah mov ah,al mov al,stopsec add al,ah mov timesec,al mov ah,timemin add al,ah mov ah,0h printint ax finish: writeln " sec" .exit end