1 | Calling conventions, stack frame and zero page:
|
---|
2 |
|
---|
3 | The variables that normally are placed on the stack or in registers in C
|
---|
4 | are instead allocated in the zero page and saved on a (fictive) stack
|
---|
5 | when calling functions. Some locations have predefined functions though.
|
---|
6 | Arrays allocated as automatics are stored on the stack with a pointer
|
---|
7 | in zero page to its destination.
|
---|
8 |
|
---|
9 | 0-7 Unused
|
---|
10 | 10 Stack pointer
|
---|
11 | 11 Frame pointer
|
---|
12 | 12-14 Unused
|
---|
13 | 15 Used by prolog
|
---|
14 | 16 Prolog address, written in crt0
|
---|
15 | 17 Epilog address, written in crt0
|
---|
16 | 20-27 Auto-increment, scratch
|
---|
17 | 30-37 Auto-decrement, scratch
|
---|
18 | 40-47 Unused
|
---|
19 | 50-57 Scratch/Arguments
|
---|
20 | 60-77 Permanent, save before use.
|
---|
21 | 100-377 Addresses for subroutines, written by the assembler
|
---|
22 |
|
---|
23 | The normal registers (AC0-AC3) are all considered scratch registers.
|
---|
24 |
|
---|
25 | Register classes are assigned as:
|
---|
26 | AC0-AC3: AREGs.
|
---|
27 | AC2-AC3: BREGs.
|
---|
28 | 50-77: CREGs.
|
---|
29 | ...and eventually register pairs as DREGs.
|
---|
30 |
|
---|
31 | In byte code the low half of a word is the first byte (little-endian).
|
---|
32 | This is bit 8-15 in Nova syntax.
|
---|
33 |
|
---|
34 | The stack is growing towards lower adresses (as opposed to the Eclipse stack).
|
---|
35 | Stack layout:
|
---|
36 |
|
---|
37 | ! arg1 !
|
---|
38 | ! arg0 !
|
---|
39 | fp -> ! old pc!
|
---|
40 | ! old fp!
|
---|
41 | pc -> ! saved !
|
---|
42 |
|
---|
43 | A reference to a struct member in assembler, a = b->c; b is in ZP 50
|
---|
44 | + is zeropage-addressing
|
---|
45 | * is fp-adressing
|
---|
46 |
|
---|
47 | # offset 0
|
---|
48 | + lda 0,@50 # load value from indirect ZP 50 into ac0
|
---|
49 | * lda 2,,3 # load value from (ac3) into ac2
|
---|
50 | * lda 0,,2 # load value from (ac2) into ac0
|
---|
51 |
|
---|
52 | # offset 12
|
---|
53 | + lda 2,50 # load value from ZP 50 into ac2
|
---|
54 | + lda 0,12,2 # load value from (ac2+12) into ac0
|
---|
55 | * lda 2,,3 # load value from (ac3) into ac2
|
---|
56 | * lda 0,12,2 # load value from 12(ac2) into ac0
|
---|
57 |
|
---|
58 | # offset 517
|
---|
59 | + lda 2,50 # load value from ZP 50 into ac2
|
---|
60 | + lda 0,.L42-.,1 # load offset from .L42 PC-indexed
|
---|
61 | + addz 0,2,skp # add offset to ac2 and skip
|
---|
62 | +.L42: .word 517 # offset value
|
---|
63 | + lda 0,,2 # load value from (ac2) into ac0
|
---|
64 |
|
---|
65 | The prolog/epilog implementation; it is implemented as subroutines.
|
---|
66 |
|
---|
67 | .L42: .word 13 # number of words to save
|
---|
68 | func:
|
---|
69 | sta 3,@40 # save return address on stack
|
---|
70 | lda 2,.L42-.,1 # get save word count
|
---|
71 | jsr @45 # go to prolog
|
---|
72 | ...
|
---|
73 | lda 2,.L42-.,1 # get restore word count
|
---|
74 | jmp @46 # jump to epilog
|
---|
75 |
|
---|
76 | # words to save in 2, return address in 3
|
---|
77 | prolog:
|
---|
78 | sta 2,45 # save # of words to move at scratch
|
---|
79 | lda 0,41 # get old fp
|
---|
80 | lda 1,40 # get sp
|
---|
81 | sta 1,41 # save new fp
|
---|
82 | dsz 40 # decrement stack, will never be 0
|
---|
83 | sta 0,@40 # save old fp
|
---|
84 | dsz 40
|
---|
85 |
|
---|
86 | lda 0,off57 # fetch address of regs to save - 1
|
---|
87 | sta 0,20 # store address at autoincr
|
---|
88 | 1: lda 0,@20 # get word to copy
|
---|
89 | sta 0,@40 # push on stack
|
---|
90 | dsz 40 # manually decrement sp
|
---|
91 | dsz 45 # copied all words?
|
---|
92 | jmp 1b,1 # no, continue
|
---|
93 | jmp 0,3 # return
|
---|
94 |
|
---|
95 | epilog:
|
---|
96 | sta 2,45 # save # of words to move at scratch
|
---|
97 |
|
---|
98 | lda 3,off57 # fetch address of regs to save
|
---|
99 | sta 3,20 # store at autoincr
|
---|
100 | lda 3,41 # fetch fp
|
---|
101 | sta 3,30 # store at autodecr
|
---|
102 | lda 3,@30 # get old fp
|
---|
103 |
|
---|
104 | 1: lda 2,@30 # fetch word from stack
|
---|
105 | sta 2,@20 # store at orig place
|
---|
106 | dsz 45 # enough?
|
---|
107 | jmp 1b,1 # no, continue
|
---|
108 |
|
---|
109 | lda 2,41 # get new fp
|
---|
110 | sta 2,40 # restore stack
|
---|
111 | sta 3,41 # restore old fp
|
---|
112 | jmp @40 # Return
|
---|
113 |
|
---|
114 | Assembler syntax and functions.
|
---|
115 |
|
---|
116 | The assembler syntax mimics the DG assembler.
|
---|
117 | Load and store to addresses is written "lda 0,foo" to load from address foo.
|
---|
118 | If foo is not in zero page then the assembler will put the lda in the
|
---|
119 | text area close to the instruction and do an indirect pc-relative load.
|
---|
120 |
|
---|