nes-proj/platform/pc-6001/ctk/ctk-conio_arch-asm.cS
2009-12-11 15:00:38 +00:00

1176 lines
24 KiB
C#

;;;
;;;
;;; ctk-conio_arch-asm.hS
;;;
;;; Architecture depend ctk-conio implementation.
;;; This assembler source contributes saving speed and memory.
;;;
;;; @author Takahide Matsutsuka <markn@markn.org>
;;;
;;; $Id: ctk-conio_arch-asm.cS,v 1.3 2009/12/11 15:00:38 matsutsuka Exp $
;;;
;; uses preprocessor to enable definitions
#include "ctk_arch-def.h"
;; export symbols
.globl _ctk_draw_init
.globl _ctk_draw_clear
.globl _ctk_draw_clear_window
.globl _ctk_draw_window
.globl _ctk_draw_dialog
.globl _ctk_draw_widget
.globl _ctk_draw_windowtitle_height
.if CTK_CONF_MENUS
.globl _ctk_draw_menus
.endif
.globl _ctk_draw_width
.globl _ctk_draw_height
;; import symbols
.globl _wherex_arch
.globl _wherey_arch
.globl _cputc_arch_asm
.globl _cputs_arch_asm
.globl _cputsn_arch_asm
.globl _clip_arch_asm
.globl _clearto_arch_asm
.globl _revers_arch_asm
.globl _chline_arch_asm
.globl _cvline_arch_asm
.globl _gotoxy_arch_asm
;; offsets
.globl _off_window_x
.globl _off_window_y
.globl _off_window_h
.globl _off_window_w
.globl _off_window_inactive
.globl _off_window_active
.globl _off_window_next
.globl _off_window_focused
.globl _off_widget_x
.globl _off_widget_y
.globl _off_widget_w
.globl _off_widget_h
.globl _off_widget_type
.globl _off_widget_window
.globl _off_widget_label_text
.globl _off_widget_button_text
.globl _off_widget_textentry_text
.globl _off_widget_textentry_xpos
.globl _off_widget_textentry_ypos
.globl _off_widget_textentry_state
.if CTK_CONF_HYPERLINK
.globl _off_widget_hyperlink_text
.endif
.if CTK_CONF_ICONS
.globl _off_widget_icon_title
.globl _off_widget_icon_textmap
.endif
.if CTK_CONF_MENUS
.globl _off_menu_title
.globl _off_menu_active
.globl _off_menu_nitems
.globl _off_menu_items
.globl _off_menu_next
.globl _off_menuitem_title
.globl _size_menuitem
.globl _off_menus_open
.globl _off_menus_menus
.globl _off_menus_desktopmenu
.endif
.area _DATA
.area _CODE
_ctk_draw_windowtitle_height:
.db 1
_ctk_conio_arch_asm_start::
;; ---------------------------------
;; void ctk_draw_init(void)
;; Stack; retl reth
;; _F____HL____ AFBCDEHL____
;; return void
;; ---------------------------------
_ctk_draw_init:
xor a
call _revers_arch_asm
ld h, #SCREEN_HEIGHT
ld l, #0
jr _ctk_draw_clear_asm
;; ---------------------------------
;; ctk_draw_clear(unsigned char clipy1, unsigned char clipy2);
;; Stack; retl reth clipy1 clipy2
;; AFBCDEHL____
;; return void
;; ---------------------------------
_ctk_draw_clear:
ld hl, #2
add hl, sp
ld e, (hl) ; clipy1
inc hl
ld d, (hl) ; clipy2
;; E = clip1, D = clip2
ex de, hl
_ctk_draw_clear_asm:
call _clip_arch_asm
ld a, h
sub l ; A = clipy2 - clipy1
ld b, a ; height
ld c, #SCREEN_WIDTH ; width
ld d, l ; y
ld e, #0 ; x
call _clearbox_arch_asm
ret
_get_offset:
;; BC = offset address
;; HL = base address
;; return DE = data
;; ___DE______
push af
push hl
ld a, (bc)
add a, l
ld l, a
ld a, h
adc #0
ld h, a
ld e, (hl)
inc hl
ld d, (hl)
pop hl
pop af
ret
;; ---------------------------------
;; ctk_draw_clear_window(struct ctk_window *window,
;; unsigned char focus,
;; unsigned char clipy1,
;; unsigned char clipy2)
;; Stack; retl reth winl winh focus clipy1 clipy2
;; AFBCDEHL____
;; return void
;; ---------------------------------
_ctk_draw_clear_window:
;; clip_arch(clipy1, clipy2);
ld hl, #5
add hl, sp
ld e, (hl)
inc hl
ld d, (hl)
ex de, hl
call _clip_arch_asm
;; clearbox_arch(window->x + 1, window->y + 2, window->w, window->h);
ld hl, #2
add hl, sp
ld e, (hl)
inc hl
ld d, (hl)
ld h, d
ld l, e ; HL = window
ld bc, #_off_window_h
call _get_offset
ld d, e ; D = window->h
ld bc, #_off_window_w
call _get_offset ; E = window->w
push de
ld bc, #_off_window_y
call _get_offset ; E = window->y
ld a, e
inc a
inc a
ld bc, #_off_window_x
call _get_offset ; E = window->x
inc e
ld d, a ; D = window->y + 2, E = window->x + 1
pop bc ; B = h, C = w
call _clearbox_arch_asm
ret
;; ---------------------------------
;; void ctk_draw_dialog(struct ctk_window *dialog)
;; Stack; retl reth dialogl dialogh
;; AFBCDEHL____
;; return void
;; ---------------------------------
_ctk_draw_dialog:
;; ctk_draw_clear_window(dialog, 0, 0, SCREEN_HEIGHT)
ld hl, #2
add hl, sp
ld e, (hl)
inc hl
ld d, (hl)
ld h, #SCREEN_HEIGHT
ld l, #0
push hl
xor a
push af
inc sp
push de
call _ctk_draw_clear_window
pop de
inc sp
pop hl
;; draw_window_asm(dialog, CTK_FOCUS_DIALOG)
ld a, #_CTK_FOCUS_DIALOG
call _draw_window_asm
ret
;; ---------------------------------
;; void ctk_draw_window(struct ctk_window *window, unsigned char focus,
;; unsigned char clipy1, unsigned char clipy2,
;; unsigned char draw_borders)
;; Stack; retl reth winl winh focus cy1 cy2 borders
;; AFBCDEHL____
;; return void
;; ---------------------------------
_ctk_draw_window:
;; clip_arch(clipy1, clipy2);
ld hl, #5
add hl, sp
ld e, (hl)
inc hl
ld d, (hl)
ex de, hl
call _clip_arch_asm
;; DE = window
;; A = focus = focus & CTK_FOCUS_WINDOW
;; draw_window_asm(window, focus);
ld hl, #2
add hl, sp
ld e, (hl)
inc hl
ld d, (hl)
inc hl
ld a, (hl)
and a, #_CTK_FOCUS_WINDOW
call _draw_window_asm
ret
;; ---------------------------------
;; void draw_window_asm
;; (struct ctk_window *window, unsigned char focus)
;; DE = window, A = focus
;; Stack; retl reth
;; AFBCDEHL____
;; return void
;; ---------------------------------
_draw_window_asm:
;; drawbox_asm(window->x, window->y + 1, window->w, window->h);
push af ; focus
ld h, d
ld l, e ; HL = window
ld bc, #_off_window_h
call _get_offset
ld a, e
ld bc, #_off_window_w
call _get_offset
ld d, a
push de ; D = window->h, E = window->w
ld bc, #_off_window_y
call _get_offset
ld a, e
inc a
ld bc, #_off_window_x
call _get_offset
ld d, a ; D = window->y + 1, E = window->x
pop bc ; B = h, C = w, HL = window
call _drawbox_asm
inc d ; D = y = window->y + 2
inc e ; E = x = window->x + 1
push de ; Stack; yx focus
;; for(w = window->inactive; w != NULL; w = w->next) {
ld bc, #_off_window_inactive
call _get_offset ; DE = w = window->inactive
pop bc ; yx
pop af ; focus
push hl
;; de = widget, bc = yx, a = focus, hl = window; Stack; window
_ctk_draw_window_asm_loop1: ; draw inactive widgets
;; HL = e4cd
push af ; Stack; focus window
ld a, d
or e
jr z, _draw_window_asm_next1 ; if (DE == NULL)
pop af ; A = focus, Stack; window
;; bc = yx, de = w, a = focus
;; draw_widget(w, x, y, focus);
call _draw_widget_asm
push bc ; Stack; BC=xy HL=window
ld h, d
ld l, e ; HL = w
ld bc, #_off_window_next
call _get_offset ; DE = window->next
pop bc ; bc = yx, Stack; window
jr _ctk_draw_window_asm_loop1
;; for(w = window->active; w != NULL; w = w->next)
;; HL = window, BC = xy, A = focus; Stack; focus
_draw_window_asm_next1: ; Stack; focus window
pop af ; A = focus
pop hl ; HL = window; Stack null
push bc ; Stack yx
;; calc window->focused
ld bc, #_off_window_focused
call _get_offset ; DE = window->focused
push de ; Stack focused yx
ld bc, #_off_window_active
call _get_offset ; DE = window->active
pop hl ; HL = window->focused, Stack; yx
pop bc ; BC = yx, Stack; null
push af ; Stack; focus
push hl ; Stack; focused focus
;; BC = yx, DE = widget, Stack; focused focus
_ctk_draw_window_asm_loop2: ; draw active widgets
ld a, d ; DE = w
or e
jr z, _draw_window_asm_next2
;; if (w == window->focused) focus |= CTK_FOCUS_WIDGET;
pop hl ; HL = window->focused; Stack focus
ld a, h
cp d
jr nz, _draw_window_asm_nofocus
ld a, l
cp e
jr nz, _draw_window_asm_nofocus
pop af
push af
or a, #_CTK_FOCUS_WIDGET
jr _draw_window_asm_draw
_draw_window_asm_nofocus:
pop af
push af
;; A = wfocus, BC = yx de = widget hl = focused
_draw_window_asm_draw: ; Stack; focus
;; draw_widget(w, posx, posy, wfocus);
call _draw_widget_asm
push hl ; Stack; focused focus
push bc ; Stack; yx focused focus
ld h, d
ld l, e
ld bc, #_off_window_next
call _get_offset ; DE = w->next
pop bc ; BC = yx, Stack; focused focus
jr _ctk_draw_window_asm_loop2
_draw_window_asm_next2: ; Stack; focused focus
pop hl
pop af
ret
;; ---------------------------------
;; ctk_draw_widget(struct ctk_widget *w,
;; unsigned char focus,
;; unsigned char clipy1,
;; unsigned char clipy2);
;; Stack; retl reth wl wh focus clipy1 clipy2
;; AFBCDEHL____
;; return void
;; ---------------------------------
_ctk_draw_widget:
ld hl, #2
add hl, sp
ld e, (hl)
inc hl
ld d, (hl) ; DE = widget
inc hl
ld a, (hl) ; A = focus
inc hl
ld c, (hl) ; clipy1
inc hl
ld b, (hl) ; clipy2
push af ; focus
ld h, b
ld l, c
call _clip_arch_asm
push de ; Stack; widget focus
ex de, hl ; HL = widget
ld bc, #_off_widget_window
call _get_offset
ex de, hl ; HL = window
ld bc, #_off_window_focused
call _get_offset ; DE = focused
pop bc ; pop widget, Stack focus
ld a, b ; compare DE(fucosed) and BC(widget)
sub d
jr nz, _ctk_draw_widget_nofocus
ld a, c
sub e
jr nz, _ctk_draw_widget_nofocus
pop af
or a, #_CTK_FOCUS_WIDGET
push af
_ctk_draw_widget_nofocus:
push bc ; widget, Stack widget focus
ld bc, #_off_window_x
call _get_offset
inc e
ld c, e
push bc
ld bc, #_off_window_y
call _get_offset
inc e
inc e
pop bc
ld b, e ; yx
pop de ; widget
pop af ; focus
;; FALL THROUGH
;; ---------------------------------
;; static void draw_widget_asm(struct ctk_widget *w,
;; unsigned char x, unsigned char y,
;; unsigned char focus)
;; Stack; retl reth
;; in; A = focus, BC = yx, DE = widget
;; ____________
;; return void
;; ---------------------------------
_draw_widget_asm:
push hl
push de
push bc
push af
push de ; Stack; w
ld h, d
ld l, e
push af
push bc ; Stack; xy, focus, w
ld bc, #_off_widget_x
call _get_offset
ld a, e
pop bc ; Stack; focus w
add c
ld c, a
push bc
ld bc, #_off_widget_y
call _get_offset
ld a, e
pop bc ; Stack; focus, w
add b
ld b, a ; B = ypos, C = xpos
pop af
and a, #_CTK_FOCUS_WIDGET
call _revers_arch_asm
ld h, b
ld l, c
call _gotoxy_arch_asm
pop hl ; Stack; null, HL = w
push hl
push bc
ld bc, #_off_widget_type
call _get_offset
ld a, e ; A = type
ld bc, #_off_widget_w
call _get_offset ; E = w->w;
pop bc ; B = ypos, C = xpos
pop hl ; HL = w
cp a, #_CTK_WIDGET_SEPARATOR
jp z, _draw_widget_separator
cp a, #_CTK_WIDGET_LABEL
jp z, _draw_widget_label
cp a, #_CTK_WIDGET_BUTTON
jp z, _draw_widget_button
.if CTK_CONF_HYPERLINK
cp a, #_CTK_WIDGET_HYPERLINK
jp z, _draw_widget_hyperlink
.endif
cp a, #_CTK_WIDGET_TEXTENTRY
jp z, _draw_widget_textentry
.if CTK_CONF_ICONS
cp a, #_CTK_WIDGET_ICON
jp z, _draw_widget_icon
.endif
_draw_widget_ret:
xor a
call _revers_arch_asm
pop af
pop bc
pop de
pop hl
ret
;; BC = ypos, xpos, HL = w, E = w->w, Stack; null
_draw_widget_separator:
ld b, e
call _chline_arch_asm
jr _draw_widget_ret
;; BC = ypos, xpos, HL = w, E = w->w, Stack; null
_draw_widget_label:
ld a, e
push bc
push hl
ld bc, #_off_widget_h
call _get_offset ; E = h
ld h, e
ld l, a ; H = h, L = w->w
ex (sp), hl ; Stack; H = h, L = w->w; HL = w
ld bc, #_off_widget_label_text
call _get_offset ; DE = text
pop hl ; Stack; yx; H = h, L = w->w
pop bc ; BC = yx
_draw_widget_label_loop:
ld a, h
or a
jr z, _draw_widget_ret
;; BC = ypos, xpos, H = h, L = w->w, DE = text
push hl ; Stack; hw
ld h, b
ld l, c
call _gotoxy_arch_asm
pop hl
;; cputsn_arch(text, w->w);
push hl
push bc
push de ; Stack; text yx hw
ld b, l
call _cputsn_arch_asm ; DE = text
pop de
pop bc
pop hl ; Stack; null
;; clearto_arch(xpos + w->w);
ld a, c
add a, l
push hl
push de
push bc
call _clearto_arch_asm
pop bc
pop de
pop hl
;; ++ypos;
inc b
;; text += w->w;
ld a, e
add a, l
ld e, a
ld a, d
adc a, #0
ld d, a
dec h
jr _draw_widget_label_loop
;; BC = ypos, xpos, HL = w, E = w->w, Stack; null
_draw_widget_button:
push hl ; w
push de ; w->w
ld a, #0x5b ; '['
call _cputc_arch_asm
pop de
pop hl
ld a, e
ld bc, #_off_widget_button_text
call _get_offset
ld b, a
call _cputsn_arch_asm
ld a, #0x5d ; ']'
call _cputc_arch_asm
jp _draw_widget_ret
.if CTK_CONF_HYPERLINK
;; BC = ypos, xpos, HL = w, E = w->w, Stack; null
_draw_widget_hyperlink:
ld a, e
ld bc, #_off_widget_hyperlink_text
call _get_offset
ld b, a
call _cputsn_arch_asm
jp _draw_widget_ret
.endif
;; BC = ypos, xpos, HL = w, E = w->w, Stack; null
_draw_widget_textentry: ; 0xc5dc sp=0xf97e ;widget=e3be
;; e3cd;textentry.xpos<-b224
;; stable variables;
;; w->w, w->h, w->widget.textentry.{state,ypos,xpos), xscroll
push ix
ld ix, #-6
add ix, sp
ld sp, ix
push bc ; yx
ld 0(ix), e ; w->w
ld bc, #_off_widget_h
call _get_offset
ld 1(ix), e ; w->h
ld bc, #_off_widget_textentry_state
call _get_offset
ld a, e
sub a, #_CTK_TEXTENTRY_EDIT
ld 2(ix), a ; w->widget.textentry.state
ld bc, #_off_widget_textentry_ypos
call _get_offset
ld 3(ix), e ; w->widget.textentry.ypos
ld bc, #_off_widget_textentry_xpos
call _get_offset
ld 4(ix), e ; w->widget.textentry.xpos
;; xscroll = 0;
;; if(w->widget.textentry.xpos >= w->w - 1) {
;; xscroll = w->widget.textentry.xpos - w->w + 1;
;; }
ld a, e
inc a
sub 0(ix) ; xscroll = w->widget.textentry.xpos - w->w + 1
jr nc, _draw_widget_textentry_next
xor a ; if (xscroll < 0) xscroll = 0
_draw_widget_textentry_next: ; A = xscroll, Stack; yx - IX
ld 5(ix), a ; xscroll
ld bc, #_off_widget_textentry_text
call _get_offset ; DE = text
ld l, #0 ; loop counter
pop bc
;; L = counter, IX = sp, DE = text, BC = yx, Stack; null
_draw_widget_textentry_loop1: ; 0xc629
;; gotoxy_arch(xpos, ypos);
push hl ; Stack; text
ld h, b
ld l, c
call _gotoxy_arch_asm
;; if(w->widget.textentry.state == CTK_TEXTENTRY_EDIT &&
;; w->widget.textentry.ypos == j)
pop hl ; Stack; null, BC = yx, DE = text, L = count
push bc ; Stack; yx
ld a, l
cp a, 1(ix) ; j - w->h
jp nc, _draw_widget_textentry_ret
ld a, 2(ix) ; state
or a ; state == EDIT?
jr nz, _draw_widget_textentry_else
ld a, 3(ix) ; ypos
cp a, l ; ypos == j?
jr nz, _draw_widget_textentry_else
;; revers_arch(0);
push hl ; Stack count yx
push de ; Stack text count yx
xor a
call _revers_arch_asm
;; cputc_arch('>');
ld a, #0x3e ; '>'
call _cputc_arch_asm
pop de ; Stack count yx
push de ; Stack text count yx
ld a, 5(ix) ; xscroll
add a, e
ld e, a
ld a, d
adc a, #0
ld d, a ; DE = text[xscroll]
ld h, #0 ; loop counter
;; for(i = 0; i < w->w; ++i)
_draw_widget_textentry_loop2: ; 0xc39d Stack text count yx
;; H = count2, DE = text[xscroll + i]
ld a, h
cp a, 0(ix) ; i - w->w
jr nc, _draw_widget_textentry_loop2exit
;; revers_arch(i == w->widget.textentry.xpos - xscroll);
push hl ; Stack count2 text count1 yx
ld a, 4(ix) ; w->w.widget.textentry.xpos
sub 5(ix) ; xscroll
sub h ; textentry.xpos - xscroll- i
ld a, #00 ; flags do not change
jr nz, _draw_widget_textentry_revers
ld a, #01
_draw_widget_textentry_revers:
call _revers_arch_asm
;; DE = text, Stack; count2 text count1 yx
;; cputc((c == 0) ? CH_SPACE : c);
ld a, (de) ; ch
or a
jr nz, _draw_widget_textentry_nospace
ld a, #CH_SPACE
_draw_widget_textentry_nospace:
push de
call _cputc_arch_asm
pop de
pop hl ; Stack text count1 yx, H = count2
inc h
inc de
jr _draw_widget_textentry_loop2
_draw_widget_textentry_loop2exit: ; Stack text count yx
xor a
call _revers_arch_asm
ld a, #0x3c ; '<'
call _cputc_arch_asm
jr _draw_widget_textentry_endif
_draw_widget_textentry_else: ; 0xc68a DE = text, L = count1, Stack yx
;; cputc_arch(CH_VERTLINE);
ld a, #CH_VERTLINE
push hl
push de
call _cputc_arch_asm
pop de
;; cputsn_arch(text, w->w);
ld b, 0(ix) ; w->w
push de
call _cputsn_arch_asm
pop de ; Stack count1 yx
;; clearto_arch(xpos + w->w + 1);
pop hl
pop bc
push bc
push hl
push de ; Stack text count yx
ld a, 0(ix) ; w->w
add a, c
inc a ; xpos + w->w + 1
call _clearto_arch_asm
;; cputc_arch(CH_VERTLINE);
ld a, #CH_VERTLINE
call _cputc_arch_asm
_draw_widget_textentry_endif: ; Stack text count yx
;; text += w->w
pop de
ld a, e
add a, 0(ix)
ld e, a
ld a, d
adc a, #0
ld d, a
pop hl
;; i++
inc l
pop bc
;; ++ypos;
inc b
jp _draw_widget_textentry_loop1
_draw_widget_textentry_ret:
pop bc
ld hl, #6
add hl, sp
ld sp, hl
pop ix
jp _draw_widget_ret
.if CTK_CONF_ICONS
;; BC = ypos, xpos, HL = w, E = w->w, Stack; null
_draw_widget_icon:
push bc ; Stack; yx
ld bc, #_off_widget_icon_title
call _get_offset
push de ; Stack; title yx
ld bc, #_off_widget_icon_textmap
call _get_offset
pop hl ; HL = title, DE = textmap
pop bc ; BC = yx
;; BC = yx, DE = textmap, HL = title
push hl ; Stack; title
ld h, b
ld l, c ; HL = yx
ld a, e
or d
jr z, _draw_widget_icon_title
;; push hl
;; call _wherex_arch
;; ld c, l
;; call _wherey_arch
;; ld b, l
;; pop hl
ld a, #3 ; loop counter
_draw_widget_icon_loop: ; HL = yx, DE = textmap, Stack; title
call _gotoxy_arch_asm
push af ; Stack; loop title
push hl ; DE = textmap, Stack; yx loop title
ld b, #3
call _cputsn_arch_asm ; DE = DE + 3
pop hl
pop af ; HL = yx, A = count, Stack; title
inc h ; y++
dec a
jr nz, _draw_widget_icon_loop
;; Stack; title, HL = yx
_draw_widget_icon_title:
pop de ; Stack; null, HL = yx, DE = title
push de ; Stack; title, HL = yx, DE = title
ld b, h
ld c, l ; BC = yx
ex de, hl ; BC = yx, HL = title
ld d, #0
_draw_widget_icon_title_strlen:
ld a, (hl)
or a
jr z, _draw_widget_icon_title_setpos
inc hl
inc d
jr _draw_widget_icon_title_strlen
;; D = len, BC = yx, Stack; title
_draw_widget_icon_title_setpos:
ld h, d ; H = len
ld a, d
add a, c ; x + len
cp a, #SCREEN_WIDTH ; x + len - SCREEN_WIDTH
jr c, _draw_widget_icon_title_show
ld a, #SCREEN_WIDTH
sub h
ld c, a
;; B = y, C = x; H = len, Stack; title
_draw_widget_icon_title_show:
ld a, h ; A = len
ld h, b
ld l, c
call _gotoxy_arch_asm
pop de ; DE = title
ld b, a ; B = len
call _cputsn_arch_asm
jp _draw_widget_ret
.endif
.if CTK_CONF_MENUS
;; ---------------------------------
;; static void draw_menu(struct ctk_menu *m, struct ctk_menu *open)
;; in; HL = menu, BC = open
;; AFBCDEHL____
;; return void
;; ---------------------------------
_draw_menu_asm:
;; x = wherex_arch();
push hl
call _wherex_arch ; A = x
pop hl
push af
;; cputs_arch(m->title);
push bc
ld bc, #_off_menu_title
call _get_offset ; DE = m->title
push hl ; Stack; menu open x
call _cputs_arch_asm
;; cputc_arch(CH_SPACE);
ld a, #CH_SPACE
call _cputc_arch_asm
pop hl ; menu
pop bc ; open, Stack; x
ld a, h
sub b
jp nz, _draw_menu_ret2
ld a, l
sub c
jp nz, _draw_menu_ret2
;; x2 = wherex_arch();
;; 0xc473
push hl
call _wherex_arch ; A = x2
ld c, l ; C = x2
pop hl ; Stack; x
;; HL = menu
push bc
ld bc, #_off_menu_active
call _get_offset
pop bc ; E = m->active
ld d, #0 ; D = y
pop af ; A = x, Stack; null
ld b, a
add a, #CTK_CONF_MENUWIDTH
sub #SCREEN_WIDTH
jr c, _draw_menu_loop1
jr z, _draw_menu_loop1
ld a, #SCREEN_WIDTH
sub #CTK_CONF_MENUWIDTH
ld b, a
;; B = x, C = x2, D = y, E = m->active, HL = menu
_draw_menu_loop1:
;; if (y == m->nitems) _draw_menu_ret
ld a, d
push de
push hl
push bc
ld bc, #_off_menu_nitems
call _get_offset
cp e
pop bc
pop hl
jr z, _draw_menu_ret ; leave 2byte to pop while return
pop de
;; if (y == m->active) revers_arch(0);
cp e
jr nz, _draw_menu_next1
xor a
push hl
call _revers_arch_asm
pop hl
;; B = x, C = x2, D = y, HL = menu
_draw_menu_next1: ; c4ae
;; gotoxy_arch(x, y + 1);
push hl
ld h, d
ld l, b
inc h
call _gotoxy_arch_asm
pop hl ; HL = menu, Stack; null
;; if(m->items[y].title[0] == '-')
push de
push hl ; e7ca
push bc ; Stack; x2x menu y
ld bc, #_off_menu_items
ld a, (bc)
add a, l
ld l, a
ld a, h
adc #0
ld h, a ; HL = m->items[0]
ld bc, #_size_menuitem
ld a, (bc)
ld c, a
ld b, #0 ; BC = sizeof(struct menuitem)
ld a, d ; A = y
_draw_menu_loop2:
or a
jr z, _draw_menu_next2
add hl, bc
dec a
jr _draw_menu_loop2
_draw_menu_next2:
ld bc, #_off_menuitem_title
call _get_offset
ld a, (de)
cp a, #0x2d ; '-'
jr nz, _draw_menu_else
;; chline_arch(CTK_CONF_MENUWIDTH);
ld b, #CTK_CONF_MENUWIDTH
call _chline_arch_asm
jr _draw_menu_next3
_draw_menu_else:
;; cputs_arch(m->items[y].title);
call _cputs_arch_asm
_draw_menu_next3:
;; clearto_arch(x + CTK_CONF_MENUWIDTH);
pop bc ; B = x, C = x2, Stack; menu y
push bc
ld a, b
add a, #CTK_CONF_MENUWIDTH
call _clearto_arch_asm
;; revers_arch(1);
ld a, #1
call _revers_arch_asm
pop bc
pop hl
pop de
inc d
jr _draw_menu_loop1
_draw_menu_ret: ; C = x2
ld h, #0
ld l, c
call _gotoxy_arch_asm
_draw_menu_ret2:
pop af
ret
_ctk_draw_menus:
;; ---------------------------------
;; void ctk_draw_menus(struct ctk_menus *menus);
;; Stack; retl reth menusl menush
;; AFBCDEHL____
;; return void
;; ---------------------------------
;; clip_arch(0, SCREEN_HEIGHT);
ld h, #SCREEN_HEIGHT
ld l, #0
call _clip_arch_asm
;; gotoxy_arch(0, 0);
ld h, #0
call _gotoxy_arch_asm
;; revers_arch(1);
ld a, #1
call _revers_arch_asm
ld hl, #2
add hl, sp
ld e, (hl)
inc hl
ld d, (hl)
ld h, d
ld l, e ; HL = menus
ld bc, #_off_menus_desktopmenu
call _get_offset
push de ; Stack; menus->desktopmenu
ld bc, #_off_menus_open
call _get_offset
push de ; Stack; menus->open menus->desktopmenu
ld bc, #_off_menus_menus
call _get_offset
ld h, d
ld l, e ; HL = menu
_ctk_draw_menus_loop1:
ld bc, #_off_menu_next
call _get_offset
;; if (menu == NULL) _ctk_draw_menus_next1
ld a, d
or e
jr z, _ctk_draw_menus_next1
;; draw_menu_asm(m, menus->open);
ld h, d
ld l, e ; HL = menu->next
pop bc
push bc ; Stack; menus->open menus->desktopmenu
push hl ; Stack; menu menus->open menus->desktopmenu
call _draw_menu_asm
pop hl ; Stack; menus->open menus->desktopmenu
jr _ctk_draw_menus_loop1
_ctk_draw_menus_next1:
pop de ; menus->open
pop hl ; menus->desktopmenu
push de ; Stack; menus->open
;; clearto_arch(SCREEN_WIDTH - strlen(menus->desktopmenu->title) - 1);
ld bc, #_off_menu_title
call _get_offset
ld b ,#0
_ctk_draw_menus_loop2:
ld a, (de)
or a
jr z, _ctk_draw_menus_next2
inc b
inc de
jr _ctk_draw_menus_loop2
_ctk_draw_menus_next2:
ld a, #SCREEN_WIDTH
sub b ; strlen(menus->desktopmenu->title)
dec a ; SCREEN_WIDTH - strlen(menus->desktopmenu->title) - 1
push hl
call _clearto_arch_asm
pop hl ; desktopmenu
pop bc ; open, Stack; null
call _draw_menu_asm
xor a
call _revers_arch_asm
ret
.endif
;; ---------------------------------
;; unsigned char ctk_draw_width(void);
;; Stack; retl reth
;; _______L____
;; return width
;; ---------------------------------
_ctk_draw_width:
ld l, #SCREEN_WIDTH
ret
;; ---------------------------------
;; unsigned char ctk_draw_height(void);
;; Stack; retl reth
;; _______L____
;; return width
;; ---------------------------------
_ctk_draw_height:
ld l, #SCREEN_HEIGHT
ret
;; ---------------------------------
;; internal functions
;; ---------------------------------
;; ---------------------------------
;; static void clearbox_arch_asm(unsigned char x, y, w, h)
;; Stack; retl reth
;; AFBCDEHL____
;; return void
;; ---------------------------------
;; DE = yx, B = h, C = w
_clearbox_arch_asm:
ld a, e
add a, c
ld c, a ; to_x = x + w
ld h, d
ld l, e
_clearbox_arch_loop::
call _gotoxy_arch_asm ; (x, y)
push hl
push bc ; B = h, HL = yx
ld a, c
call _clearto_arch_asm
pop bc
pop hl
inc h ; y++
djnz _clearbox_arch_loop
ret
;; ---------------------------------
;; void drawbox_asm(unsigned char x, y, w, h)
;; Stack; retl reth
;; B = h, C = w, D = y, E = x
;; AF__________
;; return void
;; ---------------------------------
_drawbox_asm:
push bc
push de
push hl
ld h, d
ld l, e
inc h
call _gotoxy_arch_asm ; (x, y + 1)
dec h
push hl
push bc ; Stack; hw, yx, B = h
call _cvline_arch_asm
ld a, #CH_LLCORNER
call _cputc_arch_asm
pop bc
push bc ; Stack; hw yx
ld b, c ; w
call _chline_arch_asm
ld a, #CH_LRCORNER
call _cputc_arch_asm
pop bc
pop hl
call _gotoxy_arch_asm ; (x, y)
push hl
push bc ; Stack; hw yx
ld a, #CH_ULCORNER
call _cputc_arch_asm
pop bc
push bc ; Stack; hw yx
ld b, c ; B = w
call _chline_arch_asm
ld a, #CH_URCORNER
call _cputc_arch_asm
pop bc ; B = h
pop hl
ld a, l
inc a
add a, c
ld l, a ; L = x + 1 + w
inc h ; H = y + 1
call _gotoxy_arch_asm
call _cvline_arch_asm
pop hl
pop de
pop bc
ret
_ctk_conio_arch_asm_end::