Guest User

Untitled

a guest
Sep 28th, 2012
895
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 37.97 KB | None | 0 0
  1. ; --------------------------------------------
  2. ; Title: cli
  3. ; Version:
  4. ; --------------------------------------------
  5.  
  6. ; CLI
  7. ; the command line interface is the default method for user to interact with OS
  8. ; etc stuff blahblahblah
  9. #segment text
  10.  
  11. :cli_name
  12. dat "Command Prompt", 0
  13.  
  14. #segment data
  15.  
  16. :cmd_start
  17. dat 0x0
  18.  
  19. :cmd_buffer
  20. dat 0x0
  21.  
  22. #segment code
  23.  
  24. ; prints the prompt
  25. :cli_prompt
  26. set push, a
  27. set a, cliprompt_data
  28. jsr print
  29. set a, pop
  30. set pc, pop
  31.  
  32. :cli
  33. ; set up command buffer
  34. set a, 128 ; 64 word buffer
  35. jsr malloc
  36. set [cmd_buffer], c ; store that
  37.  
  38. jsr clearscreen
  39. ;set a, clistart
  40. ;jsr print
  41. ;jsr newline
  42.  
  43. jsr cli_prompt ; print prompt
  44. set [cmd_start], [vram_pointer]
  45. :cli_input_loop
  46. set j, [vram_pointer]
  47. jsr getc
  48. ife c, 0
  49. set pc, cli_input_loop
  50. ifl c, 0x20
  51. set pc, cli_handle_lowspec ; handle low special character
  52. ifg c, 0x7f
  53. set pc, cli_handle_hispec ; handle high special character
  54.  
  55. :standard_char
  56. bor c, [defaultcolor]
  57. set [j], c
  58. add j, 1
  59. set [vram_pointer], j
  60.  
  61. set pc, cli_input_loop
  62.  
  63.  
  64. ; handle 0x10-0x19
  65. :cli_handle_lowspec
  66. ife c, 0x10 ; backspace
  67. jsr backspace
  68. ife c, 0x11 ; return
  69. jsr cli_handle_input ; deal with the input
  70. ife c, 0x12 ; insert
  71. add pc, 0 ; placeholder
  72. ife c, 0x13 ; delete
  73. add pc, 0 ; placeholder
  74.  
  75. set pc, cli_input_loop
  76.  
  77.  
  78.  
  79.  
  80. ; handle 0x80+
  81. :cli_handle_hispec
  82.  
  83. set pc, cli_input_loop
  84.  
  85.  
  86. ; handle an inputted command
  87. :cli_handle_input
  88. jsr newline ; go to a new line
  89. set push, a
  90. set push, b
  91. set push, c
  92. set push, z
  93. set push, i
  94. set push, j
  95. set y, 0
  96. set i, 0 ; argc
  97. set z, 0 ; *argv
  98.  
  99. set a, 32 ; stores the arguments
  100. jsr malloc
  101. set z, c
  102.  
  103. set [argv_buffer_pointer], z
  104. set a, [cmd_start] ; start of command
  105. set b, [cmd_buffer] ; copy into buffer
  106. set c, [vram_pointer]
  107. sub c, [cmd_start] ; length of command
  108. jsr memcpy ; do copy
  109.  
  110. set a, b ; set a to buffer
  111.  
  112. set push, a ; store a
  113. set push, b
  114. set b, a
  115. add b, 128
  116.  
  117. :buf_other_loop
  118. and [a], 0x7f
  119. add a, 1
  120. ifl a, b
  121. set pc, buf_other_loop
  122.  
  123. set b, pop
  124. set a, pop
  125.  
  126. set push, a
  127. set push, b
  128. set push, z
  129.  
  130. set b, a
  131. add b, 128
  132.  
  133. :buf_clean_loop ; clean out any text effects
  134. ifn [a], 0x20 ; space
  135. set pc, buf_clean_loop_skip
  136.  
  137. ; deal with space stuff
  138. set [a], 0 ; clear for nts delimiter
  139. add i, 1 ; increment argc
  140.  
  141. set push, b
  142. set push, c
  143. add a, 1
  144.  
  145. set [z], a
  146. add z, 1
  147.  
  148. sub a, 1
  149. set c, pop
  150. set b, pop
  151.  
  152.  
  153. :buf_clean_loop_skip
  154. add a, 1
  155. ifl a, b
  156. set pc, buf_clean_loop
  157.  
  158. set z, pop
  159. set b, pop
  160. set a, pop
  161.  
  162. ; handle buffer:
  163. jsr cmd_process ; process the actual command
  164.  
  165. jsr cli_prompt ; reprint new prompt
  166.  
  167. set b, 128 ; clear 64 words
  168. set a, [cmd_buffer]
  169. jsr memclear ; clear buffer
  170.  
  171. set c, pop
  172. set b, pop
  173. set a, pop
  174.  
  175. set j, pop
  176. set i, pop
  177. set z, pop
  178.  
  179. set [cmd_start], [vram_pointer] ; update cmd_start
  180.  
  181. set pc, cli_input_loop
  182.  
  183.  
  184. ; process the given command
  185. :cmd_process
  186. ; just check for default commands
  187. set push, a
  188. set push, b
  189. set push, c
  190. set push, x
  191. set push, y
  192.  
  193. set a, [cmd_buffer] ; first string is buffer
  194.  
  195. set push, cmd_process_end ; pseudo-jsr
  196.  
  197. set x, [cmd_buffer]
  198. ifn [x], 0x26 ; not ampersand
  199. set pc, cmd_process_l2 ; skip that stuff
  200.  
  201. ; set new thread stuff
  202. set y, 1 ; flag new process
  203. add a, 1 ; skip ampersand
  204.  
  205. :cmd_process_l2
  206. set x, 0
  207.  
  208. set b, proclist_cmd
  209. jsr strcmp ; compare
  210. ife c, 1 ; match
  211. set x, proclist ; do that
  212.  
  213. set b, disp_time_cmd
  214. jsr strcmp
  215. ife c, 1
  216. set x, disp_time
  217.  
  218. set b, testproc_cmd
  219. jsr strcmp
  220. ife c, 1
  221. set x, testproc2
  222.  
  223. set b, devicelist_cmd
  224. jsr strcmp
  225. ife c, 1
  226. set x, devicelist
  227.  
  228. set b, cli_kill_cmd
  229. jsr strcmp
  230. ife c, 1
  231. set x, cli_kill
  232.  
  233. set b, ls_cmd
  234. jsr strcmp
  235. ife c, 1
  236. set x, ls
  237.  
  238. set b, test_cmd
  239. jsr strcmp
  240. ife c, 1
  241. set x, testing
  242.  
  243. ifn x, 0 ; we are going to do something
  244. set pc, cmd_execute_base ; execute command
  245.  
  246. ; command not understood
  247. set a, cmd_unrecog
  248. jsr print
  249. add sp, 1
  250. jsr newline
  251.  
  252. :cmd_process_end
  253. set y, pop
  254. set x, pop
  255. set c, pop
  256. set b, pop
  257. set a, pop
  258. set pc, pop
  259.  
  260. :cmd_execute_base
  261. ife y, 1 ; gotta spawn new process
  262. jsr cmd_execute_new ; new process
  263. ife y, 0
  264. jsr cmd_execute_current ; just do it within current process
  265. set pc, pop
  266.  
  267. :cmd_execute_current
  268. set a, i
  269. set b, z
  270. set z, 0
  271. set i, 0
  272. set j, 0
  273. set push, x
  274. set x, 0
  275. jsr pop
  276. set pc, pop
  277.  
  278. :cmd_execute_new
  279. set push, a
  280. set push, b
  281. set a, x
  282. jsr newproc
  283. set b, cmd_new_proc_name
  284. jsr setprocname
  285. jsr startproc
  286. set b, pop
  287. set a, pop
  288. set pc, pop
  289.  
  290. ; CLI DATA
  291. #segment data
  292. :argv_buffer_pointer
  293. dat 0x0
  294.  
  295. #segment text
  296. :clistart
  297. dat "", 0
  298. :cliprompt_data
  299. dat "%>", 0
  300. :cmd_unrecog
  301. dat "Command not recognized.", 0
  302. :cmd_new_proc_name
  303. dat "Console spawned", 0; --------------------------------------------
  304. ; Title: file
  305. ; Date: 7/13/2012
  306. ; Version:
  307. ; --------------------------------------------
  308.  
  309. ; Sector Header Format: 32 words
  310. ;----------------------------------
  311. ; Word | What it is
  312. ;----------------------------------
  313. ; 0: Sector data type:
  314. ; 0: nothing
  315. ; 1: file
  316. ; 2: directory
  317. ;
  318. ; 1: Flags
  319. ;
  320. ; 2: Previous sector (0xFFFF if none)
  321. ;
  322. ; 3: Next sector (0xFFFF if none)
  323. ;
  324. ; 4:
  325.  
  326. #segment data
  327.  
  328. ; pointer to sector buffer
  329. :sector_buffer
  330. dat 0x0
  331.  
  332. ; sector of hard_drive that we are currently at
  333. :cur_sector
  334. dat 0x0
  335.  
  336. ; pointer to path string that we're currently at
  337. :cur_path
  338. dat 0x0
  339.  
  340.  
  341. #segment text
  342. :root_path
  343. dat "/", 0
  344.  
  345.  
  346. #segment code
  347.  
  348. ; initialize file system stuff
  349. :fs_init
  350. set push, a
  351.  
  352. set [hd_hwnum], i
  353.  
  354. set a, 512 ; sector buffer
  355. jsr malloc ; allocate it
  356. set [sector_buffer], c ; store that
  357.  
  358. set a, 128
  359. jsr malloc
  360. set [cur_path], c
  361.  
  362. jsr fs_format
  363.  
  364. set [cur_path], root_path ; default path
  365.  
  366. set a, pop
  367. set pc, pop
  368.  
  369.  
  370.  
  371. ; format the hard drive
  372. :fs_format
  373. set push, a
  374. set push, b
  375. set push, c
  376. set push, x
  377. set push, i
  378.  
  379. set i, [hd_hwnum]
  380.  
  381. ; check there is media
  382. set a, 0
  383. hwi i
  384. ife b, 0 ; no media
  385. set pc, fsf_end ; return
  386.  
  387. set c, 1438 ; sector for root directory
  388. set a, fs_format_data ; data to write
  389.  
  390. jsr sector_write ; write that data to that sector
  391.  
  392.  
  393.  
  394. :fsf_end
  395. set i, pop
  396. set x, pop
  397. set c, pop
  398. set b, pop
  399. set a, pop
  400.  
  401. set pc, pop
  402.  
  403.  
  404. #segment data
  405. :fs_format_data
  406. dat 0x0002, 0x0000, 0xFFFF, 0x059f, 0x0000, 0x0000, 0x0000, 0x0000
  407. dat 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
  408. dat 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
  409. dat 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
  410.  
  411.  
  412. #segment code
  413.  
  414.  
  415. ; write *A to sector C on disk I
  416. :sector_write
  417. set push, a
  418. set push, b
  419. set push, c
  420. set push, x
  421.  
  422. set b, c
  423. set x, a
  424. set c, 1
  425. set a, 0x11 ; interrupt code
  426.  
  427. hwi i ; do the interrupt
  428.  
  429. set x, pop
  430. set c, pop
  431. set b, pop
  432. set a, pop
  433. set pc, pop
  434.  
  435.  
  436. ; Go to specified relative/absolute path
  437. :cd
  438.  
  439.  
  440.  
  441.  
  442. #segment text
  443. :ls_cmd
  444. dat "ls", 0
  445.  
  446. #segment code
  447. ; List contents of current directory
  448. :ls
  449. ; first, print current path to screen
  450. set push, a
  451.  
  452. set a, [cur_path]
  453. jsr print ; print current path string
  454. jsr newline ; newline of course
  455.  
  456. ; now, print out contents of current directory
  457.  
  458. set a, pop
  459. set pc, pop; --------------------------------------------
  460. ; Title: graphics
  461. ; Date: 7/13/2012
  462. ; Version:
  463. ; --------------------------------------------
  464.  
  465. ; LEM1802 Driver
  466. ; Monitor display driver
  467. #segment data
  468. ; default print color
  469. :defaultcolor
  470. dat 0xf000
  471.  
  472. #segment code
  473.  
  474. ; print_hex
  475. ; prints the hex value in A, digit by digit, to screen
  476. :print_hex
  477. set push, a
  478. set push, b
  479. set push, c
  480.  
  481. set b, a
  482. and b, 0xf000 ; highest digit
  483. shr b, 12
  484. jsr print_hex_sub
  485.  
  486. set b, a
  487. and b, 0x0f00
  488. shr b, 8
  489. jsr print_hex_sub
  490.  
  491. set b, a
  492. and b, 0x00f0
  493. shr b, 4
  494. jsr print_hex_sub
  495.  
  496. set b, a
  497. and b, 0x000f
  498. jsr print_hex_sub
  499.  
  500. set c, pop
  501. set b, pop
  502. set a, pop
  503. set pc, pop ; return
  504.  
  505.  
  506. :print_hex_sub
  507. ifg b, 0x9 ; alphabetical digit
  508. add b, 0x37 ; bring to ascii
  509. ifl b, 0xa ; numerical digit
  510. add b, 0x30 ; bring to ascii
  511.  
  512. bor b, [defaultcolor]
  513. set c, [vram_pointer]
  514. set [c], b
  515. add c, 1
  516.  
  517. set [vram_pointer], c
  518.  
  519. ifg [vram_pointer], [vram_end]
  520. jsr shiftlines
  521.  
  522. set pc, pop
  523.  
  524.  
  525. ; print
  526. ; This function prints nt string pointed by A to the monitor
  527. :print
  528. set push, a
  529. set push, b
  530. set push, c
  531. set push, x
  532.  
  533. :print_loop
  534. set x, [a] ; character to print
  535.  
  536. jsr putc
  537.  
  538. :print_loop_end
  539.  
  540. add a, 1
  541. ifn [a], 0 ; not at end!
  542. set pc, print_loop ; keep going
  543.  
  544. :print_end
  545. set x, pop
  546. set c, pop
  547. set b, pop
  548. set a, pop
  549.  
  550. set pc, pop ; return
  551.  
  552.  
  553. ; handle a carriage return
  554. :carriage_ret
  555. and [vram_pointer], 0xffe0
  556.  
  557. set pc, pop
  558.  
  559. ; prints ascii character in a
  560. :putc
  561. ; check for overflow
  562. set b, [vram_pointer]
  563.  
  564. ifl b, [vram_end]
  565. set pc, putc_cont ; good to go
  566.  
  567. jsr shiftlines
  568.  
  569. :putc_cont
  570. ife x, 10 ; newline
  571. set pc, newline
  572. ife x, 8 ; backspace - this probably shouldn't show up but you never know
  573. set pc, backspace
  574. ife x, 13
  575. set pc, carriage_ret
  576.  
  577. bor x, [defaultcolor] ; add in color
  578.  
  579. set b, [vram_pointer] ; get vram pointer
  580. set [b], x ; print
  581. add b, 1 ; increment
  582. set [vram_pointer], b
  583.  
  584. set pc, pop
  585.  
  586.  
  587. ; print something out asynchronously from command line
  588. :async_print
  589. jsr newline ; force newline
  590. jsr print ; print the thing
  591. jsr newline
  592. set pc, pop
  593.  
  594. ; inserts a space
  595. :space
  596. add [vram_pointer], 1
  597. set pc, pop
  598.  
  599. ; shift the lines of everything down
  600. :shiftlines
  601. set push, i
  602. set push, j
  603. set push, z
  604.  
  605. set z, 0
  606.  
  607. set i, [vram_loc] ; i is beginning of vram
  608. set j, [vram_end]
  609. sub j, 32 ; j is end of 11th line (because 12th will be empty)
  610.  
  611. :sl_loop
  612. set [i], [i+32] ; set everything to the respective value a line below
  613. add i, 1 ; increment
  614. ifl i, j ; if not to end
  615. set pc, sl_loop ; go again
  616.  
  617. add j, 32 ; bring j to end
  618. :sl_loop2
  619. set [i], z ; clear i
  620. add i, 1 ; increment
  621. ifl i, j ; not at end...
  622. set pc, sl_loop2 ; ...keep going
  623.  
  624. set [vram_pointer], 0x1360
  625.  
  626. set z, pop
  627. set j, pop
  628. set i, pop
  629.  
  630. set pc, pop ; return
  631.  
  632. :addcolor
  633. set push, a
  634. set push, b
  635. set push, c
  636. jsr strlen
  637.  
  638. set b, [defaultcolor]
  639. add c, a
  640.  
  641. :addcolor_loop
  642. bor [a], b ; add in the color to this word
  643.  
  644. add a, 1
  645. ifl a, c
  646. set pc, addcolor_loop
  647.  
  648. set c, pop
  649. set b, pop
  650. set a, pop
  651.  
  652. set pc, pop
  653.  
  654.  
  655. :clearscreen
  656. set push, a
  657. set push, b
  658. set push, c
  659.  
  660. set a, [vram_loc]
  661. set b, [vram_end]
  662.  
  663. :csloop
  664. set [a], 0
  665. add a, 1
  666.  
  667. ifl a, b
  668. set pc, csloop
  669.  
  670.  
  671. ; reset vram pointer
  672. set [vram_pointer], [vram_loc]
  673.  
  674. set c, pop
  675. set b, pop
  676. set a, pop
  677.  
  678. set pc, pop
  679.  
  680. :newline
  681. set push, x
  682. set x, [vram_pointer]
  683. sub x, [vram_loc]
  684. and x, 0xffe0
  685. add x, 32
  686. add x, [vram_loc]
  687.  
  688. set [vram_pointer], x
  689.  
  690. ; check for overflow
  691. ifg [vram_pointer], [vram_end]
  692. jsr shiftlines ; if so shift lines up
  693.  
  694. set x, pop
  695. set pc, pop ; return
  696.  
  697.  
  698.  
  699. :backspace
  700. set push, i
  701. set i, [vram_pointer]
  702. ifg i, [vram_loc] ; not out of vram
  703. ifg i, [cmd_start] ; nor out of current command
  704. sub i, 1 ; go back one
  705. set [i], 0 ; clear old
  706.  
  707. set [vram_pointer], i ; re-store
  708.  
  709. set i, pop
  710. set pc, pop ; return; --------------------------------------------
  711. ; Title: hardware
  712. ; Date: 7/13/2012
  713. ; Version:
  714. ; --------------------------------------------
  715.  
  716. ; HARDWARE FUNCTIONS
  717. ; Functions designed to allow the OS to interact with hardware
  718.  
  719. ; hardware_init
  720. ; looks through all connected hardware devices, attempts to recognize each one,
  721. ; and initializes it as appropriate
  722.  
  723. :hardware_init
  724. set push, a
  725. set push, b
  726. set push, c
  727. set push, x
  728. set push, y
  729. set push, z
  730. set push, i
  731.  
  732.  
  733. hwn z ; find number of hardware devices
  734.  
  735. ; get ready for loop
  736. set i, 0 ; counter
  737.  
  738. ; loop for hardware init
  739. :hi_loop
  740. hwq i ; get info on i
  741.  
  742. ; find lem1802
  743. ife b, 0x7349
  744. ife a, 0xf615
  745. jsr lem1802_init ; initialize found monitor
  746.  
  747. ; find clock
  748. ife b, 0x12d0
  749. ife a, 0xb402
  750. jsr clock_init ; initialize found clock
  751.  
  752. ; find keyboard
  753. ife b, 0x30cf
  754. ife a, 0x7406
  755. jsr keyboard_init ; initialize found keyboard
  756.  
  757. ife b, 0x4cae
  758. ife a, 0x74fa
  759. jsr fs_init
  760.  
  761. add i, 1
  762.  
  763. ; if we haven't found every hardware device, keep going
  764. ifl i, z ; still less than z (total num)
  765. set pc, hi_loop
  766.  
  767. ; end of hi_loop
  768. set i, pop ; start restoring registers
  769. set z, pop
  770. set y, pop
  771. set x, pop
  772. set c, pop
  773. set b, pop
  774. set a, pop
  775.  
  776. set pc, pop ; return to calling function
  777.  
  778.  
  779. ; lem1802_init
  780. ; This function initializes hardware device I as a lem1802 monitor.
  781.  
  782. :lem1802_init
  783. ifn [lem_hwnum], 0 ; monitor already initializes
  784. set pc, pop ; go back, only one monitor (currently)
  785.  
  786. set [lem_hwnum], i ; store the hwnum of the monitor
  787.  
  788. set push, a
  789. set push, b
  790. set push, c
  791.  
  792. set a, 0x0 ; interrupt num for vram-set
  793. set b, [vram_loc] ; location of VRAM
  794. hwi i ; send vram-set interrupt
  795.  
  796. ; if desired, add additional configuration interrupts for monitor here
  797.  
  798.  
  799. ; calculate vram end
  800. set b, [vram_loc]
  801. add b, 384
  802. set [vram_end], b
  803.  
  804. set [vram_pointer], [vram_loc]
  805.  
  806. set c, pop
  807. set b, pop
  808. set a, pop
  809.  
  810. set pc, pop ; return to calling function
  811.  
  812.  
  813. ; clock_init
  814. ; This function initializes a clock at hwnum I
  815. :clock_init
  816. set push, a
  817. set push, b
  818. set push, c
  819.  
  820. set [clock_hwnum], i
  821.  
  822. set a, 0 ; set clock freq interrupt num
  823. set b, [clock_freq] ; frequency of clock data
  824. hwi i ; do the interrupt
  825.  
  826. set a, 2 ; set interrupt code interupt num
  827. set b, 0x01 ; code of clock
  828. hwi i ; do the interrupt again
  829.  
  830. set c, pop
  831. set b, pop
  832. set a, pop
  833.  
  834. set pc, pop
  835.  
  836.  
  837.  
  838. ; keyboard_init
  839. ; Initializes keyboard at hwnum i
  840. :keyboard_init
  841. set push, a
  842. set push, b
  843. set push, c
  844.  
  845. set [kb_hwnum], i
  846. ; do that interrupt
  847.  
  848. set c, pop
  849. set b, pop
  850. set a, pop
  851.  
  852. set pc, pop
  853.  
  854.  
  855. ; disp_time
  856. ; This function prints the current system time to the screen
  857. :disp_time
  858. set push, a
  859. set a, disp_time_data
  860. jsr print
  861.  
  862. set a, [sys_time+1]
  863. jsr print_hex
  864. set a, [sys_time]
  865. jsr print_hex
  866.  
  867. jsr newline
  868. set a, pop
  869. set pc, pop
  870.  
  871. #segment text
  872. :disp_time_data
  873. dat "Current system time: ", 0
  874. :disp_time_cmd
  875. dat "time", 0
  876. #segment code
  877.  
  878. ; list all devices and print formatted list
  879. :devicelist
  880. hwn i
  881. sub i, 1
  882. :dl_loop
  883. hwq i
  884.  
  885. set x, device_unrecog
  886.  
  887. ; find lem1802
  888. ife b, 0x7349
  889. ife a, 0xf615
  890. set x, monitor_text
  891.  
  892. ; find clock
  893. ife b, 0x12d0
  894. ife a, 0xb402
  895. set x, clock_text
  896.  
  897. ; find keyboard
  898. ife b, 0x30cf
  899. ife a, 0x7406
  900. set x, kb_text
  901.  
  902. set a, x
  903.  
  904. jsr print ; print text
  905. jsr newline ; advance line
  906.  
  907. sub i, 1
  908. ifn i, 0xffff
  909. set pc, dl_loop
  910.  
  911. set pc, pop
  912.  
  913. #segment text
  914.  
  915. :monitor_text
  916. dat "LEM1802 Monitor", 0
  917. :clock_text
  918. dat "Generic Clock", 0
  919. :kb_text
  920. dat "Generic Keyboard", 0
  921. :device_unrecog
  922. dat "Unrecognized Device", 0
  923. :devicelist_cmd
  924. dat "devicelist", 0; --------------------------------------------
  925. ; Title: kernel
  926. ; Date: 7/13/2012
  927. ; Version:
  928. ; --------------------------------------------
  929.  
  930. ; Operating system for DCPU16
  931.  
  932. #segment boot
  933. ; Go to beginning of OS:
  934. set pc, boot
  935.  
  936.  
  937.  
  938.  
  939. ; OS DATA
  940. #segment data
  941. ; location of kernel's stack
  942. :kernel_sp
  943. dat 0x1200 ; provides 512-word stack for kernel
  944.  
  945. ; clock interrupt frequency
  946. :clock_freq
  947. dat 1 ; 10 hertz
  948.  
  949. ; system time
  950. :sys_time
  951. dat 0, 0 ; 32-bit time value, represents clock ticks since startup
  952.  
  953. ; hwnum of the monitor the OS is using
  954. :lem_hwnum
  955. dat 0x0
  956.  
  957. ; hwnum of the active keyboard
  958. :kb_hwnum
  959. dat 0x0
  960.  
  961. ; hwnum of active clock
  962. :clock_hwnum
  963. dat 0x0
  964.  
  965. :hd_hwnum
  966. dat 0x0
  967.  
  968.  
  969.  
  970. ; process data
  971.  
  972. ; pid of the current process
  973. :cur_proc
  974. dat 0x0
  975.  
  976. :proc_list_start
  977. dat 0x1b00 ; start of data of process pointer list
  978.  
  979. :proc_maxnum
  980. dat 0x10 ; max number of processes (16)
  981.  
  982.  
  983. ; malloc data
  984. :malloc_reg
  985. dat 0x1400
  986.  
  987. :malloc_reg_end
  988. dat 0x0 ; calculated
  989.  
  990. :malloc_start
  991. dat 0x2000
  992.  
  993. :malloc_length
  994. dat 0xe000
  995.  
  996. :malloc_end
  997. dat 0x0 ; calculated
  998.  
  999. :malloc_reg_pointer
  1000. dat 0x0
  1001.  
  1002.  
  1003. ; video data
  1004. :vram_loc
  1005. dat 0x1200
  1006.  
  1007. :vram_pointer
  1008. dat 0x0 ; calculated
  1009.  
  1010. :vram_end
  1011. dat 0x0 ; calculated
  1012.  
  1013.  
  1014. ; AUTO CLOCKSPEED FLAG
  1015. :autoclockflag
  1016. dat 0x0 ; 1 for yes, 0 for no
  1017.  
  1018.  
  1019. ; Kernel Boot Functions
  1020. #segment code
  1021. ; This is what happens when the dcpu is turned on originally.
  1022. :boot
  1023. set sp, [kernel_sp] ; move sp to the proper place
  1024. set [cur_proc], 0x1 ; this is the "pid" assigned to the launch process (for pid-dependent function purposes)
  1025.  
  1026. jsr malloc_init ; initialize dynamically allocated memory
  1027.  
  1028. ; start test process for testing
  1029. ;jsr testproc2_start
  1030.  
  1031. jsr hardware_init ; recognize and initialize hardware
  1032. jsr fs_init
  1033.  
  1034. jsr bootscreen
  1035.  
  1036. set a, [autoclockflag]
  1037. ife a, 1
  1038. jsr autoclock
  1039. ife a, 0
  1040. jsr standardclock
  1041.  
  1042. ; Now, we need to set up the CLI process to get it all rolling
  1043. set a, cli ; starter PC of newproc
  1044. jsr newproc ; get the process for it going
  1045. set b, cli_name ; name of process
  1046. jsr setprocname ; set that
  1047. set b, 3 ; desired priority
  1048. jsr setprocpriority ; set that too
  1049. jsr startproc ; get process schedulable
  1050.  
  1051. ; start up our processcleaner
  1052. jsr processcleaner
  1053.  
  1054. ; start up interrupt handler, which will get actual OS running and end boot process
  1055. ias inthand
  1056.  
  1057. ; after the boot process, idle until scheduler takes over
  1058. :idle
  1059. iaq 0 ; make sure interrupts are on (for scheduler to resume control)
  1060. :idleloop
  1061. set pc, idleloop ; endless loop
  1062.  
  1063.  
  1064. ; OS has crashed for some reason
  1065. :crash
  1066. ias 0 ; no interrupts
  1067. sub pc, 1 ; hang
  1068.  
  1069.  
  1070. ; autosset clock settings
  1071. :autoclock
  1072. ; test cpu clock speed to set scheduling speed
  1073.  
  1074. set b, 1
  1075. set i, [clock_hwnum]
  1076. set a, 0
  1077. hwi i
  1078.  
  1079. set i, 0
  1080. :speed_test_loop
  1081. add i, 1
  1082. ifl i, 0xffff
  1083. set pc, speed_test_loop
  1084.  
  1085. set i, [clock_hwnum]
  1086. set a, 1
  1087. hwi i
  1088.  
  1089. div c, 40
  1090. add c, 1
  1091. set b, c
  1092.  
  1093. set a, 0
  1094. hwi i
  1095.  
  1096. set pc, pop
  1097.  
  1098. #segment text
  1099.  
  1100. :autoclock_cmd
  1101. dat "autoclock", 0
  1102.  
  1103. #segment code
  1104.  
  1105.  
  1106. :standardclock
  1107. set i, [clock_hwnum]
  1108. set a, 0
  1109. set b, 6
  1110. hwi i
  1111.  
  1112. set pc, pop
  1113.  
  1114.  
  1115.  
  1116. ; TEST FUNCTIONS
  1117.  
  1118. :testproc2_start
  1119. set push, a
  1120.  
  1121. set a, testproc2
  1122. jsr newproc
  1123. set b, testprocname
  1124. jsr setprocname
  1125. jsr startproc
  1126.  
  1127. set a, pop
  1128. set pc, pop
  1129.  
  1130. :testproc2
  1131. set a, 0
  1132. set b, 0
  1133. set c, 0
  1134. :loopy
  1135. add a, 1
  1136. add b, ex
  1137. add c, ex
  1138. set pc, loopy
  1139. #segment text
  1140. :testprocname
  1141. dat "Test process", 0
  1142. :testproc_cmd
  1143. dat "testproc", 0
  1144.  
  1145.  
  1146. ; OS API FUNCTIONS
  1147. ; Designed to be used by other programs and the OS alike
  1148. #segment code
  1149.  
  1150.  
  1151.  
  1152.  
  1153. ; STANDARD FUNCTIONS
  1154.  
  1155. ; memcpy
  1156. ; copies C words from A to B
  1157. :memcpy
  1158. set push, i
  1159. set push, j
  1160. set push, c
  1161.  
  1162. set i, a
  1163. set j, b
  1164. add c, i
  1165.  
  1166. :memcpy_loop
  1167. sti [j], [i]
  1168.  
  1169. ifl i, c
  1170. set pc, memcpy_loop
  1171.  
  1172. set c, pop
  1173. set j, pop
  1174. set i, pop
  1175.  
  1176. set pc, pop ; return
  1177.  
  1178.  
  1179. ; memclear
  1180. ; clears b words of memory starting at A
  1181. :memclear
  1182. set push, i
  1183. set push, j
  1184.  
  1185. set i, a ; beginning
  1186. set j, a
  1187. add j, b ; end
  1188.  
  1189. :memclear_loop
  1190. set [i], 0 ; clear
  1191. add i, 1 ; increment
  1192. ifl i, j ; not at end
  1193. set pc, memclear_loop ; keep going
  1194.  
  1195. set j, pop
  1196. set i, pop
  1197. set pc, pop
  1198.  
  1199.  
  1200.  
  1201.  
  1202. #segment code
  1203.  
  1204. ; INTERRUPT HANDLER
  1205. ; This is the OS interrupt handler. It handles all interrupts that can be caused.
  1206.  
  1207. ; Interrupt Codes
  1208. ; 0x01 - clock interrupt
  1209. ; 0x02 - non-clock scheduling interrupt
  1210. ; 0x03 - keyboard interrupt
  1211. ; 0x20 - malloc
  1212.  
  1213. ; Interrupt Handler data
  1214.  
  1215. :inthand
  1216. iaq 1 ; queue interrupts
  1217. set [extempstore], ex ; quickly store this
  1218. ; handle the interrupts
  1219. set push, intreturn ; pseudo-jsr
  1220.  
  1221. ife a, 0x01 ; clock interrupt
  1222. set pc, clock_interrupt
  1223.  
  1224. ife a, 0x02
  1225. set pc, ci_cont ; schedule without incrementing clock
  1226.  
  1227. ife a, 0x20 ; malloc interrupt
  1228. set pc, malloc_interrupt
  1229.  
  1230. :intreturn
  1231. ; end interrupt handler for non-process-switching interrupts and go back to proper code
  1232. rfi 1
  1233.  
  1234.  
  1235. ; specific interrupt handlers
  1236. :keyboard_interrupt
  1237.  
  1238. set pc, pop ; return
  1239.  
  1240.  
  1241.  
  1242. :clock_interrupt
  1243. ; increase system time
  1244. add [sys_time], 1 ; 32 bit increment
  1245. add [sys_time+1], ex
  1246.  
  1247. :ci_cont
  1248. ; get all the things as they should be
  1249. add sp, 1 ; undo inthand's push
  1250. set pc, schedule ; go schedule next process
  1251.  
  1252.  
  1253. :malloc_interrupt
  1254. ; do a malloc
  1255. set a, pop ; get a off stack
  1256. iaq 0 ; unqueue interrupts
  1257. set pc, malloc ; go do that
  1258.  
  1259.  
  1260.  
  1261. ; PROCESS FUNCTIONS
  1262. ; functions to handle the OS processes stuff
  1263.  
  1264.  
  1265. ; process stati:
  1266. ; 1 - run as normal
  1267. ; 2 - in creation
  1268. ; 3 - sleeping
  1269. ; 4 - being killed
  1270. ; 5 - indefinitely suspended
  1271. #segment data
  1272. ; schedule
  1273. ; Decide what process to run next, then set up and give that process control of dcpu
  1274. :stempstore
  1275. dat 0
  1276.  
  1277. :extempstore
  1278. dat 0
  1279.  
  1280. #segment code
  1281.  
  1282. :schedule
  1283. ; first things first: store data of currently running process
  1284. set [stempstore], b
  1285.  
  1286. set a, [cur_proc]
  1287. ifl a, 2 ; not legit process
  1288. set pc, sched_start2
  1289. add a, [proc_list_start]
  1290. set b, [a] ; data of current process
  1291. set [b+7], pop ; pop A from stack
  1292. set [b+4], pop ; pop PC from stack
  1293. set [b+8], [stempstore] ; get b from temp
  1294. set [b+9], c ; store the rest of registers
  1295. set [b+10], x
  1296. set [b+11], y
  1297. set [b+12], z
  1298. set [b+13], i
  1299. set [b+14], j
  1300. set [b+5], sp ; store sp
  1301.  
  1302.  
  1303. :sched_start2
  1304. set [cur_proc], 0x1 ; kernel process
  1305. set sp, [kernel_sp]
  1306.  
  1307. set i, [proc_list_start]
  1308. add i, 2 ; bring i to start of processes
  1309.  
  1310. set z, [proc_list_start]
  1311. add z, [proc_maxnum]
  1312.  
  1313. set a, 0 ; maxval
  1314. set b, 0 ; maxpid
  1315.  
  1316. :sched_loop
  1317. set c, [i] ; proc data for i
  1318. set x, [c] ; shortcut
  1319.  
  1320. ife c, 0 ; nothing to do here...
  1321. set pc, sched_loop_end
  1322.  
  1323. ife x, 3 ; process sleeping
  1324. set pc, sched_sleep_handle ; handle that stuff
  1325.  
  1326. ifn x, 1 ; process not supposed to be running
  1327. set pc, sched_loop_end
  1328.  
  1329. set x, [sys_time]
  1330. set y, [sys_time+1]
  1331. sub x, [c+2] ; lower 16 bit difference
  1332. add y, ex ; factor in overflow
  1333. sub y, [c+3] ; upper 16 bit difference
  1334.  
  1335. add x, [c+1] ; increase time based on priority
  1336. add y, ex ; overflow
  1337.  
  1338. ifg y, 0 ; something present in y
  1339. set x, 0xffff ; set x to max possible
  1340.  
  1341. ifl x, a ; didn't set new max
  1342. set pc, sched_loop_end
  1343.  
  1344. ; did set new max
  1345. set a, x ; change vals
  1346. set b, i
  1347.  
  1348. :sched_loop_end
  1349. add i, 1 ; increment
  1350. ifl i, z ; not at end
  1351. set pc, sched_loop
  1352.  
  1353. ; now we know what process to launch, we have to launch it
  1354. set a, b ; move b to a
  1355.  
  1356. ife a, 0 ; no process wants to be fun
  1357. set pc, idle ; idle and wait
  1358.  
  1359. set b, [a]
  1360. set [b+2], [sys_time]
  1361. set [b+3], [sys_time+1]
  1362.  
  1363. sub a, [proc_list_start] ; a is pid of process to launch
  1364. ; automatically continue to launch...
  1365. iaq 0 ; unqueue
  1366. :launch ; can also be started not from scheduler
  1367. ifl a, 2 ; not valid process
  1368. set pc, idle ; go idle and wait
  1369. iaq 1 ; queue interrupts
  1370. set [cur_proc], a ; set up current process
  1371. add a, [proc_list_start] ; bring a to entry in list
  1372. set a, [a] ; bring a to proc data
  1373. set b, [a+8] ; start setting registers
  1374. set c, [a+9]
  1375. set x, [a+10]
  1376. set y, [a+11]
  1377. set z, [a+12]
  1378. set i, [a+13]
  1379. set j, [a+14]
  1380. set ex, [a+6]
  1381. set sp, [a+5]
  1382. set push, [a+4] ; push pc
  1383. set a, [a+7]
  1384. iaq 0 ; unqueue interrupts
  1385. set pc, pop ; process launched
  1386.  
  1387. ; handle sleeping process
  1388. :sched_sleep_handle
  1389. set x, [sys_time]
  1390. set y, [sys_time+1]
  1391.  
  1392. ifl y, [c+16] ; upper 16 bits less
  1393. set pc, sched_loop_end
  1394. ifl x, [c+15] ; lower 16 bits less
  1395. set pc, sched_loop_end
  1396.  
  1397. ; stop sleeping!
  1398. set [c], 1 ; set status 1 - run normally
  1399. set pc, sched_loop_end ; go back into scheduling loop
  1400.  
  1401.  
  1402. :cli_kill
  1403. ifl a, 1 ; missing argument
  1404. set pc, cli_kill_fail
  1405. set a, [b]
  1406. set i, [a]
  1407. sub i, 0x30 ; ascii number to
  1408.  
  1409. add a, 1
  1410. set j, [a]
  1411. ife j, 0 ; single number given in arguments
  1412. set pc, cli_kill_1d
  1413.  
  1414. ; 2 digit
  1415. sub j, 0x30
  1416. mul i, 10
  1417. add j, i ; j is pid
  1418.  
  1419. set a, j
  1420. jsr killproc
  1421. set pc, pop
  1422.  
  1423. :cli_kill_1d
  1424. set a, i
  1425. jsr killproc
  1426. set pc, pop
  1427.  
  1428. :cli_kill_fail
  1429. set pc, pop
  1430.  
  1431. #segment text
  1432. :cli_kill_cmd
  1433. dat "kill", 0
  1434.  
  1435. ; processcleaner
  1436. ; This process goes and cleans up after dead processes.
  1437. #segment text
  1438. :procclean_name
  1439. dat "Process Cleaner", 0
  1440. #segment code
  1441.  
  1442. :processcleaner
  1443. ; start up processcleaner process
  1444. set push, a
  1445. set a, processcleaner_outer
  1446. jsr newproc
  1447. set b, procclean_name
  1448. jsr setprocname
  1449. jsr startproc
  1450. set a, pop
  1451.  
  1452. set pc, pop ; return
  1453.  
  1454. :processcleaner_outer ; outer loops
  1455. set i, [proc_list_start]
  1456. set j, i
  1457. add i, 1
  1458. add j, [proc_maxnum]
  1459.  
  1460. :pcloop
  1461. add i, 1
  1462. set b, [i]
  1463. ife [b], 4
  1464. set pc, pc_clean
  1465. :pcloop_return
  1466. ifl i, j ; not and end
  1467. set pc, pcloop
  1468.  
  1469. :pc_break
  1470. set a, 10 ; 10 cycle sleep
  1471. jsr sleepproc ; go sleep
  1472.  
  1473. set pc, processcleaner_outer
  1474. :pc_clean
  1475. set [i], 0 ; remove process listing
  1476. set a, i
  1477. sub a, [proc_list_start] ; get pid
  1478. jsr free_pid ; remove memory
  1479. set pc, pcloop_return
  1480.  
  1481.  
  1482. ; Lists data on all active processes
  1483. :proclist
  1484. set push, a
  1485. set push, c
  1486. set push, x
  1487. set push, y
  1488. set push, i
  1489. set push, j
  1490.  
  1491. set a, proclist_header
  1492. jsr print
  1493. jsr newline
  1494.  
  1495. set a, 32
  1496. jsr malloc ; allocate some stuff
  1497.  
  1498. set i, [proc_list_start]
  1499. set j, i
  1500. add i, 2
  1501. add j, [proc_maxnum] ; j to end
  1502.  
  1503. :proclist_loop
  1504. set a, [i]
  1505. ife a, 0 ; no process in this slot
  1506. set pc, proclist_loop_end
  1507. ife [a], 4 ; process to be killed
  1508. set pc, proclist_loop_end
  1509.  
  1510. ; there is a process here
  1511.  
  1512. set x, i
  1513. sub x, [proc_list_start] ; x is pid
  1514. set y, x ; y too
  1515. div x, 10 ; upper digit base 10
  1516. mod y, 10 ; lower digit base 10
  1517.  
  1518. add x, 48 ; bring to ascii
  1519. add y, 48
  1520. set [c], x ; put into string in malloc'ed area
  1521. set [c+1], y
  1522.  
  1523. set push, a
  1524. set a, c
  1525. jsr print
  1526. set a, pop
  1527.  
  1528. jsr space
  1529. jsr space
  1530.  
  1531. set a, [a+18] ; pointer to process name
  1532. jsr print ; print name
  1533.  
  1534. jsr newline ; get newline
  1535.  
  1536. :proclist_loop_end
  1537. add i, 1
  1538. ifl i, j
  1539. set pc, proclist_loop
  1540.  
  1541. set a, 32
  1542. jsr free ; free what we malloced
  1543.  
  1544. set j, pop
  1545. set i, pop
  1546. set y, pop
  1547. set x, pop
  1548. set c, pop
  1549. set a, pop
  1550. set pc, pop
  1551.  
  1552. #segment text
  1553.  
  1554. :proclist_header
  1555. dat "PID Process Name", 0
  1556. :proclist_cmd
  1557. dat "proclist", 0
  1558.  
  1559. #segment code
  1560.  
  1561. :getc
  1562. set push, a
  1563. set push, b
  1564. set push, j
  1565.  
  1566. set j, [kb_hwnum]
  1567.  
  1568. set a, 1
  1569.  
  1570. :getc_loop
  1571. hwi j
  1572. ife c, 0 ; nothing yet
  1573. set pc, getc_loop
  1574.  
  1575. set j, pop
  1576. set b, pop
  1577. set a, pop
  1578.  
  1579. set pc, pop
  1580.  
  1581. #segment text
  1582.  
  1583. ; Screen for OS to display while booting
  1584. :bootsdat
  1585. dat " Booting up OS!", 10
  1586. dat " Please wait...", 0
  1587.  
  1588. #segment code
  1589.  
  1590. :bootscreen
  1591. set push, a
  1592.  
  1593. jsr newline
  1594. jsr newline
  1595. jsr newline
  1596.  
  1597. set a, bootsdat
  1598. jsr print
  1599.  
  1600. set a, pop
  1601.  
  1602. set pc, pop; --------------------------------------------
  1603. ; Title: malloc
  1604. ; Date: 7/13/2012
  1605. ; Version:
  1606. ; --------------------------------------------
  1607.  
  1608. ; MALLOC
  1609. ; allocates A words of RAM, returning in C the address of the RAM
  1610.  
  1611. :malloc
  1612. set push, a
  1613. set push, b
  1614. set push, i
  1615. set push, j
  1616.  
  1617. ife [cur_proc], 0
  1618. set [cur_proc], 0xffff
  1619.  
  1620. ; find in registry enough spaces for what we want
  1621. ; convert A from words to blocks
  1622. jsr calc_block_num
  1623.  
  1624. set i, [malloc_reg]
  1625. ;set i, [malloc_reg_pointer]
  1626.  
  1627. :malloc_find_loop
  1628. set j, 0 ; number of found blocks
  1629.  
  1630. :malloc_inner_loop
  1631. ifn [i], 0 ; current block unused
  1632. set pc, mil_fail ; found a used block, restart looking
  1633.  
  1634. add j, 1 ; increment found blocks count
  1635. add i, 1 ; increment search counter
  1636. ife j, a ; we've found enough blocks
  1637. set pc, malloc_success ; finished alloc
  1638.  
  1639. ife i, malloc_reg_end ; finished search, malloc failed
  1640. set pc, malloc_fail
  1641.  
  1642. set pc, malloc_inner_loop
  1643.  
  1644. :malloc_success
  1645. sub i, j ; set i to beginning of found area in registry
  1646.  
  1647. ; indicate allocation
  1648. set push, i
  1649.  
  1650. set j, i
  1651. add j, a
  1652. :m_allocate_loop
  1653. set [i], [cur_proc]
  1654.  
  1655. add i, 1
  1656.  
  1657. ifl i, j
  1658. set pc, m_allocate_loop
  1659.  
  1660. set [malloc_reg_pointer], i
  1661. set i, pop
  1662.  
  1663. sub i, [malloc_reg] ; set i to number of blocks after start
  1664. mul i, 32 ; set i to offset of data start
  1665. add i, [malloc_start] ; set i to actual location
  1666.  
  1667. set c, i ; move that into c
  1668.  
  1669. :malloc_break
  1670.  
  1671. set j, pop
  1672. set i, pop
  1673. set b, pop
  1674. set a, pop
  1675.  
  1676. set pc, pop
  1677.  
  1678. ; failure of malloc inner loop, just increment and restart
  1679. :mil_fail
  1680. set j, 0 ; reset found blocks
  1681. add i, 1 ; go to next block for search
  1682. set pc, malloc_inner_loop
  1683.  
  1684. :malloc_fail
  1685. ; this is bad - not enough memory for what we want
  1686. ; have to terminate current process
  1687. set pc, crash
  1688.  
  1689. ; FREE
  1690. ; frees A words starting at address given in C
  1691.  
  1692. :free
  1693. set push, a
  1694. set push, b
  1695. set push, c
  1696.  
  1697. jsr calc_block_num ; switch a from words to blocks
  1698.  
  1699. sub c, [malloc_start]
  1700. div c, 32
  1701. add c, [malloc_reg] ; c is place in malloc reg
  1702.  
  1703. set b, c
  1704. add b, a
  1705.  
  1706. :free_loop
  1707. set [c], 0 ; clear
  1708. add c, 1 ; increment
  1709. ifl c, b ; not at end
  1710. set pc, free_loop ; continue
  1711.  
  1712. set c, pop
  1713. set b, pop
  1714. set a, pop
  1715. set pc, pop
  1716.  
  1717.  
  1718. ; free_pid
  1719. ; frees all blocks for a certain pid
  1720. :free_pid
  1721. set push, i
  1722. set push, j
  1723.  
  1724. set i, [malloc_reg]
  1725. set j, [malloc_reg_end]
  1726. :freepid_loop
  1727. ife [i], a ; remove this allocation.
  1728. set [i], 0 ; do that
  1729. add i, 1 ; increment
  1730. ifl i, j ; not at end yet
  1731. set pc, freepid_loop ; keep going
  1732.  
  1733. set j, pop
  1734. set i, pop
  1735. set pc, pop ; return
  1736.  
  1737. :calc_block_num
  1738. set push, x
  1739. set x, a
  1740. mod x, 32
  1741. div a, 32
  1742. ifn x, 0
  1743. add a, 1
  1744. set x, pop
  1745.  
  1746. set pc, pop ; return
  1747.  
  1748. ; malloc_init
  1749. ; Initializes dynamic memory stuff
  1750.  
  1751. :malloc_init
  1752. set push, a
  1753. set push, b
  1754. set push, c
  1755.  
  1756. set a, [malloc_reg]
  1757. set b, [malloc_length]
  1758. div b, 32
  1759. add b, a
  1760. set [malloc_reg_end], b
  1761.  
  1762. set a, [malloc_start]
  1763. add a, [malloc_length]
  1764. set [malloc_end], a
  1765.  
  1766. set [malloc_reg_pointer], [malloc_reg]
  1767.  
  1768. set c, pop
  1769. set b, pop
  1770. set a, pop
  1771.  
  1772. set pc, pop ; return
  1773. ; --------------------------------------------
  1774. ; Title: proc
  1775. ; Date: 7/13/2012
  1776. ; Version:
  1777. ; --------------------------------------------
  1778.  
  1779. #segment code
  1780.  
  1781. ; newproc
  1782. ; Creates a process skeleton and returns a pointer in A
  1783. ; Skeleton does not contain most critical data required to start it
  1784. :newproc
  1785. iaq 1 ; queue interrupts during this
  1786.  
  1787. set push, a
  1788. set push, b
  1789. set push, c
  1790.  
  1791. set push, [cur_proc]
  1792. set [cur_proc], 0x1 ; proc data stored under kernel pid
  1793.  
  1794. jsr newpid ; get a new pid in a
  1795.  
  1796. set push, a ; push pid
  1797.  
  1798. set a, 32 ; length of proc data
  1799. jsr malloc ; allocate proc data
  1800. set a, pop
  1801. set [a], c ; set pointer to new process data location
  1802. set [c], 2 ; status of 2 - in creation
  1803. set [c+1], 1 ; priority - 1 (standard)
  1804. set b, c
  1805. add b, 32 ; b is end
  1806. set push, c
  1807. :newprocloop
  1808. add c, 1 ; increment
  1809. set [c], 0 ; clear a
  1810.  
  1811. ifl c, b ; not at end
  1812. set pc, newprocloop ; keep going
  1813.  
  1814. set [cur_proc], a ; new process's pid
  1815. sub [cur_proc], [proc_list_start]
  1816. set push, a
  1817. set a, 1024 ; size of new process's stack
  1818. jsr malloc ; allocate its stack
  1819.  
  1820. set b, c ; temp
  1821. set a, pop
  1822. add b, 1023 ; bring to start of stack - 1
  1823. set c, pop ; restore
  1824. set [c+5], b ; set SP
  1825. set [b], kill_me ; last address on stack, if it set pc, pops one time too many
  1826. set [c+2], [sys_time] ; time of creation
  1827. set [c+3], [sys_time + 1] ; cont
  1828.  
  1829. set a, [cur_proc]
  1830. set [cur_proc], pop
  1831.  
  1832. set c, pop
  1833. set b, pop
  1834. set push, a
  1835. add a, [proc_list_start]
  1836. set a, [a]
  1837. set [a+4], pick 1 ; pc
  1838. set a, pop
  1839. add sp, 1
  1840.  
  1841. iaq 0 ; unqueue interrupts
  1842.  
  1843. set pc, pop ; return
  1844.  
  1845. ; newpid
  1846. ; Finds a new, empty process id and returns it.
  1847. :newpid
  1848. set push, i
  1849. set push, j
  1850.  
  1851. set i, [proc_list_start]
  1852. add i, 2
  1853.  
  1854. set j, i
  1855. add j, [proc_maxnum]
  1856. sub j, 2
  1857.  
  1858. :np_loop
  1859. ife [i], 0
  1860. set pc, np_found
  1861. add i, 1
  1862. ife i, j
  1863. set pc, np_fail
  1864. set pc, np_loop
  1865.  
  1866. :np_fail
  1867. :np_found
  1868. set a, i
  1869.  
  1870. set j, pop
  1871. set i, pop
  1872.  
  1873. set pc, pop ; return
  1874.  
  1875.  
  1876.  
  1877. ; startproc
  1878. ; This process takes a pid of a process "in creation," and sets it to
  1879. ; actually start, aka eligiblizes it for scheduling
  1880. :startproc
  1881. set push, a
  1882.  
  1883. ifl a, 2
  1884. ifg a, 16
  1885. set pc, pop ; invalid pid
  1886.  
  1887. add a, [proc_list_start] ; get to proc list entry
  1888. set a, [a] ; get pointer to proc data
  1889.  
  1890. ifn [a], 2 ; process NOT in creation
  1891. set pc, pop ; return without doing anything
  1892.  
  1893. set [a], 1 ; set status 1: run normally
  1894.  
  1895. set a, pop
  1896.  
  1897. set pc, pop ; return
  1898.  
  1899.  
  1900. ; killproc
  1901. ; "kills" the process with pid A
  1902. ; This doesn't actually kill it, but rather mark it for death,
  1903. ; to be cleaned up later.
  1904. :killproc
  1905. set push, a
  1906. add a, [proc_list_start]
  1907.  
  1908. ifl a, 2
  1909. ifg a, 16
  1910. set pc, pop ; invalid pid
  1911.  
  1912. set a, [a]
  1913. set [a], 4 ; set status 4: kill process
  1914.  
  1915. set a, pop
  1916.  
  1917. set pc, pop ; return
  1918.  
  1919.  
  1920. ; kill_me
  1921. ; This function causes the process that calls it to die.
  1922. :kill_me
  1923. set a, [cur_proc]
  1924. jsr killproc ; flag process to die
  1925. int 0x02 ; auto-reschedule
  1926. set pc, idle
  1927.  
  1928.  
  1929.  
  1930.  
  1931.  
  1932. ; set the name of a pid A to *B
  1933. :setprocname
  1934. ifl a, 2
  1935. ifg a, 0x10
  1936. set pc, pop ; do nothing
  1937.  
  1938. set push, a
  1939. add a, [proc_list_start]
  1940. set a, [a]
  1941. set [a+18], b ; set that pointer there
  1942. set a, pop
  1943. set pc, pop
  1944.  
  1945. :setprocpriority
  1946. ifl a, 2
  1947. ifg a, 0x10
  1948. set pc, pop ; do nothing
  1949.  
  1950. set push, a
  1951. add a, [proc_list_start]
  1952. set a, [a]
  1953. set [a+1], b ; set that pointer there
  1954. set a, pop
  1955. set pc, pop
  1956.  
  1957.  
  1958.  
  1959.  
  1960. #segment code
  1961.  
  1962. ; sleepproc
  1963. ; causes caller to sleep for A cycles
  1964. :sleepproc
  1965. set push, z
  1966. set push, y
  1967. set push, x
  1968. set push, a
  1969.  
  1970. set a, [cur_proc] ; get current process
  1971. add a, [proc_list_start]
  1972. set a, [a]
  1973.  
  1974.  
  1975. set y, [sys_time+1]
  1976.  
  1977.  
  1978. set x, [sys_time]
  1979.  
  1980. set z, a
  1981. set a, pop
  1982. add x, a
  1983. add y, ex
  1984. set a, z
  1985.  
  1986. set [a+15], x
  1987. set [a+16], y
  1988.  
  1989. set [a], 3 ; set status 3 - sleeping
  1990.  
  1991. set x, pop
  1992. set y, pop
  1993. set z, pop
  1994.  
  1995. int 0x02 ; reschedule
  1996.  
  1997. set pc, pop ; wait
  1998. ; --------------------------------------------
  1999. ; Title: string
  2000. ; Date: 9/23/2012
  2001. ; Version:
  2002. ; --------------------------------------------
  2003.  
  2004. ; strcpy
  2005. ; copies null-terminated string from A to B
  2006. :strcpy
  2007. set push, c
  2008.  
  2009. jsr strlen ; get length in C
  2010. jsr memcpy ; do the copy
  2011.  
  2012. set c, pop
  2013.  
  2014. set pc, pop ; return
  2015.  
  2016.  
  2017.  
  2018. ; strlen
  2019. ; gets the length of a null-terminated string at A into C
  2020. :strlen
  2021. set push, i
  2022.  
  2023. set i, a
  2024.  
  2025. :strlen_loop
  2026. ife [i], 0 ; found end
  2027. set pc, strlen_end ; break loop
  2028.  
  2029. add i, 1 ; increment
  2030. set pc, strlen_loop ; restart loop
  2031.  
  2032. :strlen_end
  2033. sub i, a ; set i to length
  2034. set c, i ; set c to length
  2035.  
  2036. set i, pop
  2037.  
  2038. set pc, pop ; return
  2039.  
  2040.  
  2041. ; Compares string *a and *b, c = 0 for mismatch, c = 1 for match
  2042. :strcmp
  2043. set push, a
  2044. set push, i
  2045. set push, j
  2046. set i, a
  2047. set j, b
  2048.  
  2049. :strcmp_inner_loop
  2050. set a, [i]
  2051. set b, [j]
  2052. ifn a, b ; difference found!
  2053. set pc, strcmp_fail ; go fail
  2054. ife a, 0 ; done
  2055. set pc, strcmp_succeed ; yay!
  2056.  
  2057. add i, 1 ; increment
  2058. add j, 1
  2059.  
  2060. set pc, strcmp_inner_loop ; keep going
  2061.  
  2062. :strcmp_end
  2063. set j, pop
  2064. set i, pop
  2065. set a, pop
  2066. set pc, pop ; return
  2067.  
  2068. :strcmp_fail
  2069. set c, 0 ; for fail
  2070. set pc, strcmp_end ; end function
  2071.  
  2072. :strcmp_succeed ; for success
  2073. set c, 1 ; for succeed
  2074. set pc, strcmp_end ; end function; --------------------------------------------
  2075. ; Title: tests
  2076. ; Date: 9/28/2012
  2077. ; Version:
  2078. ; --------------------------------------------
  2079.  
  2080. ; a test process for the operating system
  2081.  
  2082. #segment text
  2083. :test_text
  2084. dat "testing1234567899", 8, "0", 10, 0
  2085.  
  2086. :test_cmd
  2087. dat "test", 0
  2088.  
  2089. #segment code
  2090.  
  2091. :testing
  2092.  
  2093. ; test printing
  2094. set i, 0
  2095. set a, test_text
  2096. :test_text_loop
  2097. jsr print
  2098.  
  2099. add i, 1
  2100. ifl i, 20
  2101. set pc, test_text_loop
  2102.  
  2103. ; test printing hexes
  2104. set a, 0x1000
  2105. :test_hex_loop
  2106. jsr print_hex
  2107. jsr newline
  2108. add a, 0x20
  2109. ifl a, 0x2000
  2110. set pc, test_hex_loop
  2111.  
  2112. ; test process creation
  2113. set i, 0
  2114. set x, testproc2
  2115. :test_proc_loop
  2116. jsr cmd_execute_new ; spawn the new process
  2117. add i, 1
  2118. ifl i, 10
  2119. set pc, test_proc_loop
  2120.  
  2121. ; proclist
  2122. jsr newline
  2123. jsr proclist
  2124.  
  2125. ; wait a little bit
  2126. set a, 100
  2127. jsr sleepproc
  2128.  
  2129. ; kill all the processes
  2130. set a, 4
  2131. :test_kill_loop
  2132. jsr killproc
  2133. add a, 1
  2134. ifl a, 14
  2135. set pc, test_kill_loop
  2136.  
  2137. jsr newline
  2138. jsr proclist
  2139.  
  2140.  
  2141.  
  2142.  
  2143. ; done!
  2144. set pc, pop
Advertisement
Add Comment
Please, Sign In to add comment