summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/vt82c496.cpp
blob: cf1632edd49252cc536d0121e9281b2bb31d188d (plain) (blame)
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
// license:BSD-3-Clause
// copyright-holders:Barry Rodewald
/*

    VIA VT82C496G "Green PC" system chipset

*/

#include "emu.h"
#include "vt82c496.h"

/***************************************************************************
    IMPLEMENTATION
***************************************************************************/

DEFINE_DEVICE_TYPE(VT82C496, vt82c496_device, "vt82c496", "VIA VT82C496 system chipset")


vt82c496_device::vt82c496_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: device_t(mconfig, VT82C496, tag, owner, clock), m_cpu(*this, finder_base::DUMMY_TAG), m_space(nullptr), m_ram(*this, finder_base::DUMMY_TAG), m_rom(*this, finder_base::DUMMY_TAG),
	  m_bios_c0_r(*this, "bios_c0_r"),
	  m_bios_c4_r(*this, "bios_c4_r"),
	  m_bios_c8_r(*this, "bios_c8_r"),
	  m_bios_cc_r(*this, "bios_cc_r"),
	  m_bios_d0_r(*this, "bios_d0_r"),
	  m_bios_d4_r(*this, "bios_d4_r"),
	  m_bios_d8_r(*this, "bios_d8_r"),
	  m_bios_dc_r(*this, "bios_dc_r"),
	  m_bios_e0_r(*this, "bios_e0_r"),
	  m_bios_f0_r(*this, "bios_f0_r"),
	  m_bios_c0_w(*this, "bios_c0_w"),
	  m_bios_c4_w(*this, "bios_c4_w"),
	  m_bios_c8_w(*this, "bios_c8_w"),
	  m_bios_cc_w(*this, "bios_cc_w"),
	  m_bios_d0_w(*this, "bios_d0_w"),
	  m_bios_d4_w(*this, "bios_d4_w"),
	  m_bios_d8_w(*this, "bios_d8_w"),
	  m_bios_dc_w(*this, "bios_dc_w"),
	  m_bios_e0_w(*this, "bios_e0_w"),
	  m_bios_f0_w(*this, "bios_f0_w"),
	  m_reg_select(0)
{
}

void vt82c496_device::device_start()
{
	/* get address space we are working on */
	m_space = &m_cpu->space(AS_PROGRAM);

	save_pointer(m_reg,"Registers",0x100);
}

void vt82c496_device::device_reset()
{
	memset(m_reg,0,0x100);

	// set up default ROM banking
	m_space->install_read_bank(0xc0000,0xc3fff,0,m_bios_c0_r);
	m_space->install_read_bank(0xc4000,0xc7fff,0,m_bios_c4_r);
	m_space->install_read_bank(0xc8000,0xcbfff,0,m_bios_c8_r);
	m_space->install_read_bank(0xcc000,0xcffff,0,m_bios_cc_r);
	m_space->install_read_bank(0xd0000,0xd3fff,0,m_bios_d0_r);
	m_space->install_read_bank(0xd4000,0xd7fff,0,m_bios_d4_r);
	m_space->install_read_bank(0xd8000,0xdbfff,0,m_bios_d8_r);
	m_space->install_read_bank(0xdc000,0xdffff,0,m_bios_dc_r);
	m_space->install_read_bank(0xe0000,0xeffff,0,m_bios_e0_r);
	m_space->install_read_bank(0xf0000,0xfffff,0,m_bios_f0_r);
	m_space->nop_write(0xc0000,0xfffff);
	m_bios_c0_r->set_base(m_rom);
	m_bios_c4_r->set_base(m_rom+0x4000/4);
	m_bios_c8_r->set_base(m_rom+0x8000/4);
	m_bios_cc_r->set_base(m_rom+0xc000/4);
	m_bios_d0_r->set_base(m_rom+0x10000/4);
	m_bios_d4_r->set_base(m_rom+0x14000/4);
	m_bios_d8_r->set_base(m_rom+0x18000/4);
	m_bios_dc_r->set_base(m_rom+0x1c000/4);
	m_bios_e0_r->set_base(m_rom+0x20000/4);
	m_bios_f0_r->set_base(m_rom+0x30000/4);
}

uint8_t vt82c496_device::read(offs_t offset)
{
	if(offset == 1)
		return m_reg[m_reg_select];
	return 0x00;
}

void vt82c496_device::write(offs_t offset, uint8_t data)
{
	if(offset == 0)
		m_reg_select = data;
	if(offset == 1)
	{
		m_reg[m_reg_select] = data;
		switch(m_reg_select)
		{
			case 0x30:
				update_mem_c0(data);
				break;
			case 0x31:
				update_mem_d0(data);
				break;
			case 0x32:
				update_mem_e0(data);
				break;
		}
	}
}

