100 lines
2.2 KiB
Plaintext
100 lines
2.2 KiB
Plaintext
org 100h
|
|
jmp test
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; Takes a 16-bit integer in HL, and stores it
|
|
;; as a 0-terminated string starting at BC.
|
|
;; On exit, all registers destroyed; BC pointing at
|
|
;; end of string.
|
|
mkroman: push h ; put input on stack
|
|
lxi h,mkromantab
|
|
mkromandgt: mov a,m ; scan ahead to next entry
|
|
ana a
|
|
inx h
|
|
jnz mkromandgt
|
|
xthl ; load number
|
|
mov a,h ; if zero, we're done
|
|
ora l
|
|
jz mkromandone
|
|
xthl ; load next entry from table
|
|
mov e,m ; de = number
|
|
inx h
|
|
mov d,m
|
|
inx h
|
|
xthl ; load number
|
|
xra a ; find how many we need
|
|
subtract: inr a ; with trial subtraction
|
|
dad d
|
|
jc subtract
|
|
push psw ; keep counter
|
|
mov a,d ; we subtracted one too many
|
|
cma ; so we need to add one back
|
|
mov d,a
|
|
mov a,e
|
|
cma
|
|
mov e,a
|
|
inx d
|
|
dad d
|
|
pop d ; restore counter (into D)
|
|
xthl ; load table pointer
|
|
stringouter: dcr d ; do we need to include one?
|
|
jz mkromandgt
|
|
push h ; keep string location
|
|
stringinner: mov a,m ; copy string into target
|
|
stax b
|
|
ana a ; done yet?
|
|
jz stringdone
|
|
inx h
|
|
inx b ; copy next character
|
|
jmp stringinner
|
|
stringdone: pop h ; restore string location
|
|
jmp stringouter
|
|
mkromandone: pop d ; remove temporary variable from stack
|
|
ret
|
|
mkromantab: db 0
|
|
db 18h,0fch,'M',0 ; The value for each entry
|
|
db 7ch,0fch,'CM',0 ; is stored already negated
|
|
db 0ch,0feh,'D',0 ; so that it can be immediately
|
|
db 70h,0feh,'CD',0 ; added using `dad'.
|
|
db 9ch,0ffh,'C',0 ; This also has the convenient
|
|
db 0a6h,0ffh,'XC',0 ; property of not having any
|
|
db 0ceh,0ffh,'L',0 ; zero bytes except the string
|
|
db 0d8h,0ffh,'XL',0 ; and row terminators.
|
|
db 0f6h,0ffh,'X',0
|
|
db 0f7h,0ffh,'IX',0
|
|
db 0fbh,0ffh,'V',0
|
|
db 0fch,0ffh,'IV',0
|
|
db 0ffh,0ffh,'I',0
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; Test code
|
|
test: mvi c,10 ; read string from console
|
|
lxi d,dgtbufdef
|
|
call 5
|
|
lxi h,0 ; convert to integer
|
|
lxi b,dgtbuf
|
|
readdgt: ldax b
|
|
ana a
|
|
jz convert
|
|
dad h ; hl *= 10
|
|
mov d,h
|
|
mov e,l
|
|
dad h
|
|
dad h
|
|
dad d
|
|
sui '0'
|
|
mov e,a
|
|
mvi d,0
|
|
dad d
|
|
inx b
|
|
jmp readdgt
|
|
convert: lxi b,romanbuf ; convert to roman
|
|
call mkroman
|
|
mvi a,'$' ; switch string terminator
|
|
stax b
|
|
mvi c,9 ; output result
|
|
lxi d,romanbuf
|
|
jmp 5
|
|
nl: db 13,10,'$'
|
|
dgtbufdef: db 5,0
|
|
dgtbuf: ds 6
|
|
romanbuf:
|