* This requires a mouse in slot 4 and an 80 column card.
*  
*
* 6502 windowing system
*
* by Toshiyasu Morita
*
*   Started: 9/14/88 @ 1:0? am
* Rewritten: 9/14/88 @ 9:28 pm
*
 XC
 LST OFF
*
* Zero page equates
*
PNTR EQU $00
PNTR2 EQU $02
TEMP EQU $04
CH EQU $24
CV EQU $25
BASL EQU $26
TEMPA EQU $80
TEMPX EQU $81
TEMPY EQU $82
MOUSEX EQU $83
MOUSEY EQU $84
BUTTON EQU $85
OLDMX EQU $86
OLDMY EQU $87
*
* Program data equates
*
MOUSEXL EQU $47C
MOUSEXH EQU $57C
MOUSEYL EQU $4FC
MOUSEYH EQU $5FC
BUTTONST EQU $77C
*
* Hardware equates
*
VBL EQU $C019
BANK EQU $C054
SETMOUSE EQU $C412
READMOUSE EQU $C414
CLAMPMOUSE EQU $C417
INITMOUSE EQU $C419
*
* Start of actual code
*
 JMP MAIN
********************************
* Start character output subroutines
********************************
*
* Column 0 lookup table
*
COL0TBLL DFB $400,$480,$500,$580,$600,$680,$700,$780
 DFB $428,$4A8,$528,$5A8,$628,$6A8,$728,$7A8
 DFB $450,$4D0,$550,$5D0,$650,$6D0,$750,$7D0
COL0TBLH DFB /$400,/$480,/$500,/$580,/$600,/$680,/$700,/$780
 DFB /$428,/$4A8,/$528,/$5A8,/$628,/$6A8,/$728,/$7A8
 DFB /$450,/$4D0,/$550,/$5D0,/$650,/$6D0,/$750,/$7D0
*
* Lookup BASL & Y-register value
*
BASLKUP LDX CV
 LDA COL0TBLL,X
 STA BASL
 LDA COL0TBLH,X
 STA BASL+1
 BIT BANK
 LDA CH
 LSR
 TAY
 BCS :NOBIT
 BIT BANK+1
:NOBIT RTS
*
* Character output
*
RAWCOUT STA TEMPA
 STX TEMPX
 STY TEMPY
 LDX CV
 LDA COL0TBLL,X
 STA BASL
 LDA COL0TBLH,X
 STA BASL+1
 BIT BANK
 LDA CH
 LSR
 TAY
 BCS :NOBIT
 BIT BANK+1
:NOBIT LDA TEMPA
 STA (BASL),Y
 BIT BANK
 INC CH
 LDX TEMPX
 LDY TEMPY
 RTS
********************************
* End character output subroutines
********************************
*********************************
* Start mouse subroutines
********************************
*
* Mouse data
*
UNDER? HEX 00 ; Flag indicating valid byte in UNDER
UNDER HEX 00 ; Character currently under mouse
*
* Jmp to (PNTR)
*
JMPPNTR JMP (PNTR)
*
* Jump to mouse routine
*
GOMOUSE LDX #$C4
 LDY #$40
 PHP
 SEI
 BIT BANK ; Make sure we have right screen holes!
 JSR JMPPNTR
 PLP
 RTS
*
* Initialize mouse
*
INITM STZ UNDER? ; No character in UNDER
 LDA INITMOUSE ; First do INITMOUSE call
 STA PNTR
 LDA #/INITMOUSE
 STA PNTR+1
 JSR GOMOUSE
 LDA SETMOUSE ; Set passive mouse mode
 STA PNTR
 LDA #/SETMOUSE
 STA PNTR+1
 LDA #$01 ; Passive mouse mode
 JSR GOMOUSE
 LDA CLAMPMOUSE ; Set clamping values
 STA PNTR
 LDA #/CLAMPMOUSE
 STA PNTR+1
 LDA #$00 ; Set X clamps first
 STZ $478
 STZ $578
 LDX #632 ; Low = 0, high = 316
 STX $4F8
 LDX #/632
 STX $5F8
 JSR GOMOUSE
 LDA #$01 ; Set Y clamps next
 STZ $478
 STZ $578
 LDX #184
 STX $4F8
 LDX #/184
 STX $5F8
 JMP GOMOUSE
