hello-dosdl/dosdl.asm

1124 lines
17 KiB
NASM
Raw Permalink Normal View History

2022-02-23 00:31:52 +00:00
bits 16
cpu 8086
2022-02-22 22:38:06 +00:00
org 0x100
2022-02-24 22:04:10 +00:00
args_length equ 0x80
args_area equ 0x81
2022-02-23 00:31:52 +00:00
section .code
2022-02-24 22:04:10 +00:00
parse_arguments:
xor ch, ch
mov cl, [args_length]
2022-02-24 23:05:50 +00:00
mov si, args_area
; Skip leading spaces
.skip_leading_space:
test cx, cx
jz .leading_spaces_skipped
cmp byte [si], ' '
jne .leading_spaces_skipped
dec cx
inc si
jmp .skip_leading_space
.leading_spaces_skipped:
2022-02-25 00:05:00 +00:00
; See whether we have /h, /u, /l, or /?
2022-02-24 23:05:50 +00:00
cmp cx, 2
jb .not_mode_option
cmp byte [si], '/'
jne .not_mode_option
cmp byte [si + 1], 'h'
2022-02-25 00:19:44 +00:00
je .hard_mode
cmp byte [si + 1], 'H'
2022-02-24 23:05:50 +00:00
jne .not_hard_mode
.hard_mode:
mov byte [hard_mode], 1
add si, 2
sub cx, 2
jmp .after_option_space
.not_hard_mode:
cmp byte [si + 1], 'u'
2022-02-25 00:19:44 +00:00
je .ultra_hard_mode
cmp byte [si + 1], 'U'
2022-02-24 23:05:50 +00:00
jne .not_ultra_hard_mode
.ultra_hard_mode:
mov byte [hard_mode], 1
mov byte [ultra_hard_mode], 1
add si, 2
sub cx, 2
.after_option_space:
test cx, cx
jz .option_done
cmp byte [si], ' '
jne .option_done
dec cx
inc si
jmp .after_option_space
.option_done:
.not_ultra_hard_mode:
2022-02-25 00:05:00 +00:00
cmp byte [si + 1], 'l'
je print_license
2022-02-25 00:19:44 +00:00
cmp byte [si + 1], 'L'
je print_license
2022-02-25 00:05:00 +00:00
cmp byte [si + 2], '?'
je print_help
2022-02-24 23:05:50 +00:00
.not_mode_option:
2022-02-24 22:04:10 +00:00
test cx, cx
jz seed_rng_date
2022-02-25 00:19:12 +00:00
seed_rng_argument:
xor ax, ax
xor dx, dx
mov bp, mull32
call store32
.loop:
xor dx, dx
mov ax, 10
mov bp, mulr32
call store32
call mul32
mov bp, addl32
call store32
lodsb
cmp al, '0'
jb print_help
cmp al, '9'
ja print_help
sub al, '0'
xor ah, ah
xor dx, dx
mov bp, addr32
call store32
call add32
mov bp, mull32
call store32
loop .loop
mov bp, rng_seed
call store32
jmp select_target
2022-02-24 22:04:10 +00:00
print_help:
mov ah, 9
mov dx, help_str
int 0x21
ret
2022-02-25 00:05:00 +00:00
print_license:
mov ah, 9
mov dx, license_str
int 0x21
ret
2022-02-24 19:33:35 +00:00
seed_rng_date:
; Get date
mov ah, 0x2a
int 0x21
mov [year], cx
mov [month], dh
2022-02-24 23:15:35 +00:00
%ifdef DEBUG
mov cx, 2022
mov dh, 2
mov dl, 24
%endif
2022-02-24 19:33:35 +00:00
mov [day], dl
; addl32 = year * 10000
mov ax, 10000
mul word [year]
mov bp, addl32
call store32
2022-02-24 19:14:37 +00:00
2022-02-24 19:33:35 +00:00
; addr32 = month * 100 + day
mov ax, 100
mul word [month]
add ax, [day]
mov bp, addr32
call store32
; rng_seed = addl32 + addr32 = year * 10000 + month * 100 + day
call add32
mov bp, rng_seed
call store32
2022-02-24 19:14:37 +00:00
2022-02-23 00:31:52 +00:00
select_target:
2022-02-24 19:14:37 +00:00
; Call rng to get a number
call rng
mov bp, rng_output
call store32
2022-02-24 19:19:02 +00:00
; Multiply rng output by number of target words
2022-02-24 19:14:37 +00:00
xor si, si
xor dx, dx
xor ax, ax
mov cx, targets_len
.multiply_loop:
add ax, [rng_output + 0]
adc dx, [rng_output + 2]
adc si, 0
loop .multiply_loop
mov ax, si
2022-02-24 19:19:02 +00:00
%ifdef DEBUG
2022-02-24 19:14:37 +00:00
call hexprint16
call newline
2022-02-24 19:19:02 +00:00
%endif
2022-02-23 00:31:52 +00:00
2022-02-24 19:14:37 +00:00
load_target:
2022-02-23 00:31:52 +00:00
shl si, 1
shl si, 1
add si, targets
mov di, target
call unpack_target
2022-02-23 00:31:52 +00:00
2022-02-24 19:14:37 +00:00
; Figure out whether this is a removed word
; If so, reroll target word
cmp byte [target], '{'
je select_target
2022-02-24 22:04:10 +00:00
print_greeting:
mov ah, 9
mov dx, greeting_str
int 0x21
2022-02-23 00:31:52 +00:00
read_guess:
; Number of thus far guessed letters stored in bx
xor bx, bx
.loop:
mov ah, 8
int 0x21
2022-02-24 23:42:51 +00:00
cmp al, 3
je .ctrl_c
2022-02-23 00:31:52 +00:00
cmp al, 8
je .backspace
cmp bx, 5
je .full
cmp al, 'A'
jb .loop
cmp al, 'Z'
jbe .letter
cmp al, 'a'
jb .loop
cmp al, 'z'
jbe .letter
jmp .loop
.full:
cmp al, 13
je .done
jmp .loop
.letter:
; Lowercase
or al, 32
mov byte [guess + bx], al
inc bx
; Echo to screen
mov dl, al
mov ah, 2
int 0x21
jmp .loop
.backspace:
test bx, bx
jz .loop
; Rub out the letter
; PC-DOS 1.1 documentation says only 8 is needed, but DOSBox
; seems buggy here
mov ah, 2
mov dl, 8
int 0x21
mov dl, ' '
int 0x21
mov dl, 8
int 0x21
dec bx
jmp .loop
2022-02-24 23:42:51 +00:00
.ctrl_c:
ret
2022-02-23 00:31:52 +00:00
.done:
2022-02-24 23:15:35 +00:00
check_hard_mode:
cmp byte [hard_mode], 1
jne .done
; See whether exact hits are reused
xor bp, bp
mov cx, 5
.exact_hits:
mov al, [exact_hits + bp]
test al, al
jz .not_exact_hit
cmp al, [guess + bp]
je .exact_hit_match
mov dx, bp
add dl, '1'
mov [exact_hit_error_str.position], dl
mov [exact_hit_error_str.letter], al
mov si, exact_hit_error_str
jmp print_error
.exact_hit_match:
.not_exact_hit:
inc bp
loop .exact_hits
; See whether wrongly placed letters are reused
xor bp, bp
.wrong_places:
cmp bp, 5
je .done
mov dl, [wrong_places + bp]
test dl, dl
jz .not_wrong_place
; Count how many times letter is used in exact_hits + wrong_places
xor bx, bx
mov cx, 5
mov si, exact_hits
.count_exact_hits:
lodsb
cmp al, dl
jne .not_count_exact_hit
inc bh
.not_count_exact_hit:
loop .count_exact_hits
mov cx, 5
mov si, wrong_places
.count_wrong_places:
lodsb
cmp al, dl
jne .not_count_wrong_places
inc bh
.not_count_wrong_places:
loop .count_wrong_places
; Count how many times letter is used in guess
mov cx, 5
mov si, guess
.count_guess:
lodsb
cmp al, dl
jne .not_count_guess
inc bl
.not_count_guess:
loop .count_guess
cmp bl, bh
jae .used_enough
mov [wrong_place_error_str.letter], dl
mov ax, bp
add ax, '1'
mov [wrong_place_error_str.position], al
mov si, wrong_place_error_str
jmp print_error
.used_enough:
.not_wrong_place:
inc bp
jmp .wrong_places
.done:
check_ultra_hard_mode:
cmp byte [ultra_hard_mode], 1
jne .done
2022-02-24 23:40:59 +00:00
; See whether any ruled-out letters were used
xor bp, bp
mov cx, 5
.ruled_out:
xor bh, bh
mov bl, [guess + bp]
mov ax, bx
mov al, [alphabet + bx - 'a']
cmp al, ' '
jne .not_ruled_out
mov [ruled_out_error_str.letter], bl
mov ax, bp
add al, '1'
mov [ruled_out_error_str.position], al
mov si, ruled_out_error_str
jmp print_error
.not_ruled_out:
inc bp
loop .ruled_out
; See whether wrongly places letters were moved
xor bp, bp
mov cx, 5
.wrong_places:
mov al, [wrong_places + bp]
test al, al
jz .not_wrong_place
cmp al, [guess + bp]
jne .moved
mov [not_moved_error_str.letter], al
mov ax, bp
add ax, '1'
mov [not_moved_error_str.position], al
mov si, not_moved_error_str
jmp print_error
.moved:
.not_wrong_place:
inc bp
loop .wrong_places
2022-02-24 23:15:35 +00:00
.done:
2022-02-23 01:00:03 +00:00
check_dictionary:
; Dictionary is split by initial letter
xor bx, bx
mov bl, [guess]
sub bl, 'a'
; Entry in the table is 4 bytes
shl bx, 1
shl bx, 1
mov si, [dictionaries + bx] ; Start address
mov cx, [dictionaries + bx + 2] ; Number of letters
.dictionary_loop:
push cx
mov di, dictionary_entry
; Entry is stored 5 bits per letter (first letter is implicit)
; 3332_2222 5444_4433 0000_5555
; Load 5444_4433_3332_2222 into dx and extract 3 first letters
mov dx, [si]
add si, 2
mov cl, 5
%rep 3
mov al, dl
and al, 0x1f
add al, 'a'
stosb
shr dx, cl
%endrep
; Load 0000_5555 into al, shift one over, or with dl which has
; 0000_0005
mov al, [si]
inc si
shl al, 1
or al, dl
add al, 'a'
stosb
sub di, 4
mov bp, 1
mov cx, 4
.compare_loop:
mov al, [di]
inc di
cmp al, [guess + bp]
jne .not_match
inc bp
loop .compare_loop
pop cx
jmp word_found
.not_match:
pop cx
loop .dictionary_loop
check_targets:
mov cx, targets_len
mov si, targets
.targets_loop:
mov di, dictionary_entry
call unpack_target
xor bp, bp
.compare_loop:
cmp bp, 5
je .match
mov al, [di + bp]
cmp al, [guess + bp]
jne .not_match
inc bp
jmp .compare_loop
.match:
jmp word_found
.not_match:
loop .targets_loop
2022-02-23 01:00:03 +00:00
word_not_found:
2022-02-24 23:05:50 +00:00
mov si, not_found_str
print_error:
2022-02-23 01:00:03 +00:00
mov ah, 9
2022-02-24 23:05:50 +00:00
mov dx, si
2022-02-23 01:00:03 +00:00
int 0x21
; Wait for a keypress
mov ah, 8
int 0x21
; Clear line
mov ah, 2
mov dl, 13
int 0x21
mov ah, 9
mov dx, erase_word_str
int 0x21
.clear_loop:
lodsb
cmp al, '$'
je .done
mov ah, 2
mov dl, ' '
int 0x21
jmp .clear_loop
2022-02-24 23:05:50 +00:00
.done:
2022-02-23 01:00:03 +00:00
mov ah, 2
mov dl, 13
int 0x21
jmp read_guess
word_found:
2022-02-23 00:31:52 +00:00
find_exact_hits:
mov si, guess
mov di, exact_hits
mov cx, 5
.loop:
lodsb
cmp al, [si - guess + target - 1]
je .hit
; Zero out if not the right letter
xor al, al
.hit:
stosb
loop .loop
find_wrong_places:
; Zero out first
mov cx, 5
xor al, al
rep stosb
xor bp, bp
.loop:
cmp bp, 5
je .done
mov al, [exact_hits + bp]
inc bp
test al, al
jnz .loop
; What was the guessed letter?
mov dl, [guess + bp - 1]
; How many times does it appear in the target?
xor bh, bh
mov cx, 5
mov si, target
.count_target:
lodsb
cmp al, dl
jne .not_found_in_target
inc bh
.not_found_in_target:
loop .count_target
; How many times does it appear in the feedback already?
xor bl, bl
mov cx, 5
mov si, exact_hits
.count_exact_hits:
lodsb
cmp al, dl
jne .not_found_in_exact_hits
inc bl
.not_found_in_exact_hits:
loop .count_exact_hits
mov cx, 5
mov si, wrong_places
.count_wrong_places:
lodsb
cmp al, dl
jne .not_found_in_wrong_places
inc bl
.not_found_in_wrong_places:
loop .count_wrong_places
; If not used in target at all, remove from list of possible letters
test bh, bh
jnz .used_in_target
xor dh, dh
mov di, dx
mov byte [alphabet + di - 'a'], ' '
.used_in_target:
2022-02-23 00:31:52 +00:00
; If in target more than in feedback → wrong place
cmp bh, bl ; target <= feedback
jbe .loop
mov byte [wrong_places + bp - 1], dl
jmp .loop
.done:
print_feedback:
call newline
mov cx, 5
xor bp, bp
xor bx, bx ; How many exact hits?
.loop:
mov al, [exact_hits + bp]
test al, al
jnz .exact_hit
mov al, [wrong_places + bp]
test al, al
jnz .wrong_place
mov dl, 'x'
jmp .print
.exact_hit:
mov dl, ' '
inc bx
jmp .print
.wrong_place:
mov dl, '^'
.print:
mov ah, 2
int 0x21
inc bp
loop .loop
mov ah, 9
mov dx, space_dash_space_str
int 0x21
mov cx, 26
mov si, alphabet
.alphabet_loop:
lodsb
mov dl, al
mov ah, 2
int 0x21
loop .alphabet_loop
2022-02-23 00:31:52 +00:00
call newline
is_finished:
inc byte [guesses]
cmp bx, 5
je victory
cmp byte [guesses], 6
je loss
jmp read_guess
loss:
mov dx, word_was_str
mov ah, 9
int 0x21
mov cx, 5
mov si, target
.loop:
lodsb
mov dl, al
mov ah, 2
int 0x21
loop .loop
jmp exit
victory:
mov dx, correct_in_str
mov ah, 9
int 0x21
mov dl, [guesses]
add dl, '0'
mov ah, 2
int 0x21
2022-02-24 19:38:54 +00:00
cmp byte [guesses], 1
je .singular
.plural:
mov dx, guesses_str
jmp .print
.singular:
mov dx, guess_str
.print:
mov ah, 9
int 0x21
2022-02-23 00:31:52 +00:00
exit:
ret
newline:
push ax
push dx
mov ah, 2
mov dl, 13
int 0x21
mov dl, 10
int 0x21
pop dx
pop ax
ret
; in:
; si = packed target word
; di = 5 byte buffer for unpacking the target
; out:
; si = first byte after the packed target word
unpack_target:
push ax
push cx
push dx
push di
; Target word is stored packed 5 bits per letter into 32 bits
; 2221_1111 4333_3322 5555_4444 0000_0005
; Load 4333_3322_2221_1111 into dx and extracts first three letters
mov dx, [si]
add si, 2
mov cl, 5
%rep 3
mov al, dl
and al, 0x1f
add al, 'a'
stosb
shr dx, cl
%endrep
; Load 0000_0005_5555_4444 into ax, shift over by one, combine into dx
; which has 0000_0000_0000_0004, and extract last two letters
mov ax, [si]
add si, 2
shl ax, 1
or dx, ax
%rep 2
mov al, dl
and al, 0x1f
add al, 'a'
stosb
shr dx, cl
%endrep
pop di
pop dx
pop cx
pop ax
ret
2022-02-24 19:14:37 +00:00
; out:
; dx:ax = result
rng:
; https://github.com/lynn/hello-wordl/blob/7da40c1f067eb1ec157d4c5b7a9bd8257ed39342/src/util.ts#L14
; rng_t = rng_seed += rng_seed + 0x6d2b79f5
mov bp, rng_seed
call load32
add ax, 0x79f5
adc dx, 0x6d2b
call store32
mov bp, rng_t
call store32
; xorl32 = rng_t
mov bp, xorl32
call store32
; xorr32 = rng_t >> 15
mov cx, 15
call rshift32
mov bp, xorr32
call store32
; mull32 = xorl32 ^ xorr32 = rng_t ^ (rng_t >> 15)
call xor32
mov bp, mull32
call store32
; mulr32 = rng_t | 1
mov bp, rng_t
call load32
or ax, 1
mov bp, mulr32
call store32
; rng_t = mull32 * mulr32 = (rng_t ^ (rng_t >> 15)) * (rng_t | 1)
call mul32
mov bp, rng_t
call store32
; xorl32 = rng_t
mov bp, xorl32
call store32
; xorr32 = rng_t >> 7
mov cx, 7
call rshift32
mov bp, xorr32
call store32
; mull32 = xorl32 ^ xorr32 = rng_t ^ (rng_t >> 7)
call xor32
mov bp, mull32
call store32
; mulr32 = rng_t | 61
mov bp, rng_t
call load32
or ax, 61
mov bp, mulr32
call store32
; addl32 = rng_t
mov bp, rng_t
call load32
mov bp, addl32
call store32
; addr32 = mull32 * mulr32 = (rng_t ^ (rng_t >> 7)) * (rng_t | 61)
call mul32
mov bp, addr32
call store32
; xorl32 = rng_t
mov bp, rng_t
call load32
mov bp, xorl32
call store32
; xorr32 = addl32 + addr32 = rng_t + (rng_t ^ (rng_t >> 7)) * (rng_t | 61)
call add32
mov bp, xorr32
call store32
; rng_t = xorl32 ^ xorr32 = rng_t ^ (rng_t + (rng_t ^ (rng_t >> 7)) * (rng_t | 61))
call xor32
mov bp, rng_t
call store32
; xorl32 = rng_t
mov bp, xorl32
call store32
; xorr32 = rng_t >> 14
mov cx, 14
call rshift32
mov bp, xorr32
call store32
; result = xorl32 ^ xorr32 = rng_t ^ (rng_t >> 14)
call xor32
ret
; in:
; bp = address of uint32
; out:
; dx = high 16 bits
; ax = low 16 bits
load32:
mov ax, [bp + 0]
mov dx, [bp + 2]
ret
; in:
; bp = address of uint32
; dx = high 16 bits
; ax = low 16 bits
store32:
mov [bp + 0], ax
mov [bp + 2], dx
ret
; in:
; dx:ax = uint32 to be shifted
; cx = shift amount (must not be 0)
; out:
; dx:ax = result
rshift32:
push cx
.loop:
shr dx, 1
rcr ax, 1
loop .loop
pop cx
ret
; in:
; [xorl32], [xorr32] = operands
; out:
; dx:ax = result
xor32:
mov ax, [xorl32 + 0]
xor ax, [xorr32 + 0]
mov dx, [xorl32 + 2]
xor dx, [xorr32 + 2]
ret
; in:
; [mull32], [mulr32] = operands
; out:
; dx:ax = result
mul32:
push bx
push cx
; c = 1<<16
; l = l₁<<16 + l₀
; r = r₁<<16 + r₀
; l·r = (l₁<<16 + l₀)·(r₁<<16 + r₀)
; = l₁<<16·r₁<<16 + l₁<<16·r₀ + l₀·r₁<<16 + l₀·r₀
; = l₁·r₁<<32 + l₁·r₀<<16 + l₀·r₁<<16 + l₀·r₀ ||1<<32 = 0 (mod 1<<32)
; = l₁·r₀<<16 + l₀·r₁<<16 + l₀·r₀
; l₀·r₀
mov ax, [mull32 + 0]
mul word [mulr32 + 0]
mov bx, ax
mov cx, dx
; l₀·r₁<<16
mov ax, [mull32 + 0]
mul word [mulr32 + 2]
add cx, ax
; l₁·r₀<<16
mov ax, [mull32 + 2]
mul word [mulr32 + 0]
add cx, ax
mov dx, cx
mov ax, bx
pop cx
pop bx
ret
; in:
; [addl32], [addr32] = operands
; out:
; dx:ax = result
add32:
mov ax, [addl32 + 0]
mov dx, [addl32 + 2]
add ax, [addr32 + 0]
adc dx, [addr32 + 2]
ret
2022-02-24 19:19:02 +00:00
%ifdef DEBUG
hexprint32:
xchg ax, dx
call hexprint16
xchg ax, dx
hexprint16:
xchg ah, al
call hexprint8
xchg ah, al
hexprint8:
2022-02-24 19:14:37 +00:00
%rep 4
2022-02-24 19:19:02 +00:00
rol al, 1
2022-02-24 19:14:37 +00:00
%endrep
2022-02-24 19:19:02 +00:00
call hexprint4
2022-02-24 19:14:37 +00:00
%rep 4
2022-02-24 19:19:02 +00:00
rol al, 1
2022-02-24 19:14:37 +00:00
%endrep
2022-02-24 19:19:02 +00:00
hexprint4:
push ax
and al, 0xf
cmp al, 10
jb .digit09
add al, 'a' - 10 - '0'
.digit09:
add al, '0'
mov ah, 0xe
int 0x10
pop ax
ret
%endif
2022-02-24 19:14:37 +00:00
2022-02-23 00:31:52 +00:00
section .data
alphabet db 'abcdefghijklmnopqrstuvwxyz'
2022-02-23 00:31:52 +00:00
target times 5 db 0
guess times 5 db 0
2022-02-23 01:00:03 +00:00
2022-02-23 00:31:52 +00:00
exact_hits times 5 db 0
wrong_places times 5 db 0
2022-02-23 01:00:03 +00:00
2022-02-23 00:31:52 +00:00
guesses db 0
dictionary_entry times 5 db 0
2022-02-23 01:00:03 +00:00
2022-02-24 23:05:50 +00:00
hard_mode db 0
ultra_hard_mode db 0
2022-02-24 19:14:37 +00:00
rng_seed dd 0
rng_t dd 0
rng_output dd 0
xorl32 dd 0
xorr32 dd 0
mull32 dd 0
mulr32 dd 0
addl32 dd 0
addr32 dd 0
2022-02-24 19:33:35 +00:00
year dw 0
month dw 0
2022-02-24 23:15:35 +00:00
day dw 0
exact_hit_error_str:
db ' - letter at position '
.position db '#'
db " must be '"
.letter db '#'
db "'$"
2022-02-24 23:40:59 +00:00
2022-02-24 23:15:35 +00:00
wrong_place_error_str:
db " - letter '"
.letter db '#'
db "' from position "
.position db '#'
db ' must be reused$'
2022-02-24 19:33:35 +00:00
2022-02-24 23:40:59 +00:00
not_moved_error_str:
db " - letter '"
.letter db '#'
db "' in position "
.position db '#'
db ' must be moved$'
ruled_out_error_str:
db " - letter '"
.letter db '#'
db "' in position "
.position db '#'
db ' has been ruled out$'
2022-02-23 00:31:52 +00:00
section .rodata
greeting_str db 'Welcome to hello DOSdl. Press Ctrl+C to exit. Run `dosdl /?` for help.', 13, 10, '$'
2022-02-24 22:04:10 +00:00
space_dash_space_str db ' - $'
2022-02-24 23:05:50 +00:00
not_found_str db ' - word not found$'
2022-02-23 01:00:03 +00:00
erase_word_str db ' $'
2022-02-23 00:31:52 +00:00
word_was_str db 'The word was: $'
correct_in_str db 'Correct in $'
guesses_str db ' guesses.$'
2022-02-24 19:38:54 +00:00
guess_str db ' guess.$'
2022-02-22 22:38:06 +00:00
2022-02-24 22:04:10 +00:00
help_str:
2022-02-25 00:19:12 +00:00
db 'Usage: dosdl [/h | /u | /l | /?] [seed]', 13, 10
2022-02-25 13:53:55 +00:00
db '/h Enable hard mode.', 13, 10
db '/u Enable ultra hard mode.', 13, 10
db '/l Display license info.', 13, 10
db '/? Display this help.', 13, 10
2022-02-24 22:04:10 +00:00
db 13, 10
db 'Hello DOSdl is a word guessing game. You have six tries to guess the correct', 13, 10
db 'English word. After a guess the game displays feedback under each letter:', 13, 10
db 13, 10
db "' ' Letter is in the correct place.", 13, 10
db "'^' Letter is in the wrong place.", 13, 10
db "'x' Letter is not in used in the word, or its uses are already covered by the", 13, 10
db ' above cases.', 13, 10
db 13, 10
db 'After the feedback, the game shows a list of letters that have not yet been', 13, 10
2022-02-24 23:15:35 +00:00
db 'ruled out.', 13, 10
db 13, 10
db 'In hard mode all letters marked as being in the correct place must stay fixed', 13, 10
db 'and those marked as being in the wrong place must be reused. In ultra hard mode', 13, 10
db 'letters marked as being in the wrong place must also be moved and letters that', 13, 10
db 'have been ruled out must not be played again.$'
2022-02-24 22:04:10 +00:00
2022-02-22 22:38:06 +00:00
%include "dictionary.inc"
%include "targets.inc"
2022-02-25 00:05:00 +00:00
%include "license.inc"