]> git.sur5r.net Git - cc65/blob - libsrc/atari/system_check.s
Merge branch 'master' into c1p
[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 .ifdef __ATARIXL__
72
73 lmemerrxl_txt:
74         .byte   "Not enough memory to move screen", ATEOL
75         .byte   "memory to low memory. Consider using", ATEOL
76         .byte   "a higher load address.", ATEOL
77 lmemerrxl_txt_len = * - lmemerrxl_txt
78
79 ; no XL machine
80 no_xl:  print_string "This program needs an XL machine."
81         jmp     fail
82
83
84 ; ***** entry point (atarixl) *****
85
86 syschk: lda     $fcd8           ; from ostype.s
87         cmp     #$a2
88         beq     no_xl
89
90 ; we have an XL machine, now check memory
91         lda     RAMSIZ
92         cmp     #$80
93         bcs     sys_ok
94
95         jmp     mem_err
96
97 sys_ok:
98         .include "xlmemchk.inc"         ; calculate lowest address we will use when we move the screen buffer down
99
100         lda     MEMLO
101         cmp     lowadr
102         lda     MEMLO+1
103         sbc     lowadr+1
104         bcc     memlo_ok
105
106 ; load address was too low
107         print_string2 lmemerrxl_txt, lmemerrxl_txt_len
108         jsr     delay           ; long text takes longer to read, give user additional time
109         jmp     fail
110
111 .else   ; above 'atarixl', below 'atari'
112
113 .define CIOV_org CIOV           ; the print_string macros use CIOV_org, map this to CIOV
114
115 lmemerr_txt:
116         .byte   "Program would load below MEMLO.", ATEOL
117         .byte   "Consider using a higher load address.", ATEOL
118 lmemerr_txt_len = * - lmemerr_txt
119
120
121 ; ***** entry point (atari) *****
122
123 syschk:
124         sec
125         lda     MEMTOP
126         sbc     #<__RESERVED_MEMORY__
127         sta     tmp
128         lda     MEMTOP+1
129         sbc     #>__RESERVED_MEMORY__
130         sta     tmp+1
131         lda     tmp
132         sec
133         sbc     #<__STACKSIZE__
134         sta     tmp
135         lda     tmp+1
136         sbc     #>__STACKSIZE__
137         sta     tmp+1
138
139 ;tmp contains address which must be above .bss's end
140
141         lda     tmp
142         cmp     #<(__BSS_RUN__ + __BSS_SIZE__)
143         lda     tmp+1
144         sbc     #>(__BSS_RUN__ + __BSS_SIZE__)
145
146         bcc     mem_err         ; program doesn't fit into memory
147
148         lda     MEMLO
149         cmp     #<__STARTADDRESS__
150         lda     MEMLO+1
151         sbc     #>__STARTADDRESS__
152         bcc     memlo_ok
153
154 ; load address was too low
155         print_string2 lmemerr_txt, lmemerr_txt_len
156         jsr     delay           ; long text takes longer to read, give user additional time
157         jmp     fail
158
159 .endif
160
161 ; all is well(tm), launch the application
162 memlo_ok:
163 .ifdef DEBUG
164         print_string "Stage #1 OK"
165         jsr     delay
166 .endif
167         rts
168
169 ; not enough memory
170 mem_err:print_string "Not enough memory."
171 fail:   jsr     delay
172         jmp     (DOSVEC)
173
174 ; short delay
175 .proc   delay
176
177         lda     #10
178 @loop:  jsr     delay1
179         clc
180         sbc     #0
181         bne     @loop
182         rts
183
184 delay1: ldx     #0
185         ldy     #0
186 @loop:  dey
187         bne     @loop
188         dex
189         bne     @loop
190         rts
191
192 .endproc
193
194 end:
195
196 .ifndef __ATARIXL__
197 tmp:            ; outside of the load chunk, some kind of poor man's .bss
198 .endif
199
200 ; ------------------------------------------------------------------------
201 ; Chunk header
202
203 .segment        "SYSCHKHDR"
204
205         .word   __SYSCHK_LOAD__
206         .word   end - 1
207
208 ; ------------------------------------------------------------------------
209 ; Chunk "trailer" - sets INITAD
210
211 .segment        "SYSCHKTRL"
212
213         .word   INITAD
214         .word   INITAD+1
215         .word   syschk