-
Notifications
You must be signed in to change notification settings - Fork 1
/
macros.inc
2773 lines (2449 loc) · 102 KB
/
macros.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
;*******************************************************************************
;* Include : MACROS.INC
;* Programmer: Tony Papadimitriou <tonyp@acm.org>
;* Purpose : Sample macro definitions for ASM8 (Win32 & Linux versions, only)
;* Language : Motorola/Freescale/NXP HC08/9S08 Assembly Language (aspisys.com/ASM8)
;* Status : FREEWARE Copyright (c) 2020 by Tony Papadimitriou <tonyp@acm.org>
;* Original : http://www.aspisys.com/code/hc08/macros.html
;* Note(s) : Use: #Include macros.inc
;* : All macros are written so that they are compatible with all
;* : macro modes (#@Macro, #Macro, and #MCF) and their @@ submode.
;* : Wherever a variable address is expected as parameter, you can use
;* : a simple variable, an expression pointing to variable, or indexed
;* : mode. Wherever a pointer value is expected you can use immediate
;* : mode, simple variable or related expression, or indexed mode to
;* : specify from where to get that pointer. This makes it possible
;* : to use the same macros in a variety of situations and regardless
;* : of addressing mode. (Of course, when an indexed mode is used,
;* : macro call parameter separator must be overridden to anything but
;* : the default comma, to properly recognize the comma inside the
;* : indexed parameter.)
;* : Some macros may call themselves with extra parameters so that
;* : they may control the loop without having the user provide those
;* : control values.
;* History : 10.07.26 v1.00 First (non-beta) release
;* : 10.07.29 v1.01 Added #SPADD in PushV macro for #SPAUTO mode
;* : 10.07.31 v1.02 Removed now redundant push-related macros with
;* : optional label as the latest version of ASM8 has
;* : this capability built-in (when in -X mode).
;* : 10.08.01 v1.03 PIN macro now allows for pin-name in label column
;* : 10.08.06 v1.04 ADD.B third parm made optional
;* : 10.08.08 v1.05 Added #SPAUTO in Pull macro (for ,SP parms)
;* : 10.08.09 v1.06 Added AND.B/W/L, ORA.B/W/L and EOR.B/W/L macros
;* : 10.08.12 v1.07 LDH & STH now see index even w/o comma override
;* : 10.08.17 v1.08 Fixed Pull macro to work with ,SP variable case
;* : 10.08.19 v1.09 Optimized CMP.W for HCS and added #PUSH/SPAUTO/PULL
;* : 10.08.20 v1.10 Log2 now uses :loop (latest ASM8)
;* : 10.08.21 v1.11 Added PROC, ENDPROC, and ClrRange macros
;* : 10.08.29 v1.12 CMP.W now works with ,X indexed 2nd operand (HCS)
;* : 10.08.31 v1.13 Added sema macro for OS8 semaphore definition
;* : 10.09.01 v1.14 Improved LDH by loading full HX while protecting X
;* : 10.09.04 v1.15 Adapted to latest ASM8 enhancements
;* : 10.09.06 v1.16 Improved LDXA & STXA (no parm override needed)
;* : 10.09.10 v1.17 Added IncByHX and DecByHX macros
;* : 10.09.16 v1.18 Macro _PUSH_ moved to COMMON.INC
;* : 10.09.19 v1.19 Improved PushV and PullV
;* : 10.09.22 v1.20 Made use of MTOP found in latest ASM8
;* : Improved DefBaud to display baud defs in any order
;* : 10.09.23 v1.21 Improved FillROM macro
;* : 10.09.24 v1.22 Replaced double-@ string delimiter with \@
;* : 10.09.25 v1.23 Improved Align2 macro to not use ?$$$
;* : 10.10.20 v1.24 Adapted to latest ASM8 (eg., use of MSET)
;* : 10.10.25 v1.25 Made use of MSWAP (latest ASM8 build)
;* : 10.10.30 v1.26 Single operand macros use index w/o override
;* : 10.11.01 v1.27 RePin macro defined (AND UNDEFINED IN v1.28)
;* : 10.11.03 v1.28 Pin macro redefines if label appears on right side
;* : 10.11.05 v1.29 Replaced :loop with MSWAP in DefBaud, sema macros
;* : 10.11.08 v1.30 Added 'X-index not allowed' error in DIVs
;* : 10.11.09 v1.31 Macro DEFAULT removed. Use built-in DEF instead.
;* : FillROM moved to MACROS2.INC
;* : 10.11.19 v1.32 Renamed Align2 to Align, and allowed for label
;* : 10.11.20 v1.33 Add optional shift left parameter to Log2
;* : 10.11.25 v1.34 Input, Output, On, Off now accept multiple PinNames
;* : 10.11.26 v1.35 Added ABS (abs.b, abs.w, abs.l) for absolute value
;* : 10.11.28 v1.36 Align macro improved to also align label values
;* : 10.12.01 v1.37 Adapted to latest ASM8 => shorter/faster macros
;* : 10.12.03 v1.38 Adapted to latest ASM8 => macros OK in @@ sub-mode
;* : 10.12.28 v1.39 Added ReadPin to set the CCR[C] based on pin status
;* : 11.02.03 v1.40 Improved fNextTask to behave similarly if no MTOS
;* : 11.02.06 v1.41 ReadPin improved to accept regular BRSET syntax
;* : 11.02.11 v1.42 Renamed Align back to Align2 (because power of 2)
;* : Added Align to align based on multiple (not power)
;* : 11.02.28 v1.43 Added #SPADD in ReVector (in case it is under SPAUTO)
;* : 11.03.04 v1.44 Added TST.B TST.W and TST.L macros
;* : Log2 macro now also returns answer in :MEXIT
;* : 11.03.16 v1.45 Made use of #EXIT directive to speedup assembly
;* : 11.03.20 v1.46 Optimized Pull and fixed for SPAUTO mode use
;* : 11.03.27 v1.47 Improved RSP/LDS allows for index without override
;* : 11.03.31 v1.48 Improved DefADKey to also accept ~label~ format
;* : 11.04.20 v1.49 Changed ,X to ,AX in some macros (in case we use #X)
;* : 11.04.26 v1.50 Added CopyRange macro
;* : 11.08.17 v1.51 Added Pullup macro to set pull-up for given PIN(s)
;* : 11.08.30 v1.52 Improved ClrRange for empty immediate range
;* : 11.09.06 v1.53 Added XA2HX and HX2XA
;* : 11.10.17 v1.54 Allowed multiple parameters for CheckPin
;* : 11.10.26 v1.55 Added REP (repeat) macro
;* : 11.11.11 v1.56 PIN macro now gives warning if pin number over 7
;* : 11.11.24 v1.57 Updated PULLUP macro to use BSET when possible
;* : 11.12.01 v1.58 Corrected PULLUP macro for BSET case
;* : 12.03.17 v1.59 Shortened DIV.W and DIV.L by use of DIV.B
;* : AIS & AIX no longer allow non-immediate operand
;* : Macro ALIGN commented out, use built-in ALIGN
;* : 12.06.13 v1.60 Improved PIN macro for sequential auto-assignment
;* : 12.06.25 v1.61 Improved DefBaud macro to not redefine for same values
;* : 12.08.06 v1.62 Added EndStats macro (for showing final statistics)
;* : 12.09.28 v1.63 DIV.B improved to allow X-index mode for divisor
;* : 12.10.22 v1.64 BugFix: cmp.w and ClrRange macros X-index mode detection
;* : 12.11.19 v1.65 Improved EndStats macro, and better support for MMU mode
;* : 12.12.05 v1.66 Added CAX & CXA (Cmp A to X and vice-versa) macros
;* : REP macro improved to also allow macro(s) as parameter
;* : 13.01.21 v1.67 Added ADC.B and SBC.B macros. Changed certain .L
;* : macros to use .W, and .W to use .B internally
;* : 13.02.03 v1.68 Improved PIN macro
;* : 13.02.11 v2.00 Made use ~[n.p]~ macro placeholder. May produce
;* : different object code.
;* : Made ADD.B and ADC.B smarter for #0 parm cases
;* : Added ADC.W, ADC.L, SBC.W and SBC.L macros
;* : Several macros improved.
;* : W A R N I N G Because of the new ~[n.p]~ capability the six
;* : macros SUB.[BWL] and CMP.[BWL] now 'subtract' 2nd
;* : from 1st for immediate mode operand(s). These
;* : macros now also work with X-indexed mode in all
;* : cases. IMPORTANT: Source code in apps that use
;* : any of these macros may need revision to correct
;* : the 1st/2nd parameter order when immediate mode is
;* : involved.
;* : 13.03.03 v2.01 Added calls to _#_ and _not_#_ in some macros
;* : Improved ReVector, tst.w, and tst.l macros
;* : Moved some frequently used macros to COMMON.INC
;* : ClrRange no longer destroys registers
;* : 13.03.13 v2.02 Added _FindStr_ macro (Find String)
;* : 13.04.05 v2.03 Optimized PushV macro
;* : 13.04.12 v2.04 PushV / PullV macros moved to COMMON.INC
;* : 13.04.23 v2.05 BugFix: _ldacmp_ macro (in COMMON.INC) now compares
;* : even with #0 to adjust the Carry like the real CMP
;* : instruction. This corrects all CMP.x macros in here.
;* : 13.05.07 v2.06 BugFix: EndStats macro for MMU case
;* : 13.05.07 v2.07 ADD.B and ADC.B moved to COMMON.INC as they are
;* : also used by ADD.S
;* : 13.05.14 v2.08 Added PORT macro for single line port bit(s) definition
;* : (eg., FSTAT @port $1825,,,FBLANK,,FACCERR,FPVIOL,FCCF,FCBEF)
;* : 13.08.08 v2.09 CopyRange now shows error if size is not word
;* : 13.08.13 v2.10 Improved CopyRange to accept either byte or word size
;* : 13.09.29 v2.11 Improved EndStats macro to use ?_OBJECT_? by default
;* : 13.10.12 v2.12 Renamed "copy" macro to "copy.b"
;* : 13.10.24 v2.13 Rewrote AddOS to use #ROM (moved to COMMON.INC)
;* : 13.11.01 v2.14 Moved (improved version of) AIX into COMMON.INC
;* : 13.11.07 v2.15 Improved Pullup macro
;* : 14.10.11 v2.16 Added MarkModuleVars & ClrModuleVars macros
;* : 15.04.03 v2.17 Added sema #SAVE# option to create Lock/Unlock code
;* : 15.05.15 v2.18 Adapted to latest sema lock/unlock parameter passing scheme
;* : Added fLock, fLockAttempt, fUnlock, fUnlockOnly
;* : global macros to deal with compatibility issues
;* : between old and new semaphore schemes
;* : 15.05.27 v2.19 Removed deprecated fUnlockOnly macro
;* : 15.09.17 v2.20 Added is8bit & is16bit helper macros
;* : Incorporated is8bit into mov.b & is16bit into mov.w
;* : 17.10.01 v2.21 Moved PROC and ENDPROC macros into their own file (proc.inc)
;* : 17.10.13 v2.22 MarkModuleVars adds #push-#pull to protect user segment use
;* : 19.04.13 v2.23 Pullup macro forces BSET to avoid macro invocation
;* : 19.04.25 v2.24 EndStats macro now always shows 'Module size'
;* : 19.11.26 v2.25 EndStats macro now adds ?HANDLER_CYCLES display
;* : 20.02.12 v2.26 Added Msg macro to silence debugging messages
;* : unless SHOW_ALL_MESSAGES is defined
;*******************************************************************************
#Exit _MACROS_
_MACROS_
;*******************************************************************************
; My personal preferences for most situations (adjust to suit your needs)
MyDefaultDirectives macro
#CaseOn ;Case-sensitive labels
#OptRelOn ;Jump->Branch warnings
#OptRtsOff ;No redundant RTS warnings
#SpacesOff ;No non-string spaces in operands
#ExtraOn ;Extra mnemonics enabled
#MapOn ;Source-level mapping enabled
#TraceOff ;No source-level macro mapping
#HcsOn ;Enable HCS08 instructions
#S1 ;S1/S2 auto-selection
#Jump ;Auto CALL->JSR & RTC->RTS conversion
#@Macro ;Macro syntax is @macro
#Parms ;Default macro parameter delimiter
endm
;*******************************************************************************
;*******************************************************************************
@MyDefaultDirectives ;this one called at inclusion
;*******************************************************************************
;*******************************************************************************
COP macro ;kick the COP watchdog
#ifparm ~1~ = #SAVE# ;to be compatible with special COP macro versions
mexit
#endif
#ifdef COP
sta COP
#endif
endm
;*******************************************************************************
Msg macro
#ifndef SHOW_ALL_MESSAGES ;;define this to show messages
mexit
#endif
mset #
#Message ~1~
endm
;*******************************************************************************
; Test if any immediate value in list is greater than 8-bit
is8bit macro
mreq 1
mswap 1,:loop
#ifnb ~#~
#if ~#1~&$FFFFFF00 > 0
#Warning Value {:loop} ({~#1~}) is bigger than 8-bit
#endif
#endif
mtop :n
endm
;*******************************************************************************
; Test if any immediate value in list is greater than 16-bit
is16bit macro
mreq 1
mswap 1,:loop
#ifnb ~#~
#if ~#1~&$FFFF0000 > 0
#Warning Value {:loop} ({~#1~}) is bigger than 16-bit
#endif
#endif
mtop :n
endm
;*******************************************************************************
; Simulate 68HC11's LDS instruction (HX is destroyed, however)
lds macro [#]StackTop
ldhx ~@~
txs
endm
;*******************************************************************************
rsp macro [[#]StackTop] ;does LDS with most-used value
mdef 1,#STACKTOP
@lds ~@~
endm
;*******************************************************************************
; Mark the beginning and end of variables for either RAM or XRAM
MarkModuleVars macro
#push
?RAM_BEGIN equ :RAM
?XRAM_BEGIN equ :XRAM
msuspend ;;here, code adds variables
?RAM_END equ :RAM
?XRAM_END equ :XRAM
#pull
endm
;*******************************************************************************
; Clear variables marked by the MarkModuleVars macro
ClrModuleVars macro
@@ClrRange #?RAM_BEGIN,#?RAM_END
@ClrRange #?XRAM_BEGIN,#?XRAM_END
endm
;*******************************************************************************
; Clear a range to zero (or given value)
ClrRange macro [#]FromAddressPtr,[#]ToAddressPtr[,[#]WithValue]
mreq 1,2:[#]FromAddressPtr,[#]ToAddressPtr[,[#]WithValue]
mdef 3,#0 ;;default value is zero
@@_not_x_ ~2~
#ifparm ~#~
#ifnoparm ~#2~ = ~2~
#if ~#1~ = ~#2~
mexit ;;nothing to do
#endif
#endif
#endif
#push
#spauto :sp
push
@@_lda_ ~3~
ldhx ~1~
Loop$$$
sta ,ax
aix #1
cphx ~2~
blo Loop$$$
pull
#pull
endm
;*******************************************************************************
; Copy a range of bytes between fixed addresses - no registers destroyed
CopyRange macro #Source,#Destination,[#]Size
mreq 1,2,3:#Source,#Destination,[#]Size
#ifparm ~,1~~,2~
merror Source/Destination is indexed
#endif
@@_#_ ~1~
@@_#_ ~2~
@@_not_x_ ~3~
mset 0,cphx ;;default comparison is word
#ifnb ~3~ = ~#3~ ;except for immediate mode
#if ::~3,~ <> 2 ;if size is not word
#if ::~3,~ <> 1 ;and byte is not byte
merror Non-byte or non-word size (~3~)
#endif
#endif
#if ::~3,~ = 1
mset 0,cmpx
#endif
#endif
#push
#spauto :sp
push
clrhx ;;HX to be used as counter
Loop$$$ lda ~#1~,ax ;;copy source byte
sta ~#2~,ax ;;to destination byte
aix #1 ;;advance index
~text~ ~3~ ;;are we done?
blo Loop$$$ ;;repeat while not done
pull
#pull
endm
;*******************************************************************************
; LDXA (Load XA) in one step
ldxa macro [#]Operand
mset #
lda ~[1.-2]~
ldx ~[1.-1]~
endm
;*******************************************************************************
; STXA (Store XA) in one step
stxa macro Address
mset #
stx ~1~
sta ~1,~+1~,1~
endm
;*******************************************************************************
; CAX - Compare A to X
cax macro
pshx
cmpa 1,asp
pulx
endm
;*******************************************************************************
; CXA - Compare X to A
cxa macro
psha
cmpx 1,asp
pula
endm
;*******************************************************************************
; LDH (Load H register)
ldh macro [#]Operand
#ifparm ~#~
pshx
ldhx ~1~<8
pulx
mexit
#endif
#push
#spauto :sp
#ifhcs
pshx
ldhx ~@~
pulx
#else
psha
lda ~@~
tah
pula
#endif
#pull
endm
;*******************************************************************************
; STH (Store H register)
sth macro Operand
#push
#spauto :sp
psha
tha
sta ~@~
pula
#pull
endm
;*******************************************************************************
; Copy XA to HX
XA2HX macro
txh
tax
endm
;*******************************************************************************
; Copy HX to XA
HX2XA macro
txa
thx
endm
;*******************************************************************************
; Swap the values of two symbols (using old XOR technique, and no temp symbol)
SwapSymbols macro Symbol1,Symbol2
~1~ set {~1~}^{~2~}
~2~ set {~1~}^{~2~}
~1~ set {~1~}^{~2~}
endm
;*******************************************************************************
; Swap two byte-size variables (does not destroy any registers)
swap.b macro Variable1 Variable2
mset #' '
mreq 1,2:Variable1 Variable2
#push
#spauto :sp
psha
@@_swap_ ~@~
pula
#pull
endm
;*******************************************************************************
; Swap two word-size variables (does not destroy any registers)
swap.w macro Variable1 Variable2
mset #' '
mreq 1,2:Variable1 Variable2
#push
#spauto :sp
psha
@@_swap_ ~[1.-1]~ ~[2.-1]~
@@_swap_ ~[1.-2]~ ~[2.-2]~
pula
#pull
endm
;*******************************************************************************
; Swap two long variables (does not destroy any registers)
swap.l macro Variable1 Variable2
mset #' '
mreq 1,2:Variable1 Variable2
#push
#spauto :sp
psha
@@_swap_ ~[1.1]~ ~[2.1]~
@@_swap_ ~[1.2]~ ~[2.2]~
@@_swap_ ~[1.3]~ ~[2.3]~
@@_swap_ ~[1.4]~ ~[2.4]~
pula
#pull
endm
;*******************************************************************************
; Align the current segment (e.g, #ROM) to specific power-of-two block size.
; If a label is present on the same line as the macro call, set the label to the
; value after the alignment occurs. Default power is 0, byte alignment.
; If the "UnalignedValue" expression is present (and its value is other than
; :PC, then instead of aligning the current segment, it only sets the label to
; aligned value. This way, it can be used to align just a label without the
; segment.
Align2 macro Power[,UnalignedValue]
mdef 1,0
mdef 2,:PC
mset 1,{1<{~1~}+{~2~}-1(h)}&{1<{~1~}-1^$FFFFFF(h)}
#ifparm ~2~ = :PC
org ~1~
#endif
#ifparm ~label~
~label~ set ~1~
#endif
mexit ~1~
endm
;*******************************************************************************
; CLR for bytes (differs from built-in CLR in that it works for any address)
clr.b macro Variable
#ifparm ~,1~~2~
clr ~@~
mexit
#endif
#ifz ~1~&$FFFFFF00
clr ~@~
mexit
#endif
psha
clra
sta ~@~
pula
endm
;*******************************************************************************
; CLR for words
clr.w macro Variable
#ifparm ~,1~~2~
clr ~@~
clr ~1,~+1~,1~,~2~
mexit
#endif
#ifz ~1~&$FFFFFF00 ;assumes whole word in zero page
clr ~@~
clr ~1~+1
mexit
#endif
psha
clra
sta ~@~
sta ~1~+1
pula
endm
;*******************************************************************************
; CLR for longs
clr.l macro Variable
#ifparm ~,1~~2~
clr ~@~
clr ~1,~+1~,1~,~2~
clr ~1,~+2~,1~,~2~
clr ~1,~+3~,1~,~2~
mexit
#endif
#ifz ~1~&$FFFFFF00 ;assumes whole word in zero page
clr ~1~
clr ~1~+1
clr ~1~+2
clr ~1~+3
mexit
#endif
#ifhcs
pshhx
clrhx
sthx ~1~
sthx ~1~+2
pulhx
mexit
#endif
psha
clra
sta ~1~
sta ~1~+1
sta ~1~+2
sta ~1~+3
pula
endm
;*******************************************************************************
; INC for bytes (differs from built-in INC in that it works for any address)
inc.b macro Variable
#ifparm ~,1~~2~
inc ~@~
mexit
#endif
#ifz ~1~&$FFFFFF00
inc ~@~
mexit
#endif
psha
lda ~@~
inca
sta ~@~
pula
endm
;*******************************************************************************
; INC for words
inc.w macro Variable
#ifparm ~,1~~2~
inc ~1,~+1~,1~,~2~
bne Done$$$
inc ~@~
Done$$$
mexit
#endif
#ifz ~1~&$FFFFFF00 ;assumes whole word in zero page
inc ~1~+1
bne Done$$$
inc ~1~
Done$$$
mexit
#endif
#ifhcs
pshhx
ldhx ~1~
aix #1
sthx ~1~
pulhx
mexit
#endif
pshhx
ldhx #~1~
inc 1,ax
bne Done$$$
inc ,ax
Done$$$
pulhx
endm
;*******************************************************************************
; INC for longs
inc.l macro Variable
#ifparm ~,1~~2~
inc ~1,~+3~,1~,~2~
bne Done$$$
inc ~1,~+2~,1~,~2~
bne Done$$$
inc ~1,~+1~,1~,~2~
bne Done$$$
inc ~@~
Done$$$
mexit
#endif
#ifz ~1~&$FFFFFF00 ;assumes whole word in zero page
inc ~1~+3
bne Done$$$
inc ~1~+2
bne Done$$$
inc ~1~+1
bne Done$$$
inc ~1~
Done$$$
mexit
#endif
pshhx
ldhx #~1~
inc 3,ax
bne Done$$$
inc 2,ax
bne Done$$$
inc 1,ax
bne Done$$$
inc ,ax
Done$$$
pulhx
endm
;*******************************************************************************
; (In/De)crement word using HX without protecting its original value (quicker)
; User is responsible for saving/restoring HX as needed by application
IncByHX macro Variable
mset #
#ifnhcs
mstop Macro works with 9S08 only
#endif
@@_not_x_ ~1~
@@_size_, ~1~ 2
ldhx ~1~
aix #1
sthx ~1~
endm
;-------------------------------------------------------------------------------
DecByHX macro Variable
mset #
#ifnhcs
mstop Macro works with 9S08 only
#endif
@@_not_x_ ~1~
@@_size_, ~1~ 2
ldhx ~1~
aix #-1
sthx ~1~
endm
;*******************************************************************************
; COM for bytes (differs from built-in COM in that it works for any address)
com.b macro Variable
#ifparm ~,1~~2~
com ~@~
mexit
#endif
#ifz ~1~&$FFFFFF00
com ~@~
mexit
#endif
psha
lda ~@~
coma
sta ~@~
pula
endm
;*******************************************************************************
; COM for words
com.w macro Variable
#ifparm ~,1~~2~
com ~@~
com ~1,~+1~,1~,~2~
mexit
#endif
#ifz ~1~&$FFFFFF00 ;assumes whole word in zero page
com ~1~
com ~1~+1
mexit
#endif
pshhx
ldhx #~1~
com ,ax
com 1,ax
pulhx
endm
;*******************************************************************************
; COM for longs
com.l macro Variable
#ifparm ~,1~~2~
com ~@~
com ~1,~+1~,1~,~2~
com ~1,~+2~,1~,~2~
com ~1,~+3~,1~,~2~
mexit
#endif
#ifz ~1~&$FFFFFF00 ;assumes whole word in zero page
com ~1~
com ~1~+1
com ~1~+2
com ~1~+3
mexit
#endif
pshhx
ldhx #~1~
com ,ax
com 1,ax
com 2,ax
com 3,ax
pulhx
endm
;*******************************************************************************
; NEG for bytes (differs from built-in NEG in that it works for any address)
neg.b macro Variable
#ifparm ~,1~~2~
neg ~@~
mexit
#endif
#ifz ~1~&$FFFFFF00
neg ~@~
mexit
#endif
psha
lda ~@~
nega
sta ~@~
pula
endm
;*******************************************************************************
; NEG for words
neg.w macro Variable
#ifparm ~,1~~2~
com ~@~
neg ~1,~+1~,1~,~2~
bne Done$$$
inc ~@~
Done$$$
mexit
#endif
#ifz ~1~&$FFFFFF00 ;assumes whole word in zero page
com ~1~
neg ~1~+1
bne Done$$$
inc ~1~
Done$$$
mexit
#endif
pshhx
ldhx #~1~
com ,ax
neg 1,ax
bne Done$$$
inc ,ax
Done$$$
pulhx
endm
;*******************************************************************************
; NEG for longs
neg.l macro Variable
#ifparm ~,1~~2~
com ~@~
com ~1,~+1~,1~,~2~
com ~1,~+2~,1~,~2~
neg ~1,~+3~,1~,~2~
bne Done$$$
inc ~1,~+2~,1~,~2~
bne Done$$$
inc ~1,~+1~,1~,~2~
bne Done$$$
inc ~@~
Done$$$
mexit
#endif
#ifz ~1~&$FFFFFF00 ;assumes whole word in zero page
com ~1~
com ~1~+1
com ~1~+2
neg ~1~+3
bne Done$$$
inc ~1~+2
bne Done$$$
inc ~1~+1
bne Done$$$
inc ~1~
Done$$$
mexit
#endif
pshhx
ldhx #~1~
com ,ax
com 1,ax
com 2,ax
neg 3,ax
bne Done$$$
inc 2,ax
bne Done$$$
inc 1,ax
bne Done$$$
inc ,ax
Done$$$
pulhx
endm
;*******************************************************************************
; (ABS) Make operand positive
abs.b macro ByteVariable
mreq 1:ByteVariable
@@tst.b ~@~
bpl Done$$$
@@neg.b ~@~
Done$$$
endm
;-------------------------------------------------------------------------------
abs.w macro WordVariable
mreq 1:WordVariable
@@tst.b ~@~
bpl Done$$$
@@neg.w ~@~
Done$$$
endm
;-------------------------------------------------------------------------------
abs.l macro LongVariable
mreq 1:LongVariable
@@tst.b ~@~
bpl Done$$$
@@neg.l ~@~
Done$$$
endm
;*******************************************************************************
; MOV for bytes (differs from built-in MOV in that it works for any address)
; (uses COPY if MOV not possible)
mov.b macro [#]Source,Destination
@@is8bit ~1~
#ifparm ~#~
#ifz ~2~&$FFFFFF00
mov ~@~
mexit
#endif
@Copy.b ~@~
mexit
#endif
#ifz ~1~&$FFFFFF00
#ifz ~2~&$FFFFFF00
mov ~@~
mexit
#endif
#endif
@Copy.b ~@~
endm
;*******************************************************************************
; MOV for words (uses COPY if MOV not possible)
; MSB moved last to correctly adjust the N flag.
mov.w macro [#]Source,Destination
@@is16bit ~1~
#ifnz ~2~&$FFFFFF00
@Copy.w ~@~
mexit
#endif
#ifb ~#~
#ifnz ~1~&$FFFFFF00
@Copy.w ~@~
mexit
#endif
#endif
mov ~[1.-2]~,~[2.-2]~
mov ~[1.-1]~,~[2.-1]~
endm
;*******************************************************************************
; MOV for longs (uses COPY if MOV not possible)
; MSB moved last to correctly adjust the N flag.
mov.l macro [#]Source,Destination
#ifnz ~2~&$FFFFFF00
@Copy.l ~@~
mexit
#endif
#ifb ~#~
#ifnz ~1~&$FFFFFF00
@Copy.l ~@~
mexit
#endif
#endif
mov ~[1.4]~,~[2.4]~
mov ~[1.3]~,~[2.3]~
mov ~[1.2]~,~[2.2]~
mov ~[1.1]~,~[2.1]~
endm
;*******************************************************************************
; LSL for bytes (differs from built-in LSL in that it works for any address)
lsl.b macro Variable
#ifparm ~,1~~2~
lsl ~@~
mexit
#endif
#ifz ~1~&$FFFFFF00
lsl ~@~
mexit
#endif
psha
lda ~@~
lsla
sta ~@~
pula
endm
;*******************************************************************************
; LSL for words
lsl.w macro Variable
#ifparm ~,1~~2~
lsl ~1,~+1~,1~,~2~
rol ~@~
mexit
#endif
#ifz ~1~&$FFFFFF00 ;assumes whole word in zero page
lsl ~1~+1
rol ~1~
mexit
#endif
pshhx
ldhx #~1~
lsl 1,ax
rol ,ax
pulhx
endm
;*******************************************************************************
; LSL for longs
lsl.l macro Variable
#ifparm ~,1~~2~
lsl ~1,~+3~,1~,~2~
rol ~1,~+2~,1~,~2~