1 а что если при включении нужной банки она уже и так включенна?
2 а что если вместе с ней выключиться кусок стека или кода на который указывает вектор прерывания или который сейчас выполняется?
Вид для печати
1 а что если при включении нужной банки она уже и так включенна?
2 а что если вместе с ней выключиться кусок стека или кода на который указывает вектор прерывания или который сейчас выполняется?
Лучше б они возможность размещать глобальные переменные в кодовом сегменте сделали. Объявлять нужные переменные константами и обращаться к ним через указатели очень не айс. Есть какой-то макрос для этого, но для z80 он не работает.
Компилятор вставляет минимально необходимое кол-во вызовов функции переключения банка. (это в мануале написано: SDCC inserts the minimum possible number calls to the bank selection functions. )
Программист в ответе за правильный setup памяти (где код/данные/стек).
Просто нужно, один раз, правильно сконфигурить раскладку памяти для программы и юзать.
Я пару месяцев назад начал патчить sdcc, чтоб научить его генерировать asm-код, совместимый с ассемблером из GNU binutils for z80. Если закончу, можно будет линковаться через обычные объектные файлы в coff-формате.
Примерчик, чтобы был.
Ситуация:
В видео-памяти лежит 15 фонтов, размером 8x8 (1байт на пиксел). Фонты занимают 12 страниц видео памяти (0-11).
(Любую страницу видео-памяти, можно подключить в 8KB адресное окно z80 и затем уже в этом окне, z80 может работать с видео-памятью.)
Нужно:
Пройтись по этим фонтам и присвоить не-нулевым пикселям нужный цвет. Цвет для каждого фонта разный, рассчитывается по ходу дела.
Заметка:
4 байта локальных переменных легло на регистры z80.
Остальные переменные объявлены как static, что ускорит обращение к ним через константный адрес, а не через стэк и ix (например ld a,(ix+1) )
Код:#define FONT_8x8_SIZE (96UL*8*8) // chunky font size
void Display_SetFontPixelColors(void)
{
BYTE* pFont = (BYTE*)VIDEO_BASE;
WORD counter = 0;
static BYTE fontColor = 1;
static BYTE video_page = 0;
PAGE_IN_VIDEO_RAM();
SET_VIDEO_PAGE(video_page);
while(video_page < 12) {
// modify pixel
if(*pFont)
*pFont = fontColor; // if pixel is not zero, set pixel to font color
pFont++;
if(pFont >= (BYTE*)VIDEO_BASE + 0x2000) {
pFont = (BYTE*)VIDEO_BASE;
video_page++; // inc video page
SET_VIDEO_PAGE(video_page);
}
counter++;
if(counter >= (WORD)FONT_8x8_SIZE) {
counter = 0;
fontColor++; // inc font color
}
}
PAGE_OUT_VIDEO_RAM();
}
Код:; ---------------------------------
; Function Display_SetFontPixelColors
; ---------------------------------
_Display_SetFontPixelColors_start::
_Display_SetFontPixelColors:
;src/fs/display_tilemap.c:409: BYTE* pFont = (BYTE*)VIDEO_BASE;
ld de,#0x2000
;src/fs/display_tilemap.c:410: WORD counter = 0;
ld bc,#0x0000
;src/fs/display_tilemap.c:416: PAGE_IN_VIDEO_RAM();
in a,(_io__sys_mem_select)
set 6, a
out (_io__sys_mem_select),a
;src/fs/display_tilemap.c:417: SET_VIDEO_PAGE(video_page);
ld a,(#_Display_SetFontPixelColors_video_page_1_122 + 0)
;src/fs/display_tilemap.c:419: while(video_page < 12) {
ld (#_mm__vreg_vidpage + 0),a
00107$:
ld iy,#_Display_SetFontPixelColors_video_page_1_122
ld a,0 (iy)
sub a, #0x0C
jr NC,00109$
;src/fs/display_tilemap.c:421: if(*pFont)
ld a,(de)
or a, a
jr Z,00102$
;src/fs/display_tilemap.c:422: *pFont = fontColor; // if pixel is not zero, set pixel to font color
ld a,(#_Display_SetFontPixelColors_fontColor_1_122 + 0)
ld (de),a
00102$:
;src/fs/display_tilemap.c:423: pFont++;
inc de
;src/fs/display_tilemap.c:424: if(pFont >= (BYTE*)VIDEO_BASE + 0x2000) {
ld a,d
sub a, #0x40
jr C,00104$
;src/fs/display_tilemap.c:425: pFont = (BYTE*)VIDEO_BASE;
ld de,#0x2000
;src/fs/display_tilemap.c:426: video_page++; // inc video page
ld iy,#_Display_SetFontPixelColors_video_page_1_122
inc 0 (iy)
;src/fs/display_tilemap.c:427: SET_VIDEO_PAGE(video_page);
ld a,0 (iy)
ld iy,#_mm__vreg_vidpage
ld 0 (iy),a
00104$:
;src/fs/display_tilemap.c:430: counter++;
inc bc
;src/fs/display_tilemap.c:431: if(counter >= (WORD)FONT_8x8_SIZE) {
ld a,b
sub a, #0x18
jr C,00107$
;src/fs/display_tilemap.c:432: counter = 0;
ld bc,#0x0000
;src/fs/display_tilemap.c:433: fontColor++; // inc font color
ld iy,#_Display_SetFontPixelColors_fontColor_1_122
inc 0 (iy)
jr 00107$
00109$:
;src/fs/display_tilemap.c:438: PAGE_OUT_VIDEO_RAM();
in a,(_io__sys_mem_select)
and a, #0xBF
out (_io__sys_mem_select),a
ret
_Display_SetFontPixelColors_end::
Valen, ты на будущее сразу сюда пиши все интересные фичи SDCC, если что полезное добавили, чтобы не плодить кучу тем.