*
* Read mouse
*
READM LDA READMOUSE ; Read the mouse
 STA PNTR
 LDA #/READMOUSE
 STA PNTR+1
 JSR GOMOUSE
 LDA MOUSEXH ; Divide mouse X position by 4
 STA PNTR
 LDA MOUSEXL
 LSR PNTR
 ROR
 LSR PNTR
 ROR
 STA MOUSEX
 LDA MOUSEYH ; Divide mouse Y position by 8
 STA PNTR
 LDA MOUSEYL
 LSR PNTR
 ROR
 LSR PNTR
 ROR
 LSR PNTR
 ROR
 STA MOUSEY
 LDA BUTTONST ; Set up button status
 STA BUTTON
 RTS
*
* Erase mouse pointer at MOUSEX, MOUSEY
*
* Note: leaves X-register intact
*
ERASEMP STX TEMP ; Lot of routines need X-register intact
 BIT UNDER? ; If no valid character in UNDER
 BPL :FINIS ;   don't do anything
 LDA OLDMY ; Set up bank, BASL, Y-register
 STA CV
 LDA OLDMX
 STA CH
 JSR BASLKUP
 LDA UNDER ; Restore character at mouse pointer
 STA (BASL),Y
 STZ UNDER?
:FINIS LDX TEMP
 RTS
*
* Draw mouse pointer at MOUSEX, MOUSEY
*
DRAWMP BIT UNDER? ; See if there is a character waiting
 BPL :DRAWIT ;   to be restored
 JSR ERASEMP ; Erase character first
:DRAWIT LDA MOUSEY ; Set up bank, BASL, Y-register
 STA CV
 LDA MOUSEX
 STA CH
 JSR BASLKUP
 LDA (BASL),Y ; Load character under mouse pointer
 STA UNDER ;   and save it
 SEC
 ROR UNDER?
 LDA #$42 ; Draw mouse pointer
 STA (BASL),Y
 LDA MOUSEX ; Store coordinates as OLDMX, OLDMY
 STA OLDMX
 LDA MOUSEY
 STA OLDMY
 RTS
********************************
* End mouse subroutines
********************************
********************************
* Start menu bar subroutines
********************************
*
* Menu bar data
*
MBITEML DS 8 ; Pointer to text for each menu bar item
MBITEMH DS 8
MBITEMX DS 9 ; Leftmost column of each item
MBITEMS HEX 00 ; Number of menu bar items
*
* Clear menu bar
*
CLRMB STZ MBITEMS
 RTS
*
* Add item to menu bar
*
ADDMB LDY MBITEMS
 CPY #$07
 BEQ :FULL
 STA MBITEML,Y
 TXA
 STA MBITEMH,Y
 INY
 STY MBITEMS
:FULL RTS
*
* Show menu bar
*
SHOWMB STZ CV ; Set up cursor position
 STZ CH
 LDA #$20 ; Menu bar's leading space
 JSR RAWCOUT
 LDX #$00
 CPX MBITEMS
 BEQ :PADREST
:OUTER LDA MBITEML,X ; Fetch pointer to menu bar item
 STA PNTR
 LDA MBITEMH,X
 STA PNTR+1
 LDA CH ; Store leftmost column of menu bar item
 STA MBITEMX,X
 LDA #$20 ; Menu bar item's leading space
 JSR RAWCOUT
 LDY #$00 ; Print out menu bar item in inverse
:INNER LDA (PNTR),Y
 BEQ :EOL
 CMP #$41 ; Do translation on capital letters
 BCC :NOTRANS
 CMP #$41+26
 BCS :NOTRANS
 AND #%10111111
:NOTRANS JSR RAWCOUT
 INY
 BRA :INNER
:EOL LDA #$20 ; Print trailing two spaces
 JSR RAWCOUT
 JSR RAWCOUT
 INX ; Loop through all menu bar items
 CPX MBITEMS
 BNE :OUTER
