summaryrefslogtreecommitdiff
path: root/memory.s
blob: f53bdbeb0d2ec632768e44698334bc9a5eb1d4eb (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
|| -*- gas -*-

|| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
||  _ __ ___   ___ _ __ ___   ___  _ __ _   _   |||||||||||||||||||||||||||
|| | '_ ` _ \ / _ \ '_ ` _ \ / _ \| '__| | | |  \\\\\\\\\\\\\\\\\\\\\\\\\\\
|| | | | | | |  __/ | | | | | (_) | |  | |_| |  |||||||||||||||||||||||||||
|| |_| |_| |_|\___|_| |_| |_|\___/|_|   \__, |  ///////////////////////////
|| of the virtual type                  |___/   |||||||||||||||||||||||||||
|| =============================================JJJJJJJJJJJJJJJJJJJJJJJJJJJ

	|| Take a virtual address in d1 and dereference it.  Returns the
	|| host address in a0.  Destroys a0, d0.
deref:	| 76 cycles + 18 cycles for bsr
	| 20 bytes to inline, saves 34 cycles per call
	move.w	d1,d0
	andi.w	#0x3FFF,d0
	movea.w	d0,a0
	move.w	d1,d0
	andi.w	#0xC000,d0	| Can cut this out by pre-masking the table.
	rol.w	#4,d0
	adda.l	deref_table(pc,d0.w),a0	| TODO gas doesn't like this
	rts

.even
.bss
deref_table:
mem_page_0:	.long	0		| bank 0 / 0x0000
mem_page_1:	.long	0		| bank 1 / 0x4000
mem_page_2:	.long	0		| bank 2 / 0x8000
mem_page_3:	.long	0		| bank 3 / 0xc000

.xdef	mem_page_0
.xdef	mem_page_1
.xdef	mem_page_2
.xdef	mem_page_3

mem_page_loc_0:	.byte	0
mem_page_loc_1:	.byte	0
mem_page_loc_2:	.byte	0
mem_page_loc_3:	.byte	0

.xdef	mem_page_loc_0
.xdef	mem_page_loc_1
.xdef	mem_page_loc_2
.xdef	mem_page_loc_3

pages:	.long	0

.xdef pages

.text

	|| Take a physical address in a0 and turn it into a virtual
	|| address in d0
	|| Destroys d0, a1
| XXX AFAICS, a1 is currently a scratch address register, so you can load deref_table in it, and then save some space:
| But you may wish to use it for other purposes in the future, so you needn't integrate that immediately.

	|| Guessing this is 300 cycles.
underef:
	move.l	d2,-(a7)
	lea	deref_table(pc),a1
	move.l	a0,d0
	clr.w	d2
	sub.l	(a1)+,d0
	bmi.s	underef_not0
	cmpi.l	#0x4000,d0
	bmi.s	underef_thatsit
underef_not0:
	move.l	a0,d0
	move.w	#0x4000,d2
	sub.l	(a1)+,d0
	bmi.s	underef_not1
	cmpi.l	#0x4000,d0
	bmi.s	underef_thatsit
underef_not1:
	move.l	a0,d0
	move.w	#0x8000,d2
	sub.l	(a1)+,d0
	bmi.s	underef_not2
	cmpi.l	#0x4000,d0
	bmi.s	underef_thatsit
underef_not2:
	move.w	#0xc000,d2
	suba.l	(a1)+,a0
	|| if that fails too, well shit man!
	moveq	#0,d0
underef_thatsit:
	add.w	d2,d0
	move.l	(a7)+,d2
	rts