add docs with doxygen using custom filter
This commit is contained in:
parent
5ee9610616
commit
8b2e7c2752
2861
.doxygen_config
Normal file
2861
.doxygen_config
Normal file
File diff suppressed because it is too large
Load Diff
4
Makefile
4
Makefile
@ -57,3 +57,7 @@ clean:
|
|||||||
rm -r $(OBJ_DIR)
|
rm -r $(OBJ_DIR)
|
||||||
rm $(ROM)
|
rm $(ROM)
|
||||||
rm $(SPI)
|
rm $(SPI)
|
||||||
|
|
||||||
|
docs:
|
||||||
|
doxygen .doxygen_config
|
||||||
|
|
||||||
|
181
doxy-asm65.py
Normal file
181
doxy-asm65.py
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
import sys
|
||||||
|
import re
|
||||||
|
from typing import Callable
|
||||||
|
|
||||||
|
filename = "unknown"
|
||||||
|
|
||||||
|
def pdebug(*args, **k):
|
||||||
|
print(f"DEBUG ({filename}):", *args, file=sys.stderr, **k)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_custom_language(file_content: str):
|
||||||
|
# procedure_name: scope_name
|
||||||
|
exported_names = {}
|
||||||
|
def handle_export(m):
|
||||||
|
export_type = m.groups()[0]
|
||||||
|
scope = m.groups()[1]
|
||||||
|
functions = m.groups()[2].replace(" ", "").strip(",")
|
||||||
|
for f in functions.split(","):
|
||||||
|
pdebug(f"Add Exported function: '{f}' in '{scope}'")
|
||||||
|
exported_names[f] = scope
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def handle_procedure(m):
|
||||||
|
# print("handle procedure:", m.groups())
|
||||||
|
p_docs = m.groups()[0].strip("\n")
|
||||||
|
p_type = m.groups()[1]
|
||||||
|
p_name = m.groups()[2]
|
||||||
|
p_args = m.groups()[3].strip(" ")
|
||||||
|
p_code = m.groups()[4]
|
||||||
|
s = ""
|
||||||
|
in_namespace = False
|
||||||
|
if p_name in exported_names:
|
||||||
|
# print(f"{p_name} is exported")
|
||||||
|
in_namespace = True
|
||||||
|
# wrap function in namespace {}, which consumes the first line of the docstring, which must be ;;***...
|
||||||
|
namespace = exported_names[p_name]
|
||||||
|
# assert p_docs.startswith(";;*"), f"Documentation of an exported procedure must start with ';;***...' ({p_name})"
|
||||||
|
# assert p_docs[p_docs.rfind('\n'):].startswith("\n;;*"), f"Documentation of an exported procedure must end with ';;***...' ({p_name})"
|
||||||
|
s += f"namespace {namespace}" + " {" + p_docs
|
||||||
|
# s += p_docs[p_docs.find('\n'):p_docs.rfind('\n')]
|
||||||
|
s += "\n"
|
||||||
|
# s += f"@ingroup {namespace}\n"
|
||||||
|
else:
|
||||||
|
s += p_docs + "\n" #re.sub(r";;\*+", ";;", p_docs, 0, re.MULTILINE) + "\n"
|
||||||
|
|
||||||
|
if p_type == "proc":
|
||||||
|
s += f"proc {p_name}("
|
||||||
|
for match in re.finditer(r"[\@\\]param +(.+?) *:", p_docs):
|
||||||
|
s += f"Param {match.groups()[0]},"
|
||||||
|
if s[-1] == ",": s = s[:-1]
|
||||||
|
s += ");\n"
|
||||||
|
elif p_type == "macro":
|
||||||
|
pdebug(f"Processing macro '{p_name}' with args '{'TXT'.join(p_args.replace(' ', '').split(','))}'")
|
||||||
|
s += f"macro {p_name}("
|
||||||
|
p_args = "".join("Param " + param + "," for param in p_args.replace(" ", "").split(',')).strip(",")
|
||||||
|
s += p_args
|
||||||
|
s += ");\n"
|
||||||
|
pdebug("Found macro", p_name, s)
|
||||||
|
elif p_type == "enum":
|
||||||
|
p_code = re.sub(r"( *(?:;;.*)?\n)", r",\1", p_code)
|
||||||
|
s += f"enum {p_name}" + "{\n" + p_code + "};"
|
||||||
|
else:
|
||||||
|
raise NotImplementedError(f"handle_procedure not implemented for procedure type {p_type}")
|
||||||
|
s += re.sub(".*", "", p_code)
|
||||||
|
if in_namespace:
|
||||||
|
s += "} // namespace"
|
||||||
|
else:
|
||||||
|
s += "\n"
|
||||||
|
return s
|
||||||
|
|
||||||
|
def handle_storage_label(m):
|
||||||
|
l_docs = m.groups()[0].strip('\n')
|
||||||
|
l_name = m.groups()[1]
|
||||||
|
l_allocs = m.groups()[2]
|
||||||
|
storage_alloc = r"(?:\.(byte|res|dbyte|word|addr|faraddr|dword|ascii|asciiz)([, ]+(?:0x[a-fA-F0-9]+|0b[01]+|\d+|\w+|\"[^\n]*?[^\\\n]\")[ \n]*)*)"
|
||||||
|
storage_alloc_arg = r"(0x[a-fA-F0-9]+|0b[01]+|\d+|\w+|\"[^\n]*[^\\\n]\")"
|
||||||
|
|
||||||
|
args = []
|
||||||
|
allocs = []
|
||||||
|
for alloc_match in re.finditer(storage_alloc, l_allocs):
|
||||||
|
allocs.append(alloc_match)
|
||||||
|
alloc_args = alloc_match.groups()[1]
|
||||||
|
if alloc_args:
|
||||||
|
args += re.findall(storage_alloc_arg, alloc_args)
|
||||||
|
|
||||||
|
s = ""
|
||||||
|
in_namespace = False
|
||||||
|
# pdebug("ldocs for", l_name, l_docs)
|
||||||
|
# pdebug(m.groups())
|
||||||
|
if l_name in exported_names:
|
||||||
|
in_namespace = True
|
||||||
|
namespace = exported_names[l_name]
|
||||||
|
s += f"namespace {namespace}" + " {" + l_docs
|
||||||
|
s += "\n"
|
||||||
|
else:
|
||||||
|
s += l_docs + "\n"
|
||||||
|
if len(args) > 1:
|
||||||
|
if all(arg.startswith("\"") for arg in args):
|
||||||
|
s += f'char* {l_name} = "' + "".join(map(lambda x: x.strip('"'), args)) + '"'
|
||||||
|
else:
|
||||||
|
s += "bytes[] = {"
|
||||||
|
for arg in args:
|
||||||
|
s += arg + ","
|
||||||
|
s += "}"
|
||||||
|
s += s.strip(",") + "}"
|
||||||
|
else:
|
||||||
|
# alloc_type label =
|
||||||
|
l_type = allocs[0].groups()[0]
|
||||||
|
if len(args) == 0:
|
||||||
|
l_arg = None
|
||||||
|
else:
|
||||||
|
l_arg = args[0]
|
||||||
|
if l_type == "res":
|
||||||
|
l_type = f"bytes[{l_arg}]"
|
||||||
|
l_arg = None
|
||||||
|
else: l_type += "*"
|
||||||
|
s += f"{l_type} {l_name}"
|
||||||
|
if l_arg:
|
||||||
|
s += f" = {l_arg}"
|
||||||
|
s += ";"
|
||||||
|
if in_namespace: s += "} // namespace"
|
||||||
|
s += m.group().count('\n') * '\n' # make sure the #lines is the same
|
||||||
|
# pdebug(args, "\n---\n", s)
|
||||||
|
return s
|
||||||
|
|
||||||
|
patterns: dict[str, str|Callable[[re.Match], str]] = {
|
||||||
|
r"\@(?:macro|function)": "@brief",
|
||||||
|
r"^\.scope ([a-zA-Z0-9_]+)": r"namespace \1 {",
|
||||||
|
# r"^\.macro ([a-zA-Z0-9_]+)(.*)?": r"macro \1(\2 \2); ",
|
||||||
|
# r"^\.end(?:macro)": "",
|
||||||
|
r"^\.end(?:scope)": "}",
|
||||||
|
r"^\.(include)": r"#\1",
|
||||||
|
r"^(Export(?:Zp)?) (\w+)((?: *, *\w+)+)": handle_export,
|
||||||
|
r"^(Import(?:Zp)?) (\w+)((?: *, *\w+)+)": "",
|
||||||
|
r"(?<!^;)\$([A-Fa-f0-9_]+)": r"0x\1", # $HEX -> 0xHEX except in comments
|
||||||
|
r"(?<!^;)%([01_]+)": r"0b\1", # %BIN -> 0bBIN except in comments
|
||||||
|
r"^((?:;;.*\n)*)^\.(proc|enum|macro) (\w+)(.*?)\n((?:.|\n)*?)\.end(proc|enum|macro).*": handle_procedure,
|
||||||
|
r"^((?:;;.*\n)*) *(\w+):((?:\s*\.(?:byte|res|dbyte|word|addr|faraddr|dword|ascii|asciiz)(?:[, ]+(?:0x[a-fA-F0-9]+|0b[01]+|\d+|\w+|\"[^\n]*[^\\\n]\")[ \n]*)*)+)": handle_storage_label,
|
||||||
|
r";;": "//!", # C++ comments
|
||||||
|
# TODO this is currently case sensitive
|
||||||
|
r"(?<!^;)( *\w+ *= *[^;,\n]+?) *(//.*)?$": r"\1;\2", # semicolons after assignments, except in comments and when they already end with a comma or semicolon. Also preserve comments after the assignment
|
||||||
|
r"^([^\n;]*)(?<!\w)\.(\w+)": r"\1// #\2", # all .preprocessor commands
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
compiled_patterns = []
|
||||||
|
for k,v in patterns.items():
|
||||||
|
compiled_patterns.append((re.compile(k), v))
|
||||||
|
|
||||||
|
resub_patterns: dict[str, str|Callable[[re.Match], str]] = {
|
||||||
|
r"(?<!^;;)[ \t\r\f\v]+": " ", # turn all spaces into single whitespace except if in doxygen comment
|
||||||
|
r"^((?:[^\"\n;]||[^\"\n;]*\"(?:[^\"\n]|\\\")+\")+);(?!;).*": r"\1", # remove normal comments, detect strings
|
||||||
|
r"^;;\*+": ";;", # remove ;;*** comments
|
||||||
|
r"[ \t\r\f\v]+$": "", # remove trailing spaces print(file_content)
|
||||||
|
|
||||||
|
}
|
||||||
|
for pat, subst in resub_patterns.items():
|
||||||
|
file_content = re.sub(pat, subst, file_content, 0, re.MULTILINE)
|
||||||
|
for pat,subst in patterns.items():
|
||||||
|
pdebug(f"Now doing pattern: {pat}")
|
||||||
|
(file_content, n_subst) = re.subn(pat, subst, file_content, 0, re.MULTILINE)
|
||||||
|
return file_content
|
||||||
|
|
||||||
|
def main():
|
||||||
|
global filename
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print("Usage: python doxy-asm65.py <input_file>")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
filename = sys.argv[1]
|
||||||
|
|
||||||
|
with open(filename, 'r') as file:
|
||||||
|
file_content = file.read()
|
||||||
|
|
||||||
|
transformed_content = parse_custom_language(file_content)
|
||||||
|
|
||||||
|
print(transformed_content)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
@ -5,26 +5,30 @@
|
|||||||
;; This module processes keyboard scancodes from the ps2_keyboard driver.
|
;; This module processes keyboard scancodes from the ps2_keyboard driver.
|
||||||
;; It requires a PS/2 keyboard that supports scancode set 3.
|
;; It requires a PS/2 keyboard that supports scancode set 3.
|
||||||
;;
|
;;
|
||||||
;; @section What it does
|
;; @section what What it does
|
||||||
;; - swallow break (release) scancodes
|
;; - swallow break (release) scancodes
|
||||||
;;
|
;;
|
||||||
;; This handler is designed for debug purposes.
|
;; This handler is designed for debug purposes.
|
||||||
;;
|
;;
|
||||||
;; @section How to use it
|
;; @section usage How to use it
|
||||||
;; Call `kb::init` and check if it was successful (Z = 1).
|
;; Call `kb::init` and check if it was successful (`Z = 1`).
|
||||||
;; In your program loop, check if kb::scancode is 0. If it is not, a key has been pressed.
|
;; In your program loop, check if kb::scancode is 0. If it is not, a key has been pressed.
|
||||||
;;
|
;;
|
||||||
;; @subsection Changing the keyboard behaviour
|
;; @subsection change_behaviour Changing the keyboard behaviour
|
||||||
;; You can change the typematic rate and delay (see PS/2 keyboard command 0xF3)
|
;; You can change the typematic rate and delay (see PS/2 keyboard command `0xF3`)
|
||||||
;; and the typematic behavior (make, make/release, typematic) for all keys.
|
;; and the typematic behavior (make, make/release, typematic) for all keys.
|
||||||
;;
|
;;
|
||||||
;; You may also send the echo (0xEE) and identify (0xF2) commands to the keyboard.
|
;; You may also send the echo (`0xEE`) and identify (`0xF2`) commands to the keyboard.
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
.ifndef INCLUDE_KEYBOARD_SIMPLE
|
.ifndef INCLUDE_KEYBOARD_SIMPLE
|
||||||
INCLUDE_KEYBOARD_SIMPLE = 1
|
INCLUDE_KEYBOARD_SIMPLE = 1
|
||||||
|
|
||||||
.include "ps2_keyboard.h65"
|
.include "ps2_keyboard.h65"
|
||||||
|
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; @brief Simple Keyboard Handler
|
||||||
|
;;********************************************************************************
|
||||||
.scope skb
|
.scope skb
|
||||||
Import skb, init, scancode
|
Import skb, init, scancode
|
||||||
|
|
||||||
|
@ -1,69 +1,76 @@
|
|||||||
|
; normal
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
;; @module ps2_keyboard_text_handler
|
;; @module ps2_keyboard_text_handler
|
||||||
;; @type system
|
;; @type system
|
||||||
;; @details:
|
;; @details
|
||||||
;; This module processes keyboard scancodes from the ps2_keyboard driver.
|
;; This module processes keyboard scancodes from the ps2_keyboard driver.
|
||||||
;; It requires a PS/2 keyboard that supports scancode set 3.
|
;; It requires a PS/2 keyboard that supports scancode set 3.
|
||||||
;;
|
;;
|
||||||
;; @section What it does
|
;; @section what What it does
|
||||||
;; - keeps track of modifier keys: shift, left/right alt, left right meta (super),
|
;; - keeps track of modifier keys: shift, left/right alt, left right meta (super),
|
||||||
;; control, capslock, numlock, scrollock
|
;; control, capslock, numlock, scrollock
|
||||||
;; - convert valid keycodes to chars, dependening on the state of shift and right alt
|
;; - convert valid keycodes to chars, dependening on the state of shift and right alt
|
||||||
;; - update the keyboard LEDs (numlock, capslock,, scrolllock)
|
;; - update the keyboard LEDs (numlock, capslock,, scrolllock)
|
||||||
|
;;
|
||||||
;; This handler is designed for efficient text input.
|
;; This handler is designed for efficient text input.
|
||||||
;; It does not track the status of the keys (except modifiers) and is therefore not suitable for games.
|
;; It does not track the status of the keys (except modifiers) and is therefore not suitable for games.
|
||||||
;;
|
;;
|
||||||
;; @section How it works
|
;; @section working_principle How it works
|
||||||
;; In the init function, the module disables the typematic behaviour for the modifier keys by
|
;; In the init function, the module disables the *typematic* behaviour for the modifier keys by
|
||||||
;; sending commands to the keyboard. The 3 lock keys will be set to make only mode and
|
;; sending commands to the keyboard. The 3 lock keys will be set to *make only* mode and
|
||||||
;; the others to make release.
|
;; the others to *make release*.
|
||||||
;; This makes tracking the modifier keys much easier and is the reason why scancode set 3
|
;; This makes tracking the modifier keys much easier and is the reason why scancode set 3
|
||||||
;; is required, as these commands are only available with that.
|
;; is required, as these commands are only available with this set.
|
||||||
;;
|
;;
|
||||||
;; Using scancode set 3 also adds the benefit that all scancodes are only 1 byte large,
|
;; Using scancode set 3 also adds the benefit that all scancodes are only 1 byte large,
|
||||||
;; making the recognition of scancodes trivial.
|
;; making the recognition of scancodes trivial.
|
||||||
;;
|
;;
|
||||||
;; Scancodes from the keyboard are processed immediately, as the handling functions is called
|
;; Scancodes sent from the keyboard are processed immediately, as the handling functions is called
|
||||||
;; from the keyboard's interrupt handler.
|
;; from the keyboard's interrupt handler.
|
||||||
;;
|
;;
|
||||||
;; @subsection Mapping keycodes to chars
|
;; @subsection mapping Mapping keycodes to chars
|
||||||
;; The mapping of keycodes to chars is done using an array of chars for each state:
|
;; The mapping of keycodes to chars is done using an array of chars for each state:
|
||||||
;; default, shift and right alt. The tables contains the ascii characters, 0 where the keycode does not
|
;; default, shift and right alt. The tables contains the ascii characters, `0` where the keycode does not
|
||||||
;; generate a character and 1 where the keycode is modifier key.
|
;; generate a character and `1` where the keycode is a modifier key.
|
||||||
;; This approach consumes a relatively large amount of ROM (3 * 144 bytes), but is super fast,
|
;; This approach consumes a relatively large amount of ROM (3 * 144 bytes), but is super fast,
|
||||||
;; as loading a character is merely one indexed load instruction.
|
;; as loading a character is merely one indexed load instruction.
|
||||||
;; Checking for mod keys is now also fast, beceause we only have to do 1 comparison to see IF it is a modifier key.
|
;; Checking for mod keys is now also fast, beceause we only have to do 1 comparison to see IF it is a modifier key.
|
||||||
;;
|
;;
|
||||||
;; @section How to use it
|
;; @section usage How to use it
|
||||||
;; Call `kb::init` and check if it was successful (Z = 1).
|
;; Call `kb::init` and check if it was successful (`Z = 1`).
|
||||||
;; In your program loop, check if kb::keycode is 0. If it is not, a key has been pressed.
|
;; In your program loop, check if `kb::keycode` is 0. If it is not, a key has been pressed.
|
||||||
;;
|
;;
|
||||||
;; If the keypress generated a character `kb::char` will be non-zero and contain the character.
|
;; If the keypress generated a character `kb::char` will be non-zero and contain the character.
|
||||||
;;
|
;;
|
||||||
;; Note that if you will probably want to write a 0 to `kb::keycode` and `kb::char`
|
;; Note that if you will probably want to write a 0 to `kb::keycode` and `kb::char`
|
||||||
;; after processing the keycode. This will not be done by the handler.
|
;; after processing the keycode. This will not be done by the handler.
|
||||||
;;
|
;;
|
||||||
;; Conditional branches based on the status of a modifier (SHIFT, RALT, LALT, CTRL, META, NUMLOCK, SCROLLLOCK) can be done
|
;; Conditional branches based on the status of a modifier (`SHIFT`, `RALT`, `LALT`, `CTRL`, `META`, `NUMLOCK`, `SCROLLLOCK`) can be done
|
||||||
;; using the `bbs` and `bbr` instructions, as each modifier is represented by a bit of the `kb::modifier` variable
|
;; using the `bbs` and `bbr` instructions, as each modifier is represented by a bit of the `kb::modifier` variable
|
||||||
;; in the zeropage.
|
;; in the zeropage.
|
||||||
;;
|
;;
|
||||||
;; @subsection Changing the keyboard behaviour
|
;; @subsection change_behaviour Changing the keyboard behaviour
|
||||||
;; You can change the typematic rate and delay (see PS/2 keyboard command 0xF3)
|
;; You can change the typematic rate and delay (see PS/2 keyboard command `0xF3`)
|
||||||
;; and the typematic behavior (make, make/release, typematic) for all keys except the modifier keys.
|
;; and the typematic behavior (make, make/release, typematic) for all keys except the modifier keys.
|
||||||
;;
|
;;
|
||||||
;; You may also send the echo (0xEE) and identify (0xF2) commands to the keyboard.
|
;; You may also send the echo (`0xEE`) and identify (`0xF2`) commands to the keyboard.
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
.ifndef INCLUDE_KEYBOARD_TEXT
|
.ifndef INCLUDE_KEYBOARD_TEXT
|
||||||
INCLUDE_KEYBOARD_TEXT = 1
|
INCLUDE_KEYBOARD_TEXT = 1
|
||||||
|
|
||||||
.include "ps2_keyboard.h65"
|
.include "ps2_keyboard.h65"
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; @brief Keyboard Handler
|
||||||
|
;;********************************************************************************
|
||||||
.scope kb
|
.scope kb
|
||||||
Import kb, init, char, keycode
|
Import kb, init, char, keycode
|
||||||
Import kb, CHARS_NOMOD, CHARS_MODRALT, CHARS_MODSHIFT, CHARS_NUMLOCK_OFF, CHARS_NUMLOCK_ON
|
Import kb, CHARS_NOMOD, CHARS_MODRALT, CHARS_MODSHIFT, CHARS_NUMLOCK_OFF, CHARS_NUMLOCK_ON
|
||||||
ImportZp kb, modifier
|
ImportZp kb, modifier
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; @brief Bitmask for checking modifier keys
|
||||||
|
;;********************************************************************************
|
||||||
.enum MOD
|
.enum MOD
|
||||||
SHIFT = %10000000 ; set if either capslock is on or shift is pressed
|
SHIFT = %10000000 ; set if either capslock is on or shift is pressed
|
||||||
RALT = %01000000 ; set while rightalt is pressed
|
RALT = %01000000 ; set while rightalt is pressed
|
||||||
@ -75,8 +82,12 @@ ImportZp kb, modifier
|
|||||||
SCROLLLOCK = %00000001 ; ps/2 LED
|
SCROLLLOCK = %00000001 ; ps/2 LED
|
||||||
.endenum
|
.endenum
|
||||||
|
|
||||||
|
;; @brief Scancode that is sent by the keyboard when a key is released
|
||||||
K_BREAK = $F0
|
K_BREAK = $F0
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; @brief S3 German Keycodes
|
||||||
|
;;********************************************************************************
|
||||||
.enum K
|
.enum K
|
||||||
F1 = $07
|
F1 = $07
|
||||||
ESCAPE = $08
|
ESCAPE = $08
|
||||||
|
@ -4,11 +4,16 @@ Export kb, CHARS_NOMOD, CHARS_MODRALT, CHARS_MODSHIFT, CHARS_NUMLOCK_OFF, CHARS_
|
|||||||
ExportZp kb, modifier
|
ExportZp kb, modifier
|
||||||
|
|
||||||
.zeropage
|
.zeropage
|
||||||
modifier: .res 1
|
;; @ref kb::MOD "status of the modifier keys"
|
||||||
|
modifier: .byte
|
||||||
.bss
|
.bss
|
||||||
previous_scancode: .res 1 ; all 1 if previous_scancode is break
|
;; previous scancode is used to determine if a key was released (BREAK sent previously)
|
||||||
char: .res 1
|
;; will be $ff if the previous scancode was K_BREAK
|
||||||
keycode: .res 1
|
previous_scancode: .byte
|
||||||
|
;; 0 when no key or non-character key was pressed, otherwise character of the key (with modifiers applied)
|
||||||
|
char: .byte
|
||||||
|
;; @ref kb::K "keycode" of the last key that was pressed or 0 if none was pressed
|
||||||
|
keycode: .byte
|
||||||
|
|
||||||
.code
|
.code
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
@ -101,8 +106,8 @@ set:
|
|||||||
;; @function Process a scancode
|
;; @function Process a scancode
|
||||||
;; @details
|
;; @details
|
||||||
;; Update modifier bits if a mod key is pressed.
|
;; Update modifier bits if a mod key is pressed.
|
||||||
;; If the key is not a mod key, the keycode is stored in kb::keycode
|
;; If the key is not a mod key, the keycode is stored in @ref kb::keycode
|
||||||
;; If the key is an ascii character, the corresponding ascii character is stored in kb::char
|
;; If the key is an ascii character, the corresponding ascii character is stored in @ref kb::char
|
||||||
;; @modifies A, X
|
;; @modifies A, X
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
.proc process_scancode
|
.proc process_scancode
|
||||||
@ -280,6 +285,7 @@ CHARS_NOMOD:
|
|||||||
.byte "\x00nbhgz6\x00\x00\x01mju78\x00"
|
.byte "\x00nbhgz6\x00\x00\x01mju78\x00"
|
||||||
.byte "\x00,kio09\x00\x00.-l\xEFp\xE2\x00"
|
.byte "\x00,kio09\x00\x00.-l\xEFp\xE2\x00"
|
||||||
.byte "\x00\x00\xE1#\xF5`\x00\x00\x01\x01\x00\x00\x00\x00\x00\x01"
|
.byte "\x00\x00\xE1#\xF5`\x00\x00\x01\x01\x00\x00\x00\x00\x00\x01"
|
||||||
|
;; numlock range characters where numlock is off
|
||||||
CHARS_NUMLOCK_OFF:
|
CHARS_NUMLOCK_OFF:
|
||||||
.byte "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
.byte "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||||
.byte "\x00\x00\x00\x00\x00\x00\x01/\x00\x00\x00\x00+\x00*\x00"
|
.byte "\x00\x00\x00\x00\x00\x00\x01/\x00\x00\x00\x00+\x00*\x00"
|
||||||
|
@ -21,6 +21,7 @@ buffer: .res 256
|
|||||||
jsr kb::init
|
jsr kb::init
|
||||||
loop:
|
loop:
|
||||||
lda kb::char
|
lda kb::char
|
||||||
|
ldx ptr
|
||||||
beq @no_char
|
beq @no_char
|
||||||
stz kb::char
|
stz kb::char
|
||||||
jsr lcd::print_char
|
jsr lcd::print_char
|
||||||
@ -42,6 +43,9 @@ clear_display:
|
|||||||
jsr lcd::clear
|
jsr lcd::clear
|
||||||
bra loop
|
bra loop
|
||||||
k_backspace:
|
k_backspace:
|
||||||
; go back
|
lcd_DecrementCursor
|
||||||
lda ' '
|
lda #' '
|
||||||
|
jsr lcd::print_char
|
||||||
|
lcd_DecrementCursor
|
||||||
|
bra loop
|
||||||
.endproc
|
.endproc
|
||||||
|
13
spicode.s65
13
spicode.s65
@ -1,3 +1,10 @@
|
|||||||
|
;;********************************************************************************
|
||||||
|
;; @file
|
||||||
|
;; @details:
|
||||||
|
;; This code is loaded to the computer via a SPI interface
|
||||||
|
;; Currently, it must be loaded to $5000, where the main loop will begin
|
||||||
|
;;********************************************************************************
|
||||||
|
|
||||||
.include "system.h65"
|
.include "system.h65"
|
||||||
.include "string.h65"
|
.include "string.h65"
|
||||||
.include "lcd.h65"
|
.include "lcd.h65"
|
||||||
@ -74,6 +81,12 @@ CODE_START:
|
|||||||
@l1:
|
@l1:
|
||||||
jmp _ps2_keyboard_printer
|
jmp _ps2_keyboard_printer
|
||||||
@l2:
|
@l2:
|
||||||
|
lcd_SetCursorPos $26
|
||||||
|
lda #'6'
|
||||||
|
jsr lcd::print_char
|
||||||
|
lcd_IncrementCursor
|
||||||
|
lda #'8'
|
||||||
|
jsr lcd::print_char
|
||||||
@l3:
|
@l3:
|
||||||
@l4:
|
@l4:
|
||||||
@l5:
|
@l5:
|
||||||
|
@ -17,10 +17,15 @@ INCLUDE_LCD = 1
|
|||||||
|
|
||||||
.include "system/system.h65"
|
.include "system/system.h65"
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; @brief LCD character display
|
||||||
|
;;********************************************************************************
|
||||||
.scope lcd
|
.scope lcd
|
||||||
LCD_IO = IO1
|
LCD_IO = IO1
|
||||||
Import lcd,init,clear,print,print_char,set_position,set_custom_char
|
Import lcd,init,clear,print,print_char,set_position,set_custom_char
|
||||||
Import lcd,_cmd,_wait_nbusy,_write_ram,_read_ram,_charcount
|
Import lcd,_cmd,_wait_nbusy,_write_ram,_read_ram,_set_dd_ram_addr_from_charcount
|
||||||
|
Import lcd,_charcount
|
||||||
|
|
||||||
; PIN MASKS
|
; PIN MASKS
|
||||||
E = %10000000
|
E = %10000000
|
||||||
RW = %01000000
|
RW = %01000000
|
||||||
@ -28,17 +33,23 @@ RS = %00100000
|
|||||||
|
|
||||||
RA_MASK = %11100000
|
RA_MASK = %11100000
|
||||||
|
|
||||||
; LCD Instructions (see datasheet for more)
|
;;********************************************************************************
|
||||||
CMD_CLEAR = %00000001 ; clear display
|
;; LCD Instructions
|
||||||
CMD_ENTRY_MODE = %00000110 ; auto-shift cursor
|
;; @details See LCD-W164B datasheet for a complete list
|
||||||
CMD_DISPLAY_ON = %00001111 ; everything on, with blinking cursor
|
;;********************************************************************************
|
||||||
CMD_SHIFT_CUR_LEFT = %00101000 ; shift the display to the left
|
.enum CMD
|
||||||
CMD_SHIFT_DIS_LEFT = %00111000 ; shift the display to the left
|
CLEAR = %00000001 ;; clear display
|
||||||
CMD_SHIFT_DIS_RIGHT = %00110000 ; shift the display to the right
|
ENTRY_MODE = %00000110 ;; auto-shift cursor
|
||||||
CMD_SHIFT_CUR_RIGHT = %00100000 ; shift the display to the right
|
DISPLAY_ON = %00001111 ;; everything on, with blinking cursor
|
||||||
CMD_FUNCTION_SET = %00111000 ; 8-bit, 4 lines, 5x7 font
|
SHIFT_CUR_LEFT = %00101000 ;; shift the cursor to the left
|
||||||
CMD_SET_CG_ADDRESS = %01000000 ; or with the address
|
SHIFT_DIS_LEFT = %00111000 ;; shift the display to the left
|
||||||
CMD_SET_ADDRESS = %10000000 ; or with the address
|
SHIFT_DIS_RIGHT = %00110000 ;; shift the display to the right
|
||||||
|
SHIFT_CUR_RIGHT = %00100000 ;; shift the cursor to the right
|
||||||
|
FUNCTION_SET = %00111000 ;; 8-bit, 4 lines, 5x7 font
|
||||||
|
SET_CG_ADDRESS = %01000000 ;; or this with the address
|
||||||
|
SET_ADDRESS = %10000000 ;; or this with the address
|
||||||
|
.endenum
|
||||||
|
|
||||||
; LCD Constants
|
; LCD Constants
|
||||||
LINE1 = $00
|
LINE1 = $00
|
||||||
LINE2 = $40
|
LINE2 = $40
|
||||||
@ -100,36 +111,53 @@ LINE4 = $50
|
|||||||
|
|
||||||
|
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
;; @macro Print a null-terminated string
|
;; @macro Set the cursor to the n-th position
|
||||||
;; @param message: Address of the message or string literal
|
;; @param n: Position [0,$40) or a register
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
.macro lcd_SetCursor pos
|
.macro lcd_SetCursorPos n
|
||||||
.if .match (pos, a)
|
.if .match (n, a)
|
||||||
.elseif .match (pos, x)
|
.elseif .match (n, x)
|
||||||
txa
|
txa
|
||||||
.elseif .match (pos, y)
|
.elseif .match (n, y)
|
||||||
tya
|
tya
|
||||||
.else
|
.else
|
||||||
lda #pos
|
lda #n
|
||||||
.endif
|
.endif
|
||||||
sta lcd::_charcount
|
sta lcd::_charcount
|
||||||
jsr lcd::_set_dd_ram_addr_from__charcount
|
jsr lcd::_set_dd_ram_addr_from_charcount
|
||||||
.endmacro
|
.endmacro
|
||||||
|
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
;; @macro Print a null-terminated string
|
;; @macro Move the cursor to the right
|
||||||
;; @param message: Address of the message or string literal
|
;; @param n: Number of characters to move n. Defaults to 1 if not provided
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
.macro lcd_AdvanceCursor n
|
.macro lcd_IncrementCursor n
|
||||||
.ifblank n
|
.ifblank n
|
||||||
inc lcd::_charcount
|
inc lcd::_charcount
|
||||||
|
.elseif n = 1
|
||||||
|
inc lcd::_charcount
|
||||||
.else
|
.else
|
||||||
lda lcd::_charcount
|
lda lcd::_charcount
|
||||||
add n
|
add #n
|
||||||
sta lcd::_charcount
|
sta lcd::_charcount
|
||||||
.endif
|
.endif
|
||||||
jsr lcd::_set_dd_ram_addr_from__charcount
|
jsr lcd::_set_dd_ram_addr_from_charcount
|
||||||
.endmacro
|
.endmacro
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; @macro Move the cursor to the left
|
||||||
|
;; @param n: Number of characters to move n. Defaults to 1 if not provided
|
||||||
|
;;********************************************************************************
|
||||||
|
.macro lcd_DecrementCursor n
|
||||||
|
.ifblank n
|
||||||
|
dec lcd::_charcount
|
||||||
|
.elseif n = 1
|
||||||
|
dec lcd::_charcount
|
||||||
|
.else
|
||||||
|
lda lcd::_charcount
|
||||||
|
sub #n
|
||||||
|
sta lcd::_charcount
|
||||||
|
.endif
|
||||||
|
jsr lcd::_set_dd_ram_addr_from_charcount
|
||||||
|
.endmacro
|
||||||
.endif ; guard
|
.endif ; guard
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
.endif
|
.endif
|
||||||
|
|
||||||
Export lcd,init,clear,print,print_char,set_position,set_custom_char
|
Export lcd,init,clear,print,print_char,set_position,set_custom_char
|
||||||
Export lcd,_cmd,_wait_nbusy,_write_ram,_read_ram,_charcount
|
Export lcd,_cmd,_wait_nbusy,_write_ram,_read_ram,_set_dd_ram_addr_from_charcount
|
||||||
|
Export lcd,_charcount
|
||||||
; RAM VARIABLES
|
; RAM VARIABLES
|
||||||
.bss
|
.bss
|
||||||
_charcount: .res 1
|
_charcount: .res 1
|
||||||
@ -27,13 +28,13 @@ _charcount: .res 1
|
|||||||
sta lcd::LCD_IO+IO::DDRA
|
sta lcd::LCD_IO+IO::DDRA
|
||||||
|
|
||||||
; init lcd
|
; init lcd
|
||||||
lda #lcd::CMD_FUNCTION_SET
|
lda #lcd::CMD::FUNCTION_SET
|
||||||
jsr _cmd
|
jsr _cmd
|
||||||
lda #lcd::CMD_DISPLAY_ON
|
lda #lcd::CMD::DISPLAY_ON
|
||||||
jsr _cmd
|
jsr _cmd
|
||||||
lda #lcd::CMD_CLEAR
|
lda #lcd::CMD::CLEAR
|
||||||
jsr _cmd
|
jsr _cmd
|
||||||
lda #lcd::CMD_ENTRY_MODE
|
lda #lcd::CMD::ENTRY_MODE
|
||||||
jsr _cmd
|
jsr _cmd
|
||||||
|
|
||||||
stz _charcount
|
stz _charcount
|
||||||
@ -74,24 +75,24 @@ _charcount: .res 1
|
|||||||
sta _charcount
|
sta _charcount
|
||||||
pla
|
pla
|
||||||
pha
|
pha
|
||||||
ora #lcd::CMD_SET_ADDRESS
|
ora #lcd::CMD::SET_ADDRESS
|
||||||
jsr _cmd
|
jsr _cmd
|
||||||
; and #(<~lcd::CMD_SET_ADDRESS) ; return original argument
|
; and #(<~lcd::CMD::SET_ADDRESS) ; return original argument
|
||||||
pla
|
pla
|
||||||
rts
|
rts
|
||||||
@invalid:
|
@invalid:
|
||||||
pla ; otherwise stack corruption
|
pla ; otherwise stack corruption
|
||||||
lda #$13
|
lda #$13
|
||||||
sta _charcount
|
sta _charcount
|
||||||
lda #(lcd::CMD_SET_ADDRESS | (lcd::LINE2 + 3))
|
lda #(lcd::CMD::SET_ADDRESS | (lcd::LINE2 + 3))
|
||||||
jsr _cmd
|
jsr _cmd
|
||||||
lda #(lcd::LINE2 + 3)
|
lda #(lcd::LINE2 + 3)
|
||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
;;********************************************************************************
|
;********************************************************************************
|
||||||
;; PRINTING TO LCD
|
; PRINTING TO LCD
|
||||||
;;********************************************************************************
|
;********************************************************************************
|
||||||
|
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
;; @function Clear the display
|
;; @function Clear the display
|
||||||
@ -100,7 +101,7 @@ _charcount: .res 1
|
|||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
.proc clear
|
.proc clear
|
||||||
stz _charcount
|
stz _charcount
|
||||||
lda #lcd::CMD_CLEAR
|
lda #lcd::CMD::CLEAR
|
||||||
jsr _cmd
|
jsr _cmd
|
||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
@ -150,7 +151,7 @@ _charcount: .res 1
|
|||||||
rol ; address is bytes 3-5
|
rol ; address is bytes 3-5
|
||||||
rol
|
rol
|
||||||
rol
|
rol
|
||||||
ora #lcd::CMD_SET_CG_ADDRESS
|
ora #lcd::CMD::SET_CG_ADDRESS
|
||||||
jsr lcd::_cmd
|
jsr lcd::_cmd
|
||||||
ldy #0
|
ldy #0
|
||||||
@loop:
|
@loop:
|
||||||
@ -203,7 +204,7 @@ _charcount: .res 1
|
|||||||
|
|
||||||
|
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
;; @function Send a command to the lcd
|
;; @function Send a @ref lcd::CMD "command" to the lcd
|
||||||
;; @param A: command
|
;; @param A: command
|
||||||
;; @modifies A
|
;; @modifies A
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
@ -289,23 +290,24 @@ _charcount: .res 1
|
|||||||
;; @function Set the LCD DD-RAM Address from the character count
|
;; @function Set the LCD DD-RAM Address from the character count
|
||||||
;; @details
|
;; @details
|
||||||
;; Sets the DD-RAM Address so that a line break occurs after 16 characters
|
;; Sets the DD-RAM Address so that a line break occurs after 16 characters
|
||||||
;; If _charcount is more than $40, the position will be set to line 1.
|
;; If _charcount is more than $40, the position will be set to _charcount % $40
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
.proc _set_dd_ram_addr_from__charcount
|
.proc _set_dd_ram_addr_from_charcount
|
||||||
cmp #$40 ; set to line1 when full
|
cmp #$40 ; set to line1 when full
|
||||||
bcs @wrap_to_line1
|
bcs @wrap_to_line1 ; a € [$40, $ff]
|
||||||
cmp #$10
|
cmp #$10
|
||||||
bcc @line1
|
bcc @line1 ; a € [$00, $0f]
|
||||||
cmp #$20
|
cmp #$20
|
||||||
bcc @line3
|
bcc @line2 ; a € [$10, $1f]
|
||||||
; bra @line4
|
cmp #$30
|
||||||
|
bcc @line3 ; a € [$20, $2f]
|
||||||
|
; bra @line4; a € [$30, $3f]
|
||||||
@line4:
|
@line4:
|
||||||
clc
|
clc
|
||||||
adc #$20 ; _charcount $30-$3f -> $50 - $5f
|
adc #$20 ; _charcount $30-$3f -> $50 - $5f
|
||||||
bra @set_address
|
bra @set_address
|
||||||
@wrap_to_line1:
|
@wrap_to_line1:
|
||||||
sbc #$40
|
and #%00111111
|
||||||
and #%00001111
|
|
||||||
; now every _charcount is mapped between 0 and $3f
|
; now every _charcount is mapped between 0 and $3f
|
||||||
bra @set_address
|
bra @set_address
|
||||||
@line2:
|
@line2:
|
||||||
@ -317,7 +319,7 @@ _charcount: .res 1
|
|||||||
bra @set_address
|
bra @set_address
|
||||||
@line1: ; _charcount $00-$1f -> $00 - $0f - nothing to do
|
@line1: ; _charcount $00-$1f -> $00 - $0f - nothing to do
|
||||||
@set_address:
|
@set_address:
|
||||||
ora #lcd::CMD_SET_ADDRESS
|
ora #lcd::CMD::SET_ADDRESS
|
||||||
jsr _cmd
|
jsr _cmd
|
||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
@ -350,19 +352,19 @@ _charcount: .res 1
|
|||||||
rts
|
rts
|
||||||
@line1:
|
@line1:
|
||||||
stz _charcount
|
stz _charcount
|
||||||
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE1)
|
lda #(lcd::CMD::SET_ADDRESS | lcd::LINE1)
|
||||||
jsr _cmd
|
jsr _cmd
|
||||||
rts
|
rts
|
||||||
@line2:
|
@line2:
|
||||||
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE2)
|
lda #(lcd::CMD::SET_ADDRESS | lcd::LINE2)
|
||||||
jsr _cmd
|
jsr _cmd
|
||||||
rts
|
rts
|
||||||
@line3:
|
@line3:
|
||||||
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE3)
|
lda #(lcd::CMD::SET_ADDRESS | lcd::LINE3)
|
||||||
jsr _cmd
|
jsr _cmd
|
||||||
rts
|
rts
|
||||||
@line4:
|
@line4:
|
||||||
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE4)
|
lda #(lcd::CMD::SET_ADDRESS | lcd::LINE4)
|
||||||
jsr _cmd
|
jsr _cmd
|
||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
;; @type driver
|
;; @type driver
|
||||||
;; @details:
|
;; @details:
|
||||||
;; Support for a PS2 Keyboard using the shift register of a 6522 VIA
|
;; Support for a PS2 Keyboard using the shift register of a 6522 VIA
|
||||||
;; @section Reading a scancode/command answer
|
;; @section reading Reading a scancode/command answer
|
||||||
;; Pressing a key causes 11 bits to be sent: 1 start - 8 scancode - 1 parity - 1 stop
|
;; Pressing a key causes 11 bits to be sent: 1 start - 8 scancode - 1 parity - 1 stop
|
||||||
;; The VIA is set up to interrupt after 8 bits have been shifted into the shift register
|
;; The VIA is set up to interrupt after 8 bits have been shifted into the shift register
|
||||||
;; from the external clock pulses of the keyboard (additional hardware required to
|
;; from the external clock pulses of the keyboard (additional hardware required to
|
||||||
@ -12,10 +12,10 @@
|
|||||||
;; the VIAs T2 timer is set to interrupt after the last 3 bits have been shifted in,
|
;; the VIAs T2 timer is set to interrupt after the last 3 bits have been shifted in,
|
||||||
;; which takes about ~230ms.
|
;; which takes about ~230ms.
|
||||||
;; T2 is used because it leaves to more versatile T1 available for something else
|
;; T2 is used because it leaves to more versatile T1 available for something else
|
||||||
|
;;
|
||||||
;; @section Processing a scancode
|
;; @section processing Processing a scancode
|
||||||
;; The scancode may be processed by storing the address of a handler subroutine in
|
;; The scancode may be processed by storing the address of a handler subroutine in
|
||||||
;; ps2kb::scancode_handler. This handler can load the scancode byte from ps2kb::scancode.
|
;; `ps2kb::scancode_handler`. This handler can load the scancode byte from `ps2kb::scancode`.
|
||||||
;;
|
;;
|
||||||
;;
|
;;
|
||||||
;; To use a different layout, change the enum K and the CHARS_NOMOD and CHARS_MODSHIFT
|
;; To use a different layout, change the enum K and the CHARS_NOMOD and CHARS_MODSHIFT
|
||||||
|
@ -21,7 +21,7 @@ scancode_handler: .res 2 ; pointer to a function that handles new scancod
|
|||||||
|
|
||||||
.code
|
.code
|
||||||
|
|
||||||
; these are macros the save time during the interrupt handler (no jsr, rts)
|
; these are macros and not subroutines to save time during the interrupt handler (no jsr, rts)
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
;; @macro Enable the clock signal from the keyboard
|
;; @macro Enable the clock signal from the keyboard
|
||||||
;; @modifies: A
|
;; @modifies: A
|
||||||
@ -242,7 +242,7 @@ scancode_handler: .res 2 ; pointer to a function that handles new scancod
|
|||||||
;; - 0: command response
|
;; - 0: command response
|
||||||
;; - 1: NO_RESPONSE or additional response byte (identify keyboard command only)
|
;; - 1: NO_RESPONSE or additional response byte (identify keyboard command only)
|
||||||
;; - 2: NO_RESPONSE or additional response byte (identify keyboard command only)
|
;; - 2: NO_RESPONSE or additional response byte (identify keyboard command only)
|
||||||
|
;;
|
||||||
;; If the command did have a data byte, cmd_response is:
|
;; If the command did have a data byte, cmd_response is:
|
||||||
;; - 0: 0xFA (ACK) or 0xFE (Resend/Error)
|
;; - 0: 0xFA (ACK) or 0xFE (Resend/Error)
|
||||||
;; - 1: 0xFA (ACK) or 0xFE (Resend/Error)
|
;; - 1: 0xFA (ACK) or 0xFE (Resend/Error)
|
||||||
@ -399,7 +399,6 @@ scancode_handler: .res 2 ; pointer to a function that handles new scancod
|
|||||||
;; - 0: command response
|
;; - 0: command response
|
||||||
;; - 1: NO_RESPONSE or additional response byte (identify keyboard command only)
|
;; - 1: NO_RESPONSE or additional response byte (identify keyboard command only)
|
||||||
;; - 2: NO_RESPONSE or additional response byte (identify keyboard command only)
|
;; - 2: NO_RESPONSE or additional response byte (identify keyboard command only)
|
||||||
|
|
||||||
;; If the command did have a data byte, cmd_response is:
|
;; If the command did have a data byte, cmd_response is:
|
||||||
;; - 0: 0xFA (ACK) or 0xFE (Resend/Error)
|
;; - 0: 0xFA (ACK) or 0xFE (Resend/Error)
|
||||||
;; - 1: 0xFA (ACK) or 0xFE (Resend/Error)
|
;; - 1: 0xFA (ACK) or 0xFE (Resend/Error)
|
||||||
|
@ -10,13 +10,22 @@ INCLUDE_SPI = 1
|
|||||||
|
|
||||||
.include "system/system.h65"
|
.include "system/system.h65"
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; @brief SPI-Peripheral
|
||||||
|
;;********************************************************************************
|
||||||
.scope spi_p
|
.scope spi_p
|
||||||
|
|
||||||
|
|
||||||
SPI_IO = IO2
|
SPI_IO = IO2
|
||||||
Import spi_p, init, irq_handler, status, buffer_size, recv_size
|
Import spi_p, init, irq_handler, status, buffer_size, recv_size
|
||||||
ImportZp spi_p, buffer_ptr
|
ImportZp spi_p, buffer_ptr
|
||||||
Import spi_p, begin_read, end_read, irq_read_byte, recv_bytes
|
Import spi_p, begin_read, end_read, irq_read_byte, recv_bytes
|
||||||
Import spi_p, begin_write, end_write, irq_write_byte, sent_bytes
|
Import spi_p, begin_write, end_write, irq_write_byte, sent_bytes
|
||||||
|
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; @brief Status of a SPI transfer
|
||||||
|
;;********************************************************************************
|
||||||
.enum STATUS
|
.enum STATUS
|
||||||
XFER_SIZEL = %10000000
|
XFER_SIZEL = %10000000
|
||||||
XFER_SIZEH = %01000000
|
XFER_SIZEH = %01000000
|
||||||
|
@ -206,12 +206,12 @@ end_write:
|
|||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
;;;********************************************************************************
|
;********************************************************************************
|
||||||
;;; @function Write a byte
|
; @function Write a byte
|
||||||
;;; @details
|
; @details
|
||||||
;;; Write a byte to the spi shift reister
|
; Write a byte to the spi shift reister
|
||||||
;;; @modifies A,Y
|
; @modifies A,Y
|
||||||
;;;********************************************************************************
|
;********************************************************************************
|
||||||
;.proc irq_write_byte
|
;.proc irq_write_byte
|
||||||
; ldy sent_bytes
|
; ldy sent_bytes
|
||||||
; lda (buffer_ptr),y
|
; lda (buffer_ptr),y
|
||||||
|
@ -10,12 +10,21 @@ INCLUDE_STRING = 1
|
|||||||
.include "system/system.h65"
|
.include "system/system.h65"
|
||||||
|
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; @brief String utility
|
||||||
|
;;********************************************************************************
|
||||||
.scope str
|
.scope str
|
||||||
Import str, strf, printf_buffer
|
Import str, strf, printf_buffer
|
||||||
Import str, hex_char_to_uint8, hex_str_to_uint
|
Import str, hex_char_to_uint8, hex_str_to_uint
|
||||||
Import str, uint8_to_hex_str, uint_to_hex_str
|
Import str, uint8_to_hex_str, uint_to_hex_str
|
||||||
|
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; @macro Helper for str::Strf macro
|
||||||
|
;; @details
|
||||||
|
;; Store arg in ARG4-ARG... and increment counter variable @N_ARGS one.
|
||||||
|
;; Arg can be x, y, immediate or an address
|
||||||
|
;;********************************************************************************
|
||||||
.macro _StrfStoreArg arg
|
.macro _StrfStoreArg arg
|
||||||
.if (.not .blank(arg))
|
.if (.not .blank(arg))
|
||||||
.if .match(arg, x)
|
.if .match(arg, x)
|
||||||
@ -31,13 +40,13 @@ Import str, uint8_to_hex_str, uint_to_hex_str
|
|||||||
.endmacro
|
.endmacro
|
||||||
|
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
;; @function Macro for passing arguments to strf
|
;; @macro Macro for passing arguments to strf
|
||||||
;; @param fmt: Format string address or string literal
|
;; @param fmt: Format string address or string literal
|
||||||
;; @param out: Output string address
|
;; @param out: Output string address
|
||||||
;; @param x0-x9: Additional parameters
|
;; @param x0-x9: Additional parameters
|
||||||
;; @warning Addresses as additional paramters must be passed like this `#<addr,#>addr`
|
;; @warning Addresses as additional paramters must be passed like this `#<addr,#>addr`
|
||||||
;; @modifies: A, X, Y, ARG4, ARG5
|
;; @modifies: A, X, Y, ARG4, ARG5
|
||||||
;; @see strf
|
;; @see str::strf
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
.macro Strf fmt,out,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9
|
.macro Strf fmt,out,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9
|
||||||
@N_ARGS .set 0 ; @ so that it doesnt break cheap labels
|
@N_ARGS .set 0 ; @ so that it doesnt break cheap labels
|
||||||
@ -74,6 +83,12 @@ Import str, uint8_to_hex_str, uint_to_hex_str
|
|||||||
; .out .sprintf("info: Strf: called with %d arguments", @N_ARGS)
|
; .out .sprintf("info: Strf: called with %d arguments", @N_ARGS)
|
||||||
.endmacro
|
.endmacro
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; @function Macro for formated printing
|
||||||
|
;; @details
|
||||||
|
;; Pass all arguments to str::Strf macro, then call lcd::PrintNC macro
|
||||||
|
;; @see str::strf
|
||||||
|
;;********************************************************************************
|
||||||
.macro Printf fmt,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9
|
.macro Printf fmt,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9
|
||||||
Strf fmt,str::printf_buffer,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9
|
Strf fmt,str::printf_buffer,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9
|
||||||
PrintNC str::printf_buffer
|
PrintNC str::printf_buffer
|
||||||
|
Loading…
Reference in New Issue
Block a user