And one of the interesting things about older systems is that you often have to write your own routines to do graphics, like linedraws on the TMS9918. Drawing lines is actually pretty easy, just plot a pixel in the pattern memory by setting a bit, and set the color byte in the color memory.


[Linked Image from i.imgur.com]


Code
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_Regs[0]"]):write(0,2)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_Regs[1]"]):write(0,0xc2)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_pattern"]):write(0,0)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_colour"]):write(0,0x2000)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_nametbl"]):write(0,0x3800)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_mode"]):write(0,2)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_spritepattern"]):write(0,0x1800)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_spriteattribute"]):write(0,0x1f80)
--set background to 4
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_Regs[7]"]):write(0,0xf4)

mem=manager:machine().devices[":sl4:arcbd:arcbd_tms"].spaces["vram"]

function plotpixel(screenaddr,x,y)
local byteaddr = screenaddr + math.floor(y/8) * 256 + (y % 8) + math.floor(x/8) * 8
if x>=0 and x <=255 and y>=0 and y <=191 then
mem:write_u8(byteaddr,mem:read_u8(byteaddr)| (1 << (7-(x%8))))
end
end


function plotcolor(screenaddr,x,y,colorfg)
local byteaddr = screenaddr + math.floor(y/8) * 256 + (y % 8) + math.floor(x/8) * 8
if x>=0 and x<=255 and y>=0 and y<=191 then
--foreground single color
mem:write_u8(byteaddr,(mem:read_u8(byteaddr)& 0x0) | (math.floor(colorfg) << (4)) )
end
end


function deltasign(x)
if x<0 then return -1
elseif x==0 then return 0
elseif x>0 then return 1
else return 0
end
end


function linedraw(x1,y1,x2,y2,colorfg)
-- using basic code converted to lua from:
-- https://rosettacode.org/wiki/Bitmap/Bresenham's_line_algorithm
--[[
 1500 REM === DRAW a LINE. Ported from C version
 1510 REM Inputs are X1, Y1, X2, Y2: Destroys value of X1, Y1
 1520 DX = ABS(X2 - X1):SX = -1:IF X1 < X2 THEN SX = 1
 1530 DY = ABS(Y2 - Y1):SY = -1:IF Y1 < Y2 THEN SY = 1
 1540 ER = -DY:IF DX > DY THEN ER = DX
 1550 ER = INT(ER / 2)
 1560 PLOT X1,Y1:REM This command may differ depending ON BASIC dialect
 1570 IF X1 = X2 AND Y1 = Y2 THEN RETURN
 1580 E2 = ER
 1590 IF E2 > -DX THEN ER = ER - DY:X1 = X1 + SX
 1600 IF E2 < DY THEN ER = ER + DX:Y1 = Y1 + SY
 1610 GOTO 1560
--]]

x1 = math.floor(x1)
x2 = math.floor(x2)
y1 = math.floor(y1)
y2 = math.floor(y2)
 dx = x2-x1
 dy = y2-y1
 sx = deltasign(dx)
 sy = deltasign(dy)
 local x = x1
 local y = y1
 local adx = math.abs(dx)
 local ady = math.abs(dy)
 local er,e2

if adx > ady then er =  adx 
else er = - ady
end 

er = math.floor(er / 2)

while 1 do
  plotpixel(0,x,y)
  plotcolor(8192,x,y,colorfg)
  if x == x2 and y == y2 then return end
  e2 = er
  if e2 > -adx then er = er - ady; x = x + sx  end
  if e2 <  ady then er = er + adx; y = y + sy  end
  if x<0 or x > 255 or y < 0 or y > 191 then return end
end  -- while
end -- function


function clearscreentms()
tms= manager:machine().devices[":sl4:arcbd:arcbd_tms"]
mem = tms.spaces["vram"]
local addr
for addr = 0,6143 do mem:write_u8(addr,0) end
end

function circlerandomcolor(step,size)
local i
for i=0,360,step do linedraw(128,96,128+math.cos(i/360*2*math.pi)*size,96+math.sin(i/360*2*math.pi)*size,math.floor(math.random()*15)) end
end

function initpatterntms()
local pat
for pat = 0,768-1 do
   mem:write_u8(pat+0x3800,pat % 256)
end
end


clearscreentms()
initpatterntms()
for i = 0,255,16 do linedraw(i,0,0,192,math.floor(i/16)) end
circlerandomcolor(1,50)
for i = 0,255,16 do linedraw(i,0,255,191,math.floor(i/16)) end