130 lines
1.9 KiB
Text
130 lines
1.9 KiB
Text
;ds:si: pointer to asciiz string containing HQ9++ source code
|
|
ExecuteHQ9:
|
|
push ax
|
|
push dx
|
|
push si
|
|
push di
|
|
push es
|
|
push bx
|
|
mov bx, si
|
|
.interpret:
|
|
lodsb
|
|
cmp al, 'H'
|
|
je .doHelloWorld
|
|
cmp al, 'Q'
|
|
je .doPrintCode
|
|
cmp al, '9'
|
|
je .doDrinkBeer
|
|
cmp al, '+'
|
|
je .doCounter
|
|
pop bx
|
|
pop es
|
|
pop di
|
|
pop si
|
|
pop dx
|
|
pop ax
|
|
ret
|
|
|
|
.doHelloWorld:
|
|
push ds
|
|
mov ax, cs
|
|
mov ds, ax
|
|
push si
|
|
mov si, .dataHelloWorld
|
|
call .printString
|
|
pop si
|
|
pop ds
|
|
jmp .interpret
|
|
|
|
.doPrintCode:
|
|
push si
|
|
mov si, bx
|
|
call .printString
|
|
pop si
|
|
jmp .interpret
|
|
|
|
.doDrinkBeer:
|
|
push ds
|
|
push si
|
|
push ax
|
|
mov ax, cs
|
|
mov ds, ax
|
|
mov ax, 99
|
|
.beer_loop:
|
|
call .printHexNumber
|
|
mov si, .dataBeerSong1
|
|
call .printString
|
|
call .printHexNumber
|
|
mov si, .dataBeerSong2
|
|
call .printString
|
|
dec ax
|
|
call .printHexNumber
|
|
mov si, .dataBeerSong3
|
|
call .printString
|
|
test ax, ax
|
|
jnz .beer_loop
|
|
pop ax
|
|
pop si
|
|
pop ds
|
|
jmp .interpret
|
|
|
|
.doCounter:
|
|
push ax
|
|
inc ax
|
|
pop ax
|
|
jmp .interpret
|
|
|
|
.printString:
|
|
push ax
|
|
push si
|
|
.looping:
|
|
lodsb
|
|
test al, al
|
|
jz .done
|
|
mov ah, 0Eh
|
|
int 10h
|
|
jmp .looping
|
|
.done:
|
|
pop si
|
|
pop ax
|
|
ret
|
|
|
|
.printHexNumber:
|
|
pusha
|
|
push ds
|
|
mov ax, cs
|
|
mov ds, ax
|
|
push word 0
|
|
mov bx, ax
|
|
xor dx, dx
|
|
mov cx, 4r
|
|
.convert_loop:
|
|
mov ax, bx
|
|
and ax, 0Fh
|
|
cmp ax, 9
|
|
ja .greater_than_9
|
|
add ax, '0'
|
|
jmp .converted
|
|
.greater_than_9:
|
|
add ax, 'A'-0Ah
|
|
.converted:
|
|
push ax
|
|
shr bx, 4
|
|
dec cx
|
|
jnz .convert_loop
|
|
.popoff:
|
|
pop ax
|
|
cmp ax, 0
|
|
je .done
|
|
mov ah, 0Eh
|
|
int 10h
|
|
jmp .popoff
|
|
.done:
|
|
pop ds
|
|
popa
|
|
ret
|
|
|
|
.dataHelloWorld: db "Hello World!", 0
|
|
.dataBeerSong1: db " bottles of beer on the wall ", 0
|
|
.dataBeerSong2: db " bottles of beer", 13, 10, "Take one down, pass it around "
|
|
.dataBeerSong3: db 0, " bottles of beer on the wall", 0
|