%define 	stdin 	00h
%define 	stdout 	01h
%define		stderr	02h
%define		write	04h
%define		read	03h

section	.data
	key_buffer	db 0, 0, 0Ah				; The ASCII Representation of the Key
	key_buffer_len	equ $-key_buffer			; the Size of the Key Buffer
	key		db 0					; the place for the key
	buffer		times 64 db 0  				; message buffer
	buffer_len	equ $-buffer				; size of the 1 byte buffer
	prompt		db 0Ah, "> "				; what the prompt looks like
	prompt_len	equ $-prompt				; the size of the prompt
	info		db "Assembly Message Encoder.  (CTRL-C) to exit.", 0Ah, "Enter a number between 01 and 25, this will be the key.", 0Ah
	info_len	equ $-info
	okay		db "Okay.", 0Ah
	okay_len	equ $-okay
	err		db "Error.", 0Ah
	err_len		equ $-err
	original	db					; the original letter
	
section	.text
global	_start
_start:	
	mov eax, write
	mov ebx, stdout
	mov ecx, info
	mov edx, info_len
	int 80h

_getKey:
	call showprompt

	mov eax, read
	mov ebx, stdin
	mov ecx, key_buffer
	mov edx, key_buffer_len
	int 80h
	cmp ecx, 0003h		; if not enough digits were entered
	jl _err1		; go into an error state

	mov bh, [key_buffer]	; first digit (TENS Place)
	mov bl, [key_buffer+1]	; second digit (ONES Place)
	and bx, 0F0Fh		; convert it to hex representation of the decimal digit
				; strip the left side of each byte

	mov al, bh		; multiply the TENS Place by Ten
	mov ah, 0Ah		; the result is put into al
	mul ah
	
	add bl, al		; add the result to the ones place
	mov [key], bl		; store it

	cmp [key], byte 19h	; compare it with 25 decimal (19h) 
	jg _err1		; if it's > 25 then redo
	cmp [key], byte 01h	; compare it with 1 decimal
	jl _err1		; if it's < 1 then redo
	jmp _prompt
_err1:
	call dumperror
	jmp _getKey

_prompt:
	call showprompt
	;; get a text message
	call readbuf
	
	call processbuffer
	
	call dumpbuffer

	call clearbuffer
	
	jmp _prompt

_done:	;; terminate control
	mov ebx, 0
	mov eax, 1
	int 80h

clearbuffer:
	pushad
	mov edx, buffer
	add edx, 0040h
	xor al, al
_cb1:

	mov [edx], al
	dec edx
	cmp edx, buffer
	jg  _cb1
	mov al, 0Ah
	mov [edx], al
	
	popad
	ret

	;; 
	;; This is the meat of the code
	;; 
processbuffer:
	pushad
	mov edx, buffer
_skip0:
	mov al, [edx]

	cmp al, 0Ah
	je _goback
	
_upper_case:
	;; CAPS FIRST
	cmp al, 61h 		; "a"
	jge _lower_case
	add al, [key]
	cmp al, 5Ah		; "Z"
	jle _skip2
	sub al, 1Ah		; subtract 26 
	jmp _skip2
	
_lower_case:
	;; Then Lowercase
	add al, [key]
	cmp al, 7Ah		; "z"
	jle _skip2
	sub al, 1Ah		; subtract 26

_skip2:
	mov [edx], al
	inc edx
	jmp _skip0
_goback:	
	popad
	ret

readbuf:
	pushad
	mov eax, read
	mov ebx, stdin
	mov ecx, buffer
	mov edx, buffer_len
	int 80h
	popad
	ret

showprompt:
	pushad
	mov eax, write
	mov ebx, stdout
	mov ecx, prompt
	mov edx, prompt_len
	int 80h
	popad
	ret

dumpbuffer:
	pushad
	mov eax, write
	mov ebx, stdout
	mov ecx, buffer
	mov edx, buffer_len
	int 80h	
	popad
	ret

dumpokay:
	pushad
	mov eax, write
	mov ebx, stdout
	mov ecx, okay
	mov edx, okay_len
	int 80h
	popad
	ret

dumperror:
	pushad
	mov eax, write
	mov ebx, stdout
	mov ecx, err
	mov edx, err_len
	int 80h
	popad
	ret
	
;;; nasm -f elf shell.asm
;;; ld shell.o -o shell
