;; Copyright (C) 2019 Jeremiah Orians
;; This file is part of mescc-tools.
;;
;; mescc-tools is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; mescc-tools is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with mescc-tools. If not, see <http://www.gnu.org/licenses/>.

DEFINE ADDI32_to_RDI 4881C7
DEFINE CMP_RAX_Immediate32 483D
DEFINE CMP_RDI_Immediate8 4883FF
DEFINE COPY_R13_to_RDI 4C89EF
DEFINE COPY_R14_to_RDI 4C89F7
DEFINE COPY_R14_to_RSI 4C89F6
DEFINE COPY_R15_to_RDI 4C89FF
DEFINE COPY_RAX_to_R13 4989C5
DEFINE COPY_RAX_to_R14 4989C6
DEFINE COPY_RAX_to_R15 4989C7
DEFINE COPY_RAX_to_RDX 4889C2
DEFINE JE32 0F84
DEFINE JMP32 E9
DEFINE LOADI32_RAX 48C7C0
DEFINE LOADI32_RDI BF
DEFINE LOADI32_RDX BA
DEFINE LOADI32_RSI BE
DEFINE POP_RAX 58
DEFINE POP_RDI 5F
DEFINE PUSH_RAX 50
DEFINE SYSCALL 0F05


	;; Register usage:
	;; R15 => OUTPUT
	;; R14 => Buffer
	;; R13 => INPUT

; Where the ELF Header is going to hit
; Simply jump to _start
; Our main function
:_start
	POP_RAX                     ; Get the number of arguments
	POP_RDI                     ; Get the program name
	POP_RDI                     ; Get the actual output name
	LOADI32_RSI %577            ; Prepare file as O_WRONLY|O_CREAT|O_TRUNC
	LOADI32_RDX %384            ; Prepare file as RW for owner only (600 in octal)
	LOADI32_RAX %2              ; the syscall number for open()
	SYSCALL                     ; Now open that file
	COPY_RAX_to_R15             ; Preserve the file pointer we were given

	LOADI32_RAX %12             ; the Syscall # for SYS_BRK
	LOADI32_RDI %0              ; Get current brk
	SYSCALL                     ; Let the kernel do the work
	COPY_RAX_to_R14             ; Set our malloc pointer

	LOADI32_RAX %12             ; the Syscall # for SYS_BRK
	COPY_R14_to_RDI             ; Using current pointer
	ADDI32_to_RDI %0x100000     ; Allocate 1MB
	SYSCALL                     ; Let the kernel do the work

:core
	POP_RDI                     ; Get the actual input name
	CMP_RDI_Immediate8 !0       ; Check for null string
	JE32 %done                  ; Hit null be done

	LOADI32_RSI %0              ; prepare read_only
	LOADI32_RDX %0              ; prevent any interactions
	LOADI32_RAX %2              ; the syscall number for open()
	SYSCALL                     ; Now open that damn file
	COPY_RAX_to_R13             ; Protect INPUT
:keep
	LOADI32_RDX %0x100000       ; set the size of chars we want
	COPY_R14_to_RSI             ; Where to put it
	COPY_R13_to_RDI             ; Where are we reading from
	LOADI32_RAX %0              ; the syscall number for read
	SYSCALL                     ; call the Kernel
	PUSH_RAX                    ; Protect the number of bytes read

	COPY_RAX_to_RDX             ; Number of bytes to write
	COPY_R14_to_RSI             ; What we are writing
	COPY_R15_to_RDI             ; Write to target file
	LOADI32_RAX %1              ; the syscall number for write
	SYSCALL                     ; call the Kernel

	POP_RAX                     ; Get bytes read
	CMP_RAX_Immediate32 %0x100000 ; Check if buffer was fully used
	JE32 %keep                  ; Keep looping if was full
	JMP32 %core                 ; Otherwise move to next file

:done
	; program completed Successfully
	LOADI32_RDI %0              ; All is well
	LOADI32_RAX %0x3C           ; put the exit syscall number in eax
	SYSCALL                     ; Call it a good day

:ELF_end