:PADREST LDA CH ; Set up rightmost column of last item
 STA MBITEMX,X
 LDA #$20 ; Pad to end of line with inverse spaces
:LOOP JSR RAWCOUT
 LDX CH
 CPX #80
 BNE :LOOP
 RTS
********************************
* End menu bar subroutines
********************************
********************************
* Start text quickdraw subroutines
********************************
*
* Text quickdraw primary data
*
LEFTEDGE HEX 00 ; Top left X position
TOPEDGE HEX 00 ; Top left Y position
WIDTH HEX 00
HEIGHT HEX 00
*
* Text quickdraw secondary data (calculated from primary data)
*
RGHTEDGE HEX 00
LEDIV2 HEX 00 ; Left edge / 2
REDIV2 HEX 00 ; Right edge / 2
BOTTOM HEX 00 ; Bottom line + 1
*
* Calculate secondary parameters
*
CALC2P LDA LEFTEDGE
 CLC
 ADC WIDTH
 STA RGHTEDGE
 DEC
 LSR
 STA REDIV2
 LDA LEFTEDGE
 LSR
 STA LEDIV2
 LDA TOPEDGE
 CLC
 ADC HEIGHT
 STA BOTTOM
 RTS
*
* Draw middle of box
*
DRAWMID LDA REDIV2 ; Number of characters
 SEC
 SBC LEDIV2
 STA TEMP
 LDX TOPEDGE
:OUTER LDA COL0TBLL,X ; Set up PNTR
 CLC
 ADC LEDIV2
 STA PNTR
 LDA COL0TBLH,X
 CLC
 ADC #$00
 STA PNTR+1
 LDA #" " ; Fill in line
 BIT BANK+1
 LDY TEMP
:INNER STA (PNTR),Y
 DEY
 BPL :INNER
 BIT BANK
 LDY TEMP
:INNER2 STA (PNTR),Y
 DEY
 BPL :INNER2
 INX ; Move down a row, do next line
 CPX BOTTOM
 BNE :OUTER
 RTS
*
* Draw line of box
*
DRAWVL STA TEMP ; Store fill character in TEMP
 BIT BANK ; Figure out bank first
 TYA
 LSR
 TAY
 BCS :NOBIT
 BIT BANK+1
:NOBIT
 LDX TOPEDGE
:OUTER LDA COL0TBLL,X
 STA PNTR
 LDA COL0TBLH,X
 STA PNTR+1
 LDA TEMP
 STA (PNTR),Y
 INX
 CPX BOTTOM
 BNE :OUTER
 RTS
*
* Draw horizontal line without leading & trailing spaces
*
DRAWHL1 LDA COL0TBLL,X ; Get pointer to column 0
 STA PNTR
 LDA COL0TBLH,X
 STA PNTR+1
 LDX LEFTEDGE ; Loop through from left to right
:LOOP BIT BANK
 TXA
 LSR
 TAY
 BCS :NOBIT
 BIT BANK+1
:NOBIT LDA TEMP
 STA (PNTR),Y
 INX
 CPX RGHTEDGE
 BNE :LOOP
 RTS
*
* Draw horizontal line with leading & trailing spaces
*
DRAWHL2 LDA COL0TBLL,X ; Get pointer to column 0
 STA PNTR
 LDA COL0TBLH,X
 STA PNTR+1
 LDX LEFTEDGE ; Catch left corner space
 DEX
 BIT BANK
 TXA
 LSR
 TAY
 BCS :NOBIT
 BIT BANK+1
:NOBIT LDA #" "
 STA (PNTR),Y
 INX ; Loop through from left to right
:LOOP BIT BANK
 TXA
 LSR
 TAY
 BCS :NOBIT2
 BIT BANK+1
:NOBIT2 LDA TEMP
 STA (PNTR),Y
 INX
 CPX RGHTEDGE
 BNE :LOOP
 BIT BANK ; Catch right corner space
 TXA
 LSR
 TAY
 BCS :NOBIT3
 BIT BANK+1
:NOBIT3 LDA #" "
 STA (PNTR),Y
 RTS