void vt82c496_device::update_mem_c0(uint8_t data)
{
	if(data & 0x80)
		m_bios_cc_r->set_base(m_ram->pointer()+0xcc000);
	else
		m_bios_cc_r->set_base(m_rom+0xc000/4);
	if(data & 0x40)
	{
		m_space->install_write_bank(0xcc000,0xcffff,0,m_bios_cc_w);
		m_bios_cc_w->set_base(m_ram->pointer()+0xcc000);
	}
	else
		m_space->nop_write(0xcc000,0xcffff);

	if(data & 0x20)
		m_bios_c8_r->set_base(m_ram->pointer()+0xc8000);
	else
		m_bios_c8_r->set_base(m_rom+0x8000/4);
	if(data & 0x10)
	{
		m_space->install_write_bank(0xc8000,0xcbfff,0,m_bios_c8_w);
		m_bios_c8_w->set_base(m_ram->pointer()+0xc8000);
	}
	else
		m_space->nop_write(0xc8000,0xcbfff);

	if(data & 0x08)
		m_bios_c4_r->set_base(m_ram->pointer()+0xc4000);
	else
		m_bios_c4_r->set_base(m_rom+0x4000/4);
	if(data & 0x04)
	{
		m_space->install_write_bank(0xc4000,0xc7fff,0,m_bios_c4_w);
		m_bios_c4_w->set_base(m_ram->pointer()+0xc4000);
	}
	else
		m_space->nop_write(0xc4000,0xc7fff);

	if(data & 0x02)
		m_bios_c0_r->set_base(m_ram->pointer()+0xc0000);
	else
		m_bios_c0_r->set_base(m_rom+0);
	if(data & 0x01)
	{
		m_space->install_write_bank(0xc0000,0xc3fff,0,m_bios_c0_w);
		m_bios_c0_w->set_base(m_ram->pointer()+0xc0000);
	}
	else
		m_space->nop_write(0xc0000,0xc3fff);
}

void vt82c496_device::update_mem_d0(uint8_t data)
{
	if(data & 0x80)
		m_bios_dc_r->set_base(m_ram->pointer()+0xdc000);
	else
		m_bios_dc_r->set_base(m_rom+0x1c000/4);
	if(data & 0x40)
	{
		m_space->install_write_bank(0xdc000,0xdffff,0,m_bios_dc_w);
		m_bios_dc_w->set_base(m_ram->pointer()+0xdc000);
	}
	else
		m_space->nop_write(0xdc000,0xdffff);

	if(data & 0x20)
		m_bios_d8_r->set_base(m_ram->pointer()+0xd8000);
	else
		m_bios_d8_r->set_base(m_rom+0x18000/4);
	if(data & 0x10)
	{
		m_space->install_write_bank(0xd8000,0xdbfff,0,m_bios_d8_w);
		m_bios_d8_w->set_base(m_ram->pointer()+0xd8000);
	}
	else
		m_space->nop_write(0xd8000,0xdbfff);

	if(data & 0x08)
		m_bios_d4_r->set_base(m_ram->pointer()+0xd4000);
	else
		m_bios_d4_r->set_base(m_rom+0x14000/4);
	if(data & 0x04)
	{
		m_space->install_write_bank(0xd4000,0xd7fff,0,m_bios_d4_w);
		m_bios_d4_w->set_base(m_ram->pointer()+0xd4000);
	}
	else
		m_space->nop_write(0xd4000,0xd7fff);

	if(data & 0x02)
		m_bios_d0_r->set_base(m_ram->pointer()+0xd0000);
	else
		m_bios_d0_r->set_base(m_rom+0x10000/4);
	if(data & 0x01)
	{
		m_space->install_write_bank(0xd0000,0xd3fff,0,m_bios_d0_w);
		m_bios_d0_w->set_base(m_ram->pointer()+0xd0000);
	}
	else
		m_space->nop_write(0xd0000,0xd3fff);
}

