DECTalk "SPEAK.EXE" program, version 4.2(?), documentation.

NOTE: This documentation is being actively built at this time. I apologise if not every function of it is yet documented, I am not Hackerman.

This program is written in the ancient computer-architectural dialect of Alpha AXP assembly language, used by the long defunct DEC processors by,
you guessed it, Digital Equipment Corporation (D.E.C). This represents a possible decyphering of the program's over-all logic, open for all to do
what they want to do with it. There is also a GitHub page for it created by me, however it is unused right now. It will be used in the future, so stay tuned! :)

If you do want to start your own discovery journey of this program, the Internet Archive link is here: https://archive.org/details/ALPHADT_ZIP
Use IDA Pro to get the complete disassembly of the SPEAK.EXE program.

SPEAK.EXE Manual Analysis Project
By Jerrymanic

********
--------------------------------------- DATE OF WRITING: August 16, 2024

402000: INSTRUCTION DESCRIPTION WIN32 API CALLS

lda $sp, -0xC0($sp) - Creates stack space
ldah $19, 0x40($31) - Loads into R19 high address of $31+0x40
stq $9, 0x30($sp) - Stores value of R9 into SP+0x30
mov 0x2B, $0 - Sets R0 to 0x2B
stq $10, 0x38($sp) - Stores value of R9 into SP+0x38
ldah $1, 0x45($31) - Loads into R1 high address of 0x45($31)
stq $11,0x40($sp) - Stores R11 into SP+0x40
lda $19, 0x2378($19) - Loads into R19 address 0x2378+R19
stq $26,0x48($sp) - Stores R26 into 0x48($sp)



---------------------------------------

Description:

What this section of code seems to do is store some registers into
the stack, with the following spaces:

-0xC0+SP+0x30 = R9 = ?? (unknown)
-0xC0+SP+0x38 = R10 = ?? (unknown)
-0xC0+SP+0x40 = R11 = ?? (unknown)
-0xC0+SP+0x48 = R26 = ?? (unknown)

Due to the unknown value of these registers at the beginning of
the program, it's safe to say that this sequence of instructions
just saves the previous values (before program start) of the
registers for restoration later.

Register changes:

The stack pointer (SP) is subtracted the value of 0xC0.

R19 has the value of 0x40+R31 << 16, so address
0x00400000 (because R31 is always 0) which also
happens to be the start of the program's allocated
addresses.

R0 is set to 0x2B.

R1 is set to 0x45+R31, which (same procedure as last
time) is 0x00450000.

********
--------------------------------------- DATE OF WRITING: August 17 -> August 19, 2024

402024: INSTRUCTION DESCRIPTION WIN32 API CALLS

mov $18,$9 - Set R9 to R18
stl $0, 0x80($sp) - Store longword R0 to 0x80+SP
ldah $18,0x59($31) - Load address high of 0x59+R31 into R18
stl $19,0x84($sp) - Store longword R19 to 0x84+SP
mov 0xA,$17 - Set R17 to 0xA
stl $31,0x8C($sp) - Store longword of R31 to 0x8C+SP
lda $10,-0x2D18($10) - Load address in R10 -0x2D18+R10 # SPEAK_MENU
stl $16,-0x1700($1) - Store longword R16 to -0x1700+R1
stl $31,0x90($sp) - Store longword R31 to 0x90+SP
ldl $27,0x44D4($18) - Load longword in R27 0x44D4+R18 # LoadIconA
jsr $26,($27),0 - Jump to R27, with return R26, 0 hint # LoadIconA
ldah $2,0x59($31) - Load address high in R2 0x59+31
stl $0,0x94($sp) - Store longword in R0 to 0x94+SP
clr $16 - Clear R16
ldl $27,0x44D0($2) - Load longword into R27 0x44D0+R2 # LoadCursorA
lda $17,0x7F00($31) - Load address into R17 from 0x7F00+R31
jsr $26,($27),0 - Jump to R27, return to R26, 0 hint # LoadCursorA
ldah $5,0x59($31) - Load address high in R5 0x59+R31
stl $0,0x98($sp) - Store longword from R0 to 0x98+SP
mov 4,$16 - Store 4 to R16
ldl $27,0x4344($2) - Load longword 0x4344+R2 into R27 # GetStockObject
jsr $26,($27),0 - Jump to R27, return to R26, 0 hint # GetStockObject
ldah $5,0x59($31) - Load address high into R5 0x59+R31
ldl $1,-0x1228,($10) - Load longword in R1 -0x1228+R10
lda $16,0x80($sp) - Load address in R16 0x80+SP
stl $0,0x9C($sp) - Store longword R0 in 0x9C+SP
stl $10,0xA0($sp) - Store longword R10 in 0xA0+SP
stl $1,0xA4($sp) - Store longword R1 in 0xA4+SP
ldl $27,0x44F0($5) - Load longword in R27 0x44F0+R5 # RegisterClassA
jsr $26,($27),0 - Jump to R27, return to R26, 0 hint # RegisterClassA
bne $0,loc_4020B0 - Branch if not equal flag R0 to loc_4020B0
clr $0 - Clear R0
br loc_40235C - Branch to loc_40235C

---------------------------------------

Description:

Some values are saved to some registers, and some saved to the stack:

STACK:
0x80+SP = R0
0x84+SP = R19
0x8C+SP = R31
0x90+SP = R31
0x94+SP = R0
0x98+SP = R0
0x9C+SP = R0
0xA0+SP = R10
0xA4+SP = R1

MODIFIED REGISTERS:

R0,R1,R2,R5,R9,R10,R16,R17,R18,R27

I won't bother writing them below here, as they are many. And they are written in the code.

There are some subroutines ran, thus before them there are some register storing operations. There is
the LoadIconA subroutine, the LoadCursorA subroutine, the GetStockObject subroutine,
and the RegisterClassA subroutine.

This section is used mostly to load the icon of the program, the mouse cursor used for
this program, and for GetStockObject, the "mov 4,$16" is probably the argument for the function,
which is the "BLACK_BRUSH" argument.

There's the RegisterClassA which is used to register a window class.

Conclusion is that this is mostly used to set up the window.


********
---------------------------------------