]> git.sur5r.net Git - cc65/blob - libsrc/atari/xlmemchk.inc
Use labels instead of segment load addresses to specify entry points
[cc65] / libsrc / atari / xlmemchk.inc
1 ;
2 ; Christian Groessler, Jun-2013
3 ;
4 ; This routine is used in preparation to move the screen memory
5 ; in front of the program.
6 ;
7 ; It calculates the value to put into RAMTOP for a subsequent
8 ; "GRAPHICS 0" call, and the lowest address which will be used
9 ; by the screen memory afterwards.
10
11 ; inputs:
12 ;       __SAVEAREA_LOAD__       -       load address of the program
13 ; outputs:
14 ;       lodadr                  -       (high byte only) value to
15 ;                                       write into RAMTOP
16 ;       lowadr                  -       lowest address occupied by
17 ;                                       screen data
18 ;
19
20
21 ; When setting a display mode, the ROM takes the RAMTOP value
22 ; and subtracts the size of the screen memory from it. This will
23 ; become the new screen memory address.
24 ; From this address it subtracts the size of the display list.
25 ; This will become the new display list address.
26 ; Screen memory cannot cross 4K boundaries and a display list
27 ; cannot cross a 1K boundary.
28 ;
29 ; Work out a sane value for RAMTOP to prevent boundary crossing.
30 ; RAMTOP is only one byte, it counts in memory pages.
31 ;
32 ; The ROM doesn't do this boundary checking, since it doesn't
33 ; expect RAMTOP to have (rather) arbitrary values. For a
34 ; "GRAPHICS 0" call and RAMTOP representing the possible physically
35 ; available memory, boundary crossing cannot happen.
36
37
38 SCRBUFSZ =      (40 * 24)               ; size of mode 0 screen buffer
39 DLSZ    =       32                      ; size of mode 0 display list
40
41
42 scrmemtst:
43
44 ; subtract screen memory size from our load address
45
46         lda     lodadr
47         sec
48         sbc     #<SCRBUFSZ
49         sta     tstadr
50         lda     lodadr+1
51         sbc     #>SCRBUFSZ
52         sta     tstadr+1
53
54 ; check if a 4K boundary is crossed
55
56         lda     lodadr+1
57         and     #$f0
58         sta     tmp
59         lda     tstadr+1
60         and     #$f0
61         cmp     tmp
62         beq     scrmemok
63
64 ; if lodadr is at an exact 4K boundary, it's still ok
65
66         lda     lodadr+1
67         and     #$0f
68         beq     scrmemok
69
70 ; 4K boundary will be crossed, use this 4K boundary address as lodadr
71
72 al4k:   lda     lodadr+1
73         and     #$f0
74         sta     lodadr+1
75         bne     scrmemtst
76 ; not reached
77
78
79 lodadr: .word   __SAVEAREA_LOAD__ & $FF00               ; our program's load address, rounded down to page boundary
80 tstadr: .res    2
81 lowadr: .res    2
82 tmp:    .res    1
83
84
85 ; subtract display list size from calculated screen address
86
87 scrmemok:
88         lda     tstadr
89         sec
90         sbc     #<DLSZ
91         sta     lowadr
92         lda     tstadr+1
93         sbc     #>DLSZ
94         sta     lowadr+1
95
96 .if 0   ; this cannot happen
97 ; check if a 1K boundary is crossed
98
99         lda     tstadr+1
100         and     #$fc
101         sta     tmp
102         lda     lowadr+1
103         and     #$fc
104         cmp     tmp
105         bne     al4k            ; 1K boundary will be crossed, decrease lodadr
106 .endif
107
108 ; address of display list is ok
109 ; decrease lowadr by two
110
111         lda     lowadr
112         sec
113         sbc     #2
114         sta     lowadr
115         bcs     dec_cont
116         dec     lowadr+1
117 dec_cont: