So why not make it so you can control the little turtle guy with the keyboard?

The ultimate goal would be to program a game in mame with lua.

This lua script assumes that you've already got the vram loaded with the dump from the smartlogo program, and you've initialized the TMS9918 registers:

Code

function heading_to_spritenumber(heading)
local heading24
-- reverse the heading direction and rotate by 90 degrees and scale to 0..23
heading24 = ((-1*(heading - 90)) % 360) *(24/360)
return math.floor(36+heading24)*4 -- turtles run from 36 to 59 (24 different sprites patterns)
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
spritespeed = 1
myspriteattributes[i]["xvel"] = math.cos(myspriteattributes[i][5]*(2*math.pi/360))
myspriteattributes[i]["yvel"] = math.sin(myspriteattributes[i][5]*(2*math.pi/360))
end
function setspritetable(tablepos,sprite,x,y,pattern,color)
bytepos=tablepos+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
function read_keys()
inp = manager:machine():input()
thrust_value = 0.05
if inp:code_pressed(inp:code_from_token("KEYCODE_UP")) then
myspriteattributes[0]["xvel"] = myspriteattributes[0]["xvel"] + math.cos(myspriteattributes[0][5]*(2*math.pi/360)) * thrust_value
myspriteattributes[0]["yvel"] = myspriteattributes[0]["yvel"] - math.sin(myspriteattributes[0][5]*(2*math.pi/360)) * thrust_value
end
if inp:code_pressed(inp:code_from_token("KEYCODE_DOWN")) then
myspriteattributes[0]["xvel"] = myspriteattributes[0]["xvel"] * 0.9
myspriteattributes[0]["yvel"] = myspriteattributes[0]["yvel"] * 0.9
end
if inp:code_pressed(inp:code_from_token("KEYCODE_LEFT")) then myspriteattributes[0][5] = myspriteattributes[0][5] + 2 end
if inp:code_pressed(inp:code_from_token("KEYCODE_RIGHT")) then myspriteattributes[0][5] = myspriteattributes[0][5] - 2 end
myspriteattributes[0][2] = heading_to_spritenumber(myspriteattributes[0][5])
if inp:code_pressed(inp:code_from_token("KEYCODE_C")) then setotherspritepattern(128) end
if inp:code_pressed(inp:code_from_token("KEYCODE_D")) then setotherspritepattern(0) end
end
function update_sprites()
for i=0,31 do
myspriteattributes[i][0] = myspriteattributes[i][0] + myspriteattributes[i]["xvel"]
myspriteattributes[i][1] = myspriteattributes[i][1] + myspriteattributes[i]["yvel"]
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
end
dispatch_list = { }
function frame_dispatcher()
for index,my_func in pairs(dispatch_list) do my_func() end
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
function cld()
dispatch_list = {}
end
print ("cld() installed type cld() and hit enter to stop dispatch")
print()
table.insert(dispatch_list,update_sprites)
table.insert(dispatch_list,read_keys)
print("table.insert(dispatch_list,update_sprites)")
print("table.insert(dispatch_list,read_keys)")
print()
print(" you will need to manually register frame since I don't want to have it done every time I run the lua file")
print()
print(" so copy and paste the following line on the console")
print()
print("emu.register_frame(frame_dispatcher)")
--print(" equivalent to: emu.register_frame(read_keys)")
print()
print("C key to clear the other sprites")
print("D key to bring the other sprites back")
print("UP key for thrust DOWN key to slow down")
print("LEFT RIGHT to turn")
function setotherspritepattern(spritepattern)
for i=1,31 do myspriteattributes[i][2]=spritepattern end
end

Just came across this while searching around on the internet and thought it was cool: A demo of Captain Pixel which ran on a "flippy card" that had a TMS 34010 and had interfaces to the Apple II and IBM PC.

According to the description:

Quote

arhenderson2006Published on Jul 17, 2007This was an interactive graphics demonstration that ran on the 34010 S.D.B. (software development board) and the TMS34010 "Flippy".

