You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

action.c 24KB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. /*
  2. Copyright 2012,2013 Jun Wako <[email protected]>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include "host.h"
  15. #include "keycode.h"
  16. #include "keyboard.h"
  17. #include "mousekey.h"
  18. #include "command.h"
  19. #include "debug.h"
  20. #include "led.h"
  21. #include "layer_switch.h"
  22. #include "action_tapping.h"
  23. #include "action_oneshot.h"
  24. #include "action_macro.h"
  25. #include "action.h"
  26. void action_exec(keyevent_t event)
  27. {
  28. if (!IS_NOEVENT(event)) {
  29. debug("\n---- action_exec: start -----\n");
  30. debug("EVENT: "); debug_event(event); debug("\n");
  31. }
  32. keyrecord_t record = { .event = event };
  33. #ifndef NO_ACTION_TAPPING
  34. action_tapping_process(record);
  35. #else
  36. process_action(&record);
  37. if (!IS_NOEVENT(record.event)) {
  38. debug("processed: "); debug_record(record); debug("\n");
  39. }
  40. #endif
  41. }
  42. void process_action(keyrecord_t *record)
  43. {
  44. keyevent_t event = record->event;
  45. uint8_t tap_count = record->tap.count;
  46. if (IS_NOEVENT(event)) { return; }
  47. action_t action = layer_switch_get_action(event.key);
  48. debug("ACTION: "); debug_action(action);
  49. debug(" overlays: "); overlay_debug();
  50. debug(" keymaps: "); keymap_debug();
  51. debug(" default_layer: "); debug_dec(default_layer); debug("\n");
  52. switch (action.kind.id) {
  53. /* Key and Mods */
  54. case ACT_LMODS:
  55. case ACT_RMODS:
  56. {
  57. uint8_t mods = (action.kind.id == ACT_LMODS) ? action.key.mods :
  58. action.key.mods<<4;
  59. if (event.pressed) {
  60. uint8_t tmp_mods = host_get_mods();
  61. if (mods) {
  62. host_add_mods(mods);
  63. host_send_keyboard_report();
  64. }
  65. register_code(action.key.code);
  66. if (mods && action.key.code) {
  67. host_set_mods(tmp_mods);
  68. host_send_keyboard_report();
  69. }
  70. } else {
  71. if (mods && !action.key.code) {
  72. host_del_mods(mods);
  73. host_send_keyboard_report();
  74. }
  75. unregister_code(action.key.code);
  76. }
  77. }
  78. break;
  79. #ifndef NO_ACTION_TAPPING
  80. case ACT_LMODS_TAP:
  81. case ACT_RMODS_TAP:
  82. {
  83. uint8_t mods = (action.kind.id == ACT_LMODS_TAP) ? action.key.mods :
  84. action.key.mods<<4;
  85. switch (action.layer.code) {
  86. #ifndef NO_ACTION_ONESHOT
  87. case 0x00:
  88. // Oneshot modifier
  89. if (event.pressed) {
  90. if (tap_count == 0) {
  91. debug("MODS_TAP: Oneshot: add_mods\n");
  92. add_mods(mods);
  93. }
  94. else if (tap_count == 1) {
  95. debug("MODS_TAP: Oneshot: start\n");
  96. oneshot_start(mods);
  97. }
  98. else if (tap_count == TAPPING_TOGGLE) {
  99. debug("MODS_TAP: Oneshot: toggle\n");
  100. oneshot_toggle();
  101. }
  102. else {
  103. debug("MODS_TAP: Oneshot: cancel&add_mods\n");
  104. // double tap cancels oneshot and works as normal modifier.
  105. oneshot_cancel();
  106. add_mods(mods);
  107. }
  108. } else {
  109. if (tap_count == 0) {
  110. debug("MODS_TAP: Oneshot: cancel/del_mods\n");
  111. // cancel oneshot on hold
  112. oneshot_cancel();
  113. del_mods(mods);
  114. }
  115. else if (tap_count == 1) {
  116. debug("MODS_TAP: Oneshot: del_mods\n");
  117. // retain Oneshot
  118. del_mods(mods);
  119. }
  120. else {
  121. debug("MODS_TAP: Oneshot: del_mods\n");
  122. // cancel Mods
  123. del_mods(mods);
  124. }
  125. }
  126. break;
  127. #endif
  128. default:
  129. if (event.pressed) {
  130. if (tap_count > 0) {
  131. if (record->tap.interrupted) {
  132. debug("MODS_TAP: Tap: Cancel: add_mods\n");
  133. // ad hoc: set 0 to cancel tap
  134. record->tap.count = 0;
  135. add_mods(mods);
  136. } else {
  137. debug("MODS_TAP: Tap: register_code\n");
  138. register_code(action.key.code);
  139. }
  140. } else {
  141. debug("MODS_TAP: No tap: add_mods\n");
  142. add_mods(mods);
  143. }
  144. } else {
  145. if (tap_count > 0) {
  146. debug("MODS_TAP: Tap: unregister_code\n");
  147. unregister_code(action.key.code);
  148. } else {
  149. debug("MODS_TAP: No tap: add_mods\n");
  150. del_mods(mods);
  151. }
  152. }
  153. break;
  154. }
  155. }
  156. break;
  157. #endif
  158. #ifdef EXTRAKEY_ENABLE
  159. /* other HID usage */
  160. case ACT_USAGE:
  161. switch (action.usage.page) {
  162. case PAGE_SYSTEM:
  163. if (event.pressed) {
  164. host_system_send(action.usage.code);
  165. } else {
  166. host_system_send(0);
  167. }
  168. break;
  169. case PAGE_CONSUMER:
  170. if (event.pressed) {
  171. host_consumer_send(action.usage.code);
  172. } else {
  173. host_consumer_send(0);
  174. }
  175. break;
  176. }
  177. break;
  178. #endif
  179. #ifdef MOUSEKEY_ENABLE
  180. /* Mouse key */
  181. case ACT_MOUSEKEY:
  182. if (event.pressed) {
  183. mousekey_on(action.key.code);
  184. mousekey_send();
  185. } else {
  186. mousekey_off(action.key.code);
  187. mousekey_send();
  188. }
  189. break;
  190. #endif
  191. #ifndef NO_ACTION_KEYMAP
  192. case ACT_KEYMAP:
  193. switch (action.layer.code) {
  194. /* Keymap clear */
  195. case OP_RESET:
  196. switch (action.layer.val & 0x03) {
  197. case 0:
  198. // NOTE: reserved
  199. overlay_clear();
  200. keymap_clear();
  201. break;
  202. case ON_PRESS:
  203. if (event.pressed) {
  204. overlay_clear();
  205. keymap_clear();
  206. }
  207. break;
  208. case ON_RELEASE:
  209. if (!event.pressed) {
  210. overlay_clear();
  211. keymap_clear();
  212. }
  213. break;
  214. case ON_BOTH:
  215. overlay_clear();
  216. keymap_clear();
  217. break;
  218. /* NOTE: 4-7 rserved */
  219. }
  220. break;
  221. /* Keymap Reset default layer */
  222. case (OP_RESET | ON_PRESS):
  223. if (event.pressed) {
  224. default_layer_set(action.layer.val);
  225. }
  226. break;
  227. case (OP_RESET | ON_RELEASE):
  228. if (!event.pressed) {
  229. default_layer_set(action.layer.val);
  230. }
  231. break;
  232. case (OP_RESET | ON_BOTH):
  233. default_layer_set(action.layer.val);
  234. break;
  235. /* Keymap Bit invert */
  236. case OP_INV:
  237. /* with tap toggle */
  238. if (event.pressed) {
  239. if (tap_count < TAPPING_TOGGLE) {
  240. debug("KEYMAP_INV: tap toggle(press).\n");
  241. keymap_invert(action.layer.val);
  242. }
  243. } else {
  244. if (tap_count <= TAPPING_TOGGLE) {
  245. debug("KEYMAP_INV: tap toggle(release).\n");
  246. keymap_invert(action.layer.val);
  247. }
  248. }
  249. break;
  250. case (OP_INV | ON_PRESS):
  251. if (event.pressed) {
  252. keymap_invert(action.layer.val);
  253. }
  254. break;
  255. case (OP_INV | ON_RELEASE):
  256. if (!event.pressed) {
  257. keymap_invert(action.layer.val);
  258. }
  259. break;
  260. case (OP_INV | ON_BOTH):
  261. keymap_invert(action.layer.val);
  262. break;
  263. /* Keymap Bit on */
  264. case OP_ON:
  265. if (event.pressed) {
  266. keymap_on(action.layer.val);
  267. } else {
  268. keymap_off(action.layer.val);
  269. }
  270. break;
  271. case (OP_ON | ON_PRESS):
  272. if (event.pressed) {
  273. keymap_on(action.layer.val);
  274. }
  275. break;
  276. case (OP_ON | ON_RELEASE):
  277. if (!event.pressed) {
  278. keymap_on(action.layer.val);
  279. }
  280. break;
  281. case (OP_ON | ON_BOTH):
  282. keymap_on(action.layer.val);
  283. break;
  284. /* Keymap Bit off */
  285. case OP_OFF:
  286. if (event.pressed) {
  287. keymap_off(action.layer.val);
  288. } else {
  289. keymap_on(action.layer.val);
  290. }
  291. break;
  292. case (OP_OFF | ON_PRESS):
  293. if (event.pressed) {
  294. keymap_off(action.layer.val);
  295. }
  296. break;
  297. case (OP_OFF | ON_RELEASE):
  298. if (!event.pressed) {
  299. keymap_off(action.layer.val);
  300. }
  301. break;
  302. case (OP_OFF | ON_BOTH):
  303. keymap_off(action.layer.val);
  304. break;
  305. /* Keymap Bit set */
  306. case OP_SET:
  307. if (event.pressed) {
  308. keymap_set(action.layer.val);
  309. } else {
  310. keymap_clear();
  311. }
  312. break;
  313. case (OP_SET | ON_PRESS):
  314. if (event.pressed) {
  315. keymap_set(action.layer.val);
  316. }
  317. break;
  318. case (OP_SET | ON_RELEASE):
  319. if (!event.pressed) {
  320. keymap_set(action.layer.val);
  321. }
  322. break;
  323. case (OP_SET | ON_BOTH):
  324. keymap_set(action.layer.val);
  325. break;
  326. /* Keymap Bit invert with tap key */
  327. default:
  328. if (event.pressed) {
  329. if (tap_count > 0) {
  330. debug("KEYMAP_TAP_KEY: Tap: register_code\n");
  331. register_code(action.layer.code);
  332. } else {
  333. debug("KEYMAP_TAP_KEY: No tap: On on press\n");
  334. keymap_on(action.layer.val);
  335. }
  336. } else {
  337. if (tap_count > 0) {
  338. debug("KEYMAP_TAP_KEY: Tap: unregister_code\n");
  339. unregister_code(action.layer.code);
  340. } else {
  341. debug("KEYMAP_TAP_KEY: No tap: Off on release\n");
  342. keymap_off(action.layer.val);
  343. }
  344. }
  345. break;
  346. }
  347. break;
  348. #endif
  349. #ifndef NO_ACTION_OVERLAY
  350. case ACT_OVERLAY:
  351. switch (action.layer.code) {
  352. // Overlay Invert bit4
  353. case OP_INV4 | 0:
  354. if (action.layer.val == 0) {
  355. // NOTE: reserved for future use
  356. overlay_clear();
  357. } else {
  358. overlay_set(overlay_stat ^ action.layer.val);
  359. }
  360. break;
  361. case OP_INV4 | 1:
  362. if (action.layer.val == 0) {
  363. // on pressed
  364. if (event.pressed) overlay_clear();
  365. } else {
  366. overlay_set(overlay_stat ^ action.layer.val<<4);
  367. }
  368. break;
  369. case OP_INV4 | 2:
  370. if (action.layer.val == 0) {
  371. // on released
  372. if (!event.pressed) overlay_clear();
  373. } else {
  374. overlay_set(overlay_stat ^ action.layer.val<<8);
  375. }
  376. break;
  377. case OP_INV4 | 3:
  378. if (action.layer.val == 0) {
  379. // on both
  380. overlay_clear();
  381. } else {
  382. overlay_set(overlay_stat ^ action.layer.val<<12);
  383. }
  384. break;
  385. /* Overlay Bit invert */
  386. case OP_INV:
  387. /* with tap toggle */
  388. if (event.pressed) {
  389. if (tap_count < TAPPING_TOGGLE) {
  390. debug("OVERLAY_INV: tap toggle(press).\n");
  391. overlay_invert(action.layer.val);
  392. }
  393. } else {
  394. if (tap_count <= TAPPING_TOGGLE) {
  395. debug("OVERLAY_INV: tap toggle(release).\n");
  396. overlay_invert(action.layer.val);
  397. }
  398. }
  399. break;
  400. case (OP_INV | ON_PRESS):
  401. if (event.pressed) {
  402. overlay_invert(action.layer.val);
  403. }
  404. break;
  405. case (OP_INV | ON_RELEASE):
  406. if (!event.pressed) {
  407. overlay_invert(action.layer.val);
  408. }
  409. break;
  410. case (OP_INV | ON_BOTH):
  411. overlay_invert(action.layer.val);
  412. break;
  413. /* Overlay Bit on */
  414. case OP_ON:
  415. if (event.pressed) {
  416. overlay_on(action.layer.val);
  417. } else {
  418. overlay_off(action.layer.val);
  419. }
  420. break;
  421. case (OP_ON | ON_PRESS):
  422. if (event.pressed) {
  423. overlay_on(action.layer.val);
  424. }
  425. break;
  426. case (OP_ON | ON_RELEASE):
  427. if (!event.pressed) {
  428. overlay_on(action.layer.val);
  429. }
  430. break;
  431. case (OP_ON | ON_BOTH):
  432. overlay_on(action.layer.val);
  433. break;
  434. /* Overlay Bit off */
  435. case OP_OFF:
  436. if (event.pressed) {
  437. overlay_off(action.layer.val);
  438. } else {
  439. overlay_on(action.layer.val);
  440. }
  441. break;
  442. case (OP_OFF | ON_PRESS):
  443. if (event.pressed) {
  444. overlay_off(action.layer.val);
  445. }
  446. break;
  447. case (OP_OFF | ON_RELEASE):
  448. if (!event.pressed) {
  449. overlay_off(action.layer.val);
  450. }
  451. break;
  452. case (OP_OFF | ON_BOTH):
  453. overlay_off(action.layer.val);
  454. break;
  455. /* Overlay Bit set */
  456. case OP_SET:
  457. if (event.pressed) {
  458. overlay_move(action.layer.val);
  459. } else {
  460. overlay_clear();
  461. }
  462. break;
  463. case (OP_SET | ON_PRESS):
  464. if (event.pressed) {
  465. overlay_move(action.layer.val);
  466. }
  467. break;
  468. case (OP_SET | ON_RELEASE):
  469. if (!event.pressed) {
  470. overlay_move(action.layer.val);
  471. }
  472. break;
  473. case (OP_SET | ON_BOTH):
  474. overlay_move(action.layer.val);
  475. break;
  476. /* Overlay Bit invert with tap key */
  477. default:
  478. if (event.pressed) {
  479. if (tap_count > 0) {
  480. debug("OVERLAY_TAP_KEY: Tap: register_code\n");
  481. register_code(action.layer.code);
  482. } else {
  483. debug("OVERLAY_TAP_KEY: No tap: On on press\n");
  484. overlay_on(action.layer.val);
  485. }
  486. } else {
  487. if (tap_count > 0) {
  488. debug("OVERLAY_TAP_KEY: Tap: unregister_code\n");
  489. unregister_code(action.layer.code);
  490. } else {
  491. debug("OVERLAY_TAP_KEY: No tap: Off on release\n");
  492. overlay_off(action.layer.val);
  493. }
  494. }
  495. break;
  496. }
  497. break;
  498. #endif
  499. /* Extentions */
  500. #ifndef NO_ACTION_MACRO
  501. case ACT_MACRO:
  502. action_macro_play(action_get_macro(record, action.func.id, action.func.opt));
  503. break;
  504. #endif
  505. case ACT_COMMAND:
  506. break;
  507. #ifndef NO_ACTION_FUNCTION
  508. case ACT_FUNCTION:
  509. action_function(record, action.func.id, action.func.opt);
  510. break;
  511. #endif
  512. default:
  513. break;
  514. }
  515. }
  516. /*
  517. * Utilities for actions.
  518. */
  519. void register_code(uint8_t code)
  520. {
  521. if (code == KC_NO) {
  522. return;
  523. }
  524. #ifdef CAPSLOCK_LOCKING_ENABLE
  525. else if (KC_LOCKING_CAPS == code) {
  526. #ifdef CAPSLOCK_LOCKING_RESYNC_ENABLE
  527. // Resync: ignore if caps lock already is on
  528. if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) return;
  529. #endif
  530. host_add_key(KC_CAPSLOCK);
  531. host_send_keyboard_report();
  532. host_del_key(KC_CAPSLOCK);
  533. host_send_keyboard_report();
  534. }
  535. #endif
  536. else if IS_KEY(code) {
  537. // TODO: should push command_proc out of this block?
  538. if (command_proc(code)) return;
  539. #ifndef NO_ACTION_ONESHOT
  540. if (oneshot_state.mods && !oneshot_state.disabled) {
  541. uint8_t tmp_mods = host_get_mods();
  542. host_add_mods(oneshot_state.mods);
  543. host_add_key(code);
  544. host_send_keyboard_report();
  545. host_set_mods(tmp_mods);
  546. oneshot_cancel();
  547. } else
  548. #endif
  549. {
  550. host_add_key(code);
  551. host_send_keyboard_report();
  552. }
  553. }
  554. else if IS_MOD(code) {
  555. host_add_mods(MOD_BIT(code));
  556. host_send_keyboard_report();
  557. }
  558. }
  559. void unregister_code(uint8_t code)
  560. {
  561. if (code == KC_NO) {
  562. return;
  563. }
  564. #ifdef CAPSLOCK_LOCKING_ENABLE
  565. else if (KC_LOCKING_CAPS == code) {
  566. #ifdef CAPSLOCK_LOCKING_RESYNC_ENABLE
  567. // Resync: ignore if caps lock already is off
  568. if (!(host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK))) return;
  569. #endif
  570. host_add_key(KC_CAPSLOCK);
  571. host_send_keyboard_report();
  572. host_del_key(KC_CAPSLOCK);
  573. host_send_keyboard_report();
  574. }
  575. #endif
  576. else if IS_KEY(code) {
  577. host_del_key(code);
  578. host_send_keyboard_report();
  579. }
  580. else if IS_MOD(code) {
  581. host_del_mods(MOD_BIT(code));
  582. host_send_keyboard_report();
  583. }
  584. }
  585. void add_mods(uint8_t mods)
  586. {
  587. if (mods) {
  588. host_add_mods(mods);
  589. host_send_keyboard_report();
  590. }
  591. }
  592. void del_mods(uint8_t mods)
  593. {
  594. if (mods) {
  595. host_del_mods(mods);
  596. host_send_keyboard_report();
  597. }
  598. }
  599. void set_mods(uint8_t mods)
  600. {
  601. host_set_mods(mods);
  602. host_send_keyboard_report();
  603. }
  604. void clear_keyboard(void)
  605. {
  606. host_clear_mods();
  607. clear_keyboard_but_mods();
  608. }
  609. void clear_keyboard_but_mods(void)
  610. {
  611. host_clear_keys();
  612. host_send_keyboard_report();
  613. #ifdef MOUSEKEY_ENABLE
  614. mousekey_clear();
  615. mousekey_send();
  616. #endif
  617. #ifdef EXTRAKEY_ENABLE
  618. host_system_send(0);
  619. host_consumer_send(0);
  620. #endif
  621. }
  622. bool sending_anykey(void)
  623. {
  624. return (host_has_anykey() || host_mouse_in_use() ||
  625. host_last_sysytem_report() || host_last_consumer_report());
  626. }
  627. bool is_tap_key(key_t key)
  628. {
  629. action_t action = layer_switch_get_action(key);
  630. switch (action.kind.id) {
  631. case ACT_LMODS_TAP:
  632. case ACT_RMODS_TAP:
  633. return true;
  634. case ACT_KEYMAP:
  635. case ACT_OVERLAY:
  636. switch (action.layer.code) {
  637. case 0x04 ... 0xEF: /* tap key */
  638. case OP_INV:
  639. return true;
  640. default:
  641. return false;
  642. }
  643. case ACT_MACRO:
  644. case ACT_FUNCTION:
  645. if (action.func.opt & FUNC_TAP) { return true; }
  646. return false;
  647. }
  648. return false;
  649. }
  650. /*
  651. * debug print
  652. */
  653. void debug_event(keyevent_t event)
  654. {
  655. debug_hex16((event.key.row<<8) | event.key.col);
  656. if (event.pressed) debug("d("); else debug("u(");
  657. debug_dec(event.time); debug(")");
  658. }
  659. void debug_record(keyrecord_t record)
  660. {
  661. debug_event(record.event);
  662. #ifndef NO_ACTION_TAPPING
  663. debug(":"); debug_dec(record.tap.count);
  664. if (record.tap.interrupted) debug("-");
  665. #endif
  666. }
  667. void debug_action(action_t action)
  668. {
  669. switch (action.kind.id) {
  670. case ACT_LMODS: debug("ACT_LMODS"); break;
  671. case ACT_RMODS: debug("ACT_RMODS"); break;
  672. case ACT_LMODS_TAP: debug("ACT_LMODS_TAP"); break;
  673. case ACT_RMODS_TAP: debug("ACT_RMODS_TAP"); break;
  674. case ACT_USAGE: debug("ACT_USAGE"); break;
  675. case ACT_MOUSEKEY: debug("ACT_MOUSEKEY"); break;
  676. case ACT_KEYMAP: debug("ACT_KEYMAP"); break;
  677. case ACT_OVERLAY: debug("ACT_OVERLAY"); break;
  678. case ACT_MACRO: debug("ACT_MACRO"); break;
  679. case ACT_COMMAND: debug("ACT_COMMAND"); break;
  680. case ACT_FUNCTION: debug("ACT_FUNCTION"); break;
  681. default: debug("UNKNOWN"); break;
  682. }
  683. debug("[");
  684. debug_hex4(action.kind.param>>8);
  685. debug(":");
  686. debug_hex8(action.kind.param & 0xff);
  687. debug("]");
  688. }