summaryrefslogtreecommitdiff
path: root/runtime.S
blob: 6e685a578497a9916f0a3fae0bb2adbe1bdb86e8 (plain)
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

	.global handle_cycle_limit
handle_cycle_limit:
	ret
	
	.global m68k_write_word
m68k_write_word:
	and $0xFFFFFF, %rdi
	cmp $0x400000, %edi
	jle cart_w
	cmp $0xE00000, %edi
	jge workram_w
	jmp inccycles
workram_w:
	and $0xFFFF, %rdi
	mov %cx, (%r9, %rdi)
	jmp inccycles
cart_w:
	mov %cx, (%r8, %rdi)
	jmp inccycles

	.global m68k_write_byte
m68k_write_byte:
	and $0xFFFFFF, %rdi
	/* deal with byte swapping */
	xor $1, %edi
	cmp $0x400000, %edi
	jle cart_wb
	cmp $0xE00000, %edi
	jge workram_wb
	jmp inccycles
workram_wb:
	and $0xFFFF, %rdi
	mov %cl, (%r9, %rdi)
	jmp inccycles
cart_wb:
	mov %cl, (%r8, %rdi)
	jmp inccycles

	.global m68k_write_long_lowfirst
m68k_write_long_lowfirst:
	push %rdi
	add $2, %edi
	call m68k_write_word
	shr $16, %ecx
	pop %rdi
	jmp m68k_write_word

	.global m68k_write_long_highfirst
m68k_write_long_highfirst:
	push %rdi
	push %rcx
	shr $16, %ecx
	call m68k_write_word
	pop %rcx
	pop %rdi
	add $2, %rdi
	jmp m68k_write_word

	.global m68k_read_word_scratch1
m68k_read_word_scratch1:
	and $0xFFFFFF, %rcx
	cmp $0x400000, %ecx
	jle cart
	cmp $0xE00000, %ecx
	jge workram
	xor %cx, %cx
	jmp inccycles
workram:
	and $0xFFFF, %rcx
	mov (%r9, %rcx), %cx
	jmp inccycles
cart:
	mov (%r8, %rcx), %cx
inccycles:
	add $4, %rax
	cmp %rbp, %rax
	jge sync
	ret
sync:
	ret
	
	.global m68k_read_long_scratch1
m68k_read_long_scratch1:
	push %rcx
	call m68k_read_word_scratch1
	mov %cx, %di
	pop %rcx
	add $2, %ecx
	call m68k_read_word_scratch1
	and $0xFFFF, %ecx
	shl $16, %edi
	or %edi, %ecx
	ret

	.global m68k_read_byte_scratch1
m68k_read_byte_scratch1:
	and $0xFFFFFF, %rcx
	/* deal with byte swapping */
	xor $1, %ecx
	cmp $0x400000, %ecx
	jle cart_b
	cmp $0xE00000, %ecx
	jge workram_b
	xor %cl, %cl
	jmp inccycles
workram_b:
	and $0xFFFF, %rcx
	mov (%r9, %rcx), %cl
	jmp inccycles
cart_b:
	mov (%r8, %rcx), %cl
	jmp inccycles
	
ret_addr_msg:
	.asciz "Program modified return address on stack: found %X, expected %X\n"
	
	.global m68k_modified_ret_addr
m68k_modified_ret_addr:
	lea ret_addr_msg(%rip), %rdi
	mov %rcx, %rsi
	mov 8(%rsp), %rdx
	call printf
	mov $1, %rdi
	call exit

	.global m68k_save_context
m68k_save_context:
	mov %bl, 1(%rsi) /* N Flag */
	mov %bh, 2(%rsi) /* V flag */
	mov %dl, 3(%rsi) /* Z flag */
	mov %dh, 4(%rsi) /* C flag */
	mov %r10d, 8(%rsi) /* d0 */
	mov %r11d, 12(%rsi) /* d1 */
	mov %r12d, 16(%rsi) /* d2 */
	mov %r13d, 40(%rsi) /* a0 */
	mov %r14d, 44(%rsi) /* a1 */
	mov %r15d, 68(%rsi) /* a7 */
	ret

	.global m68k_load_context
m68k_load_context:
	mov 1(%rsi), %bl /* N Flag */
	mov 2(%rsi), %bh /* V flag */
	mov 3(%rsi), %dl /* Z flag */
	mov 4(%rsi), %dh /* C flag */
	mov 8(%rsi), %r10d /* d0 */
	mov 12(%rsi), %r11d /* d1 */
	mov 16(%rsi), %r12d /* d2 */
	mov 40(%rsi), %r13d /* a0 */
	mov 44(%rsi), %r14d /* a1 */
	mov 68(%rsi), %r15d /* a7 */
	mov 72(%rsi), %ebp /* target cycle count */
	mov 76(%rsi), %eax /* current cycle count */
	mov 80(%rsi), %r8d /* cartridge address */
	mov 88(%rsi), %r9d /* work ram address */
	ret

	.global m68k_start_context
m68k_start_context:
	call m68k_load_context
	jmp *%rdi