]> git.sur5r.net Git - cc65/blob - libsrc/atari/system_check.s
19efaf2e28ee8ea1c9f0d09ad4631bcb56f2fdff
[cc65] / libsrc / atari / system_check.s
1 ;
2 ; Atari startup system check
3 ;
4 ; This routine gets loaded prior to the main part of the executable
5 ; and checks if the system is compatible to run the program.
6 ; For the XL target it checks whether the system is an XL type one
7 ; and that enough memory is installed (which isn't the case for a 600XL).
8 ; For the non-XL target it checks whether there is enough memory
9 ; installed to run the program.
10 ; For both targets it checks that the program won't load below MEMLO.
11 ; If one of the checks fails, the loading of the main program
12 ; is aborted by jumping to DOSVEC.
13 ;
14 ; Christian Groessler, chris@groessler.org, 2013
15 ;
16
17 ;DEBUG   =       1
18
19         .export         __SYSTEM_CHECK__: absolute = 1
20         .import         __SYSCHK_LOAD__
21         .import         __STARTADDRESS__
22
23         ; the following imports are only needed for the 'atari' target version
24         .import         __BSS_SIZE__, __BSS_RUN__
25         .import         __STACKSIZE__
26         .import         __RESERVED_MEMORY__
27
28         .include        "zeropage.inc"
29         .include        "atari.inc"
30
31
32 .macro print_string text
33         .local  start, cont
34         jmp     cont
35 start:  .byte   text, ATEOL
36 cont:   ldx     #0              ; channel 0
37         lda     #<start
38         sta     ICBAL,x         ; address
39         lda     #>start
40         sta     ICBAH,x
41         lda     #<(cont - start)
42         sta     ICBLL,x         ; length
43         lda     #>(cont - start)
44         sta     ICBLH,x
45         lda     #PUTCHR
46         sta     ICCOM,x
47         jsr     CIOV_org
48 .endmacro
49
50 .macro print_string2 addr, len
51         ldx     #0              ; channel 0
52         lda     #<addr
53         sta     ICBAL,x         ; address
54         lda     #>addr
55         sta     ICBAH,x
56         lda     #<len
57         sta     ICBLL,x         ; length
58         lda     #>len
59         sta     ICBLH,x
60         lda     #PUTCHR
61         sta     ICCOM,x
62         jsr     CIOV_org
63 .endmacro
64
65
66 ; ------------------------------------------------------------------------
67 ; code
68
69 .segment        "SYSCHK"
70
71         rts     ; for older DOSes which unconditionally run the first load chunk
72
73 .ifdef __ATARIXL__
74
75 ; check for SpartaDOS and its usage of RAM below ROM
76 ; return CF 0/1 for ok/bad
77 sdcheck:lda     DOS
78         cmp     #'S'
79         bne     sdcrts0         ; not SpartaDOS, assume RAM is not used
80
81 ; check for BW-DOS, which always reports itself as SpartaDOS, but doesn't use memory under the ROM
82         lda     DOS+3           ; 'B' in BW-DOS
83         cmp     #'B'
84         bne     sdnobw
85         lda     DOS+4           ; 'W' in BW-DOS
86         cmp     #'W'
87         beq     sdcrts0         ; BW-DOS does not use RAM below ROM
88
89 sdnobw: lda     DOS+1           ; SD version
90         cmp     #$40            ; SD-X has $40 or higher
91         bcc     sdcrts1         ; older versions (except maybe 1.x) always use the RAM under the ROM
92         ldy     #31             ; offset for OSRMFLG
93         lda     (DOSVEC),y      ; get OSRMFLG
94         bne     sdcrts1
95         
96 sdcrts0:clc
97         rts
98 sdcrts1:sec
99         rts
100
101 ramrom_txt:
102         .byte   "Memory under ROM is in use.", ATEOL
103         .byte   "Cannot run this program.", ATEOL
104 ramrom_txt_len = * - ramrom_txt
105
106 lmemerrxl_txt:
107         .byte   "Not enough memory to move screen", ATEOL
108         .byte   "memory to low memory. Consider using", ATEOL
109         .byte   "a higher load address.", ATEOL
110 lmemerrxl_txt_len = * - lmemerrxl_txt
111
112 ; no XL machine
113 no_xl:  print_string "This program needs an XL machine."
114         jmp     fail
115
116
117 ; ***** entry point (atarixl) *****
118
119 syschk: lda     $fcd8           ; from ostype.s
120         cmp     #$a2
121         beq     no_xl
122
123 ; we have an XL machine, now check memory
124         lda     RAMSIZ
125         cmp     #$80
126         bcs     sys_ok
127
128         jmp     mem_err
129
130 sys_ok: jsr     sdcheck         ; check for SpartaDOS-X, and if found, whether it uses the RAM under the ROM
131         bcc     sd_ok
132
133         print_string2 ramrom_txt, ramrom_txt_len
134         jmp     fail
135
136 sd_ok:  .include "xlmemchk.inc" ; calculate lowest address we will use when we move the screen buffer down
137
138         lda     MEMLO
139         cmp     lowadr
140         lda     MEMLO+1
141         sbc     lowadr+1
142         bcc     memlo_ok
143
144 ; load address was too low
145         print_string2 lmemerrxl_txt, lmemerrxl_txt_len
146         jsr     delay           ; long text takes longer to read, give user additional time
147         jmp     fail
148
149 .else   ; above 'atarixl', below 'atari'
150
151 .define CIOV_org CIOV           ; the print_string macros use CIOV_org, map this to CIOV
152
153 lmemerr_txt:
154         .byte   "Program would load below MEMLO.", ATEOL
155         .byte   "Consider using a higher load address.", ATEOL
156 lmemerr_txt_len = * - lmemerr_txt
157
158
159 ; ***** entry point (atari) *****
160
161 syschk:
162         sec
163         lda     MEMTOP
164         sbc     #<__RESERVED_MEMORY__
165         sta     tmp
166         lda     MEMTOP+1
167         sbc     #>__RESERVED_MEMORY__
168         sta     tmp+1
169         lda     tmp
170         sec
171         sbc     #<__STACKSIZE__
172         sta     tmp
173         lda     tmp+1
174         sbc     #>__STACKSIZE__
175         sta     tmp+1
176
177 ;tmp contains address which must be above .bss's end
178
179         lda     tmp
180         cmp     #<(__BSS_RUN__ + __BSS_SIZE__)
181         lda     tmp+1
182         sbc     #>(__BSS_RUN__ + __BSS_SIZE__)
183
184         bcc     mem_err         ; program doesn't fit into memory
185
186         lda     MEMLO
187         cmp     #<__STARTADDRESS__
188         lda     MEMLO+1
189         sbc     #>__STARTADDRESS__
190         bcc     memlo_ok
191
192 ; load address was too low
193         print_string2 lmemerr_txt, lmemerr_txt_len
194         jsr     delay           ; long text takes longer to read, give user additional time
195         jmp     fail
196
197 .endif
198
199 ; all is well(tm), launch the application
200 memlo_ok:
201 .ifdef DEBUG
202         print_string "Stage #1 OK"
203         jsr     delay
204 .endif
205         rts
206
207 ; not enough memory
208 mem_err:print_string "Not enough memory."
209 fail:   jsr     delay
210         jmp     (DOSVEC)
211
212 ; short delay
213 .proc   delay
214
215         lda     #10
216 @loop:  jsr     delay1
217         clc
218         sbc     #0
219         bne     @loop
220         rts
221
222 delay1: ldx     #0
223         ldy     #0
224 @loop:  dey
225         bne     @loop
226         dex
227         bne     @loop
228         rts
229
230 .endproc
231
232 end:
233
234 .ifndef __ATARIXL__
235 tmp:            ; outside of the load chunk, some kind of poor man's .bss
236 .endif
237
238 ; ------------------------------------------------------------------------
239 ; Chunk header
240
241 .segment        "SYSCHKHDR"
242
243         .word   __SYSCHK_LOAD__
244         .word   end - 1
245
246 ; ------------------------------------------------------------------------
247 ; Chunk "trailer" - sets INITAD
248
249 .segment        "SYSCHKTRL"
250
251         .word   INITAD
252         .word   INITAD+1
253         .word   syschk