TheCryptek

[LUA][OC] RogueBIOS

Aug 20th, 2016
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.92 KB | None | 0 0
  1. local searchPaths = {
  2.     '/boot/boot.lua',
  3.     '/boot.lua',
  4.     '/init.lua',
  5. }
  6. local sf = string.format
  7. -- Boot device
  8. local bdev = {
  9.     comp = computer,
  10.     ls = component.list,
  11.     disp = false,
  12.     rom = component.list('eeprom', true)(),
  13.     sl = { version = '1.0' }
  14. }
  15. setmetatable(bdev, {__index = component})
  16.  
  17. function bdev:panic(msg, data)
  18.     self.comp.beep(2000, 0.2)
  19.     return error(msg .. (data and ': ' .. data or ''), 0)
  20. end
  21.  
  22. function bdev:pullsig(timeout)
  23.     return self.comp.pullSignal(timeout)
  24. end
  25.  
  26. function bdev:print(msg)
  27.     if self.disp then
  28.         self.gpu.set(1, self.gpu.cur_y, msg)
  29.         if self.gpu.cur_y == self.gpu.scr_h then
  30.             self.gpu.copy(1, 2, self.gpu.scr_w, self.gpu.scr_h - 1, 0, -1)
  31.             self.gpu.fill(1, self.gpu.scr_h, self.gpu.scr_w, 1, ' ')
  32.         else self.gpu.cur_y = self.gpu.cur_y + 1 end
  33.     end
  34. end
  35.  
  36. function bdev:clear()
  37.     if self.disp then
  38.         self.gpu.cur_y = 1
  39.         self.gpu.fill(1, 1, self.gpu.scr_w, self.gpu.scr_h, ' ')
  40.     end
  41. end
  42.  
  43. function bdev:sleep(timeout)
  44.     local deadline = self.comp.uptime() + (timeout or 0)
  45.     repeat self.pullsig(deadline - self.comp.uptime())
  46.     until self.comp.uptime() >= deadline
  47. end
  48.  
  49. function computer.getBootAddress()
  50.   return bdev.invoke(bdev.rom, 'getData')
  51. end
  52. function computer.setBootAddress(address)
  53.   return bdev.invoke(bdev.rom, 'setData', address)
  54. end
  55.  
  56. do
  57.     local gpu = bdev.ls('gpu', true)()
  58.     local screen = bdev.ls('screen', true)()
  59.     if gpu and screen then
  60.         bdev.disp = true
  61.         bdev.gpu = bdev.proxy(gpu)
  62.         bdev.screen = bdev.proxy(screen)
  63.         bdev.gpu.bind(screen)
  64.         bdev.screen.turnOn()
  65.         bdev.gpu.setBackground(0)
  66.         bdev.gpu.setForeground(0xFFFFFF)
  67.         bdev.gpu.scr_w, bdev.gpu.scr_h = bdev.gpu.getResolution()
  68.         bdev:clear()
  69.     end
  70. end
  71.  
  72. bdev:print(sf('RogueBIOS v%s --- by RogueNet', bdev.sl.version))
  73. bdev:print''
  74.  
  75. bdev:print'Searching for boot files ...'
  76. local bFSs = {}
  77. for address in bdev.ls('filesystem', true) do
  78.     for _,path in ipairs(searchPaths) do
  79.         if bdev.invoke(address, 'exists', path) then
  80.             table.insert(bFSs, {address, path})
  81.             break
  82.         end
  83.     end
  84.  
  85.     if #bFSs == 9 then break end
  86. end
  87. local nbFSs = #bFSs
  88.  
  89. local sFS = 0
  90. if nbFSs == 1 or not bdev.disp then sFS = 1
  91. elseif nbFSs > 1 then
  92.     bdev:print''
  93.     bdev:print'Select a filesystem to boot from:'
  94.     for i,fst in ipairs(bFSs) do
  95.         local fsLabel = bdev.invoke(fst[1], 'getLabel')
  96.         fsLabel = fsLabel and fsLabel..' ' or ''
  97.         bdev:print(sf('%i) %s:%s', i, fsLabel .. fst[1], fst[2]))
  98.     end
  99.  
  100.     local v = 0
  101.     repeat
  102.         e = table.pack(bdev:pullsig())
  103.         if e[1] == 'component_removed' or e[1] == 'component_added' then
  104.             bdev.comp.shutdown(true) end
  105.         if e[1] == 'key_down' and tonumber(e[3]) then v = tonumber(e[3]) - 48
  106.         end
  107.     until e[1] == 'key_down' and v > 0 and v <= nbFSs
  108.     sFS = v
  109.     bdev:print''
  110. else bdev:panic'No bootable medium' end
  111.  
  112. local bootaddr = bFSs[sFS][1]
  113. local bootfile = bFSs[sFS][2]
  114. bdev.bootfile = bootfile
  115. bdev.bootaddress = bootaddr
  116. bdev:print(sf('Loading %s:%s', bootaddr, bootfile))
  117.  
  118. local bfh, reason = bdev.invoke(bootaddr, 'open', bootfile)
  119. if not bfh then bdev:panic('Couldnt open boot file', reason) end
  120. local buffer = ''
  121. repeat
  122.     local data, reason = bdev.invoke(bootaddr, 'read', bfh, math.huge)
  123.     if not data and reason then bdev:panic('Couldnt read boot file', reason)
  124.     end
  125.     buffer = buffer .. (data or '')
  126. until not data
  127. bdev.invoke(bootaddr, 'close', bfh)
  128. if not buffer then bdev:panic'Empty buffer' end
  129.  
  130. bdev.comp.beep(2000, 0.2)
  131. bdev.comp.setBootAddress(bootaddr)
  132. local env = { bootdevice = bdev }
  133. setmetatable(env, {__index = _G})
  134. local boot = load(buffer, '@'..bootfile, 'bt', env)
  135. if not boot then bdev:panic('Booting failed.', 'Errors in boot file') end
  136. boot()
Advertisement
Add Comment
Please, Sign In to add comment