boot.s 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #
  2. ! $Source$
  3. ! $State$
  4. ! $Revision$
  5. ! Declare segments (the order is important).
  6. .sect .text
  7. .sect .rom
  8. .sect .data
  9. .sect .bss
  10. MAX_ARGV = 8
  11. .sect .bss
  12. STACKSIZE = 2*1024
  13. .comm stack, STACKSIZE
  14. .comm oldstack, 2
  15. .sect .text
  16. begtext:
  17. ! The absolute first thing we have to do is to clear the bss. (argify
  18. ! requires it.)
  19. lxi h, begbss
  20. lxi b, endbss
  21. mvi e, 0
  22. 1:
  23. mov m, e
  24. inx h
  25. mov a, b
  26. cmp h
  27. jnz 1b
  28. mov a, c
  29. cmp l
  30. jnz 1b
  31. ! Set up the stack (now it's been cleared, since it's in the BSS).
  32. lxi sp, oldstack + STACKSIZE
  33. ! C-ify the command line at 0x0080.
  34. lxi h, 0x0080
  35. mov a, m ! a = length of command line
  36. cpi 0x7F ! 127-byte command lines...
  37. jnz 1f
  38. dcr a ! ...lose the last character
  39. 1:
  40. adi 0x81 ! write a 0 at 0x0081+length
  41. mov l, a
  42. mov m, h
  43. ! Now argify it.
  44. lxi b, 0x0081 ! bc = command line pointer
  45. lxi d, argv ! de = argv pointer
  46. ldax b ! peek for any leading whitespace
  47. ora a
  48. cpi ' '
  49. jz 3f
  50. 1: xchg ! write out the next argument
  51. mov m, c
  52. inx h
  53. mov m, b
  54. inx h
  55. xchg
  56. lda argc ! exit if this was the last argument
  57. inr a
  58. sta argc
  59. cpi MAX_ARGV
  60. jz end_of_argify
  61. 2: inx b ! scan for whitespace
  62. ldax b
  63. ora a
  64. jz end_of_argify
  65. cpi ' '
  66. jnz 2b
  67. xra a ! replace the space with a \0
  68. stax b
  69. 3: inx b ! scan for non-whitespace
  70. ldax b
  71. ora a
  72. jz end_of_argify
  73. cpi ' '
  74. jz 3b
  75. jmp 1b
  76. end_of_argify:
  77. ! Add the fake parameter for the program name.
  78. lxi h, progname
  79. shld argv0
  80. lxi h, argc
  81. inr m
  82. ! Push the main() arguments and go.
  83. lxi h, envp
  84. push h
  85. lxi h, argv0
  86. push h
  87. lhld argc ! slightly evil
  88. mvi h, 0
  89. push h
  90. call __m_a_i_n
  91. jmp EXIT
  92. ! Emergency exit routine.
  93. .define EXIT, __exit
  94. EXIT:
  95. __exit:
  96. rst 0
  97. ! Define symbols at the beginning of our various segments, so that we can find
  98. ! them. (Except .text, which has already been done.)
  99. .define begtext, begdata, begbss
  100. .sect .data; begdata:
  101. .sect .rom; begrom:
  102. .sect .bss; begbss:
  103. ! Some magic data. All EM systems need these.
  104. .define .trppc, .ignmask, _errno
  105. .comm .trppc, 2
  106. .comm .ignmask, 2
  107. .comm _errno, 2
  108. ! Used to store the argv array.
  109. argc: .space 1 ! number of args
  110. argv0: .space 2 ! always points at progname
  111. argv: .space 2*MAX_ARGV ! argv array (must be after argv0)
  112. envp: .space 2 ! envp array (always empty, must be after argv)
  113. ! These are used specifically by the i80 code generator.
  114. .define .trapproc, .retadr, .retadr1
  115. .define .bcreg, .areg
  116. .define .tmp1, .fra, block1, block2, block3
  117. .comm .trapproc, 2
  118. .comm .retadr, 2 ! used to save return address
  119. .comm .retadr1, 2 ! reserve
  120. .comm .bcreg, 2
  121. .comm .areg, 1
  122. .comm .tmp1, 2
  123. .comm .fra, 8 ! 8 bytes function return area
  124. block1: .space 4 ! used by 32 bits divide and
  125. block2: .space 4 ! multiply routines
  126. block3: .space 4 ! must be contiguous (.comm doesn't guarantee this)
  127. .sect .rom
  128. progname: .asciz 'ACKCPM'