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