so i wrote an 8086 assembler
its not really finished but it implements most instructions and builds a port of this program attached here
Now all thats left is to combine it with my compiler, write an OS and make it self-hosting, then i will have achieved Full Software Divinity.
ORG 0X7C00 # ADD 0X7C00 TO LABEL ADDRESSES
MOV AX, 0 # SET UP SEGMENTS
MOV DS, AX
MOV ES, AX
MOV SS, AX # SETUP STACK
MOV SP, 0X7C00 # STACK GROWS DOWNWARDS FROM 0X7C00
MOV SI, WELCOME
CALL PRINT_STRING
MAINLOOP:
MOV SI, PROMPT
CALL PRINT_STRING
MOV DI, BUFFER
CALL GET_STRING
MOV SI, BUFFER
CMP BYTE [SI], 0 # BLANK LINE?
JZ MAINLOOP # YES, IGNORE IT
MOV SI, BUFFER
MOV DI, CMD_HI # "HI" COMMAND
CALL STRCMP
JB .HELLOWORLD
MOV SI, BUFFER
MOV DI, CMD_HELP # "HELP" COMMAND
CALL STRCMP
JB .HELP
MOV SI,BADCOMMAND
CALL PRINT_STRING
JMP MAINLOOP
.HELLOWORLD:
MOV SI, MSG_HELLOWORLD
CALL PRINT_STRING
JMP MAINLOOP
.HELP:
MOV SI, MSG_HELP
CALL PRINT_STRING
JMP MAINLOOP
WELCOME: DB 'WELCOME TO MY OS!', 0X0D, 0X0A, 0
MSG_HELLOWORLD: DB 'HELLO OSDEV WORLD!', 0X0D, 0X0A, 0
BADCOMMAND: DB 'BAD COMMAND ENTERED.', 0X0D, 0X0A, 0
PROMPT: DB '>', 0
CMD_HI: DB 'HI', 0
CMD_HELP: DB 'HELP', 0
MSG_HELP: DB 'MY OS: COMMANDS: HI, HELP', 0X0D, 0X0A, 0
BUFFER: PAD 64, 0
# ================
# CALLS START HERE
# ================
PRINT_STRING:
LODSB # GRAB A BYTE FROM SI
OR AL, AL # LOGICAL OR AL BY ITSELF
JZ .DONE # IF THE RESULT IS ZERO, GET OUT
MOV AH, 0X0E
INT 0X10 # OTHERWISE, PRINT OUT THE CHARACTER!
JMP PRINT_STRING
.DONE:
RET
GET_STRING:
XOR CL, CL
.LOOPL:
MOV AH, 0
INT 0X16 # WAIT FOR KEYPRESS
CMP AL, 0X08 # BACKSPACE PRESSED?
JZ .BACKSPACE # YES, HANDLE IT
CMP AL, 0X0D # ENTER PRESSED?
JZ .DONE # YES, WE'RE DONE
CMP CL, 0X3F # 63 CHARS INPUTTED?
JZ .LOOPL # YES, ONLY LET IN BACKSPACE AND ENTER
MOV AH, 0X0E
INT 0X10 # PRINT OUT CHARACTER
STOSB # PUT CHARACTER IN BUFFER
INC CL
JMP .LOOPL
.BACKSPACE:
CMP CL, 0 # BEGINNING OF STRING?
JZ .LOOPL # YES, IGNORE THE KEY
DEC DI
MOV BYTE [DI], 0 # DELETE CHARACTER
DEC CL # DECREMENT COUNTER AS WELL
MOV AH, 0X0E
MOV AL, 0X08
INT 0x10 # BACKSPACE ON THE SCREEN
MOV AL, ' '
INT 0x10 # BLANK CHARACTER OUT
MOV AL, 0X08
INT 0x10 # BACKSPACE AGAIN
JMP .LOOPL # GO TO THE MAIN LOOP
.DONE:
MOV AL, 0 # NULL TERMINATOR
STOSB
MOV AH, 0X0E
MOV AL, 0X0D
INT 0X10
MOV AL, 0X0A
INT 0X10 # NEWLINE
RET
STRCMP:
.LOOPL:
MOV AL, [SI] # GRAB A BYTE FROM SI
MOV BL, [DI] # GRAB A BYTE FROM DI
CMP AL, BL # ARE THEY EQUAL?
JNZ .NOTEQUAL # NOPE, WE'RE DONE.
CMP AL, 0 # ARE BOTH BYTES (THEY WERE EQUAL BEFORE) NULL?
JZ .DONE # YES, WE'RE DONE.
INC DI # INCREMENT DI
INC SI # INCREMENT SI
JMP .LOOPL # LOOP!
.NOTEQUAL:
CLC # NOT EQUAL, CLEAR THE CARRY FLAG
RET
.DONE:
STC # EQUAL, SET THE CARRY FLAG
RET
PAD 510 - ($ - $$), 0
DW 0xAA55
source code (needs a DRY refactor :^)
also, good resources: (http://www.mlsite.net/8086/, https://www.eng.auburn.edu/~sylee/ee2220/8086_instruction_set.htmll, http://aturing.umcs.maine.edu/~meadow/courses/cos335/8086-instformat.pdf those are really all you need, excluding official intel stuff, but those arent too nice reading