;This code was written specifically for the A86 assembler although it may ;work with others such as TASM .MODEL SMALL .STACK 200H .CODE MAIN: CALL SETUP_INTS JMP OVERDATA1 ;************************ DATA **************************** PROMPT1 DB 18, 53, 45, 47, 52, 0, 230, 198 ; L o g i n : [sp] [0] PROMPT2 DB 211, 208, 22, 39, 57, 57, 61, 53, 56, 42, 0, 230, 198 ;[cr] [lf] P a s s w o r d : [sp] [0] PASSWORD DB 17 DUP (?) LOGIN DB 17 DUP (?) SUCCESS DB 211, 208, 57, 59, 41, 41, 43, 57, 57, 198 GENERAL1 DW 0 SPECIFIC1 DW 0 ;********************* END OF DATA ************************ OVERDATA1: ;************************ CODE **************************** MOV SI, OFFSET PROMPT1 MOV DH, 58 MOV CX, 8 CALL CHANGE_DATA ;Add 58 to 8 chars at at prompt1 data CALL PRINT_MESSAGE ;Then print it MOV DI, OFFSET LOGIN XOR DH, DH ;DX = 0 = echo the char (not asterisk) CALL GET_INPUT ;Get input & put in LOGIN MOV WORD PTR [GENERAL1], OFFSET USERS ;Compare data at users (each user slot) MOV WORD PTR [SPECIFIC1], OFFSET LOGIN ;with a single LOGIN data area CALL FIND_USER ;See if it's a user, if so, return security # in AL PUSH SI ;When done, push SI b/c this last accessed security byte ;and it was INC so it now is in line with password for ;successfully identified user PRE_GET_PASS: MOV SI, OFFSET PROMPT2 MOV DH, 58 MOV CX, 13 CALL CHANGE_DATA ;Add 58 to 13 chars at prompt2 CALL PRINT_MESSAGE ;Print message MOV DI, OFFSET PASSWORD CALL GET_INPUT ;Get password from user into PASSWORD POP SI ;SI was pushed after it id'd the user now it points to password (after correct login name) MOV CX, 16 ;Password needs to have 121 added to each of its 16 chars MOV DH, 121 MOV DI, OFFSET PASSWORD CALL CHANGE_DATA ;Now add 121 to the chars CALL COMPARE_PASSWORD MOV AX, 840H ;(7C00H + 200H + 3*200H + 100H) / 10H = 850H MOV DS, AX ;THIS IS THE NASM VERSION SO 100H ISN'T ADDED ; TO THE OFFSETS => 950H MOV ES, AX ;MOV SS, AX JMP CONTINUE_OS ;If password and login correct, it will make it to ;this stage.... ;************************ PROCEDURES ************************* CHANGE_DATA: PUSH SI CYCLE_OF_CD: MOV AL, BYTE PTR [ES:SI] ADD AL, DH MOV [ES:SI], AL INC SI LOOP CYCLE_OF_CD POP SI RET ;*************** PRINT_MESSAGE: MOV AH, 0EH MOV BH, 0 PUSH SI MESSAGE_LP2: LODSB CMP AL, 0 JZ GO_BACK2 INT 10H JMP MESSAGE_LP2 GO_BACK2: POP SI RET ;*************** GET_INPUT: MOV CX, 16 MOV BH, 0 THE_CYCLE1: XOR AH, AH INT 16H CMP AL, 8 JZ DO_BACKSPACE CMP AL, 13 JZ GO_BACK1 STOSB CMP DH, 0 JNZ ECHO_AST ECHOED_AST: MOV AH, 0EH INT 10H LOOP THE_CYCLE1 GO_BACK1: RET ECHO_AST: MOV AL, 42 JMP ECHOED_AST DO_BACKSPACE: CMP DI, OFFSET PASSWORD JZ THE_CYCLE1 CMP DI, OFFSET LOGIN JZ THE_CYCLE1 DEC DI MOV BYTE [ES:DI], 0 MOV AH, 0EH INT 10H XOR AL, AL INT 10H MOV AL, 8 INC CX INC CX JMP ECHOED_AST ;'ECHOED_AST' is used for two return locations ;*************** FIND_USER: MOV CX, 30 OUTER_CYCLE: PUSH CX MOV SI, WORD PTR [GENERAL1] MOV AX, 30 SUB AX, CX MOV DX, 33 MUL DX ADD SI, AX MOV DI, WORD PTR [SPECIFIC1] MOV CX, 16 INNER_CYCLE: LODSB CMP AL, BYTE PTR [ES:DI] JNZ NO_GOOD_CHAR INC DI LOOP INNER_CYCLE POP CX JMP FOUND_ONE NO_GOOD_CHAR: POP CX CMP CX, 0 JZ NOT_FOUND LOOP OUTER_CYCLE JMP REBOOT NOT_FOUND: JMP REBOOT FOUND_ONE: ; CMP CX, 28 ; JZ ITS_DAN ;BACK_FROM_ITSDAN: MOV AH, 1 LODSB RET ;DAN_MESSAGE DB 13,10,"You SUCK!",0 ;ITS_DAN: ; MOV SI, OFFSET DAN_MESSAGE ; CALL PRINT_MESSAGE ; JMP BACK_FROM_ITSDAN ;*************** COMPARE_PASSWORD: MOV CX, 16 COMPARING: MOV AL, BYTE PTR [ES:DI] CMP BYTE PTR [ES:SI], AL JNZ GOTO_REBOOT INC SI INC DI LOOP COMPARING RET GOTO_REBOOT: JMP REBOOT ;*************** ;****************** END OF PROCEDURES ********************* ;********************* INTERRUPTS ************************* ;************* SETUP ****************** SETUP_INTS: PUSH DS XOR AX, AX MOV DS, AX MOV AX, OFFSET INT2100 MOV BX, OFFSET MAIN SUB AX, BX ADD AX, 7E00H ;7C00H+512 AKA 7C00H+200H MOV WORD [DS:132], AX ;OFFSET INT2100 XOR AX, AX MOV WORD [DS:134], AX ;SEG INT2100 MOV AX, OFFSET INT2E SUB AX, BX ADD AX, 7E00H MOV WORD [DS:184], AX XOR AX, AX MOV WORD [DS:186], AX POP AX MOV DS, AX RET ;*********** ACTUAL INTERRUPTS ************ ;Test interrupt for now... INT2100: MOV AX, 4C00H IRET ;************ INT2E: CMP AH, 0 JZ CONV_HEX ;CONV_BUFFER DB 4 DUP (?) ;DB "H",0 CONV_HEX: ;!!!!!!! DS:DI > Buffer for chars, AH = 0, DX = word to convert !!! MOV CX, 15 MOV AX, 0F000H ; ;MOV DI, OFFSET CONV_BUFFER CONV_HEX_CYCLE1: CMP DX, AX ; JAE SUBTRACT1 SUB AX, 1000H ; LOOP CONV_HEX_CYCLE1 SUBTRACT1: CALL SUBTRACT MOV AX, 0F00H ; MOV CX, 15 CONV_HEX_CYCLE2: CMP DX, AX ; JAE SUBTRACT2 SUB AX, 100H ; LOOP CONV_HEX_CYCLE2 SUBTRACT2: CALL SUBTRACT MOV AX, 0F0H ; MOV CX, 15 CONV_HEX_CYCLE3: CMP DX, AX ; JAE SUBTRACT3 SUB AX, 10H ; LOOP CONV_HEX_CYCLE3 SUBTRACT3: CALL SUBTRACT MOV AX, 0FH ; MOV CX, 15 CONV_HEX_CYCLE4: CMP DX, AX ; JAE SUBTRACT4 DEC AX ; LOOP CONV_HEX_CYCLE4 SUBTRACT4: CALL SUBTRACT IRET SUBTRACT: SUB DX, AX ; PUSH DX ; MOV DL, CL ; ADD DL, 48 ; CMP DL, 57 ; JA DO_A_LETTER BACK_FROM_LETTER: MOV AL, DL ;ADDED STOSB POP DX ; RET DO_A_LETTER: ADD DL, 7 ; JMP BACK_FROM_LETTER ;*************** ;****************** END OF INTERRUPTS ********************* ;*********************** DATA2 ***************************** REBOOT: DB 0EAH, 0, 0, 0FFH, 0FFH THE_SPACE DB 542 DUP (?) USERS DB "root", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 DB 16 dup (135) ;become nulls when added to 121 AFTER_THAT DB 479 DUP (?) CONTINUE_OS: END MAIN