void vt82c496_device::update_mem_e0(uint8_t data)
{
	if(data & 0x80)
		m_bios_e0_r->set_base(m_ram->pointer()+0xe0000);
	else
		m_bios_e0_r->set_base(m_rom+0x20000/4);

	if(data & 0x40)
	{
		m_space->install_write_bank(0xe0000,0xeffff,0,m_bios_e0_w);
		m_bios_e0_w->set_base(m_ram->pointer()+0xe0000);
	}
	else
		m_space->nop_write(0xe0000,0xeffff);

	if(data & 0x20)
		m_bios_f0_r->set_base(m_ram->pointer()+0xf0000);
	else
		m_bios_f0_r->set_base(m_rom+0x30000/4);

	if(data & 0x10)
	{
		m_space->install_write_bank(0xf0000,0xfffff,0,m_bios_f0_w);
		m_bios_f0_w->set_base(m_ram->pointer()+0xf0000);
	}
	else
		m_space->nop_write(0xf0000,0xfffff);
}
span class="p">) { void *plib; lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); lua_getfield(L, -1, path); plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */ lua_pop(L, 2); /* pop CLIBS table and 'plib' */ return plib; } static void ll_addtoclib (lua_State *L, const char *path, void *plib) { lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); lua_pushlightuserdata(L, plib); lua_pushvalue(L, -1); lua_setfield(L, -3, path); /* CLIBS[path] = plib */ lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */ lua_pop(L, 1); /* pop CLIBS table */ } /* ** __gc tag method for CLIBS table: calls 'll_unloadlib' for all lib ** handles in list CLIBS */ static int gctm (lua_State *L) { int n = luaL_len(L, 1); for (; n >= 1; n--) { /* for each handle, in reverse order */ lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */ ll_unloadlib(lua_touserdata(L, -1)); lua_pop(L, 1); /* pop handle */ } return 0; } static int ll_loadfunc (lua_State *L, const char *path, const char *sym) { void *reg = ll_checkclib(L, path); /* check loaded C libraries */ if (reg == NULL) { /* must load library? */ reg = ll_load(L, path, *sym == '*'); if (reg == NULL) return ERRLIB; /* unable to load library */ ll_addtoclib(L, path, reg); } if (*sym == '*') { /* loading only library (no function)? */ lua_pushboolean(L, 1); /* return 'true' */ return 0; /* no errors */ } else { lua_CFunction f = ll_sym(L, reg, sym); if (f == NULL) return ERRFUNC; /* unable to find function */ lua_pushcfunction(L, f); /* else create new function */ return 0; /* no errors */ } } static int ll_loadlib (lua_State *L) { const char *path = luaL_checkstring(L, 1); const char *init = luaL_checkstring(L, 2); int stat = ll_loadfunc(L, path, init); if (stat == 0) /* no errors? */ return 1; /* return the loaded function */ else { /* error; error message is on stack top */ lua_pushnil(L); lua_insert(L, -2); lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); return 3; /* return nil, error message, and where */ } } /* ** {====================================================== ** 'require' function ** ======================================================= */ static int readable (const char *filename) { FILE *f = fopen(filename, "r"); /* try to open file */ if (f == NULL) return 0; /* open failed */ fclose(f); return 1; } static const char *pushnexttemplate (lua_State *L, const char *path) { const char *l; while (*path == *LUA_PATH_SEP) path++; /* skip separators */ if (*path == '\0') return NULL; /* no more templates */ l = strchr(path, *LUA_PATH_SEP); /* find next separator */ if (l == NULL) l = path + strlen(path); lua_pushlstring(L, path, l - path); /* template */ return l; } static const char *searchpath (lua_State *L, const char *name, const char *path, const char *sep, const char *dirsep) { luaL_Buffer msg; /* to build error message */ luaL_buffinit(L, &msg); if (*sep != '\0') /* non-empty separator? */ name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */ while ((path = pushnexttemplate(L, path)) != NULL) { const char *filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name); lua_remove(L, -2); /* remove path template */ if (readable(filename)) /* does file exist and is readable? */ return filename; /* return that file name */ lua_pushfstring(L, "\n\tno file " LUA_QS, filename); lua_remove(L, -2); /* remove file name */ luaL_addvalue(&msg); /* concatenate error msg. entry */ } luaL_pushresult(&msg); /* create error message */ return NULL; /* not found */ } static int ll_searchpath (lua_State *L) { const char *f = searchpath(L, luaL_checkstring(L, 1), luaL_checkstring(L, 2), luaL_optstring(L, 3, "."), luaL_optstring(L, 4, LUA_DIRSEP)); if (f != NULL) return 1; else { /* error message is on top of the stack */ lua_pushnil(L); lua_insert(L, -2); return 2; /* return nil + error message */ } } static const char *findfile (lua_State *L, const char *name, const char *pname, const char *dirsep) { const char *path; lua_getfield(L, lua_upvalueindex(1), pname); path = lua_tostring(L, -1); if (path == NULL) luaL_error(L, LUA_QL("package.%s") " must be a string", pname); return searchpath(L, name, path, ".", dirsep); } static int checkload (lua_State *L, int stat, const char *filename) { if (stat) { /* module loaded successfully? */ lua_pushstring(L, filename); /* will be 2nd argument to module */ return 2; /* return open function and file name */ } else return luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s", lua_tostring(L, 1), filename, lua_tostring(L, -1)); } static int searcher_Lua (lua_State *L) { const char *filename; const char *name = luaL_checkstring(L, 1); filename = findfile(L, name, "path", LUA_LSUBSEP); if (filename == NULL) return 1; /* module not found in this path */ return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename); } static int loadfunc (lua_State *L, const char *filename, const char *modname) { const char *funcname; const char *mark; modname = luaL_gsub(L, modname, ".", LUA_OFSEP); mark = strchr(modname, *LUA_IGMARK); if (mark) { int stat; funcname = lua_pushlstring(L, modname, mark - modname); funcname = lua_pushfstring(L, LUA_POF"%s", funcname); stat = ll_loadfunc(L, filename, funcname); if (stat != ERRFUNC) return stat; modname = mark + 1; /* else go ahead and try old-style name */ } funcname = lua_pushfstring(L, LUA_POF"%s", modname); return ll_loadfunc(L, filename, funcname); } static int searcher_C (lua_State *L) { const char *name = luaL_checkstring(L, 1); const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP); if (filename == NULL) return 1; /* module not found in this path */ return checkload(L, (loadfunc(L, filename, name) == 0), filename); } static int searcher_Croot (lua_State *L) { const char *filename; const char *name = luaL_checkstring(L, 1); const char *p = strchr(name, '.'); int stat; if (p == NULL) return 0; /* is root */ lua_pushlstring(L, name, p - name); filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP); if (filename == NULL) return 1; /* root not found */ if ((stat = loadfunc(L, filename, name)) != 0) { if (stat != ERRFUNC) return checkload(L, 0, filename); /* real error */ else { /* open function not found */ lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, name, filename); return 1; } } lua_pushstring(L, filename); /* will be 2nd argument to module */ return 2; } static int searcher_preload (lua_State *L) { const char *name = luaL_checkstring(L, 1); lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); lua_getfield(L, -1, name); if (lua_isnil(L, -1)) /* not found? */ lua_pushfstring(L, "\n\tno field package.preload['%s']", name); return 1; } static void findloader (lua_State *L, const char *name) { int i; luaL_Buffer msg; /* to build error message */ luaL_buffinit(L, &msg); lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */ if (!lua_istable(L, 3)) luaL_error(L, LUA_QL("package.searchers") " must be a table"); /* iterate over available searchers to find a loader */ for (i = 1; ; i++) { lua_rawgeti(L, 3, i); /* get a searcher */ if (lua_isnil(L, -1)) { /* no more searchers? */ lua_pop(L, 1); /* remove nil */ luaL_pushresult(&msg); /* create error message */ luaL_error(L, "module " LUA_QS " not found:%s", name, lua_tostring(L, -1)); } lua_pushstring(L, name); lua_call(L, 1, 2); /* call it */ if (lua_isfunction(L, -2)) /* did it find a loader? */ return; /* module loader found */ else if (lua_isstring(L, -2)) { /* searcher returned error message? */ lua_pop(L, 1); /* remove extra return */ luaL_addvalue(&msg); /* concatenate error message */ } else lua_pop(L, 2); /* remove both returns */ } } static int ll_require (lua_State *L) { const char *name = luaL_checkstring(L, 1); lua_settop(L, 1); /* _LOADED table will be at index 2 */ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); lua_getfield(L, 2, name); /* _LOADED[name] */ if (lua_toboolean(L, -1)) /* is it there? */ return 1; /* package is already loaded */ /* else must load package */ lua_pop(L, 1); /* remove 'getfield' result */ findloader(L, name); lua_pushstring(L, name); /* pass name as argument to module loader */ lua_insert(L, -2); /* name is 1st argument (before search data) */ lua_call(L, 2, 1); /* run loader to load module */ if (!lua_isnil(L, -1)) /* non-nil return? */ lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ lua_getfield(L, 2, name); if (lua_isnil(L, -1)) { /* module did not set a value? */ lua_pushboolean(L, 1); /* use true as result */ lua_pushvalue(L, -1); /* extra copy to be returned */ lua_setfield(L, 2, name); /* _LOADED[name] = true */ } return 1; } /* }====================================================== */ /* ** {====================================================== ** 'module' function ** ======================================================= */ #if defined(LUA_COMPAT_MODULE) /* ** changes the environment variable of calling function */ static void set_env (lua_State *L) { lua_Debug ar; if (lua_getstack(L, 1, &ar) == 0 || lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ lua_iscfunction(L, -1)) luaL_error(L, LUA_QL("module") " not called from a Lua function"); lua_pushvalue(L, -2); /* copy new environment table to top */ lua_setupvalue(L, -2, 1); lua_pop(L, 1); /* remove function */ } static void dooptions (lua_State *L, int n) { int i; for (i = 2; i <= n; i++) { if (lua_isfunction(L, i)) { /* avoid 'calling' extra info. */ lua_pushvalue(L, i); /* get option (a function) */ lua_pushvalue(L, -2); /* module */ lua_call(L, 1, 0); } } } static void modinit (lua_State *L, const char *modname) { const char *dot; lua_pushvalue(L, -1); lua_setfield(L, -2, "_M"); /* module._M = module */ lua_pushstring(L, modname); lua_setfield(L, -2, "_NAME"); dot = strrchr(modname, '.'); /* look for last dot in module name */ if (dot == NULL) dot = modname; else dot++; /* set _PACKAGE as package name (full module name minus last part) */ lua_pushlstring(L, modname, dot - modname); lua_setfield(L, -2, "_PACKAGE"); } static int ll_module (lua_State *L) { const char *modname = luaL_checkstring(L, 1); int lastarg = lua_gettop(L); /* last parameter */ luaL_pushmodule(L, modname, 1); /* get/create module table */ /* check whether table already has a _NAME field */ lua_getfield(L, -1, "_NAME"); if (!lua_isnil(L, -1)) /* is table an initialized module? */ lua_pop(L, 1); else { /* no; initialize it */ lua_pop(L, 1); modinit(L, modname); } lua_pushvalue(L, -1); set_env(L); dooptions(L, lastarg); return 1; } static int ll_seeall (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); if (!lua_getmetatable(L, 1)) { lua_createtable(L, 0, 1); /* create new metatable */ lua_pushvalue(L, -1); lua_setmetatable(L, 1); } lua_pushglobaltable(L); lua_setfield(L, -2, "__index"); /* mt.__index = _G */ return 0; } #endif /* }====================================================== */ /* auxiliary mark (for internal use) */ #define AUXMARK "\1" /* ** return registry.LUA_NOENV as a boolean */ static int noenv (lua_State *L) { int b; lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); b = lua_toboolean(L, -1); lua_pop(L, 1); /* remove value */ return b; } static void setpath (lua_State *L, const char *fieldname, const char *envname1, const char *envname2, const char *def) { const char *path = getenv(envname1); if (path == NULL) /* no environment variable? */ path = getenv(envname2); /* try alternative name */ if (path == NULL || noenv(L)) /* no environment variable? */ lua_pushstring(L, def); /* use default */ else { /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP, LUA_PATH_SEP AUXMARK LUA_PATH_SEP); luaL_gsub(L, path, AUXMARK, def); lua_remove(L, -2); } setprogdir(L); lua_setfield(L, -2, fieldname); } static const luaL_Reg pk_funcs[] = { {"loadlib", ll_loadlib}, {"searchpath", ll_searchpath}, #if defined(LUA_COMPAT_MODULE) {"seeall", ll_seeall}, #endif {NULL, NULL} }; static const luaL_Reg ll_funcs[] = { #if defined(LUA_COMPAT_MODULE) {"module", ll_module}, #endif {"require", ll_require}, {NULL, NULL} }; static void createsearcherstable (lua_State *L) { static const lua_CFunction searchers[] = {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL}; int i; /* create 'searchers' table */ lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0); /* fill it with pre-defined searchers */ for (i=0; searchers[i] != NULL; i++) { lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */ lua_pushcclosure(L, searchers[i], 1); lua_rawseti(L, -2, i+1); } } LUAMOD_API int luaopen_package (lua_State *L) { /* create table CLIBS to keep track of loaded C libraries */ luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); lua_createtable(L, 0, 1); /* metatable for CLIBS */ lua_pushcfunction(L, gctm); lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */ lua_setmetatable(L, -2); /* create `package' table */ luaL_newlib(L, pk_funcs); createsearcherstable(L); #if defined(LUA_COMPAT_LOADERS) lua_pushvalue(L, -1); /* make a copy of 'searchers' table */ lua_setfield(L, -3, "loaders"); /* put it in field `loaders' */ #endif lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ /* set field 'path' */ setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT); /* set field 'cpath' */ setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT); /* store config information */ lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); lua_setfield(L, -2, "config"); /* set field `loaded' */ luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); lua_setfield(L, -2, "loaded"); /* set field `preload' */ luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); lua_setfield(L, -2, "preload"); lua_pushglobaltable(L); lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */ lua_pop(L, 1); /* pop global table */ return 1; /* return 'package' table */ }