*
* Draw left edge of box
*
DRAWLEFT LDA #$5A ; Set up parameters
 LDY LEFTEDGE
 DEY
 JMP DRAWVL
*
* Draw right edge of box
*
DRAWRGHT LDA #$5F
 LDY RGHTEDGE
 JMP DRAWVL
*
* Draw bottom of menu box
*
DRAWMBOT LDA #$4C
 STA TEMP
 LDX BOTTOM
 JMP DRAWHL2
*
* Draw menu box
*
DRAWMBOX JSR CALC2P
 JSR DRAWMID ; Draw middle of box
 JSR DRAWLEFT
 JSR DRAWRGHT
 JMP DRAWMBOT
*
* Draw top line of titleless dialogue box
*
DRAWTOP1 LDA #"_"
 STA TEMP
 LDX TOPEDGE
 DEX
 JSR DRAWHL2
 LDA #$4C
 STA TEMP
 LDX TOPEDGE
 JMP DRAWHL1
*
* Draw bottom line of titleless dialogue box
*
DRAWBOT1 LDA #"_"
 STA TEMP
 LDX BOTTOM
 DEX
 JSR DRAWHL1
 LDA #$4C
 STA TEMP
 LDX BOTTOM
 JMP DRAWHL2
*
* Draw titleless dialogue box
*
DRAWDIA1 JSR CALC2P
 INC BOTTOM
 DEC TOPEDGE
 JSR DRAWMID
 DEC BOTTOM
 INC TOPEDGE
 JSR DRAWLEFT
 JSR DRAWRGHT
 JSR DRAWTOP1
 JMP DRAWBOT1
*
* Draw top of button
*
DRAWTB LDA #"_"
 STA TEMP
 LDX TOPEDGE
 DEX
 JMP DRAWHL1
*
* Draw bottom of button
*
DRAWBB LDA #$4C
 STA TEMP
 LDX BOTTOM
 JMP DRAWHL1
*
* Draw button
*
DRAWBUTN LDA #$01 ; Buttons are a fixed size
 STA HEIGHT
 LDA #10
 STA WIDTH
 JSR CALC2P
 JSR DRAWLEFT
 JSR DRAWRGHT
 JSR DRAWTB ; Draw top of button
 JMP DRAWBB ; Draw bottom of button
*
* Get a byte from (PNTR2)
*
GETPNTR2 INC PNTR2
 BNE :SKIPINC
 INC PNTR2+1
:SKIPINC LDA (PNTR2)
 RTS
*
* Figure out what we want drawn
*
TQDRAW STA PNTR2
 STX PNTR2+1
 LDA (PNTR2)
 BRA :ENTRY
:GETOBJ JSR GETPNTR2 ; Get object #
:ENTRY BNE :NOTFINI
 RTS
:NOTFINI CMP #$01
 BNE :NOTDIA1
 JSR GETPNTR2 ; Draw a titleless dialogue box
 STA TOPEDGE
 JSR GETPNTR2
 STA LEFTEDGE
 JSR GETPNTR2
 STA HEIGHT
 JSR GETPNTR2
 STA WIDTH
 JSR DRAWDIA1
 BRA :GETOBJ
:NOTDIA1 CMP #$02
 BNE :NOTDIA2
 STA TOPEDGE ; Draw titled dialogue box
 JSR GETPNTR2
 STA LEFTEDGE
 JSR GETPNTR2
 STA HEIGHT
 JSR GETPNTR2
 STA WIDTH
; Put something here
 BRA :GETOBJ
:NOTDIA2 CMP #$03
 BNE :NOTBUTN
 JSR GETPNTR2 ; Draw button
 STA TOPEDGE
 JSR GETPNTR2
 STA LEFTEDGE
 JSR DRAWBUTN
 LDA TOPEDGE ; Fill in text inside
 STA CV
 LDA LEFTEDGE
 STA CH
 LDA #$20
 JSR RAWCOUT
 LDY #$08
:LOOP JSR GETPNTR2
 ORA #$80
 JSR RAWCOUT
 DEY
 BNE :LOOP
 LDA #$20
 JSR RAWCOUT
