head_em.s 5.1 KB

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