-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmain.jl
More file actions
117 lines (99 loc) · 3.03 KB
/
main.jl
File metadata and controls
117 lines (99 loc) · 3.03 KB
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
include("JIA32.jl")
using ArgParse
function parse_options()
s = ArgParseSettings()
@add_arg_table s begin
"-m"
help = "memory size of the virtual machine (MB)"
arg_type = UInt64
default = UInt64(16)
"-b"
help = "BIOS image file path"
arg_type = UTF8String
default = UTF8String("images/bios.bin")
"-t"
help = "System time"
arg_type = UTF8String
default = UTF8String("20150101")
end
return parse_args(s)
end
function init_c_world(mem:: PhysicalMemory)
global g_phys_mem = mem
const jf_phys_ram_to_buffer =
cfunction(phys_ram_to_buffer, Void, (Culonglong, Culonglong, Ptr{UInt8},))
const jf_buffer_to_phys_ram =
cfunction(buffer_to_phys_ram, Void, (Culonglong, Culonglong, Ptr{UInt8},))
const jf_interrupt =
cfunction(interrupt_for_c_hw, Void, (Ptr{Void}, Cint, Cint))
const jf_new_timer =
cfunction(new_timer, Clonglong, (Ptr{Void}, Ptr{Void}))
const jf_mod_timer =
cfunction(mod_timer, Void, (Clonglong, Culonglong))
const jf_cancel_timer =
cfunction(cancel_timer, Void, (Clonglong,))
const jf_get_clock =
cfunction(get_clock, Culonglong, ())
ccall(("init_c_world", HW_LIB_PATH),
Void,
(Ptr{UInt8}, Ptr{Void}, Ptr{Void}, Ptr{Void}, Ptr{Void}, Ptr{Void}, Ptr{Void}, Ptr{Void}),
mem.baseptr,
jf_phys_ram_to_buffer,
jf_buffer_to_phys_ram,
jf_interrupt,
jf_new_timer, jf_mod_timer, jf_cancel_timer, jf_get_clock
)
end
function main()
parsed_args = parse_options()
# Create a global clock
global g_clock = InstructionClock()
# Create VM physical memory
memsize = parsed_args["m"]
if !(8 <= parsed_args["m"] <= 65536)
error("Memory size must be between 8 and 65536")
end
memsize <<= 20
cpu = CPU(memsize)
global g_cpu = cpu
load_opcode(cpu)
physmem = PhysicalMemory(memsize)
init_c_world(physmem)
# Mapping EPROM
# Volume 3, Chapter 9.10 : The EPROM is mapped at top 4G
eprom = EPROM(UTF8String("images/bios.bin"))
register_phys_io_map( physmem,
UInt64(0x100000000) - length(eprom.imgbuf), UInt64(length(eprom.imgbuf)),
eprom,
eprom_r64, eprom_r32, eprom_r16, eprom_r8,
eprom_w64, eprom_w32, eprom_w16, eprom_w8
)
# On IBM PC, the BIOS is also mapped at top 1M
eprom2 = EPROM(UTF8String("images/bios.bin"))
register_phys_io_map( physmem,
UInt64(0x100000) - length(eprom2.imgbuf), UInt64(length(eprom2.imgbuf)),
eprom2,
eprom_r64, eprom_r32, eprom_r16, eprom_r8,
eprom_w64, eprom_w32, eprom_w16, eprom_w8
)
# I8259 Programmable Interrupt Controller (master and slave)
i8259 = I8259()
register_port_io_map(cpu, i8259)
# I8257 DMA Controller
i8257_1 = I8257(UInt64(0x00), 0, UInt64(0x80), -1)
register_port_io_map(cpu, i8257_1)
i8257_2 = I8257(UInt64(0xc0), 1, UInt64(0x88), -1)
register_port_io_map(cpu, i8257_2)
# MC146818 Real-Time Clock
time_string = parsed_args["t"]
system_time = Date(time_string, "yyyymmdd")
mc146818 = MC146818(UInt64(0x70), i8259,
Dates.year(system_time),
Dates.month(system_time),
Dates.day(system_time))
register_port_io_map(cpu, mc146818)
connect_dev_to_irq(i8259, mc146818, 8)
reset(cpu)
loop(cpu, physmem)
end
main()