:GETOBJ2 BRA :GETOBJ ; This BRA used to extend BRA reach
:NOTBUTN CMP #$04
 BNE :NOTRADI
 JSR GETPNTR2 ; Draw radio button
 BRA :GETOBJ2
:NOTRADI CMP #$05
 BNE :NOTTEXT
 JSR GETPNTR2 ; Print text
 STA CV
 JSR GETPNTR2
 STA CH
:LOOP2 JSR GETPNTR2
 BEQ :GETOBJ2
 ORA #$80
 JSR RAWCOUT
 BRA :LOOP2
:NOTTEXT
:FINIS RTS
********************************
* End text quickdraw subroutines
********************************
********************************
* Start screen save/restore subroutines
********************************
*
* Screen save/restore data
*
SAVED? HEX 00 ; Is a screen stored or not?
*
* Restore screen
*
RESTORE BIT SAVED? ; Make sure there's a saved screen to restore
 BPL :FINIS
 JSR ERASEMP
 LDA #$FF ; No menus or items inversed
 STA CURRMENU
 STA CURRSEL
 BIT BANK+1
 LDY #120
:LOOP LDA SCREEN,Y
 STA $400,Y
 LDA SCREEN+120,Y
 STA $480,Y
 LDA SCREEN+240,Y
 STA $500,Y
 LDA SCREEN+360,Y
 STA $580,Y
 LDA SCREEN+480,Y
 STA $600,Y
 LDA SCREEN+600,Y
 STA $680,Y
 LDA SCREEN+720,Y
 STA $700,Y
 LDA SCREEN+840,Y
 STA $780,Y
 DEY
 BPL :LOOP
 BIT BANK
 LDY #120
:LOOP2 LDA SCREEN+960,Y
 STA $400,Y
 LDA SCREEN+1080,Y
 STA $480,Y
 LDA SCREEN+1200,Y
 STA $500,Y
 LDA SCREEN+1320,Y
 STA $580,Y
 LDA SCREEN+1440,Y
 STA $600,Y
 LDA SCREEN+1560,Y
 STA $680,Y
 LDA SCREEN+1680,Y
 STA $700,Y
 LDA SCREEN+1800,Y
 STA $780,Y
 DEY
 BPL :LOOP2
 STZ SAVED?
:FINIS RTS
*
* Save screen
*
SAVE JSR ERASEMP
 BIT SAVED? ; Check if we need to restore screen first
 BPL :NOREST
 JSR RESTORE
:NOREST BIT BANK+1
 LDY #120
:LOOP LDA $400,Y
 STA SCREEN,Y
 LDA $480,Y
 STA SCREEN+120,Y
 LDA $500,Y
 STA SCREEN+240,Y
 LDA $580,Y
 STA SCREEN+360,Y
 LDA $600,Y
 STA SCREEN+480,Y
 LDA $680,Y
 STA SCREEN+600,Y
 LDA $700,Y
 STA SCREEN+720,Y
 LDA $780,Y
 STA SCREEN+840,Y
 DEY
 BPL :LOOP
 BIT BANK
 LDY #120
:LOOP2 LDA $400,Y
 STA SCREEN+960,Y
 LDA $480,Y
 STA SCREEN+1080,Y
 LDA $500,Y
 STA SCREEN+1200,Y
 LDA $580,Y
 STA SCREEN+1320,Y
 LDA $600,Y
 STA SCREEN+1440,Y
 LDA $680,Y
 STA SCREEN+1560,Y
 LDA $700,Y
 STA SCREEN+1680,Y
 LDA $780,Y
 STA SCREEN+1800,Y
 DEY
 BPL :LOOP2
 LDA #$FF
 STA SAVED?
 RTS
********************************
* End screen save/restore subroutines
********************************
********************************
* Start pull-down menu subroutines
********************************
*
* Pull-down menu data
*
CURRMENU HEX 00 ; Menu currently open
CURRSEL HEX 00 ; Current selection inversed
*
* Normalize menu bar item
*
* Entry: X-register: menu bar item to normalize
*
*  Exit: X-register: intact
*
NORMMBI JSR ERASEMP ; Make sure mouse pointer is disappeared
 LDA MBITEML,X ; Fetch pointer to menu bar item
 STA PNTR
 LDA MBITEMH,X
 STA PNTR+1
 STZ CV ; Set up cursor position of
 LDA MBITEMX,X ; menu bar item
 STA CH
 LDA #" " ; Print leading space
 JSR RAWCOUT
 LDY #$00 ; Print out menu bar item in normal text
