Execute HQ9+: Difference between revisions

Add 8080 assembly
(Added Wren)
(Add 8080 assembly)
Line 4:
Implement a   ''' [[HQ9+]] '''   interpreter or compiler.
<br><br>
 
=={{header|8080 Assembly}}==
 
This program runs under CP/M. The HQ9+ source code is read from the file given
on the command line. After the program is finished, the final value of the
accumulator can be found at address <code>0252H</code>. (If you are running the
code on an emulator or on a machine that has a front panel, this is easy to do.
Alternatively, DDT can be used, though you will have to set up the FCB by hand.)
 
<lang 8080asm>putch: equ 2 ; Write character
puts: equ 9 ; Write string
fopen: equ 15 ; Open file
fread: equ 20 ; Read record
setdma: equ 26 ; Set DMA address
fcb: equ 5Ch ; FCB for first file on command line
org 100h
;;; Open source file given on command line
lxi d,fcb
mvi c,fopen
call 5 ; Open file
inr a ; A=FF = error
lxi d,efile
jz s_out ; If error, print error message and stop
lxi d,src ; Start reading file at src
;;; Load the entire source file into memory
block: push d ; Set DMA address to next free location
mvi c,setdma
call 5
lxi d,fcb ; Read 128-byte record
mvi c,fread
call 5
pop d ; Advance pointer by 128 bytes
lxi h,128
dad d
xchg
dcr a ; A=1 = end of file
jz block ; If not EOF, read next block
xchg
mvi m,26 ; Terminate last block with EOF byte to be sure
lxi b,src ; BC = source pointer
ins: ldax b ; Get current instruction
cpi 26 ; If EOF, stop
rz
ori 32 ; Make lowercase
push b ; Keep source pointer
cpi 'h' ; H=hello
cz hello
cpi 'q' ; Q=quine
cz quine
cpi '9' ; 9=bottles
cz botls
cpi '+' ; +=increment
cz incr
pop b ; Restore source pointer
inx b ; Next instruction
jmp ins
;;; Increment accumulator
incr: lxi h,accum
inr m
ret
;;; Print "Hello, World"
hello: lxi d,histr
jmp s_out
;;; Print the source
quine: lxi h,src ; Pointer to source
qloop: mov a,m ; Load byte
cpi 26 ; Reached the end?
rz ; If so, stop
push h ; Otherwise, keep pointer
mov e,a
mvi c,putch ; Print character
call 5
pop h ; Restore pointer
inx h ; Next byte
jmp qloop
;;; 99 bottles of beer
botls: mvi e,99 ; 99 bottles
bverse: call nbeer ; _ bottle(s) of beer
lxi h,otw ; on the wall
call bstr
call nbeer ; _ bottle(s) of beer
lxi h,nl ; \r\n
call bstr
lxi h,tod ; Take one down and pass it around
call bstr
dcr e ; Decrement counter
push psw ; Keep status
call nbeer ; _ bottle(s) of beer
lxi h,otw
call bstr ; on the wall
lxi h,nl ; \r\n
call bstr
pop psw ; restore status
jnz bverse ; If not at 0, next verse
ret
nbeer: push d ; keep counter
call btlstr ; _ bottle(s)
lxi d,ofbeer
call s_out ; of beer
pop d
ret
bstr: push d ; keep counter
xchg ; print string in HL
call s_out
pop d ; restore counter
ret
;;; Print "N bottle(s)"
btlstr: push d ; Keep counter
mov a,e ; Print number
call num
lxi d,bottle
call s_out ; Print " bottle"
pop d ; Restore counter
dcr e ; If counter is 1,
rz ; then stop,
mvi e,'s' ; otherwise, print S
mvi c,putch
jmp 5
;;; Print number (0-99) in A
num: ana a ; If 0, print "no more"
lxi d,nomore
jz s_out
mvi b,'0'-1 ; Tens digit
nloop: inr b ; Increment tens digit
sui 10 ; Subtract 10
jnc nloop
adi '0'+10 ; Ones digit
lxi d,snum-1
stax d ; Store ones digit
mov a,b ; Tens digit zero?
cpi '0'
jz s_out ; If so, only print ones digit
dcx d ; Otherwise, store tens digit
stax d
s_out: mvi c,puts ; Print result
jmp 5
efile: db 'File error.$'
histr: db 'Hello, world!',13,10,'$'
db '..'
snum: db '$'
nomore: db 'No more$'
bottle: db ' bottle$'
ofbeer: db ' of beer$'
otw: db ' on the wall',13,10,'$'
tod: db 'Take one down and pass it around'
nl: db 13,10,'$'
accum: db 0 ; Accumulator
src: equ $ ; Program source</lang>
 
{{out}}
 
This shows the code being run in SIMH and the accumulator checked afterwards.
For brevity, no <code>9</code> instruction is included in the HQ9+ source file.
 
<pre>A>type test.hq
HQ+hq+
qh+QH+
 
A>hq9+ test.hq
Hello, world!
HQ+hq+
qh+QH+
Hello, world!
HQ+hq+
qh+QH+
HQ+hq+
qh+QH+
Hello, world!
HQ+hq+
qh+QH+
Hello, world!
 
A>^E
Simulation stopped, PC: 0F402 (JMP F3F8h)
sim> ex 0252
252: 04
</pre>
 
=={{header|Ada}}==
2,095

edits