head_em.s 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. .define WRCH, RDCH, Earray, Erange, Eset
  2. .define Eiovfl, Eidivz, Eiund, Econv
  3. .define Estack, Eheap, Eillins, Eoddz
  4. .define Ecase , Ebadmon, OSBYTE, MON
  5. .define Ebadlin, Ebadgto, BASE, NBYTES
  6. .define hol0, IGNMASK, ADDR, PROGNAME
  7. .define LB, LBl, SP, HP, ERRPROC, UNSIGN
  8. .define Ytmp, EXG, ARTH, RETURN, SIGN
  9. .define RETSIZE, TRAPVAL, STACK, BRANCH
  10. .define start, Push, Pop, STACKTh, STACKTl
  11. .define F_DUM
  12. .sect .zero
  13. .sect .text
  14. .sect .rom
  15. .sect .data
  16. .sect .bss
  17. .sect .text
  18. ! DEFINITIONS
  19. ! The next three definitions are special for the
  20. ! BBC microcomputer
  21. WRCH = 0x0FFEE ! This subroutine writes the character in
  22. ! register A to the screen
  23. RDCH = 0x0FFE0 ! This subroutine returns a character in
  24. ! register A from the current input stream
  25. OSBYTE = 0x0FFF4 ! This subroutine performs miscelaneous
  26. ! operating system calls
  27. F_DUM = 0 ! Dummy floating point constant
  28. ! Here are the error numbers
  29. Earray = 0
  30. Erange = 1
  31. Eset = 2
  32. Eiovfl = 3
  33. Eidivz = 6
  34. Eiund = 8
  35. Econv = 10
  36. Estack = 16
  37. Eheap = 17
  38. Eillins = 18
  39. Eoddz = 19
  40. Ecase = 20
  41. Ebadmon = 25
  42. Ebadlin = 26
  43. Ebadgto = 27
  44. MON = 0x78D0
  45. BASE = 240 ! This is the offset from the localbase
  46. ! for the second localbase
  47. STACKTh = 0x78 ! This is the top of the stack
  48. STACKTl = 0x0D0
  49. ! Some zeropage declarations
  50. .sect .zero
  51. RES: .space 76 ! special for the operating system
  52. hol0: .space 16 ! the hol0 block
  53. IGNMASK: .space 2 ! can hold the ingnore mask
  54. ADDR: .space 4 ! used for indirect addressing
  55. LB: .space 2 ! the localbase
  56. LBl: .space 2 ! the second localbase (localbase-BASE)
  57. SP: .space 3 ! the stackpointer (real_stack)
  58. HP: .space 2 ! the heap pointer
  59. BRANCH: .space 2 ! used for branch instructions
  60. ERRPROC: .space 2 ! can hold the address of the error handler
  61. Ytmp: .space 1 ! used for intermediate storage in Y
  62. EXG: .space 2 ! used by the exchange subroutine Exg
  63. ARTH: .space 16 ! used for arithmetic
  64. NBYTES: .space 2 ! containes the number of bytes for a block move
  65. RETURN: .space 4 ! the return area
  66. RETSIZE: .space 1 ! the size of the object returned
  67. SIGN: .space 1 ! the sign of the calculation
  68. UNSIGN : .space 1 ! is it signed or unsigned arithmetic
  69. TRAPVAL: .space 1 ! intermediate storage of the error number
  70. STACK: .space 1 ! contains the hardware stackpointer on
  71. ! entering _m_a_i_n for a neat return
  72. RESERVED: .space 112 ! used by the operating system
  73. .sect .text
  74. .base 0x0E02 ! where to start in the BBC micro
  75. ! GENERAL PURPOSE ROUTINES
  76. start:
  77. tsx
  78. stx STACK ! save stackpointer for exit and error
  79. ! The following three operating system calls are only
  80. ! for the BBC microcomputer
  81. lda #2
  82. ldx #0
  83. ldy #0
  84. jsr OSBYTE ! return control to the keyboard
  85. lda #15
  86. ldx #0
  87. ldy #0
  88. jsr OSBYTE ! clear all internal buffers
  89. lda #3
  90. ldx #5
  91. ldy #0
  92. jsr OSBYTE ! output to screen and RS423
  93. lda #STACKTl
  94. sta LB ! set localbase (lowbyte)
  95. sta SP+2
  96. lda #0
  97. sta SP ! set stackpointer (lowbyte)
  98. sta ERRPROC ! set start address for error handler (lowbyte)
  99. sta ERRPROC+1 ! set start address for error handler (highbyte)
  100. sta hol0 ! set the line number (lowbyte)
  101. sta hol0+1 ! set the line number (highbyte)
  102. lda #STACKTh
  103. sta SP+1 ! set the stacpointer (highbyte)
  104. sta LB+1 ! set the localbase (highbyte)
  105. lda #[endbss].l
  106. sta HP ! set the heap pointer (lowbyte)
  107. lda #[endbss].h
  108. sta HP+1 ! set the heap pointer (highbyte)
  109. lda #[PROGNAME].l
  110. sta hol0+4 ! set fake programname pointer (lowbyte)
  111. lda #[PROGNAME].h
  112. sta hol0+5 ! set fake programname pointer (highbyte)
  113. lda #[beginbss].l
  114. sta ADDR ! start address of bss block (lowbyte)
  115. lda #[beginbss].h
  116. sta ADDR+1 ! start address of bss block (highbyte)
  117. ldy #0
  118. lda #0
  119. 4: ldx #[endbss].h ! clear bss block
  120. cpx ADDR+1
  121. bcc 1f ! end of bss block reached
  122. bne 2f
  123. ldx #[endbss].l
  124. cpx ADDR
  125. bcc 1f ! end of bss block reached
  126. 2: sta (ADDR),y
  127. inc ADDR
  128. bne 3f
  129. inc ADDR+1
  130. 3: jmp 4b
  131. 1: lda #0
  132. tax
  133. jsr Push ! push fake envelope pointer
  134. lda #[PROGNAME].h
  135. ldx #[PROGNAME].l
  136. jsr Push ! push argv[0]
  137. lda #0
  138. ldx #1
  139. jsr Push ! push argc
  140. jsr __m_a_i_n ! start the real program
  141. lda #0x0FF
  142. jsr WRCH ! send end of program to R423
  143. lda #3
  144. ldx #0
  145. jsr OSBYTE ! send output to screen only
  146. lda #2
  147. ldx #1
  148. jsr OSBYTE ! input only from R423
  149. rts
  150. ! The subroutine Push pushes the registerpair AX onto the stack.
  151. Push:
  152. sty Ytmp ! save Y
  153. ldy SP+2
  154. bne 1f ! lowbyte of stackpointer <> 0
  155. dec SP+1 ! decrement highbyte of stackpointer
  156. 1: dey
  157. dey ! decrement lowbyte of stackpointer
  158. sty SP+2 ! save lowbyte of stackpointer
  159. pha ! save A
  160. txa
  161. sta (SP),y ! push X onto the stack
  162. iny
  163. pla ! get A
  164. sta (SP),y ! push A onto the stack
  165. ldy Ytmp ! restore Y
  166. rts
  167. ! The subroutine Pop pops the registerpair AX from the stack.
  168. Pop:
  169. sty Ytmp ! save Y
  170. ldy SP+2
  171. lda (SP),y ! pop X from the stack
  172. tax
  173. iny
  174. lda (SP),y ! pop A from the stack
  175. iny
  176. bne 1f ! lowbyte of stackpointer <> 0
  177. inc SP+1 ! increment highbyte of stackpointer
  178. 1: sty SP+2 ! store lowbyte of stackpointer
  179. pha ! save A
  180. pla ! get A
  181. ldy Ytmp ! restore Y
  182. rts
  183. .sect .data
  184. PROGNAME: ! for initialising the programname pointer
  185. .asciz "program"
  186. .sect .bss
  187. beginbss: