RosettaCodeData/Task/RPG-attributes-generator/8086-Assembly/rpg-attributes-generator.8086
2026-04-30 12:34:36 -04:00

89 lines
2.5 KiB
Text

bits 16
cpu 8086
putch: equ 2h
time: equ 2ch
org 100h
section .text
mov ah,time ; Retrieve system time from MS-DOS
int 21h
call rseed ; Seed the RNG
rolls: xor ah,ah ; AH=0 (running total)
mov dx,6 ; DH=0 (amount >=15), DL=6 (counter)
mov di,attrs
attr: call roll4 ; Roll an attribute
mov al,14
cmp al,bh ; Set carry if BH=15 or more
mov al,bh ; AL = roll
sbb bh,bh ; BH=0 if no carry, -1 if carry
sub dh,bh ; DH+=1 if >=15
add ah,al ; Add to running total
mov [di],al ; Save roll
inc di ; Next memory address
dec dl ; One fewer roll left
jnz attr
cmp ah,75 ; Rolling total < 75?
jb rolls ; Then roll again.
cmp dh,2 ; Fewer than 2 attrs < 15?
jb rolls ; Then roll again.
;;; Print the attributes
mov cx,6 ; 6 attributes
p2: mov bl,10 ; divide by 10 to get digits
mov di,attrs
print: xor ah,ah ; AX = attribute
mov al,[di]
div bl ; divide by 10
add ax,3030h ; add '0' to quotient (AH) and remainder (AL)
mov dx,ax
mov ah,putch
int 21h ; print quotient first
mov dl,dh ; then remainder
int 21h
mov dl,' ' ; then a space
int 21h
inc di ; Next attribute
loop print
ret ; Back to DOS
;;; Do 4 rolls, and get result of max 3
roll4: xor bx,bx ; BH = running total
dec bl ; BL = lowest value
mov cx,4 ; Four times
.roll: call d6 ; Roll D6
cmp al,bl ; Lower than current lowest value?
jnb .high ; If so,
mov bl,al ; Set new lowest value
.high: add bh,al ; Add to running total
loop .roll ; If not 4 rolls yet, loop back
sub bh,bl ; Subtract lowest value (giving sum of high 3)
ret
;;; Roll a D6
d6: call rand ; Get random number
and al,7 ; Between 0 and 7
cmp al,6 ; If 6 or higher,
jae d6 ; Then get new random number
inc al ; [1..6] instead of [0..5]
ret
;;; Seed the random number generator with 4 bytes
rseed: xor [rnddat],cx
xor [rnddat+2],dx
;;; "X ABC" random number generator
;;; Generates 8-bit random number in AL
rand: push cx ; Keep registers
push dx
mov cx,[rnddat] ; CL=X CH=A
mov dx,[rnddat+2] ; DL=B DH=C
xor ch,dh ; A ^= C
xor ch,cl ; A ^= X
add dl,ch ; B += A
mov al,dl ; R = B
shr al,1 ; R >>= 1
xor al,ch ; R ^= A
add al,dh ; R += C
mov dh,al ; C = R
mov [rnddat],cx ; Store new state
mov [rnddat+2],dx
pop dx ; Restore registers
pop cx
ret
section .bss
rnddat: resb 4 ; RNG state
attrs: resb 6 ; Rolled attributes