; -----------------------------------------------
; PShell - a runtime environment for    
; sharp pocket computers                 
; file     : mainmenu.asm                   
; author   : puehringer edgar           
; date     : 06.06.2004                 
; version  : 1.0.0                      
; assembler: as61860                    
;                                       
; The pshell main menu
; -----------------------------------------------

.area pshell (REL)
        
.include "pshell.h"
.include "internal.h"

; -----------------------------------------------
; Initializes the pshell menu
; label prefix 00
; -----------------------------------------------
psm_init::
        LII   0
lb0002: LP    REG_I
        LDM
        CALL  ps_addr
        JRNCP lb0001
        INCI
        JRM   lb0002        
lb0001: LP    REG_I
        LDM
        LIDP  psm_length
        STD
        RTN


; -----------------------------------------------
; Draw or remove the selection
; label prefix 02
; -----------------------------------------------
psm_rm_sel:
	LIA  32			; " " character
	JRP  lb0201
psm_draw_sel:
	LIA  62			; ">" character
lb0201: PUSH

        RA			; cur_x = 0
        LIDP ps_cur_x
        STD

	LIDP psm_selected	; cur_y = selected - page_offs
	LDD
	EXAB
	LIDP psm_page_offs
	LDD
	LP   REG_B
	SBM
	EXAB
	LIDP ps_cur_y
	STD

	POP
	CALL ps_putchar
	RTN

        
; -----------------------------------------------
; Displays the pshell menu
; label prefix 04
; -----------------------------------------------
psm_disp:
	LIDP  psm_selected	; if page_offs<selected,
	LDD			; page_offs = selected
	EXAB
	LIDP  psm_page_offs
	LDD
	LP    REG_B
	SBM
	JRNCP lb0405
	LIDP  psm_selected
	LDD
	LIDP  psm_page_offs
	STD	
lb0405:
        CALL  ps_clrscr
        LIDP  psm_length	; tmp = length
        LDD
        LIDP  ps_tmp
        STD  
	EXAB

	LIDP  psm_page_offs	; page_offs+LCD_ROWS-tmp
	LDD
        ADIA  LCD_ROWS
	EXAB
        LIDP  ps_tmp
        LDD
	LP    REG_B
	SBM
        JRNCP lb0401		; if < 0
	LIDP  psm_page_offs	; tmp = page_offs+LCD_ROWS
	LDD
        ADIA  LCD_ROWS
	LIDP  ps_tmp
	STD

lb0401: 
	LIDP  psm_page_offs	; page_offs -> stack
	LDD
	PUSH
lb0402:
	POP			; counter-tmp
	PUSH
	EXAB
	LIDP ps_tmp
	LDD
	LP   REG_B
	SBM
	JRNCP lb0403		; exit the loop
        RA			; cur_x = 0
        LIDP ps_cur_x
        STD
        LIA 3			; cur_x = 3
        LIDP ps_cur_x
        STD
	POP
	PUSH
        CALL ps_addr		; x = addr of prog
        IXL
        IXL
        CALL ps_putstr		; print the string

        LIA 1			; cur_x = 1
        LIDP ps_cur_x
        STD
	IXL			; length of icon pattern in A
	CALL  ps_gprint		; print icon

	LIDP ps_cur_y		; cur_y++
	LDD
	INCA
	STD
	POP			; increase counter (on stack)
	INCA
	PUSH
	JRM  lb0402

lb0403:
        POP
        RTN

        
; -----------------------------------------------
; Keybord read loop for the main menu
; label prefix 06
; -----------------------------------------------
psm_main:
	CALL	psm_init
	CALL	psm_disp
	CALL    psm_draw_sel
lb0602:	CALL   ps_kbd_raw
	PTC    0x04, lb0602
	DTC
	.case  KEY_DOWN,   lb0604
	.case  KEY_UP,     lb0605
	.case  KEY_ESC,    lb0606
	.case  KEY_RETURN, lb0607
        .default           lb0608
	RTN

lb0604:		; case KEY_DOWN
	LIDP  psm_selected	; psm_selected+1 -> stack
	LDD
	INCA
	PUSH
	EXAB			; psm_selected+1 -> B
	LIDP  psm_length	; psm_length -> A
	LDD
	LP    REG_B
	SBM			; B = psm_selected+1 - psm_length
	JRNCP lb0610		; if >= 0, go ahead

	CALL  psm_rm_sel	; remove the old selection

	POP			; psm_selected = psm_selected+1
	PUSH
	LIDP  psm_selected
	STD

	EXAB			; B = psm_selected

	LIDP psm_page_offs	; A = psm_page_offs, A -> stack
	LDD

	LP    REG_B
	SBM			; B = psm_selected - psm_page_offs
	LIA   LCD_ROWS		; B = B - LCD_ROWS
	SBM
	JRCP  lb0612		; if <0, go ahead

	LIDP  psm_page_offs
	LDD
	INCA
	STD
	CALL  psm_disp

lb0612: CALL  psm_draw_sel
	JRP   lb0611

lb0610:	
	CALL  ps_beep
lb0611:	POP
	RTN

lb0605:		; case KEY_UP
	LIDP  psm_selected	; psm_selected-1 -> stack
	LDD
	DECA
	PUSH
	JRCP lb0620		; if <0, go ahead

	CALL  psm_rm_sel	; remove the old selection

	POP			; psm_selected = psm_selected-1
	PUSH
	LIDP  psm_selected
	STD

	EXAB			; B = psm_selected

	LIDP psm_page_offs	; A = psm_page_offs, A -> stack
	LDD

	LP    REG_B
	SBM			; B = psm_selected - psm_page_offs
	JRNCP  lb0622		; if >=0, go ahead

	LIDP  psm_page_offs
	LDD
	DECA
	STD
	CALL  psm_disp

lb0622: CALL  psm_draw_sel
	JRP   lb0621

lb0620:	
	CALL  ps_beep
lb0621:	POP
	RTN

	LIDP  psm_selected
	LDD
	DECA
	STD
	RTN

lb0606:
	CALL ps_clrscr
	RA
	JP   ps_exit

lb0607:		; case KEY_RETURN
	LIDP psm_selected
	LDD
	CALL ps_exec
	CALL psm_disp
	CALL psm_draw_sel
	RTN

lb0608: RTN
	PUSH
	CALL  ps_clrscr
        LP   REG_YL
        LIA  <(ps_tmp_str-1)
        EXAM
        LP   REG_YH
        LIA  >(ps_tmp_str-1)
        EXAM
	RA
	EXAB
	POP
	CALL  ps_word2str
        LP   REG_XL
        LIA  <(ps_tmp_str-1)
        EXAM
        LP   REG_XH
        LIA  >(ps_tmp_str-1)
        EXAM
	CALL  ps_putstr
	RTN
