]> git.sur5r.net Git - cc65/blob - libsrc/atari/system_check.s
fix comment in last change
[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         lda     DOS+1           ; SD version
81         cmp     #$40            ; SD-X has $40 or higher
82         bcc     sdcrts1         ; older versions (except maybe 1.x) always use the RAM under the ROM
83         ldy     #31             ; offset for OSRMFLG
84         lda     (DOSVEC),y      ; get OSRMFLG
85         bne     sdcrts1
86         
87 sdcrts0:clc
88         rts
89 sdcrts1:sec
90         rts
91
92 ramrom_txt:
93         .byte   "Memory under ROM is in use.", ATEOL
94         .byte   "Cannot run this program.", ATEOL
95 ramrom_txt_len = * - ramrom_txt
96
97 lmemerrxl_txt:
98         .byte   "Not enough memory to move screen", ATEOL
99         .byte   "memory to low memory. Consider using", ATEOL
100         .byte   "a higher load address.", ATEOL
101 lmemerrxl_txt_len = * - lmemerrxl_txt
102
103 ; no XL machine
104 no_xl:  print_string "This program needs an XL machine."
105         jmp     fail
106
107
108 ; ***** entry point (atarixl) *****
109
110 syschk: lda     $fcd8           ; from ostype.s
111         cmp     #$a2
112         beq     no_xl
113
114 ; we have an XL machine, now check memory
115         lda     RAMSIZ
116         cmp     #$80
117         bcs     sys_ok
118
119         jmp     mem_err
120
121 sys_ok: jsr     sdcheck         ; check for SpartaDOS-X, and if found, whether it uses the RAM under the ROM
122         bcc     sd_ok
123
124         print_string2 ramrom_txt, ramrom_txt_len
125         jmp     fail
126
127 sd_ok:  .include "xlmemchk.inc" ; calculate lowest address we will use when we move the screen buffer down
128
129         lda     MEMLO
130         cmp     lowadr
131         lda     MEMLO+1
132         sbc     lowadr+1
133         bcc     memlo_ok
134
135 ; load address was too low
136         print_string2 lmemerrxl_txt, lmemerrxl_txt_len
137         jsr     delay           ; long text takes longer to read, give user additional time
138         jmp     fail
139
140 .else   ; above 'atarixl', below 'atari'
141
142 .define CIOV_org CIOV           ; the print_string macros use CIOV_org, map this to CIOV
143
144 lmemerr_txt:
145         .byte   "Program would load below MEMLO.", ATEOL
146         .byte   "Consider using a higher load address.", ATEOL
147 lmemerr_txt_len = * - lmemerr_txt
148
149
150 ; ***** entry point (atari) *****
151
152 syschk:
153         sec
154         lda     MEMTOP
155         sbc     #<__RESERVED_MEMORY__
156         sta     tmp
157         lda     MEMTOP+1
158         sbc     #>__RESERVED_MEMORY__
159         sta     tmp+1
160         lda     tmp
161         sec
162         sbc     #<__STACKSIZE__
163         sta     tmp
164         lda     tmp+1
165         sbc     #>__STACKSIZE__
166         sta     tmp+1
167
168 ;tmp contains address which must be above .bss's end
169
170         lda     tmp
171         cmp     #<(__BSS_RUN__ + __BSS_SIZE__)
172         lda     tmp+1
173         sbc     #>(__BSS_RUN__ + __BSS_SIZE__)
174
175         bcc     mem_err         ; program doesn't fit into memory
176
177         lda     MEMLO
178         cmp     #<__STARTADDRESS__
179         lda     MEMLO+1
180         sbc     #>__STARTADDRESS__
181         bcc     memlo_ok
182
183 ; load address was too low
184         print_string2 lmemerr_txt, lmemerr_txt_len
185         jsr     delay           ; long text takes longer to read, give user additional time
186         jmp     fail
187
188 .endif
189
190 ; all is well(tm), launch the application
191 memlo_ok:
192 .ifdef DEBUG
193         print_string "Stage #1 OK"
194         jsr     delay
195 .endif
196         rts
197
198 ; not enough memory
199 mem_err:print_string "Not enough memory."
200 fail:   jsr     delay
201         jmp     (DOSVEC)
202
203 ; short delay
204 .proc   delay
205
206         lda     #10
207 @loop:  jsr     delay1
208         clc
209         sbc     #0
210         bne     @loop
211         rts
212
213 delay1: ldx     #0
214         ldy     #0
215 @loop:  dey
216         bne     @loop
217         dex
218         bne     @loop
219         rts
220
221 .endproc
222
223 end:
224
225 .ifndef __ATARIXL__
226 tmp:            ; outside of the load chunk, some kind of poor man's .bss
227 .endif
228
229 ; ------------------------------------------------------------------------
230 ; Chunk header
231
232 .segment        "SYSCHKHDR"
233
234         .word   __SYSCHK_LOAD__
235         .word   end - 1
236
237 ; ------------------------------------------------------------------------
238 ; Chunk "trailer" - sets INITAD
239
240 .segment        "SYSCHKTRL"
241
242         .word   INITAD
243         .word   INITAD+1
244         .word   syschk