; *************************************************************************** ; copyright : (C) 2026 by Martin Preuss ; email : martin@libchipcard.de ; ; *************************************************************************** ; * This file is part of the project "AqHome". * ; * Please see toplevel file COPYING of that project for license details. * ; *************************************************************************** #ifndef AQH_AVR_DEVICES_ALL_HANDLEVALUEMSG_ASM #define AQH_AVR_DEVICES_ALL_HANDLEVALUEMSG_ASM ; table: ; Byte 0 : command ; Byte 1 : value ; Byte 2, 3: handler fn ; CF set: send ACK ; *************************************************************************** ; defines .equ HANDLEVALUEMSG_OFFS_COMMAND = 0 .equ HANDLEVALUEMSG_OFFS_VALUEID = 1 .equ HANDLEVALUEMSG_OFFS_HANDLER_LO = 2 .equ HANDLEVALUEMSG_OFFS_HANDLER_HI = 3 .equ HANDLEVALUEMSG_SIZE = 4 ; *************************************************************************** ; code .cseg ; --------------------------------------------------------------------------- ; @routine Main_HandleValueMsg ; ; Finds a handler for the given message using a table. ; Input for the hander routine is the result of @ref NETMSG_ValueRead ; Output from the handler is CFLAG set if ACK should be send, in this case r23 ; should contain the command code to use for the ACK message. ; ; @param Z byte address pointer to handler table (for LPM!) ; @param X pointer to msg ; @param Y argument for handler routine ; @return CFLAG set if msg handled, cleared otherwise ; @clobbers any Main_HandleValueMsg: bigcall NETMSG_ValueRead push r22 push r24 push r25 rcall mainFindEntryForValueMsg ; CF set: Z=routine (r16, r22, r24, r25, Z) pop r25 pop r24 pop r22 brcc Main_HandleValueMsg_ret ; not found, jmp push xl push xh icall ; handler, in: y=arg out: CF=needAck, r23=command pop xh pop xl brcs Main_HandleValueMsg_sendAck sec rjmp Main_HandleValueMsg_ret Main_HandleValueMsg_sendAck: push r23 bigcall NETMSG_ValueRead pop r23 push xl push xh bigcall Main_SendValueResponse ; (R16, R17, R18, R19, R20, R21, R23, R24, R25, X, Y) pop xh pop xl sec Main_HandleValueMsg_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine mainFindEntryForValueMsg ; ; @param Z byte address pointer to handler table (for LPM!) ; @param r17 value id ; @param r23 command ; @return CFLAG set if entry found ; @param r25:r24 word address pointer to handler routine ; @clobbers r16, r22, r24, r25, Z mainFindEntryForValueMsg: mainFindEntryForValueMsg_loop: lpm r16, Z+ ; command lpm r22, Z+ ; value id lpm r24, Z+ ; routine lo lpm r25, Z+ ; routine hi tst r24 brne mainFindEntryForValueMsg_l0 tst r25 breq mainFindEntryForValueMsg_notFound mainFindEntryForValueMsg_l0: tst r16 ; command breq mainFindEntryForValueMsg_l1 cp r16, r23 brne mainFindEntryForValueMsg_next mainFindEntryForValueMsg_l1: tst r22 ; value id breq mainFindEntryForValueMsg_l2 cp r22, r17 brne mainFindEntryForValueMsg_next mainFindEntryForValueMsg_l2: mov zl, r24 mov zh, r25 sec rjmp mainFindEntryForValueMsg_ret mainFindEntryForValueMsg_next: rjmp mainFindEntryForValueMsg_loop mainFindEntryForValueMsg_notFound: clc mainFindEntryForValueMsg_ret: ret ; @end #endif