The "Flippy" was a 34010 graphics card with an Apple // compatible edge connector on one side and a PC compat. connector on the other. There was a machine specific "loader" module for each platform but a single executable. "Flippy" code was cross platform compatible because the actual application executed on the 34010.

Captain Pixel went on to have two offspring: Captain Comic for the PC by Michael Denio and a version of Captain Comic for the NES that Mike and I collaborated on.

Wow, that would've been a very powerful card. Games like the arcade versions of Smash TV and Mortal Kombat ran entirely on a 34010. If the Apple II software exists (or the PC software, but A2 would be more fun) we could definitely emulate it.

TI tried to push 34010 ISA cards on the PC as a "TIGA" standard but they were too pricey to catch on.

Texas Instruments came to Media Cybernetics as a then market leader with their latest bleeding edge graphics chip, the TMS34010. The 34010 was a true 32-bit processor with thirty-two 32-bit registers, bit addressability (and variable field width!), and a few graphics instructions. It sat in its own address space on an ISA card, where it communicated with the outside world through memory mapped registers. It was basically an embedded device that ran in true parallel with the host processor. Our development board had no BIOS, no OS, only the 34010 and its own address space. Only the open steppe. So management in its infinite wisdom agreed to port the HALO 2D graphics library in time for the upcoming trade show in San Jose, a ridiculously short 6 weeks away. I didn't step back fast enough when they asked for volunteers, so I "volunteered" for the work. Between myself and another guy on my HALO team we managed to port the entire HALO graphics kernel from 8086 assembler to 34010 assembler.(As a principal engineer and manager I rated a screaming 10 Mhz 286 with a full 640 KB, he had only a 6 Mhz 286 with 512 KB of memory.) I designed a way to download and bootstrap the HALO 34010 kernel onto the 34010 device, using only a simulator and a serial port built into the 34010 device. We had no hardware assistance for debugging. A truly Herculean achievement. You could do a warm reboot and the 34010 device would still be running, merrily drawing graphics from a vector list on its own display. Way cool. And this was way back in prehistory, in 1988. Truly revolutionary. Try doing that with a dual-core x64, dual-graphics card computer.

Recently I received an out of the blue inquiry from a hobbyist requesting some information on the TMS34010. Interestingly a few days prior I had run across my design notes for the TMS34010 where I had detailed the port of the Media Cybernetics Halo graphics kernel onto the 34010 for an upcoming trade show. Talk about deja vu all over again.

The TMS34010 was a fully independent processor that ran in it's own address space, a relatively small memory window being mapped into the host adress space for data transfer and control. You could program the word size from 1 to 32 bits. You could also read or write the arbitrary word size from or to an arbitrary bit address. Totally awesome! Quite an advantage in the mid-80s when pixels were smaller than bytes, and had to be read and written using shifts and bitwise logical operations. Processor speed on a high end PC AT was 10 mHz, so this provided a significant speed advantage.

Even though the herculean effort to design and port the Halo graphics kernel was a success, the TMS34010 never seemed to find widespread success in the graphics card market. I heard rumors of it being used in the unglamorous niche markets of fax machines and printers, where it's bit twiddling prowess would have provided a significant benefit. So to me the TMS34010 drifted out of thought, to be relegated to that twilight of yet another technology that was just too far ahead of its time.

So imagine my surprise when I heard the hobbyist was tinkering with an arcade game complete with 34010 processor on board. (Below are a closeup of the 34010 on the board and the entire arcade game board.) I've been meaning for years to transfer the 34010 compiler and other tools from the aging 5-1/4" floppies (with the gargantuan capacity of 360 KB!) Hopefully they still are readable. (I was told that VHS tapes would lose the image in a few years but I still have movies taped from HBO in 1984 that are still alive and well, so I'm optimistic.) I hope to make this page a resource for others trying to breathe life into an old 34010 system or trying to port 34010 code onto a more modern platform. I still have the 34010 programmer's manual (a fascinating architecture, a 32-bit word with Motorola like instructions and a scan line by scan line programmable palette) but whereas I may try to set up an old machine to read the floppies I can't see myself scanning the manual. Any links to a digital version of the programmer's manual would be awesome.