:LOOP LDA (PNTR),Y
 BEQ :EOL
 ORA #$80
 CMP #"@" ; Translate "@" to an apple-sign
 BNE :NOTRANS
 LDA #$41
:NOTRANS JSR RAWCOUT
 INY
 BRA :LOOP
:EOL LDA #" " ; Print trailing two spaces
 JSR RAWCOUT
 JMP RAWCOUT
*
* Print out text in pull-down menu
*
SHOWTEXT LDX #21 ; Clear out all divider flags
:LOOP STZ DIVIDER?,X
 DEX
 BPL :LOOP
 LDA #$01 ; Set up first row of text
 STA CV
:OUTER LDA LEFTEDGE ; Set up column
 STA CH
:INNER INY ; Print text out
 BNE :SKIPINC
 INC PNTR2+1
:SKIPINC LDA (PNTR2),Y ; Check if finished already
 BEQ :FINIS
 CMP #$0D
 BEQ :EOL
 ORA #$80
 CMP #$D3
 BNE :NOTDIV
 LDX WIDTH ; Print out a divider line
 LDA #$53
:LOOP2 JSR RAWCOUT
 DEX
 BNE :LOOP2
 LDX CV ; This is a divider row so can't select
 STA DIVIDER?,X
 BRA :INNER
:NOTDIV CMP #"@" ; Translate "@" to Apple-sign
 BNE :NOTATSN
 LDA #$41
:NOTATSN JSR RAWCOUT
 BRA :INNER
:EOL INC CV ; Go to next row of text
 BRA :OUTER
:FINIS RTS
*
* Check if mouse pointer is in pull-down menu area
*
CHKPDM LDX MBITEMS ; If mouse pointer is to right of last
 LDA MBITEMX,X ;  item then don't need to check
 CMP MOUSEX
 BCC :FINIS
 DEX
 LDA MOUSEX ; Find which menu bar item
:LOOP CMP MBITEMX,X ;   mouse pointer is currently over
 BCC :NEXT
 CMP MBITEMX+1,X
 BCC :MATCH
:NEXT DEX
 BPL :LOOP
:FINIS JMP RESTORE ; Mouse pointer is probably over column 0
:MATCH CPX CURRMENU ; Check to see if this menu is already open
 BNE :OPENIT
 RTS
:OPENIT PHX
 JSR SAVE ; Save the screen first
 PLX
 STX CURRMENU
 JSR NORMMBI ; Normalize menu bar item that pointer is on
 LDA MBITEMX,X ; Set up parameters for DRAWMBOX call
 STA LEFTEDGE
 LDA #$01
 STA TOPEDGE
 INY ; (Pick up pointer to pull-down menu left by
 LDA (PNTR),Y ;   NORMMBI)
 TAX
 INY
 LDA (PNTR),Y
 STA PNTR2+1
 STX PNTR2
 LDA (PNTR2) ; Set up more parameters for DRAWMBOX call
 STA HEIGHT
 LDY #$01
 LDA (PNTR2),Y
 STA WIDTH
 JSR DRAWMBOX ; Draw the box
 LDY #$01
 JSR SHOWTEXT ; Show the text in pull-down menu
 RTS
********************************
* End pull-down menu subroutines
********************************
********************************
* Start pull-down menu select subroutines
********************************
*
* Pull-down menu select data
*
DIVIDER? DS 22 ; If text is divider then null
SELECTS HEX 00 ; Number of selections
*
* Normalize menu item
*
NORMMI LDA CURRMENU
 BMI :FINIS
 LDA CURRSEL ; Set up pointer to column 0 of row
 BMI :FINIS
 JSR ERASEMP
 LDX CURRSEL
 LDA COL0TBLL,X
 STA PNTR
 LDA COL0TBLH,X
 STA PNTR+1
 LDX LEFTEDGE
