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