neilobremski
Experienced Member
I finally reached back into some of my first assembler [SUP][1][/SUP] to write a routine called cubicnom() that generates a random cubic polynomial as the title implies. This pulls together several recent bits of code to seed the random number generator using a string and sprintf the results to a location in memory.
First, here's a random() function which accepts range parameters BX to CX. Thus if I pass in 1 and 9, respectively, then I'll get back a random number in the range of 1 to 9. On top of this, it also makes DS = CS which is required by rand().
Using that and the code from before, I present cubicnom() ...
This is a heavy weight that sets a bunch of registers (see screenshot above) and prints the string to ES:DI. Here's the register breakdown:
Finally, the screenshot also shows that the output from this for the seed "MAGSMAZE" is identical to the first version of the game!
Footnotes:
[SUP][1][/SUP]. Generating Polynomials post from March 9th, 2017.
First, here's a random() function which accepts range parameters BX to CX. Thus if I pass in 1 and 9, respectively, then I'll get back a random number in the range of 1 to 9. On top of this, it also makes DS = CS which is required by rand().
Code:
a 390
; ----------------------------------------------------------------------------
; random () :RANDOM
;
; Calls BX + (rand() % (CX - BX + 1)) and outputs the result in AX.
;
PUSH DS ; 390
PUSH DX ; 391
PUSH CS ; 392
POP DS ; 393 DS = CS
PUSH CX ; 394
PUSH BX ; 395
PUSH SI ; 396
CALL 0300 ; 397 >RAND
POP SI ; 39A
POP BX ; 39B
POP CX ; 39C
CWD ; 39D
PUSH CX ; 39E
SUB CX, BX ; 39F
INC CX ; 3A1 (CX - BX + 1)
DIV CX ; 3A2
POP CX ; 3A4
XCHG AX, DX ; 3A5
ADD AX, BX ; 3A6
POP DX ; 3A8
POP DS ; 3A9
RET ; 3AA
Using that and the code from before, I present cubicnom() ...
Code:
a 590
NOP ; 590 :STRING_POLNOM
e 590 "X" FC " - %uX² + %uX - %u = (x-?)(x-?)(x-?)" 00 00
a 5C0
; ----------------------------------------------------------------------------
; cubicnom () :CUBICNOM
;
; Generates a cubic polynomial to ES:DI with CL, DH, and DL set to its roots.
;
; CH = X² = -(A + B + C)
; BL = X = (A * B)(A * C)(B * C)
; AX = C = -(A * B * C)
;
MOV BX, 0001; 5C0 minimum
MOV CX, 0009; 5C3 maximum
CALL 0390 ; 5C6 >RANDOM
MOV DL, AL ; 5C9
CALL 0390 ; 5CB >RANDOM
MOV DH, AL ; 5CE
CALL 0390 ; 5D0 >RANDOM
MOV CL, AL ; 5D3
;
MOV CH, CL ; 5D5 CH will be X^2 coefficient / start with root A
ADD CH, DH ; 5D7 add root B to X^2 coefficient
ADD CH, DL ; 5D9 add root C to X^2 coefficient (finished)
MOV AL, CL ; 5DB load root A in accumulator
MUL DH ; 5DD (A * B)
MOV BL, AL ; 5DF BL will be X coefficient / start with (A * B)
MOV AL, CL ; 5E1 load root A in accumulator
MUL DL ; 5E3 (A * C)
ADD BL, AL ; 5E5 add (A * C) to X coefficient
MOV AL, DH ; 5E7 load root B in accumulator
MUL DL ; 5E9 (B * C)
ADD BL, AL ; 5EB add (B * C) to X coefficient (finished)
XOR AX, AX ; 5ED clear accumulator
MOV AL, CL ; 5EF AX will be constant / start with root A
MUL DH ; 5F1 multiply root B by constant
MUL DL ; 5F3 multiply root C by constant (finished)
;
PUSH AX ; 5F5
PUSH BX ; 5F6
PUSH CX ; 5F7
PUSH DX ; 5F8
PUSH DS ; 5F9
;
PUSH CS ; 5FA
POP DS ; 5FB
MOV BP, 00F0; 5FC
MOV WORD[BP+4],AX; 5FF constant
XOR AX, AX ; 602
MOV AL, CH ; 604
MOV WORD[BP],AX; 606 X^2 coefficient
MOV AL, BL ; 609
MOV WORD[BP+2],AX; 60B X coefficient
MOV SI, 0590; 60E $STRING_POLNOM
CALL 0480 ; 611 >SPRINTF
;
POP DS ; 614
POP DX ; 615
POP CX ; 616
POP BX ; 617
POP AX ; 618
;
RET ; 619
This is a heavy weight that sets a bunch of registers (see screenshot above) and prints the string to ES:DI. Here's the register breakdown:
- AX = Constant
- BL = X Coefficient
- CH = X^2 Coefficient
- CL = Root A
- DL = Root B
- DH = Root C
Finally, the screenshot also shows that the output from this for the seed "MAGSMAZE" is identical to the first version of the game!
Footnotes:
[SUP][1][/SUP]. Generating Polynomials post from March 9th, 2017.