:LOOP BIT BANK
 TXA
 LSR
 TAY
 BCS :NOBIT
 BIT BANK+1
:NOBIT LDA (PNTR),Y
 CMP #$40 ; Make sure apple stays intact
 BNE :NOTAPPL
 INC
 BRA :NOTRANS
:NOTAPPL ORA #$80
 CMP #$81 ; Do translation on capital letters
 BCC :NOTRANS ;   to move them where they're supposed to be
 CMP #$81+26
 BCS :NOTRANS
 ORA #$40
:NOTRANS STA (PNTR),Y
 INX
 CPX RGHTEDGE
 BNE :LOOP
:FINIS LDA #$FF ; Nothing inversed now
 STA CURRSEL
 RTS
*
* Select menu item
*
SELECTMI LDA CURRMENU ; Make sure there's a window open
 BMI :FINIS
 LDA MOUSEY ; Check if mouse is within menu
 DEC ; If not within menu, then check for
 CMP HEIGHT ;   normalizing selected items
 BCS NORMMI
 LDA MOUSEX
 CMP LEFTEDGE
 BCC NORMMI
 CMP RGHTEDGE
 BCS NORMMI
 LDX MOUSEY ; Check to see if it's a divider
 LDA DIVIDER?,X
 BNE NORMMI
 LDX CURRSEL ; See if it's already inversed
 CPX MOUSEY
 BEQ :FINIS
 TXA ; If there's a menu selection inversed
 BMI :NONORM ;   then normalize it first
 JSR NORMMI
:NONORM JSR ERASEMP
 LDX MOUSEY ; Store selection we're inversing
 STX CURRSEL
 LDA COL0TBLL,X ; Set up pointer to column 0 of row
 STA PNTR
 LDA COL0TBLH,X
 STA PNTR+1
 LDX LEFTEDGE
:LOOP BIT BANK
 TXA
 LSR
 TAY
 BCS :NOBIT
 BIT BANK+1
:NOBIT LDA (PNTR),Y
 CMP #$41 ; Make sure open-apple doesn't get munched
 BNE :NOTAPPL
 DEC
 BRA :NOTRANS
:NOTAPPL AND #$7F
 CMP #$41 ; Do translation on capital letters
 BCC :NOTRANS ;   to move them out of mousetext area
 CMP #$41+26
 BCS :NOTRANS
 AND #$3F
:NOTRANS STA (PNTR),Y
 INX
 CPX RGHTEDGE
 BNE :LOOP
:FINIS RTS
********************************
* End pull-down menu select subroutines
********************************
********************************
* Start event loop subroutines
********************************
*
* Wait a bit
*
WAIT LDX #$03
:MAIN BIT VBL
 BPL :MAIN
:LOOP BIT VBL
 BMI :LOOP
 DEX
 BNE :MAIN
 RTS
*
* Event loop
*
EVENTLOOP
 LDA #$FF ; No menus open or items selected
 STA CURRMENU
 STA CURRSEL
:LOOP BIT VBL
 BMI :LOOP
:WAIT BIT VBL
 BPL :WAIT
 JSR READM ; Read mouse position
 JSR DRAWMP ; Draw mouse pointer
 LDA MOUSEY ; Check if mouse is over menu bar
 BNE :NOTMB
 LDA BUTTON ; Check if mouse button is pressed
 BPL :NOTPRES
 JSR NORMMI ; Normalize any selected items
 JSR CHKPDM ; Check if pull-down menu needs to be opened
 BRA :LOOP
:NOTPRES JSR RESTORE ; Restore screen to normal
 BRA :LOOP
:NOTMB LDA BUTTON ; Mouse is not over menu bar, button pressed?
 BPL :NOTPR2
 JSR SELECTMI ; See mouse pointer is over menu selections
 BRA :LOOP
:NOTPR2 LDX CURRMENU ; See if any menus open & selected
 BMI :NOTPRES
 LDY CURRSEL
 BMI :NOTPRES
 PHX
 DEY
 PHY
 JSR NORMMI
 JSR WAIT
 JSR SELECTMI
 JSR WAIT
 JSR NORMMI
 JSR WAIT
 JSR SELECTMI
 JSR WAIT
 JSR NORMMI
 JSR WAIT
 JSR RESTORE
 PLY
 PLX
 RTS
