|
Joined: Mar 2001
Posts: 17,217 Likes: 234
Very Senior Member
|
Very Senior Member
Joined: Mar 2001
Posts: 17,217 Likes: 234 |
You could write the TMS registers from Lua by going through the Apple II's address space, I think. Obviously it wouldn't be slot-independent then, but
|
|
|
|
Joined: Jan 2012
Posts: 891 Likes: 17
Senior Member
|
Senior Member
Joined: Jan 2012
Posts: 891 Likes: 17 |
Now if I just had a way to do an emu.frameadvance() (which doesn't work) or some kind of way to do a delay like wait for vblank. emu.register_frame(cbfunction) will call cbfunction at vblank. If you want to draw to the screen though lua (directly, not by writing to the emulated vram) you need to use emu.register_frame_done(cbfunction) which calls cbfunction after the frame is drawn to the host screen.
|
|
|
|
Joined: Feb 2014
Posts: 1,102 Likes: 173
Very Senior Member
|
Very Senior Member
Joined: Feb 2014
Posts: 1,102 Likes: 173 |
Thanks RB, you're right, I can just mem:write_i8(0xc0c1,data). I don't know why I couldn't get it to work before, probably because I had an OBOE where I write the registers. I had a for loop whose index started at 1 but the register write was mem:write_i8(0xc0c1,128+i) instead of write_i8(0xc0c1,128+(i-1)) so the wrong register was getting the value.
cpu = manager:machine().devices[":maincpu"];mem = cpu.spaces["program"]
reginitarray = {2,196,14,255,3,118,3,15}
for i=1,table.maxn(reginitarray) do
dummy=mem:read_i8(0xc0c1);
mem:write_i8(0xc0c1,reginitarray[i]); mem:write_i8(0xc0c1,128+(i-1)); end
-- dofile("tms9918_apple_memspace.lua")
fontarray = {32, 0,0,0,0,0,0,0,0,
33, 24,60,60,24,24,0,24,0,
34, 108,108,0,0,0,0,0,0,
35, 108,108,254,108,254,108,108,0,
36, 24,62,96,60,6,124,24,0,
37, 0,198,204,24,48,102,198,0,
38, 56,108,104,118,220,204,118,0,
39, 24,24,48,0,0,0,0,0,
40, 12,24,48,48,48,24,12,0,
41, 48,24,12,12,12,24,48,0,
42, 0,102,60,255,60,102,0,0,
43, 0,24,24,126,24,24,0,0,
44, 0,0,0,0,0,24,24,48,
45, 0,0,0,126,0,0,0,0,
46, 0,0,0,0,0,24,24,0,
47, 3,6,12,24,48,96,192,0,
48, 60,102,110,126,118,102,60,0,
49, 24,56,24,24,24,24,126,0,
50, 60,102,6,28,48,102,126,0,
51, 60,102,6,28,6,102,60,0,
52, 28,60,108,204,254,12,30,0,
53, 126,96,124,6,6,102,60,0,
54, 28,48,96,124,102,102,60,0,
55, 126,102,6,12,24,24,24,0,
56, 60,102,102,60,102,102,60,0,
57, 60,102,102,62,6,12,56,0,
58, 0,24,24,0,0,24,24,0,
59, 0,24,24,0,0,24,24,48,
60, 12,24,48,96,48,24,12,0,
61, 0,0,126,0,0,126,0,0,
62, 48,24,12,6,12,24,48,0,
63, 60,102,6,12,24,0,24,0,
64, 124,198,222,222,222,192,120,0,
65, 24,60,60,102,126,195,195,0,
66, 252,102,102,124,102,102,252,0,
67, 60,102,192,192,192,102,60,0,
68, 248,108,102,102,102,108,248,0,
69, 254,102,96,120,96,102,254,0,
70, 254,102,96,120,96,96,240,0,
71, 60,102,192,206,198,102,62,0,
72, 102,102,102,126,102,102,102,0,
73, 126,24,24,24,24,24,126,0,
74, 14,6,6,6,102,102,60,0,
75, 230,102,108,120,108,102,230,0,
76, 240,96,96,96,98,102,254,0,
77, 130,198,238,254,214,198,198,0,
78, 198,230,246,222,206,198,198,0,
79, 56,108,198,198,198,108,56,0,
80, 252,102,102,124,96,96,240,0,
81, 56,108,198,198,198,108,60,6,
82, 252,102,102,124,108,102,227,0,
83, 60,102,112,56,14,102,60,0,
84, 126,90,24,24,24,24,60,0,
85, 102,102,102,102,102,102,62,0,
86, 195,195,102,102,60,60,24,0,
87, 198,198,198,214,254,238,198,0,
88, 195,102,60,24,60,102,195,0,
89, 195,195,102,60,24,24,60,0,
90, 254,198,140,24,50,102,254,0,
91, 60,48,48,48,48,48,60,0,
92, 192,96,48,24,12,6,3,0,
93, 60,12,12,12,12,12,60,0,
94, 16,56,108,198,0,0,0,0,
95, 0,0,0,0,0,0,0,254,
96, 24,24,12,0,0,0,0,0,
97, 0,0,60,6,30,102,59,0,
98, 224,96,108,118,102,102,60,0,
99, 0,0,60,102,96,102,60,0,
100, 14,6,54,110,102,102,59,0,
101, 0,0,60,102,126,96,60,0,
102, 28,54,48,120,48,48,120,0,
103, 0,0,59,102,102,60,198,124,
104, 224,96,108,118,102,102,230,0,
105, 24,0,56,24,24,24,60,0,
106, 6,0,6,6,6,6,102,60,
107, 224,96,102,108,120,108,230,0,
108, 56,24,24,24,24,24,60,0,
109, 0,0,102,119,107,99,99,0,
110, 0,0,124,102,102,102,102,0,
111, 0,0,60,102,102,102,60,0,
112, 0,0,220,102,102,124,96,240,
113, 0,0,61,102,102,62,6,7,
114, 0,0,236,118,102,96,240,0,
115, 0,0,62,96,60,6,124,0,
116, 16,48,124,48,48,52,24,0,
117, 0,0,204,204,204,204,118,0,
118, 0,0,204,204,204,120,48,0,
119, 0,0,198,214,214,108,108,0,
120, 0,0,99,54,28,54,99,0,
121, 0,0,102,102,102,60,24,112,
122, 0,0,126,76,24,50,126,0,
123, 14,24,24,112,24,24,14,0,
124, 24,24,24,24,24,24,24,0,
125, 112,24,24,14,24,24,112,0,
126, 114,156,0,0,0,0,0,0,
127, 0,0,0,0,0,0,0,0
}
cpu = manager:machine().devices[":maincpu"];mem = cpu.spaces["program"]
reginitarray = {2,196,14,255,3,118,3,15}
for i=1,table.maxn(reginitarray) do
dummy=mem:read_i8(0xc0c1);
mem:write_i8(0xc0c1,reginitarray[i]); mem:write_i8(0xc0c1,128+(i-1)); end
-- name table at 0x3800
mem:write_i8(0xc0c1,0x0);
mem:write_i8(0xc0c1,0x38+64);
for j=0,2 do
for i=0,255 do mem:write_i8(0xc0c0,i) end
end
-- color table at 0x2000
mem:write_i8(0xc0c1,0x0);
mem:write_i8(0xc0c1,0x20+64);
for i=0,6143 do mem:write_i8(0xc0c0,15*16+4) end
-- pattern table at 0, but we'll start at 0x100 because our character data starts at 32
mem:write_i8(0xc0c1,0x0);
mem:write_i8(0xc0c1,0x0+1+64); -- going to write data, so we add 64
i=1
while(true) do
if i>table.maxn(fontarray) then break; end;
charnum = fontarray[i];
i = i + 1;
for j=1,8 do mem:write_i8(0xc0c0,fontarray[i]); i = i + 1; end
end
a = "Writing to the TMS9918 using addresses C0C0 and C0C1 with Lua"
xpos = 0 -- horizontal character pos (in characters)
ypos = 16*8 -- y character pos (in pixels)
copychar = {} -- init array copychar
for aindex = 1,string.len(a) do
screenaddr = math.floor(ypos/8)*256+xpos*8 + (ypos % 8)
char = string.byte(a,aindex)
charaddr = char*8
-- get char into copychar array
mem:write_i8(0xc0c1,charaddr % 256);
mem:write_i8(0xc0c1,math.floor(charaddr/256)); -- going to read data, don't need to add anything
for i = 0,7 do copychar[i]=mem:read_i8(0xc0c0) end
mem:write_i8(0xc0c1,screenaddr % 256);
mem:write_i8(0xc0c1,math.floor(screenaddr/256)+64); -- going to write data, add 64
for i= 0,7 do mem:write_i8(0xc0c0,copychar[i]); end
xpos = xpos + 1
end
|
|
|
|
Joined: Feb 2014
Posts: 1,102 Likes: 173
Very Senior Member
|
Very Senior Member
Joined: Feb 2014
Posts: 1,102 Likes: 173 |
Thanks for the emu.register_frame(cbfunction) suggestion. I'll give it a try. For some reason I had always had problems wrapping my head around that style of programming where you have functions that are called.
I've always thought linearly where the program follows a strict sequence. I like the concept of having a regular function that can pause itself and pick right up where it left off.
|
|
|
|
Joined: Feb 2014
Posts: 1,102 Likes: 173
Very Senior Member
|
Very Senior Member
Joined: Feb 2014
Posts: 1,102 Likes: 173 |
Ok, just tried writing a little routine for emu.register_frame() This will make the TMS9918 sprites swing back and forth. I did run into a little trouble with write_i8 because it wants integer values, not floating point. If you send it a floating point value, it will write a zero. -- mem:write_i8(0,255) -- mem:write_i8(0,5.5) writes a ZERO for a floating point value, so we'd better use math.floor to integerize it. So I can register_frame(), how do I unregister a function? Every time I execute this lua script, it calls emu.register_frame again and swings back and forth faster and faster. Whee!
-- dofile("tms_frame_call.lua")
framecount = 0
function tms_frame_call()
framecount = framecount + 4
sinoffset = math.floor(math.sin((framecount % 360)/360*(2*math.pi))*20);
for i=0,string.len(a)-1 do
setsprite(i,math.floor(50+(i%4)*20+sinoffset),30+math.floor(i/4)*20,string.byte(a,i+1),(i*2+1)%16);
end
end
emu.register_frame(tms_frame_call) This script sets everything up beforehand:
-- dofile("fontarray_tms.lua")
tms= manager:machine().devices[":sl4:arcbd:arcbd_tms"]
-- tms= manager:machine().devices[":sl4:ezcgi:ezcgi_tms"]
mem = tms.spaces["vram"]
fontarray = {32, 0,0,0,0,0,0,0,0,
33, 24,60,60,24,24,0,24,0,
34, 108,108,0,0,0,0,0,0,
35, 108,108,254,108,254,108,108,0,
36, 24,62,96,60,6,124,24,0,
37, 0,198,204,24,48,102,198,0,
38, 56,108,104,118,220,204,118,0,
39, 24,24,48,0,0,0,0,0,
40, 12,24,48,48,48,24,12,0,
41, 48,24,12,12,12,24,48,0,
42, 0,102,60,255,60,102,0,0,
43, 0,24,24,126,24,24,0,0,
44, 0,0,0,0,0,24,24,48,
45, 0,0,0,126,0,0,0,0,
46, 0,0,0,0,0,24,24,0,
47, 3,6,12,24,48,96,192,0,
48, 60,102,110,126,118,102,60,0,
49, 24,56,24,24,24,24,126,0,
50, 60,102,6,28,48,102,126,0,
51, 60,102,6,28,6,102,60,0,
52, 28,60,108,204,254,12,30,0,
53, 126,96,124,6,6,102,60,0,
54, 28,48,96,124,102,102,60,0,
55, 126,102,6,12,24,24,24,0,
56, 60,102,102,60,102,102,60,0,
57, 60,102,102,62,6,12,56,0,
58, 0,24,24,0,0,24,24,0,
59, 0,24,24,0,0,24,24,48,
60, 12,24,48,96,48,24,12,0,
61, 0,0,126,0,0,126,0,0,
62, 48,24,12,6,12,24,48,0,
63, 60,102,6,12,24,0,24,0,
64, 124,198,222,222,222,192,120,0,
65, 24,60,60,102,126,195,195,0,
66, 252,102,102,124,102,102,252,0,
67, 60,102,192,192,192,102,60,0,
68, 248,108,102,102,102,108,248,0,
69, 254,102,96,120,96,102,254,0,
70, 254,102,96,120,96,96,240,0,
71, 60,102,192,206,198,102,62,0,
72, 102,102,102,126,102,102,102,0,
73, 126,24,24,24,24,24,126,0,
74, 14,6,6,6,102,102,60,0,
75, 230,102,108,120,108,102,230,0,
76, 240,96,96,96,98,102,254,0,
77, 130,198,238,254,214,198,198,0,
78, 198,230,246,222,206,198,198,0,
79, 56,108,198,198,198,108,56,0,
80, 252,102,102,124,96,96,240,0,
81, 56,108,198,198,198,108,60,6,
82, 252,102,102,124,108,102,227,0,
83, 60,102,112,56,14,102,60,0,
84, 126,90,24,24,24,24,60,0,
85, 102,102,102,102,102,102,62,0,
86, 195,195,102,102,60,60,24,0,
87, 198,198,198,214,254,238,198,0,
88, 195,102,60,24,60,102,195,0,
89, 195,195,102,60,24,24,60,0,
90, 254,198,140,24,50,102,254,0,
91, 60,48,48,48,48,48,60,0,
92, 192,96,48,24,12,6,3,0,
93, 60,12,12,12,12,12,60,0,
94, 16,56,108,198,0,0,0,0,
95, 0,0,0,0,0,0,0,254,
96, 24,24,12,0,0,0,0,0,
97, 0,0,60,6,30,102,59,0,
98, 224,96,108,118,102,102,60,0,
99, 0,0,60,102,96,102,60,0,
100, 14,6,54,110,102,102,59,0,
101, 0,0,60,102,126,96,60,0,
102, 28,54,48,120,48,48,120,0,
103, 0,0,59,102,102,60,198,124,
104, 224,96,108,118,102,102,230,0,
105, 24,0,56,24,24,24,60,0,
106, 6,0,6,6,6,6,102,60,
107, 224,96,102,108,120,108,230,0,
108, 56,24,24,24,24,24,60,0,
109, 0,0,102,119,107,99,99,0,
110, 0,0,124,102,102,102,102,0,
111, 0,0,60,102,102,102,60,0,
112, 0,0,220,102,102,124,96,240,
113, 0,0,61,102,102,62,6,7,
114, 0,0,236,118,102,96,240,0,
115, 0,0,62,96,60,6,124,0,
116, 16,48,124,48,48,52,24,0,
117, 0,0,204,204,204,204,118,0,
118, 0,0,204,204,204,120,48,0,
119, 0,0,198,214,214,108,108,0,
120, 0,0,99,54,28,54,99,0,
121, 0,0,102,102,102,60,24,112,
122, 0,0,126,76,24,50,126,0,
123, 14,24,24,112,24,24,14,0,
124, 24,24,24,24,24,24,24,0,
125, 112,24,24,14,24,24,112,0,
126, 114,156,0,0,0,0,0,0,
127, 0,0,0,0,0,0,0,0
}
cpu = manager:machine().devices[":maincpu"];apmem = cpu.spaces["program"]
reginitarray = {2,197,14,255,3,118,3,15}
for i=1,table.maxn(reginitarray) do
dummy=apmem:read_i8(0xc0c1);
apmem:write_i8(0xc0c1,reginitarray[i]); apmem:write_i8(0xc0c1,128+(i-1)); end
-- pattern table at 0x0000
i=1
bytepos=0x0000+32*8
while(true) do
if i>table.maxn(fontarray) then break; end;
charnum = fontarray[i];
i = i + 1;
for j=1,8 do mem:write_i8(bytepos,fontarray[i]); i = i + 1; bytepos = bytepos+1; end
end
-- name table at 0x3800
bytepos = 0x3800
for j=0,2 do
for i=0,255 do mem:write_i8(bytepos,i); bytepos = bytepos+1; end
end
-- color table at 0x2000
bytepos = 0x2000
for i=0,6143 do mem:write_i8(bytepos,15*16+4); bytepos = bytepos+1; end
-- use our font array for a sprite pattern table also
i=1
bytepos=0x1800+32*8
while(true) do
if i>table.maxn(fontarray) then break; end;
charnum = fontarray[i];
i = i + 1;
for j=1,8 do mem:write_i8(bytepos,fontarray[i]); i = i + 1; bytepos = bytepos+1; end
end
function setsprite(sprite,x,y,pattern,color)
--print ("sprite: " .. sprite .. " x: " .. x)
bytepos=0x3b00+sprite*4
if y>=0 then mem:write_i8(bytepos,y) end -- vertical first
if x>=0 then mem:write_i8(bytepos+1,x) end
if pattern>=0 then mem:write_i8(bytepos+2,pattern) end
if color >=0 then mem:write_i8(bytepos+3,color) end
end
a = "MameTMS 99184 spriteper line max"
for i=0,string.len(a)-1 do
setsprite(i,50+(i%4)*20,30+math.floor(i/4)*20,string.byte(a,i+1),(i*2+1)%16);
end
|
|
|
|
Joined: Feb 2014
Posts: 1,102 Likes: 173
Very Senior Member
|
Very Senior Member
Joined: Feb 2014
Posts: 1,102 Likes: 173 |
A couple of modifications to my little routine so you can control it from the console: deactivate = true to stop it speed = 8 to change the speed speed = 184 looks kind of ghostly with each frame alternating out of phase
deactivate = false
speed = 4
framecount = 0
function tms_frame_call()
if not deactivate then
framecount = framecount + speed
sinoffset = math.floor(math.sin((framecount % 360)/360*(2*math.pi))*20);
for i=0,string.len(a)-1 do
setsprite(i,math.floor(50+(i%4)*20+sinoffset),30+math.floor(i/4)*20,string.byte(a,i+1),(i*2+1)%16);
end
end
end
emu.register_frame(tms_frame_call)
|
|
|
|
Joined: Feb 2014
Posts: 1,102 Likes: 173
Very Senior Member
|
Very Senior Member
Joined: Feb 2014
Posts: 1,102 Likes: 173 |
I saw the Coleco Adam SmartLogo demo where it shows all 32 sprites flying around the screen and wanted to see if I could reproduce it. I run the adam driver and wrote a little lua script to save out the vram to a file. So we launch the adam driver with "./mame64 adam smartlog -plugin console" and get to the examples screen so we can dump the vram. We run the following script with dofile("adam_dump_vram.lua") -- Coleco Adam calls its tms device ":tms9928a"
tms= manager:machine().devices[":tms9928a"]
mem = tms.spaces["vram"]
-- read vram and save to a file
outfile = assert(io.open("vram_dump_file", "wb"))
for i=0,16384-1 do
outfile:write(string.char(mem:read_u8(i)))
end
assert(outfile:close())
I take the vram dump and load it into the apple2 arcade board's memory. "./mame64 apple2e -sl4 arcbd -plugin console" and run this script to load the vram dump: dofile("arcbd_load_vram.lua") tms= manager:machine().devices[":sl4:arcbd:arcbd_tms"]
mem = tms.spaces["vram"]
-- read vram from a file and close it
infile = assert(io.open("vram_dump_file", "rb"))
datablock = infile:read("*all")
assert(infile:close())
for i=0,16384-1 do
mem:write_i8(i,string.byte(datablock,(i+1))) -- datablock index starts at 1
end and init the TMS9918 registers to match (since it puts its sprite attribute tables in a different spot than I was using at 1F80). dofile("smartlogo_demo.lua") cpu = manager:machine().devices[":maincpu"];apmem = cpu.spaces["program"]
reginitarray = {2,194,14,255,3,63,3,1}
for i=1,table.maxn(reginitarray) do
dummy=apmem:read_i8(0xc0c1);
apmem:write_i8(0xc0c1,reginitarray[i]); apmem:write_i8(0xc0c1,128+(i-1)); end
myspriteattributes = {}
for i=0,31 do
myspriteattributes[i]={ }
end
for i = 0,31 do
myspriteattributes[i][0] = 128
myspriteattributes[i][1] = 96
myspriteattributes[i][2] = (i+1)*4 -- pattern (since we are doing 16x16 sprites must be multiples of 4
myspriteattributes[i][3] = (i % 14) + 2 --color
myspriteattributes[i][4] = .5 --speed
myspriteattributes[i][5] = i * (360/32) -- heading
end
function setspritetable(tablepos,sprite,x,y,pattern,color)
bytepos=tablepos+sprite*4
if y>=0 then mem:write_i8(bytepos,y) end
if x>=0 then mem:write_i8(bytepos+1,x) end
if pattern>=0 then mem:write_i8(bytepos+2,pattern) end
if color >=0 then mem:write_i8(bytepos+3,color) end
end
deactivate = false
function do_each_frame()
if not deactivate then
for i=0,31 do
xoffset = spritespeed*math.cos(myspriteattributes[i][5]/360*2*math.pi)
yoffset = spritespeed*math.sin(myspriteattributes[i][5]/360*2*math.pi)
myspriteattributes[i][0] = myspriteattributes[i][0] + xoffset
myspriteattributes[i][1] = myspriteattributes[i][1] - yoffset
if myspriteattributes[i][0] < 0 then myspriteattributes[i][0] = 256 end
if myspriteattributes[i][0] > 256 then myspriteattributes[i][0] = 0 end
if myspriteattributes[i][1] < 0 then myspriteattributes[i][1] = 192 end
if myspriteattributes[i][1] > 192 then myspriteattributes[i][1] = 0 end
setspritetable(0x1f80,i,math.floor(myspriteattributes[i][0]),
math.floor(myspriteattributes[i][1]),
myspriteattributes[i][2],
myspriteattributes[i][3])
end -- for
end -- if
end -- function
print("do you want to add the function do each frame to emu.register_frame?")
if io.read() == "y" then emu.register_frame(do_each_frame) end
spritespeed = 4
What's cool is to modify the myspriteattributes array in real time from the console and see the result. For example: for i = 0,31 do myspriteattributes[i][2]=36*4 end spritespeed = 0.5
|
|
|
|
Joined: Mar 2001
Posts: 17,217 Likes: 234
Very Senior Member
|
Very Senior Member
Joined: Mar 2001
Posts: 17,217 Likes: 234 |
That's really awesome. I'm glad to see someone combining MAME capabilities in unexpected-to-us ways
|
|
|
|
Joined: Feb 2004
Posts: 2,598 Likes: 301
Very Senior Member
|
Very Senior Member
Joined: Feb 2004
Posts: 2,598 Likes: 301 |
trying to do more gets me a segfault:
./mame64 apple2e -sl7 ssprite -sl4 arcbd -sl5 arcbd -sl2 arcbd Segmentation fault (core dumped) MAME has a hardcoded max of 4 screens. I'm not sure where it comes from, it limits my ability to put 6 NuBus video cards in a Mac II and have real fun Happy new year
|
|
|
|
Joined: Feb 2014
Posts: 1,102 Likes: 173
Very Senior Member
|
Very Senior Member
Joined: Feb 2014
Posts: 1,102 Likes: 173 |
Thanks RB, Mame is super addictive and fun. I figure something new out every day. It's like a learning lab for old systems. I was struggling so hard trying to get the tms9918 to do something interesting with applesoft and now I've discovered lua is 300x faster and easier. I wish I'd had this back in the days of the apple 2. I remember reading about the SuperSprite / Arcade Board in Creative Computing back in 1984 and being fascinated with the concept. Now I finally get a chance to actually give it a try. BTW, thanks for putting in the ssprite stuff in for 0.190. My discovery for today: how to roll your own dispatch function in lua. I'd make a mistake in a lua function that I called emu.register_frame() on and it would run away happily typing garbage in the console forever until you killed it (and your whole mame session) with CTRL+C. Once you get a runaway, you can't see what you're typing at all with all of the output clogging the terminal. So if you get in trouble, just type "cld()" and hit enter and that clears the dispatch_list. Or if you like to type, type "dispatch_list = {}"
dispatch_list = { }
function frame_dispatcher()
for index,my_func in pairs(dispatch_list) do my_func() end
end
function print_hello() print("hello") end
function print_there() print("there") end
function print_howareyou() print("how are you") end
function dispatch_list_remove(a_func)
for my_index,my_func in pairs(dispatch_list) do if my_func == a_func then table.remove(dispatch_list,my_index) end end
end
function print_dispatch_list() for my_index,my_func in pairs(dispatch_list) do print(my_func) end end
table.insert(dispatch_list,print_hello)
table.insert(dispatch_list,print_there)
table.insert(dispatch_list,print_howareyou)
frame_dispatcher()
print_dispatch_list()
dispatch_list_remove(print_there)
frame_dispatcher()
print_dispatch_list()
function cld()
dispatch_list = {}
end
-- emu.register_frame(frame_dispatcher);
print("type cld(); to stop a runaway dispatch");
print("copy the next line and paste to execute to add our frame dispatcher:");
print("emu.register_frame(frame_dispatcher);");
|
|
|
2 members (AJR, 1 invisible),
351
guests, and
6
robots. |
Key:
Admin,
Global Mod,
Mod
|
|
Forums9
Topics9,320
Posts121,944
Members5,074
|
Most Online1,283 Dec 21st, 2022
|
|
These forums are sponsored by Superior Solitaire, an ad-free card game collection for macOS and iOS. Download it today!
|
|
|
|