diff --git a/firmware/asdf/src/asdf_keymap_setup.c.in b/firmware/asdf/src/asdf_keymap_setup.c.in
new file mode 100644
index 0000000..a935157
--- /dev/null
+++ b/firmware/asdf/src/asdf_keymap_setup.c.in
@@ -0,0 +1,63 @@
+// -*- mode: C; tab-width: 2 ; indent-tabs-mode: nil -*-
+//
+// Unified Keyboard Project
+// ASDF keyboard firmware
+//
+// asdf_keymap_table.c
+//
+// initialize keymap setup function table
+//
+// *** AUTO-generated file. DO NOT EDIT. ***
+// *** To modify template, edit $ROOT/src/Keymaps/asdf_keymap_table.c.in ***
+// *** To modify keymap list, edit $ROOT/keymap_list.cmake
+//
+// Copyright 2019 David Fenyes
+//
+// This program 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.
+//
+// This program 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
+// this program. If not, see .
+//
+
+#include
+
+@keymap_declarations@
+
+// PROCEDURE: asdf_keymap_setup
+//
+// INPUTS: (uint8_t) index - index of the keymap setup function to call
+// OUTPUTS: none
+////
+// DESCRIPTION: This function calls the keymap setup function specified
+// by the index.
+//
+// SIDE EFFECTS: See Description
+//
+// NOTES: This function is necessary because functions defined in external
+// modules are not considered compile-time constants by the C99 standard, so the
+// array cannot be initialized with a compile-time declaration.
+//
+// SCOPE: public
+//
+// COMPLEXITY: 1
+//
+
+void asdf_keymap_setup(uint8_t index) {
+ switch(index) {
+@keymap_table@
+ default:
+ break;
+ }
+};
+
+//-------|---------|---------+---------+---------+---------+---------+---------+
+// Above line is 80 columns, and should display completely in the editor.
+
diff --git a/firmware/asdf/src/asdf_keymap_setup.h.in b/firmware/asdf/src/asdf_keymap_setup.h.in
new file mode 100644
index 0000000..3b14739
--- /dev/null
+++ b/firmware/asdf/src/asdf_keymap_setup.h.in
@@ -0,0 +1,42 @@
+// -*- mode: C; tab-width: 2 ; indent-tabs-mode: nil -*-
+//
+// Unified Keyboard Project
+// ASDF keyboard firmware
+//
+// asdf_keymap_table.c
+//
+// initialize keymap setup function table
+//
+// *** AUTO-generated file. DO NOT EDIT. ***
+// *** To modify template, edit $ROOT/src/Keymaps/asdf_keymap_table.c.in ***
+// *** To modify keymap list, edit $ROOT/keymap_list.cmake
+//
+// Copyright 2019 David Fenyes
+//
+// This program 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.
+//
+// This program 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
+// this program. If not, see .
+//
+
+#define ASDF_NUM_KEYMAPS @num_keymaps@
+
+// PROCEDURE: asdf_keymap_setup
+// INPUTS: (uint8_t) index - index of the keymap setup function to call
+// OUTPUTS: none
+// DESCRIPTION: This function calls the keymap setup function specified
+// by the index.
+// SIDE EFFECTS: See Description
+void asdf_keymap_setup(uint8_t index);
+
+//-------|---------|---------+---------+---------+---------+---------+---------+
+// Above line is 80 columns, and should display completely in the editor.
+
diff --git a/firmware/asdf/src/asdf_print.c b/firmware/asdf/src/asdf_print.c
new file mode 100644
index 0000000..a263997
--- /dev/null
+++ b/firmware/asdf/src/asdf_print.c
@@ -0,0 +1,68 @@
+// -*- mode: C; tab-width: 2 ; indent-tabs-mode: nil -*-
+//
+// Unified Keyboard Project
+// ASDF keyboard firmware
+//
+// .c
+//
+// Copyright 2019 David Fenyes
+//
+// This program 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.
+//
+// This program 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
+// this program. If not, see .
+//
+
+
+//
+// Headers
+//
+#include
+#include
+#include "asdf_arch.h"
+
+
+static FILE ascii_port = FDEV_SETUP_STREAM(asdf_arch_send_code, NULL,
+ _FDEV_SETUP_WRITE);
+
+//
+// Regular functions
+//
+
+// PROCEDURE: asdf_print
+// INPUTS: (*char) fmt - format string
+// va_arglist - list of args for fmt string
+// OUTPUTS: none
+//
+// DESCRIPTION: output to ascii output port using vfprintf()
+//
+// SIDE EFFECTS: see DESCRIPTION
+//
+// NOTES:
+//
+// SCOPE: public
+//
+// COMPLEXITY: 1
+//
+void asdf_print(char *fmt, ...)
+{
+ va_list arg_ptr;
+
+ va_start(arg_ptr, fmt);
+ vfprintf(&ascii_port, fmt, arg_ptr);
+ va_end(arg_ptr);
+}
+
+
+
+//-------|---------|---------+---------+---------+---------+---------+---------+
+// Above line is 80 columns, and should display completely in the editor.
+
diff --git a/firmware/asdf/src/asdf_print.h b/firmware/asdf/src/asdf_print.h
new file mode 100644
index 0000000..eddd4de
--- /dev/null
+++ b/firmware/asdf/src/asdf_print.h
@@ -0,0 +1,37 @@
+// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
+//
+// Unfified Keyboard Project
+// ASDF keyboard firmware
+//
+// asdf_print.h
+//
+// Copyright 2019 David Fenyes
+// This program 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.
+//
+// This program 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
+// this program. If not, see .
+//
+
+#if !defined (ASDF_PRINT_H)
+#define ASDF_PRINT_H
+
+//-------|---------|---------+---------+---------+---------+---------+---------+
+// Above line is 80 columns, and should display completely in the editor.
+
+// PROCEDURE: asdf_print
+// INPUTS: (*char) fmt - format string
+// va_arglist - list of args for fmt string
+// OUTPUTS: none
+// DESCRIPTION: output to ascii output port using vfprintf()
+// COMPLEXITY: 1
+void asdf_print(const char *fmt, ...);
+
+#endif /* !defined (ASDF_PRINT_H) */