********************************
* End event loop subroutines
********************************
MAIN STA $C00D ; 80 cols on
 STA $C001 ; 80 col store on
 STA $C00F ; Alt character set
 STZ CV
 STZ CH
 LDX #$06 ; Print out background gunk
 LDY #$00
:LOOP LDA #$FF
 JSR RAWCOUT
 LDA CH
 CMP #80
 BNE :SKIP
 STZ CH
 INC CV
:SKIP DEY
 BNE :LOOP
 DEX
 BNE :LOOP
 JSR CLRMB
 LDA #:ITEM0
 LDX #/:ITEM0
 JSR ADDMB
 LDA #:ITEM1
 LDX #/:ITEM1
 JSR ADDMB
 LDA #:ITEM2
 LDX #/:ITEM2
 JSR ADDMB
 LDA #:ITEM3
 LDX #/:ITEM3
 JSR ADDMB
 JSR INITM
 JSR SHOWMB
:LOOP2 JSR EVENTLOOP
 CPX #$03
 BNE :LOOP
 CPY #$00
 BNE :LOOP
 JMP TEST1
 BRA :LOOP2
:ITEM0 ASC '@',00
 DW :MENU0
:ITEM1 ASC 'File',00
 DW :MENU1
:ITEM2 ASC 'Options',00
 DW :MENU2
:ITEM3 ASC 'K-rad features',00
 DW :MENU3
:MENU0 DFB 7,26
 ASC '  About this program      ',0D
 HEX 7F
 ASC ' About the author       ',7F0D
 ASC '  About his friends       ',0D
 HEX 530D
 ASC '  About the authors dog   ',0D
 ASC '  About the authors cat   ',0D
 ASC '  About the Apple //gs    ',00
:MENU1 DFB 3,7
 ASC '  Gnu  ',0d
 ASC '  Open ',0d
 ASC ' Close ',00
:MENU2 DFB 1,17
 ASC '  What options?  ',00
:MENU3 DFB 14,24
 ASC '  Emit radiation     @R ',0d
 ASC '  Cause power failure   ',0d
 ASC '  Destroy nearby disks  ',0d
 ASC '  Incinerate chips      ',0d
 ASC '  Rain cats and dogs    ',0d
 ASC '  Ginsu knife option    ',0d
 ASC '  Debug any program     ',0d
 ASC '  Crash randomly        ',0D
 ASC '  Barbecue chicken      ',0D
 HEX 530D
 ASC '  Do the twist          ',0d
 ASC '  Do the mamba          ',0d
 ASC '  Do disco Donald       ',0d
 ASC '  Get down! Be hIp!     ',00
*
* Test titleless dialogue box
*
TEST2 LDA #5
 STA TOPEDGE
 STA LEFTEDGE
 LDA #10
 STA HEIGHT
 LDA #50
 STA WIDTH
 JSR DRAWDIA1
 LDA #7
 STA TOPEDGE
 STA LEFTEDGE
 JSR DRAWBUTN
 BRK
TEST0 LDA #:DATA
 LDX #/:DATA
 JMP TQDRAW
:DATA DFB 1 ; Titleless dialogue
 DFB 4,15
 DFB 10,40
 DFB 5
 DFB 5,15
 ASC '  '
TEST1 LDA #:DATA
 LDX #/:DATA
 JSR TQDRAW
 RTS
:DATA DFB 1 ; Draw titleless dialogue box
 DFB 10,10 ; At position 10,10
 DFB 6,45 ; Height - 5, Width - 45
 DFB 5
 DFB 11,15
 ASC 'Lethal radiation has been emitted.',00
 DFB 3 ; Draw button
 DFB 13,12 ; At relative position 5,5
 ASC '   OK   ' ; With text "OK" inside
 DFB 3 ; Draw another button
 DFB 13,24
 ASC ' Cancel '
 HEX 00 ; no more objects
SCREEN
 SAV NEAT
