diff --git a/.gitignore b/.gitignore
index 6962046..d7ce796 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@
!*.sct
!*.uvprojx
!*.uvproj
+!STARTUP.A51
### Source Insight
*.IAB
diff --git a/keilp/STARTUP.A51 b/keilp/STARTUP.A51
new file mode 100644
index 0000000..fbe7294
--- /dev/null
+++ b/keilp/STARTUP.A51
@@ -0,0 +1,198 @@
+$NOMOD51
+;------------------------------------------------------------------------------
+; This file is part of the C51 Compiler package
+; Copyright (c) 1988-2005 Keil Elektronik GmbH and Keil Software, Inc.
+; Version 8.01
+;
+; *** <<< Use Configuration Wizard in Context Menu >>> ***
+;------------------------------------------------------------------------------
+; STARTUP.A51: This code is executed after processor reset.
+;
+; To translate this file use A51 with the following invocation:
+;
+; A51 STARTUP.A51
+;
+; To link the modified STARTUP.OBJ file to your application use the following
+; Lx51 invocation:
+;
+; Lx51 your object file list, STARTUP.OBJ controls
+;
+;------------------------------------------------------------------------------
+;
+; User-defined Power-On Initialization of Memory
+;
+; With the following EQU statements the initialization of memory
+; at processor reset can be defined:
+;
+; IDATALEN: IDATA memory size <0x0-0x100>
+; Note: The absolute start-address of IDATA memory is always 0
+; The IDATA space overlaps physically the DATA and BIT areas.
+IDATALEN EQU 80H
+;
+; XDATASTART: XDATA memory start address <0x0-0xFFFF>
+; The absolute start address of XDATA memory
+XDATASTART EQU 0
+;
+; XDATALEN: XDATA memory size <0x0-0xFFFF>
+; The length of XDATA memory in bytes.
+XDATALEN EQU 0
+;
+; PDATASTART: PDATA memory start address <0x0-0xFFFF>
+; The absolute start address of PDATA memory
+PDATASTART EQU 0H
+;
+; PDATALEN: PDATA memory size <0x0-0xFF>
+; The length of PDATA memory in bytes.
+PDATALEN EQU 0H
+;
+;
+;------------------------------------------------------------------------------
+;
+; Reentrant Stack Initialization
+;
+; The following EQU statements define the stack pointer for reentrant
+; functions and initialized it:
+;
+; Stack Space for reentrant functions in the SMALL model.
+; IBPSTACK: Enable SMALL model reentrant stack
+; Stack space for reentrant functions in the SMALL model.
+IBPSTACK EQU 0 ; set to 1 if small reentrant is used.
+; IBPSTACKTOP: End address of SMALL model stack <0x0-0xFF>
+; Set the top of the stack to the highest location.
+IBPSTACKTOP EQU 0xFF +1 ; default 0FFH+1
+;
+;
+; Stack Space for reentrant functions in the LARGE model.
+; XBPSTACK: Enable LARGE model reentrant stack
+; Stack space for reentrant functions in the LARGE model.
+XBPSTACK EQU 1 ; set to 1 if large reentrant is used.
+; XBPSTACKTOP: End address of LARGE model stack <0x0-0xFFFF>
+; Set the top of the stack to the highest location.
+XBPSTACKTOP EQU 0xFFFF +1 ; default 0FFFFH+1
+;
+;
+; Stack Space for reentrant functions in the COMPACT model.
+; PBPSTACK: Enable COMPACT model reentrant stack
+; Stack space for reentrant functions in the COMPACT model.
+PBPSTACK EQU 0 ; set to 1 if compact reentrant is used.
+;
+; PBPSTACKTOP: End address of COMPACT model stack <0x0-0xFFFF>
+; Set the top of the stack to the highest location.
+PBPSTACKTOP EQU 0xFF +1 ; default 0FFH+1
+;
+;
+;------------------------------------------------------------------------------
+;
+; Memory Page for Using the Compact Model with 64 KByte xdata RAM
+; Compact Model Page Definition
+;
+; Define the XDATA page used for PDATA variables.
+; PPAGE must conform with the PPAGE set in the linker invocation.
+;
+; Enable pdata memory page initalization
+PPAGEENABLE EQU 0 ; set to 1 if pdata object are used.
+;
+; PPAGE number <0x0-0xFF>
+; uppermost 256-byte address of the page used for PDATA variables.
+PPAGE EQU 0
+;
+; SFR address which supplies uppermost address byte <0x0-0xFF>
+; most 8051 variants use P2 as uppermost address byte
+PPAGE_SFR DATA 0A0H
+;
+;
+;------------------------------------------------------------------------------
+
+; Standard SFR Symbols
+ACC DATA 0E0H
+B DATA 0F0H
+SP DATA 81H
+DPL DATA 82H
+DPH DATA 83H
+
+ NAME ?C_STARTUP
+
+
+?C_C51STARTUP SEGMENT CODE
+?STACK SEGMENT IDATA
+
+ RSEG ?STACK
+ DS 1
+
+ EXTRN CODE (?C_START)
+ PUBLIC ?C_STARTUP
+
+ CSEG AT 0
+?C_STARTUP: LJMP STARTUP1
+
+ RSEG ?C_C51STARTUP
+
+STARTUP1:
+
+IF IDATALEN <> 0
+ MOV R0,#IDATALEN - 1
+ CLR A
+IDATALOOP: MOV @R0,A
+ DJNZ R0,IDATALOOP
+ENDIF
+
+IF XDATALEN <> 0
+ MOV DPTR,#XDATASTART
+ MOV R7,#LOW (XDATALEN)
+ IF (LOW (XDATALEN)) <> 0
+ MOV R6,#(HIGH (XDATALEN)) +1
+ ELSE
+ MOV R6,#HIGH (XDATALEN)
+ ENDIF
+ CLR A
+XDATALOOP: MOVX @DPTR,A
+ INC DPTR
+ DJNZ R7,XDATALOOP
+ DJNZ R6,XDATALOOP
+ENDIF
+
+IF PPAGEENABLE <> 0
+ MOV PPAGE_SFR,#PPAGE
+ENDIF
+
+IF PDATALEN <> 0
+ MOV R0,#LOW (PDATASTART)
+ MOV R7,#LOW (PDATALEN)
+ CLR A
+PDATALOOP: MOVX @R0,A
+ INC R0
+ DJNZ R7,PDATALOOP
+ENDIF
+
+IF IBPSTACK <> 0
+EXTRN DATA (?C_IBP)
+
+ MOV ?C_IBP,#LOW IBPSTACKTOP
+ENDIF
+
+IF XBPSTACK <> 0
+EXTRN DATA (?C_XBP)
+
+ MOV ?C_XBP,#HIGH XBPSTACKTOP
+ MOV ?C_XBP+1,#LOW XBPSTACKTOP
+ENDIF
+
+IF PBPSTACK <> 0
+EXTRN DATA (?C_PBP)
+ MOV ?C_PBP,#LOW PBPSTACKTOP
+ENDIF
+
+ MOV SP,#?STACK-1
+
+; This code is required if you use L51_BANK.A51 with Banking Mode 4
+; Code Banking
+; Select Bank 0 for L51_BANK.A51 Mode 4
+#if 0
+; Initialize bank mechanism to code bank 0 when using L51_BANK.A51 with Banking Mode 4.
+EXTRN CODE (?B_SWITCH0)
+ CALL ?B_SWITCH0 ; init bank mechanism to code bank 0
+#endif
+;
+ LJMP ?C_START
+
+ END