* Demo07.a  (SC of GlyphViewer)  Version 1.00   20.7.00   by Ken Shillito


*  This program loads and displays the contents of glyph files
*  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


 IFND what
 INCLUDE 'exec/types.i'
 INCLUDE 'UCODE:Includes/ucode.i'
 INCLUDE 'UCODE:Includes/ucodeasms.i'
 ENDC

 INCLUDE 'exec/memory.i'
 INCLUDE 'dos/dosextens.i'
 INCLUDE 'intuition/intuition.i'
 INCLUDE 'intuition/icclass.i'
 INCLUDE 'libraries/locale.i'

 INCLUDE 'UCODE:Includes/lvos.i'       ;LVOs for system library calls
 INCLUDE 'UCODE:Includes/scrollers.i'  ;Structures for tll_stuff.i calls


*>>************************************************************************
*
*   Cold start up, call TLUjob, close down
*   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
***************************************************************************


Start:                     ;cold startup...

; do workbench startup if required

 moveq #0,d2               ;d2 = 0 if cli, else workbench startup

 move.l _AbsExecBase,a6
 sub.l a1,a1               ;for current task..
 jsr _LVOFindTask(a6)      ;.. find own Process structure
 move.l d0,a2              ;(A2) = our own Process structure
 tst.l pr_CLI(a2)          ;pr_CLI<>0 if from CLI
 bne.s .both               ;go if from CLI

 lea pr_MsgPort(a2),a0     ;wait for workbench startup message to arrive
 jsr _LVOWaitPort(a6)
 lea pr_MsgPort(a2),a0     ;get workbench startup message now it's here
 jsr _LVOGetMsg(a6)
 move.l d0,d2              ;d2 = startup message

.both:
 movem.l d2,-(a7)

 bsr TLUjob                ;do a ucode.library-type job

 move.l (a7)+,d2           ;go if was from cli
 beq.s .quit

 move.l _AbsExecBase,a6    ;reply to startup message
 jsr _LVOForbid(a6)
 move.l d2,a1
 jsr _LVOReplyMsg(a6)

.quit:
 rts



*>>************************************************************************
*
*   TLUjob - set up gui for ucode.library programs, call TLGlyphviewer
*   ~~~~~~
***************************************************************************


TLUjob:

; no input register values
; call from any process
;
; n.b. will use 'UCODE:catalogs/[pref language]/glyphviewer.catalog'
;      if it exists
;
; returns D0 = 0 if bad, else D0 = -1


 STRUCTURE .soffs,0        ;stack offsets
 APTR .ubase               ;ucode.library base
 APTR .tbase               ;gadtools.library base
 APTR .gbase               ;graphic.library base
 APTR .ibase               ;intuition.library base
 APTR .dbase               ;dos.library base
 APTR .upath               ;ucode_path
 APTR .clone               ;clone of .upath
 APTR .scren               ;lock on default public screen
 APTR .wndow               ;window
 APTR .bakup               ;TLDMakeback rastport
 APTR .gcont               ;gadget context
 APTR .strig               ;strings loaded by TLLstart
 STRUCT .mesag,im_SIZEOF   ;space to copy IntuiMessage
 STRUCT .slis,xxp_ssz2     ;xxp_slis structure for .scren
 STRUCT .scro,xxp_scs2     ;xxp_scro structure for .wndow
 ULONG .ucod               ;unicode
 UWORD .size               ;nominal size  } attributes of currently-loaded
 UWORD .wdth               ;width         } ucode_group
 UWORD .styl               ;style         }
 UWORD .wght               ;weight        }
 LABEL .sszof

.offs:  EQU (((.sszof+3)/4)*4)  ;total stack offset, rounded up to longword


 moveq #0,d0
 movem.l d0-d7/a0-a6,-(a7) ;saves all except result in D0

; make and clear the stack offsets

 move.l a7,a1
 sub.w #.offs,a7
 move.l a7,a0
.stkz:
 clr.w (a0)+
 cmp.l a1,a0
 bcs .stkz

; open ucode.library

 move.l _AbsExecBase,a6

 IFND what                 ;here if assembling free-standing
 lea .uname,a1
 moveq #xxp_uver,d0
 jsr _LVOOpenLibrary(a6)
 move.l d0,.ubase(a7)
 beq .bad1
 ENDC

 IFD  what                 ;here if assembling in ucode.asm
 IFEQ what-3
 lea .uname,a1
 moveq #xxp_uver,d0
 jsr _LVOOpenLibrary(a6)
 move.l d0,.ubase(a7)
 beq .bad1
 ENDC
 IFEQ what-4               ;here if debugging - "open" ucode.library
 move.l #Endcode+24,.ubase(a7)
 ENDC
 ENDC

; open gadtools.library

 lea .gname,a1
 moveq #37,d0
 jsr _LVOOpenLibrary(a6)
 move.l d0,.tbase(a7)
 beq .bad2

; make ucode_path and its clone

 move.l .ubase(a7),a6      ;create ucode_path (default parameters)
 moveq #0,d0
 moveq #0,d1
 moveq #0,d2
 jsr _LVOTLUstart(a6)
 move.l d0,.upath(a7)
 beq .bad3                 ;quit if can't

 move.l d0,a0              ;use library bases in ucode_path
 move.l xxp_dosp(a0),.dbase(a7)
 move.l xxp_intp(a0),.ibase(a7)
 move.l xxp_gfxp(a0),.gbase(a7)

 jsr _LVOTLUclone(a6)      ;make clone
 move.l d0,.clone(a7)
 beq .bad3                 ;quit if can't (unlikely)

; pre-load Latin-1 glyphs to clone (to make faster)

 sub.w #12,a7
 move.l a7,a2
 move.l #$0021007E,(a2)+
 move.l #$00A100FF,(a2)+
 clr.w (a2)
 move.l d0,a0              ;a0 = clone
 moveq #11,d0              ;d0 = nominal height
 moveq #4,d1               ;d1 = width
 move.w #'SS',d2           ;d2 = style
 moveq #1,d3               ;d3 = weight
 moveq #xxp_bmake,d4       ;d4 = flags = ucode_block add list in a2
 move.l a7,a2              ;a2 = ucode_block add list
 jsr _LVOTLUset(a6)
 add.w #12,a7              ;discard ucode_block list after use

; get scroller information for screen

; If we want windows with scrollers, we must call the TLSlis
; subroutine for each screen to be used. In this case, only the
; default public screen is to be used.

 move.l .ibase(a7),a6      ;a6 = intuition.library base
 sub.l a0,a0
 jsr _LVOLockPubScreen(a6) ;set .scren = lock on default public screen
 move.l d0,.scren(a7)
 beq .bad4                 ;bad if no default public screen

 move.l d0,a0              ;a0 = screen
 lea .slis(a7),a3          ;a3 = memory for screen's xxp_slis structure
 bsr TLSlis
 beq .bad5                 ;bad if TLSlis fails

; get scroller information for window

; If we want a window with scrollers, we must have already called
; TLSlis for the screen it will inhabit. Now, we must call TLScro
; for each window to be opened

 move.l .tbase(a7),a5      ;a5 = gadtools.library base
 move.l .scren(a7),a0      ;a0 = screen  a6 already = intuition.library base
 lea .gcont(a7),a1         ;a1 = ds.l for gadget context
 move.l a3,a2              ;a2 = xxp_slis defined by TLSlis
 lea .scro(a7),a3          ;a3 = memory for window's xxp_scro structure
 bsr TLScro
 beq .bad6                 ;bad if TLScro fails

; load 'GlyphViewer.catalog'

 move.l .dbase(a7),a6      ;a6 = dos.library base
 move.l #.str1,d1
 moveq #ACCESS_READ,d2     ;set d0 = lock on 'Ucode:Catalogs'
 jsr _LVOLock(a6)
 move.l d0,d7
 beq.s .dflt               ;use dflt if can't

 move.l #.str2,d1          ;d1 points to 'GlyphViewer.catalog'
 moveq #.strs,d2           ;d2 = required number of strings
 bsr TLLstart              ;get strg from catalogs
 move.l d0,d2
 move.l d7,d1              ;unlock Ucode:catalogs
 jsr _LVOUnLock(a6)
 move.l d2,.strig(a7)      ;set strig with strings as loaded
 bne.s .bkup               ;go if ok

.dflt:                     ;if TLLstart failed, use .dfalt
 move.l #.dfalt,.strig(a7)

; set up TLDBackup

.bkup:
 move.l .gbase(a7),a6
 move.l #128,d0            ;bitplanes = 128 bytes
 moveq #8,d1               ;8 bitplanes
 bsr TLDMakeback
 move.l d0,.bakup(a7)
 beq .bad7                 ;bad if can't

; open window

 move.l .ibase(a7),a6      ;a6 = intuition.library base
 move.l .scren(a7),a0      ;a0 = screen
 lea .scro(a7),a1          ;a1 = xxp_scro for window
 move.l .strig(a7),a2      ;a2 = string 1 = window name
 addq.l #1,a2
 lea .flags,a3             ;a3 = flags,idcmp
 moveq #0,d0
 moveq #0,d1               ;window dims = defaults
 moveq #0,d2
 moveq #0,d3
 moveq #0,d4
 moveq #0,d5
 moveq #-1,d6
 moveq #-1,d7
 bclr #31,d7               ;screen is public

 bsr TLSOpenWindow         ;set .wndow = window
 move.l d0,.wndow(a7)
 beq .bad8                 ;quit if can't open window

; call TLGlyphviewer to display the glyphs

 move.l .strig(a7),d0      ;d0 = strings
 move.l .tbase(a7),d1      ;d1 = gadtools.library base
 move.l a7,d2
 add.l #.mesag,d2          ;d2 = copy of IntuiMessage
 move.l .wndow(a7),a0      ;a0 = window
 move.l .upath(a7),a1      ;a1 = ucode_path (with clone)
 move.l .bakup(a7),a2      ;a2 = rastport from TLDBackmake
 lea .scro(a7),a3          ;a3 = window's xxp_scro
 move.l .ubase(a7),a6      ;a6 = ucode.library base

 bsr TLGlyphviewer         ;show glyphs - interact with user

; set stack D0 = -1 and quit ok

.good:
 subq.l #1,.offs(a7)
 bra .clos

; here if startup fails

.bad1:                     ;bad1 - can't open ucode.library
 move.l #.err1,d7
 bra.s .bad

.bad2:                     ;bad2 - can't open gadtools.library
 move.l #.err2,d7
 bra.s .bad

.bad3:                     ;bad3 - can't make ucode_path
 move.l #.err3,d7
 bra.s .bad

.bad4:                     ;bad4 - can't lock default public screen
 move.l #.err4,d7
 bra.s .bad

.bad5:                     ;bad5 - TLSlis failed
 move.l #.err5,d7
 bra.s .bad

.bad6:                     ;bad6 - TLScro failed
 move.l #.err6,d7
 bra.s .bad

.bad7:                     ;bad7 - TLDMakeback failed
 move.l #.err7,d7

.bad8:                     ;bad8 - can't open window
 move.l #.err8,d7

; here if bad - try to report error into monitor / output stream

.bad:

; open any version of dos.library

 move.l _AbsExecBase,a6
 lea .dname,a1
 moveq #0,d0
 jsr _LVOOpenLibrary(a6)
 tst.l d0
 beq .clos                 ;quit if can't (unlikely)
 move.l d0,a5

; if cli, get output stream, of workbench, open monitor

 moveq #0,d6               ;d6 = 0 if from cli, -1 if from workbench
 sub.l a1,a1               ;for current task..
 jsr _LVOFindTask(a6)      ;.. find own Process structure
 move.l d0,a2              ;(A2) = our own Process structure
 tst.l pr_CLI(a2)          ;pr_CLI<>0 if from CLI
 bne.s .cli                ;go if from CLI
 moveq #-1,d6              ;else set d6 = -1

 move.l a5,a6
 move.l #.conn,d1          ;if from workbench, open monitor
 move.l #MODE_NEWFILE,d2
 jsr _LVOOpen(a6)
 move.l d0,d5
 beq .cdos                 ;go if can't
 bra.s .both               ;yes, pick up with cli to reort error

.cli:
 move.l a5,a6              ;if cli, get output stream handle
 jsr _LVOOutput(a6)
 move.l d0,d5

; send error report

.both:                     ;d5 = cli / monitor handle
 subq.l #4,a7
 move.l #$0C0A2020,(a7)    ;send 0C0A2020
 move.l d5,d1
 move.l a7,d2
 moveq #4,d3
 jsr _LVOWrite(a6)
 addq.l #4,a7

 move.l d7,a0              ;set d3 = error message length
 moveq #-1,d3
.errl:
 addq.l #1,d3
 tst.b (a0)+
 bne .errl
 move.l d5,d1              ;send the error message
 move.l d7,d2
 jsr _LVOWrite(a6)

 subq.l #4,a7              ;send 0A0A0A0A
 move.l #$0A0A0A0A,(a7)
 move.l d5,d1
 move.l a7,d2
 moveq #4,d3
 jsr _LVOWrite(a6)
 addq.l #4,a7

 lea .errz,a0              ;send 'click to acknowledge'
 move.l a0,d2
 moveq #-1,d3
.eroz:
 addq.l #1,d3
 tst.b (a0)+
 bne .eroz
 move.l d5,d1
 jsr _LVOWrite(a6)

; get click to acknowledge

 move.l d5,d1              ;d1 = handle if monitor
 tst.l d6
 bne.s .inpt

 jsr _LVOInput(a6)         ;else get input handle for cli to d1
 move.l d0,d1

.inpt:
 sub.w #100,a7             ;get input to acknowledge
 move.l a7,d2
 moveq #10,d3
 jsr _LVORead(a6)
 add.w #100,a7

; close monitor

.cmon:
 tst.l d6                  ;go if from cli
 beq.s .cdos
 move.l d5,d1              ;if from workbench, close monitor
 jsr _LVOClose(a6)

; close dos.library

.cdos:
 move.l a6,a1              ;close dos.library
 move.l _AbsExecBase,a6
 jsr _LVOCloseLibrary(a6)

; release TLUjob resources ready to close down

.clos:

 move.l .bakup(a7),d0      ;free TLDMakeback rastport if any
 bsr TLDFreeback

 move.l .wndow(a7),d0      ;close window if ever opened
 beq.s .cls2
 move.l .ibase(a7),a6
 move.l d0,a0
 bsr TLSCloseWindow

.cls2:                     ;free TLLstart data if any
 move.l .strig(a7),d0
 cmp.l #.dfalt,d0
 beq.s .cls3
 bsr TLLfinish

.cls3:                     ;free xxp_scro objects if any
 move.l .ibase(a7),d0
 beq.s .cls4
 move.l d0,a6
 move.l .tbase(a7),a5
 lea .scro(a7),a3
 bsr TLScrk

 lea .slis(a7),a3          ;free xxp_slis objects if any
 move.l .scren(a7),d0
 beq.s .cls4
 move.l d0,a0
 bsr TLSlik

 sub.l a0,a0               ;free default public screen, if ever locked
 move.l .scren(a7),a1
 jsr _LVOUnlockPubScreen(a6)

.cls4:                     ;release ucode_path, if ever created
 move.l .ubase(a7),a6
 move.l .upath(a7),d0
 beq.s .cls5
 move.l d0,a0
 jsr _LVOTLUfinish(a6)

.cls5:                     ;close gadtools.library, if ever opened
 move.l _AbsExecBase,a6
 move.l .tbase(a7),d0
 beq.s .cls6
 move.l d0,a1
 jsr _LVOCloseLibrary(a6)

.cls6:                     ;close ucode.library, if ever opened

 IFND what
 move.l _AbsExecBase,a6
 move.l .ubase(a7),d0
 beq.s .cls7
 move.l d0,a1
 jsr _LVOCloseLibrary(a6)
 ENDC

 IFD what
 IFEQ what-3
 move.l _AbsExecBase,a6
 move.l .ubase(a7),d0
 beq.s .cls7
 move.l d0,a1
 jsr _LVOCloseLibrary(a6)
 ENDC
 ENDC

.cls7:
 add.w #.offs,a7           ;discard stack offsets
 movem.l (a7)+,d0-d7/a0-a6
 rts                       ;D0 = 0 if bad


***   data for TLUjob   ***


; system data

.gname: dc.b 'gadtools.library',0
.uname: dc.b 'UCODE:ucode.library',0
.dname: dc.b 'dos.library',0
.conn: dc.b 'CON:20/10/500/100/Console',0
 dc.w 0


; error reports if failure setting up

.err1: dc.b 'Error: can''t open ucode.library',0
.err2: dc.b 'Error: can''t open gadtools.library',0
.err3: dc.b 'Error: can''t make ucode_path',0
.err4: dc.b 'Error: can''t lock default public screen',0
.err5: dc.b 'Error: can''t set up scroller objects for screen',0
.err6: dc.b 'Error: can''t set up scroller objects for window',0
.err7: dc.b 'Error: TLLMakeback failed - out of memory',0
.err8: dc.b 'Error: can''t open window (out of memory)',0
.errz: dc.b '(Press <return> to acknowledge)',$0A,0


; flags and idcmp         ;2 longwords required by TLSOpenwindow

.flags:

.flg0: EQU WFLG_SIZEGADGET!WFLG_DRAGBAR!WFLG_CLOSEGADGET!WFLG_DEPTHGADGET
.flg1: EQU WFLG_SMART_REFRESH!WFLG_ACTIVATE!WFLG_HASZOOM
 dc.l .flg0!.flg1

.idc0: EQU IDCMP_NEWSIZE!IDCMP_MOUSEBUTTONS!IDCMP_SIZEVERIFY
.idc1: EQU IDCMP_CLOSEWINDOW!IDCMP_RAWKEY!IDCMP_ACTIVEWINDOW
.idc2: EQU IDCMP_INACTIVEWINDOW!IDCMP_VANILLAKEY!IDCMP_IDCMPUPDATE
 dc.l .idc0!.idc1!.idc2


; catalog file data

.str1:  dc.b 'Ucode:Catalogs',0
.str2:  dc.b 'GlyphViewer.catalog',0

; default strings in case catalog won't load (string 1 = window number)

.dfalt: dc.b 0             ;default strings in case catalogs won't load
 dc.b 'Ucode Glyph Viewer, by Ken Shillito',0 ;1
 dc.b 'Goto',0 ;2
 dc.b 'Load',0 ;3
 dc.b 'Help',0 ;4
 dc.b 'OK',0 ;5
 dc.b 'Ucode Glyph Viewer - Help',0 ;6
 dc.b 0 ;7
 dc.b '« Press <Esc> or close gadget when finished viewing »',0 ;7
 dc.b 0 ;9
 dc.b 'Each file has 1024 glyphs, with Unicode values from 0000 '
 dc.b 'to 03FF, or 0400 to 07FF, ..... or FC00 to FFFF. It takes '
 dc.b '64 files to cover all values from 0000 to FFFF, although '
 dc.b 'not all values in this range have Unicodes.',0 ;10
 dc.b 0 ;11
 dc.b 'Files have the following attributes:',0 ;12
 dc.b '   nominal size - e.g. 11',0 ;13
 dc.b '   width descriptor - e.g. 4',0 ;14
 dc.b '   style descriptor - e.g. SS',0 ;15
 dc.b '   weight decriptor - e.g. 1',0 ;16
 dc.b 'See the Amiga guide for an explanation of attributes.',0 ;17
 dc.b 0 ;18
 dc.b 'The [Goto] button lets you view other glyph files with the '
 dc.b 'same attributes as the file you are viewing.',0 ;19
 dc.b 0 ;20
 dc.b 'The [Load] button lets you view any glyph files, '
 dc.b 'whatever its attributes.',0 ;21
 dc.b 'Click a file to load it',0 ;22
 dc.b 'Surrogate',0 ;23
 dc.b 'Nominal Height',0 ;24
 dc.b 'Width',0 ;25
 dc.b 'Weight',0 ;26
 dc.b 'Unicode',0 ;27
 dc.b 'Style',0 ;28
 dc.b '0000',0 ;29
 dc.b '00',0 ;30
 dc.b 'Cancel',0 ;31
 dc.b '(No files match this surrogate,size)',0 ;32
 dc.b 'Click a size to choose it',0 ;33
 dc.b '(The number of files of each size is',0 ;34
 dc.b ' shown after it in parenthesis)',0 ;35
 dc.b '(Click to acknowledge)',0 ;36
 dc.b 'Click a surrogate to choose it',0 ;37
 dc.b 'Error: can''t load glyph file',0 ;38
 ds.w 0

.strs: equ 38              ;number of strings required to be in catalog



*>>************************************************************************
*
*  ucode.library glyph file routines
*  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*  TLGlyphviewer   View all the UCODE: glyhps
*  TLGfiles        Select any UCODE: glyph file
*  TLGgoto         Select a UCODE: file of apecified hght,wdth,styl,wght
*
*  These subroutines can be called from TLUjob. TLGlyphviwer calls TLGfiles
*  and TLGgoto.
*
***************************************************************************


TLGlyphviewer:

; D0 = strings
; D1 = gadtools.library base
; D2 = space to copy IntuiMessage
; A0 = window
; A1 = ucode_path (w. clone)
; A2 = backup
; A3 = xxp_scro
; A6 = ucode.library base


; stack offsets

 STRUCTURE .offs,0
 APTR  .clone         ;ucode_path (clone)
 ULONG .unic          ;unicode
 UWORD .size          ;size
 UWORD .wdth          ;width
 UWORD .styl          ;style
 UWORD .wght          ;weight
 APTR  .ibase         ;intuition.library base
 APTR  .dbase         ;dos.library base
 APTR  .gbase         ;graphics.library base
 UWORD .gmax          ;max width of glyphs in ucode_group
 UWORD .gpl           ;glyphs per line to display
 UWORD .actu          ;actual glyph height
 UWORD .visi          ;lines that will fit on window
 UWORD .totr          ;lines required to display all glyphs
 STRUCT .wint,8       ;wint
 STRUCT .wbox,8       ;wbox
 STRUCT .popp,18      ;data for popup
                      ;+0 = 10 = intuiticks before popup
                      ;+2 = address of .popup
                      ;+6 = 0 = ignore LMB clicks
                      ;+7 = 0 = ignore RMB clicks
                      ;+8 = where popup is, if popup+0 = 1 } not used by
                      ;+16 = cache popup+0 here            } TLDShow
 STRUCT .lins,204     ;TLLWrap points (enough for 50 lines)
 STRUCT .strin,512    ;string of unicode values for printing

 LABEL .ofsz

.osiz:  EQU (((.ofsz+3)/4)*4)   ;offsets rounded up longwords

.strig: EQU .osiz+0   ;D0 = TLLstartstring address
.tbase: EQU .osiz+4   ;D1 = gadtools.library base
.mesag: EQU .osiz+8   ;D2 = copy of IntuiMessages
.wndow: EQU .osiz+32  ;A0 = window
.upath: EQU .osiz+36  ;A1 = ucode_path (base)
.bakup: EQU .osiz+40  ;A2 = rastport made by TLDMakeback
.scro:  EQU .osiz+44  ;A3 = window's xxp_scro
.ubase: EQU .osiz+56  ;A6 = ucode.library base

 movem.l d0-d7/a0-a6,-(a7)     ;save all
 sub.w #.osiz,a7

 move.l xxp_clon(a1),.clone(a7)
 move.l xxp_intp(a1),.ibase(a7)
 move.l xxp_dosp(a1),.dbase(a7)
 move.l xxp_gfxp(a1),.gbase(a7)
 move.w #10,.popp(a7)
 move.l #.popup,.popp+2(a7)
 clr.w .popp+6(a7)

; set initial glyph file attributes

 clr.l .unic(a7)
 move.w #11,.size(a7)
 move.w #4,.wdth(a7)
 move.w #'SS',.styl(a7)
 move.w #1,.wght(a7)

; fill ucode_group with a glyph file

.grup:
 move.l .ubase(a7),a6      ;a6 = base of ucode.library
 move.w .size(a7),d0
 move.w .wdth(a7),d1
 move.w .styl(a7),d2
 move.w .wght(a7),d3
 moveq #xxp_gmake,d4       ;d4 = flags = xxp_gmake = load ucode_group
 move.l .unic(a7),d5
 move.l .upath(a7),a0      ;a0 = ucode_path
 jsr _LVOTLUset(a6)

; set .gmax = max width of glyphs in ucode_group

 move.w xxp_uwsl(a0),.actu(a7)  ;set .actu with actual glyph height
 move.l xxp_grup(a0),d0    ;quit if no xxp_group (out of memory)
 beq .bad
 move.l d0,a0              ;a0 scans glyphs
 add.w #xxp_glhl,a0        ;skip a0 past ucode_group header
 moveq #0,d0               ;d0 will hold max width
 move.w #1023,d1           ;d1 counts glyphs
.max:
 cmp.b xxp_xsz0(a0),d0
 bcc.s .fore
 move.b xxp_xsz0(a0),d0
.fore:
 add.w #xxp_glyt,a0
 dbra d1,.max
 move.w d0,.gmax(a7)

; re-draw window after resizing

.draw:

; set wint to window interior, wbox to entire window

 move.l .wndow(a7),a0      ;a0 = window
 lea .wint(a7),a1          ;a1 = wint
 bsr TLDWindow
 lea .wbox(a7),a2          ;a2 = wbox
 clr.l (a2)
 move.w #10000,4(a2)
 move.w #10000,6(a2)
 move.l wd_RPort(a0),a0    ;a0 = rastport

; clear window

 move.l .gbase(a7),a6
 moveq #0,d0
 moveq #0,d1
 move.w 4(a1),d2
 move.w 6(a1),d3
 moveq #0,d4
 bsr TLDArea

; draw Goto / Load / Help buttons (a0-a2/a6 already set)

 move.l .clone(a7),a5      ;a5 = ucode_path
 move.l .ubase(a7),a6      ;a6 = ucode.library base
 move.l .strig(a7),a3      ;a3 = string 2,3,4
 moveq #1,d0
.stfd:
 tst.b (a3)+
 bne .stfd
 dbra d0,.stfd
 moveq #0,d0               ;d0 = xpos
 moveq #0,d1               ;d1 = ypos
 move.w 4(a1),d2           ;d2 = width = current window interior width
 moveq #18,d3              ;d3 = actual glyph ht 14 + 3
 moveq #1,d4               ;d4 = box dark pen
 moveq #2,d5               ;d5 = box light pen
 move.l #$00030002,d6      ;d6 = pens 2,3 for text
 move.l #$00030001,d7      ;d7 = 3 columns, 1 row
 bsr TLDButtons

; calculate data for glyph array

 moveq #0,d0               ;d0 = .wint width - 4
 move.w .wint+4(a7),d0
 subq.w #4,d0
 moveq #0,d1               ;d1 = .gmax (not < 10, not > 48)
 move.w .gmax(a7),d1
 cmp.w #10,d1
 bcc.s .gml1
 moveq #10,d1
 move.w d1,.gmax(a7)
.gml1:
 cmp.w #49,d1
 bcs.s .gml2
 moveq #48,d1
 move.w d1,.gmax(a7)
.gml2:
 addq.w #2,d1              ;allow inter-chr space of 2
 divu d1,d0
 move.w d0,.gpl(a7)        ;set gpl = glyphs per line

 move.w #1024,d1           ;set .totr = total rows
 add.w d0,d1
 subq.w #1,d1
 divu d0,d1
 move.w d1,.totr(a7)

; set wbox for showing glyphs

 lea .wbox(a7),a0
 move.w #2,(a0)            ;xpos = 2
 move.w .wint+4(a7),d0
 subq.w #4,d0              ;wdth = wint wdth - 4
 move.w d0,4(a0)
 moveq #19,d0              ;ypos = 19
 move.w d0,2(a0)
 neg.w d0
 add.w .wint+6(a7),d0      ;hght = wint hght - ypos - 1
 subq.w #1,d0
 move.w d0,6(a0)

; call TLDShow to display lines

 move.w .totr(a7),d0       ;d0 = total rows = .totr
 move.w .actu(a7),d1       ;d1 = pixels per line = .actu + 1
 addq.w #1,d1
 move.l a7,d2
 add.l #.wint,d2           ;d2 = .wint
 move.l a7,d3
 add.l #.wbox,d3           ;d3 = .wbox
 move.l #$02000001,d4      ;d4 = cpsace,-,bgpen,fgpen passed to Gline
 move.l .mesag(a7),d5      ;d5 = mem to copy IntuiMessage returned = mesg
 move.l .tbase(a7),d7      ;d7 = gadtools.library base
 move.l .ibase(a7),d6      ;d6 = intuition.library base
 move.l .gbase(a7),a6      ;a6 = graphics.library base
 move.l .wndow(a7),a0      ;a0 = window = wndw
 move.l .scro(a7),a1       ;a1 = window's xxp_scro
 lea .gline,a2             ;a2 = subroutine to draw lines = .gline
 move.l a7,a3              ;a3 = callback data = a7 before TLDShow called
 lea .popp(a7),a5          ;a5 = popup data
 bsr TLDShow

 move.w d0,d7              ;d7 = ytop (current top line on window)
 swap d0
 move.w d0,d6              ;d6 = lines that will fit on window

; process message returned by TLDShow

 move.l d5,a2              ;a2 = copy of message (already replied)

 move.l a2,a0              ;set NE if LMB, mouse in wint
 lea .wint(a7),a1
 bsr TLDMouse              ;(TLDMouse makes mousex,mousey rel to wint if NE)
 beq .misc                 ;go if else

 lea .wbox(a7),a2          ;see if in buttons
 clr.l (a2)
 move.l 4(a1),4(a2)
 moveq #0,d0
 moveq #0,d1
 move.w 4(a2),d2
 moveq #18,d3
 move.l #$00030001,d7
 bsr TLDButmon

 subq.w #1,d0              ;to whichever if yes, else clicked glyphs
 bmi .glyf
 beq.s .goto
 subq.w #2,d0
 bmi .load

; here if 'Help' button clicked

 moveq #6,d0               ;d0 = first line to show
 moveq #21,d1              ;d1 = last line to show
 moveq #0,d2               ;d2 = flags
 bset #29,d2               ;     quit if lmb inside wint
 move.l #$020F0001,d4      ;d4 = cspace lspace bgpen fgpen
 moveq #50,d5              ;d5 = max lines
 move.l .clone(a7),d6      ;d6 = ucode_path
 move.l .mesag(a7),d7      ;d7 = mem for messages
 move.l .wndow(a7),a0      ;a0 = window
 move.l .scro(a7),a1       ;a1 = xxp_scro
 move.l .strig(a7),a2      ;a2 = where strings are
 lea .lins(a7),a3          ;a3 = d5+1 longwords (for TLLwrap)
 move.l .tbase(a7),a5      ;a5 = gadtools.library base
 move.l .ubase(a7),a6      ;a6 = ucode.library base
 bsr TLLinfo
 bra .draw

; here if 'Goto' button clicked

.goto:                     ;here if Goto button
 move.w .size(a7),d0
 move.w .wdth(a7),d1
 move.w .wght(a7),d2
 move.w .styl(a7),d3
 move.l .unic(a7),d4
 moveq #22,d5              ;d5 = string num
 move.l .tbase(a7),d6      ;d6 = gadtools.library base
 move.l #$02000001,d7
 move.l .wndow(a7),a0      ;a0 = window
 move.l .scro(a7),a1       ;a1 = window's xxp_scro
 move.l .clone(a7),a2
 move.l .strig(a7),a3      ;a3 = strings
 move.l .mesag(a7),a5      ;a5 = space for message
 move.l .ubase(a7),a6      ;a6 = ucode.library base
 bsr TLGgoto
 addq.l #1,d0
 beq .grup                 ;TLGgoto returns -1 if cancel
 subq.l #1,d0
 move.l d0,.unic(a7)       ;else got .unic
 bra .grup

; here if 'Load' button clicked

.load:                     ;here if Load button
 move.l a7,d0              ;d0   points to unic/wdth/styl/wght data block
 add.l #.unic,d0           ;     (results poked into this data block)
 moveq #22,d5              ;d5 = number of 1st string for load
 move.l .tbase(a7),d6      ;d6 = gadtools.library base
 move.l #$02020001,d7      ;d7 = cspc hdpen bgpen fgpen
 move.l .wndow(a7),a0      ;a0 = window
 move.l .scro(a7),a1       ;a1 = window's xxp_scro
 move.l .clone(a7),a2      ;a2 = ucode_path
 move.l .strig(a7),a3      ;a3 = strings
 move.l .mesag(a7),a5      ;a5 = where to copy message
 move.l .ubase(a7),a6      ;a6 = ucode.library base
 bsr TLGfiles              ;set unicode/size/width/weight/style
 bra .grup                 ;go load & display glyph file

; here if a glyph clicked

.glyf:
 bsr Glyph
 bra .draw

; process miscellaneous IDCMPs

.misc:                     ;process misc IDCMPs
 move.l im_Class(a2),d0

 cmp.l #IDCMP_NEWSIZE,d0   ;go redraw if window resized
 beq .draw

 cmp.l #IDCMP_CLOSEWINDOW,d0  ;keep waiting if was not closewindow
 beq .quit

 cmp.l #IDCMP_VANILLAKEY,d0   ;quit if Esc
 bne .draw
 cmp.w #$001B,im_Code(a2)
 bne .draw

 bra .quit


; bad - report can't load ucode_group

.bad:

; clear window

 move.l .wndow(a7),a0      ;a0 = window
 lea .wint(a7),a1          ;a1 = wint
 bsr TLDWindow
 lea .wbox(a7),a2          ;a2 = wbox
 move.l wd_RPort(a0),a0    ;a0 = rastport
 move.l .gbase(a7),a6      ;a6 = graphics.library base
 moveq #0,d0
 moveq #0,d1
 move.w 4(a1),d2
 move.w 6(a1),d3
 moveq #0,d4
 bsr TLDArea

 move.l .strig(a7),a2      ;point a2 to string 38  'can't ld ucode_group'
 moveq #37,d0
.nonc:
 tst.b (a2)+
 bne .nonc
 dbra d0,.nonc
 moveq #8,d0               ;d0 = xpos
 moveq #20,d1              ;d1 = ypos
 move.l a7,d2              ;d2 = wbox
 add.l #.wbox,d2
 move.l a7,d3              ;d3 = wint
 add.l #.wint,d3
 moveq #0,d4               ;d4 = flags
 bset #31,d4               ;     ascii
 bset #30,d4               ;     &...;
 moveq #2,d5
 moveq #0,d6
 moveq #2,d7
 move.l .wndow(a7),a0      ;     window
 move.l wd_RPort(a0),a1    ;a1 = rastport
 move.l .clone(a7),a0      ;a0 = ucode_path
 move.l .ubase(a7),a6      ;a6 = ucode.library base
 jsr _LVOTLUstring(a6)

 move.l .strig(a7),a2
 moveq #35,d0              ;point a2 to string 36  'click to acknowledge'
.nonf:
 tst.b (a2)+
 bne .nonf
 dbra d0,.nonf
 moveq #8,d0
 moveq #50,d1
 moveq #1,d5               ;f5 = fgpen
 jsr _LVOTLUstring(a6)

.nonw:
 move.l _AbsExecBase,a6    ;wait for message
 move.l .wndow(a7),a2      ;     window
 move.l wd_UserPort(a2),a0
 jsr _LVOWaitPort(a6)
 move.l wd_UserPort(a2),a0 ;get message
 move.l .tbase(a7),a6     ;a6 = gadtools.library base
 jsr _LVOGT_GetIMsg(a6)
 tst.l d0                  ;retry if null (can't happen?)
 beq .nonw
 move.l d0,a1              ;reply to message
 move.l im_Class(a1),d2
 move.w im_Code(a1),d3
 jsr _LVOGT_ReplyIMsg(a6)  ;reply to message
 cmp.l #IDCMP_CLOSEWINDOW,d2
 beq.s .quit               ;quit if closewindow
 cmp.l #IDCMP_MOUSEBUTTONS,d2
 bne .nonw
 cmp.w #$0068,d3           ;else keep trying unless LMB down
 bne .nonw

; quit from TLGlyphviewer

.quit:
 add.w #.osiz,a7
 movem.l (a7)+,d0-d7/a0-a6
 rts


*>>****   Subroutine - draw a line of glyphs (called via TLDShow)   ****


; d0 = string number to be printed
; d1 = ypos (rel to wbox) to print it
; d2 = wint
; d3 = wbox
; d4 = fgpen
; d5 = bgpen
; d6 = cspace
; a1 = rastport
; a3 = a3 as passed to TLDShow = a7 when TLDShow called


.gline:
 movem.l d0-d7/a0-a6,-(a7) ;save all

 move.w d0,d6
 mulu .gpl(a3),d6          ;set d6 = 1st unicode
 move.l .unic(a3),d7       ;       = unic + (d0 * gpl)
 add.l d7,d6
 add.w #1024,d7            ;set d7.w = after last d6.w
 bne.s .cry
 subq.w #1,d7

.cry:
 move.l .upath(a3),a0      ;a0 = ucode_path, a1 already = rastport
 lea .strin(a3),a2         ;a2 = string of unicode values
 move.l a2,a5
 move.w .gpl(a3),d2
 subq.w #1,d2
.fill:
 cmp.w d7,d6
 bcc.s .filn
 move.w d6,(a5)+           ;fill (a2) with .gpl consecutive unicode values
 addq.w #1,d6
.filn:
 dbra d2,.fill
 clr.w (a5)

 moveq #0,d0               ;d0 = xpos (d1 already = ypos)
 move.l 12(a7),d2          ;d2 = wbox
 move.l 8(a7),d3           ;d3 = wint
 moveq #0,d4               ;d4 = flags
 move.b .gmax+1(a3),d4     ;     fixed width gmax
 bset #28,d4               ;     disable underlines (so print 005F ok)
 move.b 16+3(a7),d5        ;d5 = fgpen = input d4
 move.b 20+3(a7),d6        ;d6 = bgpen = input d5
 move.b 24+3(a7),d7        ;d7 = cspce = input d6
 move.l .ubase(a3),a6      ;a6 = ucode.library base
 jsr _LVOTLUstring(a6)

 movem.l (a7)+,d0-d7/a0-a6
 rts


*>>******   Subroutine - Popup unicode number (called via TLDShow)   ******

; d0 = ytop
; d1 = lesser of totl,.visi
; d2 = wint
; d3 = wbox
; d4 = fgpen
; d5 = bgpen
; d6 = cspace
; d7 = code
; a1 = rastport
; a3 = a3 when TLDShow called = a7
; a5 = popup data

.popup:
 tst.w d7                  ;go if d7 = 0 = intuitext count reached
 beq.s .pp0
 cmp.w #1,(a5)             ;else TLDShow about to render / exit
 beq .poff                 ;pop off if on
 bra .pqut                 ;else quit

; here if d7 = 0

.pp0:
 cmp.w #1,(a5)             ;go pop off if pop was on
 beq .poff

; here to pop on - set d5 = unicode clicked, d6,d7 = its xpos,ypos in wbox

 move.l .mesag(a3),a0      ;a0 = intuitick which caused popup
 moveq #0,d4
 move.w im_MouseX(a0),d4
 addq.w #2,.gmax(a3)
 divu .gmax(a3),d4
 subq.w #2,.gmax(a3)
 cmp.w .gpl(a3),d4         ;quit if rhs of chrs on line
 bcc .pqut
 moveq #0,d5               ;d5 = mousey / actu+1 = line number on wbox
 move.w im_MouseY(a0),d5
 move.w .actu(a3),d7
 addq.w #1,d7
 divu d7,d5
 cmp.w d1,d5               ;quit if below bottom line number on wbox
 bcc .pqut
 mulu d5,d7                ;d7 = ypos of top of line in wbox
 move.w d4,d6
 addq.w #2,.gmax(a3)
 mulu .gmax(a3),d6         ;d6 = xpos of lhs of glyph clicked
 subq.w #2,.gmax(a3)
 add.w d0,d5
 mulu .gpl(a3),d5          ;d0 = (line num + ytop) * glyphs per line
 add.w d4,d5               ;+ glyph number on line = glyph number clicked
 cmp.w #1024,d5
 bcc .pqut                 ;go if past last unicode in ucode_group
 add.w .unic+2(a3),d5      ;d5 = unicode under mouse pointer

; flag popup as on

 move.w (a5),16(a5)        ;cache a5+0
 move.w #1,(a5)            ;replace by 1 = switched on

; select & backup region drawn to

 sub.w #40,d6              ;d6 = xpos = xpos of glyph - 40
 bcc.s .cry3
 add.w #42,d6              ;or posn of next glyph if no room at left
 add.w .gmax(a3),d6
.cry3:
 add.w .actu(a3),d7        ;d7 = ypos = bot of glyph's line - 12
 addq.w #1,d7
 sub.w #12,d7
 bcc.s .cry4
 moveq #0,d7               ;or 0 if no room above line
.cry4:
 move.l d6,d0              ;d0,d1 = xpos,ypos
 move.l d7,d1
 move.l d2,a2              ;a2 = wint
 moveq #38,d2              ;d2 = width = 38
 move.w d0,8(a5)
 move.w d1,10(a5)          ;remember where copied from
 move.w d2,12(a5)
 move.l a1,a0              ;a0 = wndw's rastport
 move.l .clone(a3),a1
 move.l xxp_gfxp(a1),a6    ;a6 = graphics.library base
 move.l .bakup(a3),a1      ;a1 = backup rastport

 move.l a3,-(a7)           ;cache a3 while temporarily changed

 move.l d3,a3              ;a3 = wbox
 moveq #12,d3              ;d3 = hght = 12
 move.w d3,14(a5)
 bsr TLDBackup             ;backup the popup region

 move.l (a7)+,a3           ;restore a3

; fill the region with pen 3

 move.l a2,a1              ;a1 = wint
 lea .wbox(a3),a2          ;a2 = wbox
 moveq #3,d4               ;d4 = pen3
 bsr TLDArea               ;fill the area with pen 3

; draw a bevelled box on region

 move.l d5,d7              ;cache unicode at d7
 moveq #1,d4               ;d4 = dark pen
 moveq #2,d5               ;d5 = light pen
 bsr TLDBox

; draw unicode value on region

 subq.l #8,a7              ;stack holds string

 moveq #3,d4
 move.w #$1000,d5
 move.l a7,a5
.pdig:
 move.b #'0'-1,(a5)        ;make ascii of unicode
.pdbm:
 addq.b #1,(a5)
 cmp.b #'9'+1,(a5)
 bne.s .pdbc
 move.b #'A',(a5)
.pdbc:
 sub.w d5,d7
 bcc .pdbm
 add.w d5,d7
 addq.l #1,a5
 lsr.w #4,d5
 dbra d4,.pdig
 clr.b (a5)

 addq.w #4,d0              ;d0 = xpos
 subq.w #3-2,d1            ;d1 = ypos   -3 since no lines above nominal ht
 move.l a2,d2              ;d2 = wint
 move.l a1,d3              ;d3 = wbox
 moveq #0,d4               ;d4 = flags
 bset #31,d4               ;     ASCII
 moveq #1,d5               ;d5 = fgpen
 moveq #3,d6               ;d6 = bgpen
 moveq #2,d7               ;d7 = cspace
 move.l a0,a1              ;a1 = rastport
 move.l .clone(a3),a0      ;a0 = ucode_path
 move.l a7,a2              ;a2 = string
 move.l .ubase(a3),a6      ;a6 = ucode.library base
 jsr _LVOTLUstring(a6)

 addq.l #8,a7              ;dispose of string

 bra.s .pqut               ;go return from Popup

; here to pop off

.poff:
 move.w 16(a5),(a5)        ;restore a5+0 from where cahced at a6+16

 move.l .bakup(a3),a0      ;a0 = backup rastport
 bsr TLDRestore            ;restore the region that was under the popup

; quit from popup

.pqut:
 rts


*>>* Use a window as a requester for files of specific hght,wdth,styl,wght *


TLGgoto:

; D0 = nominal height being looked at
; D1 = width being looked at
; D2 = weight being looked at
; D3 = style being looked at
; D4 = surr, first unicode of ucode_block being looked at
; D5 = str0
; D6 = gadtools.library base
; D7 = cspace - bgpen fgpen
; A0 = window
; A1 = window's xxp_scro
; A2 = ucode_path already TLUset to U0B/NMSS1..
; A3 = strings
; A5 = addr to copy messages
; A6 = ucode.library base

; returns D0 = -1 if cancel, else D0 = unicode chosen

; calls TLDWindow TLDArea TLDShow TLDMouse


; stack offsets

 STRUCTURE .offf,0
 UWORD .gurl               ;surrogate being looked at
 APTR  .glis               ;list applicable to .gurl
 UWORD .gnum               ;number of list items to choose from
 STRUCT .gwin,8            ;wint
 STRUCT .gbox,8            ;wbox
 UWORD .gtop               ;ytop returned by TLDShow
 UWORD .glin               ;link returned by TLDshow
 LABEL .offl

.gsiz: EQU (((.offl+3)/4)*4)  ;offset sizes rounded up to longword

.nomh: EQU .gsiz           ;D0 nominal height
.wide: EQU .gsiz+4         ;D1 width
.wght: EQU .gsiz+8         ;D2 weight
.styl: EQU .gsiz+12        ;D3 style
.suro: EQU .gsiz+16        ;D4 surrogate
.str0: EQU .gsiz+20        ;D5 1st string
.tbas: EQU .gsiz+24        ;D6 gadtools.library base
.pens: EQU .gsiz+28        ;D7 cspace - bgpen fgpen
.wndo: EQU .gsiz+32        ;A0 window
.scro: EQU .gsiz+36        ;A1 window's xxp_scro
.upth: EQU .gsiz+40        ;A2 ucode_path set to U0B/NMSS1..
.strg: EQU .gsiz+44        ;A3 strings
.mesg: EQU .gsiz+52        ;A5 copy of IntuiMessage
.ubas: EQU .gsiz+56        ;A6 ucode.library base

; make stack workspace

 movem.l d0-d7/a0-a6,-(a7)
 sub.w #.gsiz,a7

; set .gurl, .glis - use msw of unic if possible (0000 / D800-DBFF)

 clr.w .gurl(a7)
 move.l xxp_list(a2),.glis(a7)
 move.l xxp_lsts(a2),d0
 beq.s .gswk               ;.gurl = 0, .glis = xxp_list if xxp_lsts null
 move.l d0,a1
 move.w .suro(a7),d0       ;else a1 scans xxp_lsts, d0 = surr sought
.gsls:
 cmp.w (a1),d0             ;go if matches
 beq.s .gslg
 add.w #10,a1              ;else to next
 tst.w (a1)
 bne .gsls                 ;continue unless end of xxp_lsts

 moveq #0,d0               ;if search fails, .gurl = 0, .glis = 1st record
 move.l xxp_lsts(a0),a1
.gslg:
 move.w d0,.gurl(a7)       ;.gurl = 0 / high surr value
 move.l 6(a1),.glis(a7)    ;.glis points to list

; count number of matching files

.gswk:
 move.l .glis(a7),a0       ;a0 scans list
 move.w .nomh+2(a7),d0     ;d0 = size
 move.b .wide+3(a7),d1     ;d1 = width
 move.b .wght+3(a7),d2     ;d2 = weight
 move.w .styl+2(a7),d3     ;d3 = style
 move.l (a0)+,d4           ;d4 counts records
 moveq #0,d5               ;d5 counts items that match
.gswr:
 cmp.w (a0),d0
 bne.s .gswx
 cmp.b 2(a0),d1
 bne.s .gswx
 cmp.b 3(a0),d2
 bne.s .gswx
 cmp.w 6(a0),d3
 bne.s .gswx
 addq.w #1,d5
.gswx:
 addq.l #8,a0
 subq.l #1,d4
 bne .gswr
 move.w d5,.gnum(a7)      ;set .numb = number of matching items

; here if window to be re-drawn

.gdrw:

; set wint, wbox, clear window

 move.l .wndo(a7),a0       ;set wint
 lea .gwin(a7),a1
 bsr TLDWindow

 lea .gbox(a7),a2          ;set wbox to entire wint
 clr.l (a2)
 move.l 4(a1),4(a2)

 move.l .upth(a7),a3       ;clear window
 move.l xxp_gfxp(a3),a6
 move.l .wndo(a7),a3
 move.l wd_RPort(a3),a0
 moveq #0,d0
 moveq #0,d1
 move.w 4(a2),d2
 move.w 6(a2),d3
 moveq #0,d4
 bsr TLDArea

; draw title at top of window

 move.l a2,d2              ;d2 = wbox
 move.l .strg(a7),a2       ;point a2 to string str0 'click a file..'
 move.w .str0+2(a7),d0
 subq.w #1,d0
.gzfi:
 tst.b (a2)+
 bne .gzfi
 dbra d0,.gzfi
 move.l a1,d3              ;d3 = wint
 move.l a0,a1              ;a1 = rastport
 move.l .upth(a7),a0       ;a0 = ucode_path
 moveq #2,d0               ;d0 = xpos
 moveq #1,d1               ;d1 = ypos
 moveq #0,d4               ;d4 = flags
 bset #31,d4               ;     ascii
 bset #30,d4               ;     &...;
 moveq #2,d5               ;d5 = fgpen
 moveq #0,d6               ;d6 = bgpen
 moveq #2,d7               ;d7 = cspace
 move.l .ubas(a7),a6       ;a6 = ucode.library base
 jsr _LVOTLUstring(a6)

; redo wbox for showing matching items

 move.l d2,a0              ;redo wbox for lines
 addq.w #2,(a0)
 subq.w #4,4(a0)
 add.w #16,2(a0)
 sub.w #16,6(a0)

; show matching items

 move.w .gnum(a7),d0       ;d0 = items
 moveq #9,d1               ;d1 = lspace
 exg d2,d3                 ;d2 = wint, d3 = wbox
 move.l .pens(a7),d4       ;d4 = cspace - bgpen fgpen
 move.l .upth(a7),a0       ;     ucode_path
 move.l .mesg(a7),d5       ;d5 = addr for messages
 move.l xxp_intp(a0),d6    ;d6 = intuition.library base
 move.l .tbas(a7),d7       ;d7 = gadtools.library base
 move.l xxp_gfxp(a0),a6    ;a6 = graphics.library base
 move.l .wndo(a7),a0       ;a0 = window
 move.l .scro(a7),a1       ;a1 = xxp_scro
 move.l #.gline,a2         ;a2 = routine to draw lines
 move.l a7,a3              ;a3 = .gline data = stack
 sub.l a5,a5               ;a5 = pop up data = none
 bsr TLDShow
 move.w d0,.gtop(a7)       ;.ytop = top line on window
 swap d0
 move.w d0,.glin(a7)       ;.link = number of lines on window

; process message returned by TLDShow

 move.l d5,a0              ;a0 = message returned by TLDShow
 move.l d2,a1              ;a1 = wint
 bsr TLDMouse              ;see if LMB
 beq .gmsc                 ;go if else

 move.l d3,a2              ;a2 = wbox
 moveq #0,d0
 move.w im_MouseY(a0),d0   ;d0 = mousey rel to wint
 sub.w 2(a2),d0            ;make rel to wbox
 bmi .gdrw
 divu #9,d0                ;d0 = line num (9 pixels per line)
 cmp.w .glin(a7),d0
 bcc .gdrw                 ;go if below bottom line printed
 add.w .gtop(a7),d0        ;d0 = line num rel to (a5)

; seek d0'th matching record in .glis, return with its unicode

 move.l .glis(a7),a0       ;a0 scans records
 addq.l #4,a0
 move.w d0,d4              ;d4 counts down
 addq.w #1,d4
 move.w .nomh+2(a7),d0     ;d0-d3 = attributes
 move.b .wide+3(a7),d1
 move.b .wght+3(a7),d2
 move.w .styl+2(a7),d3
.glk2:
 cmp.w (a0),d0             ;go unless match
 bne.s .gln2
 cmp.b 2(a0),d1
 bne.s .gln2
 cmp.b 3(a0),d2
 bne.s .gln2
 cmp.w 6(a0),d3
 bne.s .gln2
 subq.w #1,d4              ;count down if match
 beq.s .glrp               ;go if d0'th match found
.gln2:
 addq.l #8,a0              ;to next record
 bra .glk2
.glrp:

 move.w .gurl(a7),d0       ;return with D0 = unicode chosen
 swap d0
 move.w 4(a0),d0
 bra.s .gqut

; process non-LMB messages returned by TLDShow

.gmsc:
 move.l im_Class(a0),d0
 move.w im_Code(a0),d1

 cmp.l #IDCMP_CLOSEWINDOW,d0  ;quit if close window
 beq.s .gcnc

 cmp.l #IDCMP_VANILLAKEY,d0   ;quit if Esc
 bne .gdrw
 cmp.w #$001B,d1
 bne .gdrw                    ;else go re-draw & continue

.gcnc:
 moveq #-1,d0             ;d0 = -1 if cancel, else d0 = unicode chosen

.gqut:
 add.w #.gsiz,a7
 move.l d0,(a7)           ;result to stack d0
 movem.l (a7)+,d0-d7/a0-a6
 rts


; called from TLGgoto via TLDShow - print line D0 at position D1

.gline:                    ;** A3 = stack when TLDShow called

 subq.w #3,d1              ;ignore scanlines above nominal hright

 movem.l d0-d4,-(a7)
 subq.l #8,a7

; seek d0'th matching record in .glis

 move.l .glis(a3),a0       ;a0 scans records
 addq.l #4,a0
 move.w d0,d4              ;d4 counts down
 addq.w #1,d4
 move.w .gsiz+0+2(a3),d0   ;d0-d3 = attributes
 move.b .gsiz+4+3(a3),d1
 move.b .gsiz+8+3(a3),d2
 move.w .gsiz+12+2(a3),d3
.glk:
 cmp.w (a0),d0             ;go unless match
 bne.s .glno
 cmp.b 2(a0),d1
 bne.s .glno
 cmp.b 3(a0),d2
 bne.s .glno
 cmp.w 6(a0),d3
 bne.s .glno
 subq.w #1,d4              ;count down if match
 beq.s .glrd               ;go if d0'th match found
.glno:
 addq.l #8,a0              ;to next record
 bra .glk

; make string in stack

.glrd:
 move.w 4(a0),d0           ;d0 = unicode
 move.l a7,a0
 moveq #3,d1
 move.w #$1000,d2
.gldg:
 move.b #'0'-1,(a0)
.gldk:
 addq.b #1,(a0)
 cmp.b #'9'+1,(a0)
 bne.s .gldc
 move.b #'A',(a0)
.gldc:
 sub.w d2,d0
 bcc .gldk
 add.w d2,d0
 addq.l #1,a0
 lsr.w #4,d2
 dbra d1,.gldg
 clr.b (a0)

; draw string

 moveq #0,d0               ;d0 = xpos
 move.l 8+4(a7),d1         ;d1 = ypos
 move.l 8+12(a7),d2        ;d2 = wbox
 move.l 8+8(a7),d3         ;d3 = wint
 moveq #0,d4               ;d4 = flags
 bset #31,d4               ;     ascii
 bset #30,d4               ;     &...;
 move.b d6,d7              ;d7 = cspace
 move.b d5,d6              ;d6 = bgpen
 move.b 8+16+3(a7),d5      ;d5 = fgpen
 move.l .gsiz+32+8(a3),a0  ;a0 = ucode_path   a1 already = rastport
 move.l a7,a2              ;a2 = string
 move.l .gsiz+32+24(a3),a6 ;a6 = ucoe.library base
 jsr _LVOTLUstring(a6)

 addq.l #8,a7              ;exit from .gline
 movem.l (a7)+,d0-d4
 rts



*>>**********   Use a window as a UCODE: glyph file requester   ***********


TLGfiles:

; D0 = address of data block
;      bytes 0-3   surr, unicode of 1st in group  } Input, and to contain
;            4-5   size                           } results
;            6-7   width                          }
;            8-9   style                          }
;            10-11 weight                         }
; D5 = str0
; D6 = gadtools.library base
; D7 = cspace hdpen bgpen fgpen
; A0 = window
; A1 = window's xxp_scro
; A2 = ucode_path,set to U0B/NMSS1..
; A3 = strings
; A5 = addr to copy messages
; A6 = ucode.library base


; stack offsets

 STRUCTURE .offs,0
 UWORD .surl               ;surrogate being looked at
 UWORD .nsiz               ;nominal size being looked at
 APTR  .frst               ;first item in list matching .nsiz
 UWORD .frsk               ;number of its in list matching .nsiz
 APTR  .slis               ;list applicable to .surl
 STRUCT .wint,8            ;wint
 STRUCT .wbox,8            ;wbox
 UWORD .ytop               ;topline returned by TLDShow
 UWORD .link               ;lines returned by TLDShow
 APTR  .szst               ;.size's stack when calling .sizl
 LABEL .offl

.osiz: EQU (((.offl+3)/4)*4)  ;offsets size rounded up to longword

.data: EQU .osiz+0         ;D0 data unic/size/wdth/styl/wght
.str0: EQU .osiz+20        ;D5 1st string
.tbas: EQU .osiz+24        ;D6 gadtools.library base
.pens: EQU .osiz+28        ;D7 cspace hdpen fgpen bgpen
.wndw: EQU .osiz+32        ;A0 window
.scro: EQU .osiz+36        ;A1 window's xxp_scro
.upth: EQU .osiz+40        ;A2 ucode_path, TLUset to U0B/NMSS1..
.strg: EQU .osiz+44        ;A3 strings
.mesg: EQU .osiz+52        ;A5 copy of IntuiMessage
.ubas: EQU .osiz+56        ;A6 ucode.library base


; make stack workspace

 movem.l d0-d7/a0-a6,-(a7) ;save all
 sub.w #.osiz,a7

; set .nsiz = supplied size

 move.l d0,a2
 move.w 4(a2),.nsiz(a7)

; here to redraw after window resized, &c

.draw:

; set .surl, .slis - use msw of unic if possible (0000 / D800-DBFF)

 move.l .upth(a7),a0       ;examine xxp_lsts in ucode_path
 clr.w .surl(a7)
 move.l xxp_list(a0),.slis(a7)
 move.l xxp_lsts(a0),d0
 beq.s .swin               ;.surl = 0, .slis = xxp_list if xxp_lsts null
 move.l d0,a1
 move.w (a2),d0            ;else a1 scans xxp_lsts, d0 = surr sought
.slss:
 cmp.w (a1),d0             ;go if matches
 beq.s .slsg
 add.w #10,a1              ;else to next
 tst.w (a1)
 bne .slss                 ;continue unless end of xxp_lsts

 moveq #0,d0               ;if search fails, .surl = 0, .slis = 1st record
 move.l xxp_lsts(a0),a1
.slsg:
 move.w d0,.surl(a7)       ;.surl = 0 / high surr value
 move.l 6(a1),.slis(a7)    ;.slis points to list

; set wint, wbox, clear window

.swin:
 move.l .wndw(a7),a0       ;a0 = window
 lea .wint(a7),a1          ;a1 = wint
 bsr TLDWindow

 lea .wbox(a7),a2          ;a2 = wbox = whole window
 clr.l (a2)
 move.l 4(a1),4(a2)

 move.l .upth(a7),a3       ;     ucode_path
 move.l xxp_gfxp(a3),a6    ;a6 = graphics.library base
 move.l wd_RPort(a0),a0    ;a0 = rastport
 moveq #0,d0
 moveq #0,d1
 move.w 4(a2),d2
 move.w 6(a2),d3
 move.b .pens+2(a7),d4     ;d4 = bgpen
 bsr TLDArea

; draw data around boxes at top of window

 move.l a2,d2              ;d2 = wbox
 move.l a1,d3              ;d3 = wint
 move.l a0,a1              ;a1 = rastport
 move.l a3,a0              ;a0 = ucode_path
 move.l .strg(a7),a2       ;a2 = strings
 move.w .str0+2(a7),d0     ;d0 = number of 1st string
 bra.s .finc               ;seek first string
.find:
 tst.b (a2)+               ;a2 = first string  'Click a file to load it'
 bne .find
.finc:
 dbra d0,.find
 moveq #2,d0               ;d0 = xpos
 moveq #1,d1               ;d1 = ypos
 moveq #0,d4               ;d4 = flags
 bset #31,d4               ;     ascii
 bset #30,d4               ;     &...;
 move.b .pens+1(a7),d5     ;d5 = header pen
 move.b .pens+2(a7),d6     ;d6 = bgpen
 move.b .pens+0(a7),d7     ;d7 = cspace
 move.l .ubas(a7),a6       ;a6 = ucode.library base
 jsr _LVOTLUstring(a6)

.0:                        ;'Surrogate'
 tst.b (a2)+
 bne .0
 moveq #2,d0
 moveq #16,d1
 move.b .pens+3(a7),d5     ;d5 = fgpen
 jsr _LVOTLUstring(a6)

.1:                        ;'Nominal ht'
 tst.b (a2)+
 bne .1
 moveq #0,d0
 move.w .wbox+4(a7),d0
 divu #3,d0
 addq.w #2,d0
 jsr _LVOTLUstring(a6)

.2:                        ;'Width'
 tst.b (a2)+
 bne .2
 moveq #2,d0
 moveq #50,d1
 jsr _LVOTLUstring(a6)

.3:                        ;'Weight'
 tst.b (a2)+
 bne .3
 moveq #0,d0
 move.w .wbox+4(a7),d0
 lsr.w #2,d0
 addq.w #2,d0
 jsr _LVOTLUstring(a6)

.4:                        ;'Unicode'
 tst.b (a2)+
 bne .4
 move #0,d0
 move.w .wbox+4(a7),d0
 lsr.w #1,d0
 addq.w #2,d0
 jsr _LVOTLUstring(a6)

.5:                        ;'Style'
 tst.b (a2)+
 bne .5
 move.w .wbox+4(a7),d0
 mulu #3,d0
 lsr.w #2,d0
 addq.w #2,d0
 jsr _LVOTLUstring(a6)

.6:
 tst.b (a2)+
 bne .6

; draw buttons at top of window

 move.l a2,a3              ;fill str0+7 with surrogate (in hex notation)
 moveq #3,d0
 move.w .surl(a7),d5
 move.w #$1000,d6
.7:
 move.b #'0'-1,(a3)
.8:
 addq.b #1,(a3)
 cmp.b #':',(a3)
 bne.s .9
 move.b #'A',(a3)
.9:
 sub.w d6,d5
 bcc .8
 add.w d6,d5
 addq.l #1,a3
 lsr.w #4,d6
 dbra d0,.7

 addq.l #1,a3             ;file str0+8 with nominal height (in decimal)
 move.b #' ',(a3)
 move.w .nsiz(a7),d0
 cmp.b #10,d0
 bcs.s .11
 move.b #'0',(a3)
.10:
 cmp.b #10,d0
 bcs.s .11
 addq.b #1,(a3)
 sub.b #10,d0
 bra .10
.11:
 add.b #'0',d0
 move.b d0,1(a3)

 move.l a2,a3
 move.l a0,a5              ;a5 = ucode_path
 move.l a1,a0              ;a0 = rastport
 move.l d2,a2              ;a2 = wbox
 move.l d3,a1              ;a1 = wint
 moveq #0,d0               ;d0-d3 = area
 moveq #31,d1
 move.w .wbox+4(a7),d2
 moveq #18,d3
 moveq #1,d4               ;d4 = box dark pen
 moveq #2,d5               ;d5 = box light pen
 move.l #$00030001,d6      ;d6 = text bpen, fpen
 move.l #$00030001,d7      ;d7 = columns, rows
 bsr TLDButtons            ;draw buttons

; find which lines to display - set a5 = first, d7 = number

 move.l .slis(a7),a5       ;a5 scans list
 moveq #0,d7               ;d7 counts
 move.w .nsiz(a7),d1       ;d1 = size sought
 move.l (a5)+,d2           ;d2 = number of items
 beq .quit                 ;(go if none - can't happen?)
.list:
 cmp.w (a5),d1             ;go if file matches
 beq.s .lstf
 addq.l #8,a5              ;else keep looking
 subq.w #1,d2
 bne .list
 bra.s .lstd               ;go if none match
.lstf:
 move.l a5,a1              ;see how many match
.num:
 addq.w #1,d7              ;bump count
 subq.w #1,d2
 beq.s .lstd               ;go if list exhausted
 addq.l #8,a1
 cmp.w (a1),d1             ;continue until mismatch
 beq .num
.lstd:
 tst.w d7                  ;go if matching items found
 bne .some

; here if no files match surr + size

.none:                     ;print 'no files match...'
 move.l .strg(a7),a2
 move.w .str0+2(a7),d0
 add.w #9,d0
.nonc:
 tst.b (a2)+
 bne .nonc
 dbra d0,.nonc
 moveq #8,d0               ;d0 = xpos
 moveq #80,d1              ;d1 = ypos
 move.l a7,d2              ;d2 = wbox
 add.l #.wbox,d2
 move.l a7,d3              ;d3 = wint
 add.l #.wint,d3
 moveq #0,d4               ;d4 = flags
 bset #31,d4               ;     ascii
 bset #30,d4               ;     &...;
 move.b .pens+1(a7),d5     ;d5 = hdpen
 move.b .pens+2(a7),d6     ;d6 = bgpen
 move.b .pens+0(a7),d7     ;d7 = cspace
 move.l .wndw(a7),a0       ;     window
 move.l wd_RPort(a0),a1    ;a1 = rastport
 move.l .upth(a7),a0       ;a0 = ucode_path
 move.l .ubas(a7),a6       ;a6 = ucode.library base
 jsr _LVOTLUstring(a6)

 moveq #3,d0               ;print 'click to acknowledge'
.nonf:
 tst.b (a2)+
 bne .nonf
 dbra d0,.nonf
 moveq #8,d0
 moveq #100,d1
 move.b .pens+3(a7),d5     ;d5 = fgpen
 jsr _LVOTLUstring(a6)

.nonw:
 move.l _AbsExecBase,a6    ;wait for message
 move.l .wndw(a7),a2       ;     window
 move.l wd_UserPort(a2),a0
 jsr _LVOWaitPort(a6)
 move.l wd_UserPort(a2),a0 ;get message
 move.l .tbas(a7),a6       ;a6 = gadtools.library base
 jsr _LVOGT_GetIMsg(a6)
 tst.l d0                  ;retry if null (can't happen?)
 beq .nonw
 move.l d0,a1              ;reply to message
 move.l im_Class(a1),d2
 move.w im_Code(a1),d3
 jsr _LVOGT_ReplyIMsg(a6)  ;reply to message
 cmp.l #IDCMP_CLOSEWINDOW,d2
 beq .quit                 ;quit if closewindow
 cmp.l #IDCMP_MOUSEBUTTONS,d2
 bne .nonw
 cmp.w #$0068,d3           ;else keep trying unless LMB down
 bne .nonw

 move.l .slis(a7),a5       ;set size to 1st size which exists
 move.w 4(a5),.nsiz(a7)
 bra .draw                 ;go try again

; file data to stack

.some:
 move.l a5,.frst(a7)       ;stack + 4 = 1st file to be shown
 move.w d7,.frsk(a7)       ;        8 = no. of files to be shown

; set wbox

 lea .wbox(a7),a0
 move.w #2,(a0)
 sub.w #2,4(a0)
 move.w #66,2(a0)
 sub.w #67,6(a0)

; show files on window

.show:
 move.w .frsk(a7),d0       ;d0 = number of files
 moveq #9,d1               ;d1 = line height
 move.l a7,d2
 add.l #.wint,d2           ;d2 = wint
 move.l a7,d3
 add.l #.wbox,d3           ;d3 = wbox
 move.l .pens(a7),d4       ;d4 = cspc - bgpen fgpen
 move.l .mesg(a7),d5       ;d5 = where to put messages
 move.l .upth(a7),a0       ;     ucode+path
 move.l xxp_intp(a0),d6    ;d6 = intuition.library base
 move.l .tbas(a7),d7       ;d7 = gadtools.library base
 move.l xxp_gfxp(a0),a6    ;a6 = graphics.library base
 move.l .wndw(a7),a0       ;a0 = window
 move.l .scro(a7),a1       ;a1 = window's xxp_scro
 move.l #.linp,a2          ;a2 = .linp - prints a line
 move.l a7,a3              ;a3 = data for .linp = stack when TLDShow called
 sub.l a5,a5               ;a5 = pop up data = none
 bsr TLDShow

 move.w d0,.ytop(a7)       ;.ytop = line num at top of wbox
 swap d0
 move.w d0,.link(a7)       ;.link = number of lines on wbox

; process message returned by TLDShow in (d5)

 move.l d5,a0              ;set NE if LMB, mouse in wint
 move.l d2,a1
 bsr TLDMouse
 beq .misc                 ;go if else

 move.l d3,a2              ;see if in buttons
 move.l (a2),-(a7)
 move.l 4(a2),-(a7)
 clr.l (a2)
 move.l 4(a1),4(a2)        ;(temporarily set wbox for buttons)
 moveq #0,d0
 moveq #31,d1
 move.w .wbox+4(a7),d2
 moveq #18,d3
 move.l #$00030001,d7
 bsr TLDButmon             ;returns d0 = 0 if none, else 1+
 move.l (a7)+,4(a2)
 move.l (a7)+,(a2)

 subq.w #1,d0              ;to whichever if yes, else see if clicked a file
 bmi.s .chos
 beq.s .surc               ;go if surr button
 subq.w #2,d0
 bmi.s .sizc               ;go if size button
 bra .quit                 ;quit if cancel button

.chos:                     ;clicked - here to see if a file chosen
 moveq #0,d0
 move.w im_MouseY(a0),d0   ;d0 = mousey rel to wint
 sub.w #66,d0              ;reject if < ypos 66 (= ypos of ytop line)
 bmi .show
 divu #9,d0                ;d0 = line num (9 pixels per line)
 cmp.w .link(a7),d0
 bcc .show                 ;go if below bottom line printed
 add.w .ytop(a7),d0        ;d0 = line num rel to (a5)
 mulu #8,d0
 move.l .frst(a7),a0       ;file chosen: point a0 to its record
 add.l d0,a0
 move.l .data(a7),a1       ;a1 = data block for output
 move.w .surl(a7),(a1)     ;surr to msw of unic
 move.w 4(a0),2(a1)        ;unicode to lsw of unic
 move.w (a0),4(a1)         ;set other attributes from file record
 move.b 2(a0),6+1(a1)
 move.b 3(a0),10+1(a1)
 move.w 6(a0),8(a1)
 bra .quit                 ;go return with chosen file

.surc:                     ;here if surrogate box clicked
 move.l a7,a6              ;a6 = stack before call
 bsr .surr
 bra .draw                 ;get surrogate, go redraw window

.sizc:                     ;here if size box clicked
 move.l a7,a6              ;a6 = stack before call
 bsr .size
 beq .draw                 ;go if cancel
 move.w d0,.nsiz(a7)
 bra .draw                 ;else set size as selected, go redraw window

.misc:
 cmp.l #IDCMP_NEWSIZE,im_Class(a0)      ;recycle if IDCMP_NEWSIZE
 beq .draw

 cmp.l #IDCMP_CLOSEWINDOW,im_Class(a0)  ;quit if closewindow (i.e. cancel)
 beq.s .quit

 cmp.l #IDCMP_VANILLAKEY,im_Class(a0)   ;quit if <Esc> (i.e. Cancel)
 bne .show
 cmp.w #$001B,im_Code(a0)
 bne .show                              ;else, re-call TLDShow

.quit:                                  ;return from TLGfiles
 add.w #.osiz,a7
 movem.l (a7)+,d0-d7/a0-a6
 rts

; print line d0 at posn d1 - called back by TLDShow


.linp:                     ;** print record d0
 subq.l #8,a7

 subq.w #3,d1              ;sub 3 from d1, to ignore above nominal height

 move.l .frst(a3),a5       ;a5 = 1st line  (a3 = stack when TLDShow called)
 mulu #8,d0
 add.l d0,a5               ;a5 = line d0

 exg d2,d3                 ;d2 = wbox, d3 = wint
 move.b d6,d7              ;d7 = cspace
 move.b d5,d6              ;d6 = bgpen
 move.b d4,d5              ;d5 = fgpen
 moveq #0,d4               ;d4 = flags
 bset #31,d4               ;     ascii
 bset #30,d4               ;     &...;
 moveq #0,d6
 moveq #2,d7
 move.l .osiz+32+8(a3),a0  ;a0 = ucode_path, a1 already = rastport
 move.l .osiz+32+24(a3),a6 ;a6 = ucode_path

 move.l .osiz(a3),a2       ;     input data block
 moveq #1,d5               ;fgpen = 1, or 2 if matched file loaded
 move.w (a5),d0
 cmp.w .nsiz(a3),d0        ;go if size mismatch
 bne.s .diff
 move.w 4(a5),d0           ;go if unicode mismatch
 cmp.w 2(a2),d0
 bne.s .diff
 move.w .surl(a3),d0       ;go if surrogate mismatch
 cmp.w (a2),d0
 bne.s .diff
 move.w 6(a5),d0           ;go if style mismatch
 cmp.w 8(a2),d0
 bne.s .diff
 move.b 2(a5),d0           ;go if width mismatch
 cmp.b 6+1(a2),d0
 bne.s .diff
 move.b 3(a5),d0           ;go if weight mismatch
 cmp.b 10+1(a2),d0
 bne.s .diff
 moveq #2,d5               ;matched: pgpen = 2

.diff:
 move.l a7,a2              ;build data strings in stack
 move.l d2,a3              ;a3 = wbox

 move.b 2(a5),d0           ;width
 add.b #'0',d0
 move.b d0,(a7)
 clr.b 1(a7)
 moveq #2,d0
 jsr _LVOTLUstring(a6)

 move.b 3(a5),d0           ;weight
 add.b #'0',d0
 move.b d0,(a7)
 moveq #0,d0
 move.w 4(a3),d0
 lsr.w #2,d0
 addq.w #2,d0
 jsr _LVOTLUstring(a6)

 movem.l d6-d7,-(a7)
 moveq #3,d0               ;unicode
 move.w 4(a5),d7
 move.w #$1000,d6
.unic:
 move.b #'0'-1,(a2)
.bump:
 addq.b #1,(a2)
 cmp.b #':',(a2)
 bne.s .cry
 move.b #'A',(a2)
.cry:
 sub.w d6,d7
 bcc .bump
 add.w d6,d7
 lsr.w #4,d6
 addq.l #1,a2
 dbra d0,.unic
 movem.l (a7)+,d6-d7
 clr.b (a2)
 move.l a7,a2
 moveq #0,d0
 move.w 4(a3),d0
 lsr.w #1,d0
 addq.w #2,d0
 jsr _LVOTLUstring(a6)

 move.b 6(a5),(a7)         ;style
 move.b 7(a5),1(a7)
 clr.b 2(a7)
 move.w 4(a3),d0
 mulu #3,d0
 lsr.w #2,d0
 addq.w #2,d0
 jsr _LVOTLUstring(a6)

 addq.l #8,a7
 rts


.surr:                     ;** surrogate button clicked


 rts


.size:                     ;** size button clicked (a6 = stack before call)
 move.l a6,-(a7)
 sub.w #64,a7
 move.l a7,.szst(a6)       ;set .szst to .size's SP for .sizl

 move.l a7,a0              ;fill workspace with zeroes
 moveq #15,d0              ;(32 words will hold total of each size)
.szcl:
 clr.l (a0)+
 dbra d0,.szcl

 move.l .slis(a6),a5       ;a5 scans list (a6 = stack when called)
 move.l (a5)+,d0           ;d0 counts list items
.szad:
 move.w (a5),d1            ;d1 = size of this list record
 cmp.w #32,d1
 bcc.s .sznx
 lsl.w #1,d1
 addq.w #1,0(a7,d1.w)      ;bump its count in the stack counts
.sznx:
 addq.l #8,a5              ;to next list record
 subq.w #1,d0
 bne .szad                 ;until list exhausted

; here to re-draw after resizing window

.szrs:
 move.l .wndw(a6),a0       ;a0 = window
 lea .wint(a6),a1          ;a1 = wint
 bsr TLDWindow

 lea .wbox(a6),a2          ;a2 = wbox
 add.w #.wbox,a2
 clr.l (a2)                ;set to entire wint
 move.l 4(a1),4(a2)

 move.l wd_RPort(a0),a0    ;clear window
 moveq #0,d0
 moveq #0,d1
 move.w 4(a2),d2
 move.w 6(a2),d3
 move.b .pens+2(a6),d4     ;d4 = bgpen

 move.l a6,-(a7)           ;cache a6 while temporarily changed

 move.l .upth(a6),a3       ;     ucode_path
 move.l xxp_gfxp(a3),a6    ;a6 = graphics.library base
 bsr TLDArea

 move.l (a7)+,a6           ;restore a6

; draw title at top of window

 move.l a2,d2              ;d2 = wbox
 move.l a1,d3              ;d3 = wint
 move.l .strg(a6),a2       ;point a2 to string 33 = 'click a file to load it'
 move.w .str0+2(a6),d0
 add.w #10,d0
.szfi:
 tst.b (a2)+
 bne .szfi
 dbra d0,.szfi
 move.l a0,a1              ;a1 = rastport
 move.l .upth(a6),a0       ;a0 = ucode_path
 moveq #2,d0               ;d0 = xpos
 moveq #1,d1               ;d1 = ypos
 moveq #0,d4               ;d4 = flags
 bset #31,d4               ;     ascii
 bset #30,d4               ;     &...;
 move.b .pens+1(a6),d5     ;d5 = hdpen
 move.b .pens+2(a6),d6     ;d6 = bgpen
 move.b .pens+0(a6),d7     ;d7 = cspace

 move.l a6,-(a7)

 move.l .ubas(a6),a6       ;a6 = ucode.library base
 jsr _LVOTLUstring(a6)

 move.l (a7)+,a6

; set wbox for list of sizes

 move.l d2,a0              ;change wbox for size strings
 addq.w #2,(a0)
 subq.w #4,4(a0)
 move.w #16,2(a0)
 sub.w #17,6(a0)

; display sizes, wait for response

 moveq #27,d0              ;d0 = number of strings
 moveq #9,d1               ;d1 = lspace
 exg d3,d2                 ;d2 = wint  d3 = wbox
 move.l .pens(a6),d4       ;d4 = cspace - bgpen fgpen
 move.l .mesg(a6),d5       ;d5 = where to copy message
 move.l .tbas(a6),d7       ;d7 = gadtools.library base
 move.l .wndw(a6),a0       ;a0 = window
 move.l .scro(a6),a1       ;a1 = xxp_scro
 move.l #.sizl,a2          ;a2 = addr to call to draw a line
 move.l a6,a3              ;a3 = a3 to send .sizl = stack when .size called
 sub.l a5,a5               ;a5 = pop up data = none

 move.l a6,-(a7)

 move.l .upth(a6),a6       ;     ucode_path
 move.l xxp_intp(a6),d6    ;d6 = intuition.library base
 move.l xxp_gfxp(a6),a6    ;a6 = graphics.library base
 bsr TLDShow

 move.l (a7)+,a6

 move.w d0,.ytop(a6)       ;.ytop = line num at top of window
 swap d0
 move.w d0,.link(a6)       ;.link = number of lines on window

; see if message from TLDShow was LMB

 move.l d5,a0              ;set NE if LMB, mouse in wint
 move.l d2,a1              ;a1 = wint
 bsr TLDMouse
 beq.s .szms               ;go if else

; see if LMB was a valid size selection

 moveq #0,d0
 move.w im_MouseY(a0),d0   ;d0 = mousey rel to wint
 sub.w #16,d0              ;reject if < ypos 16 (= ypos of ytop line)
 bmi .szrs
 divu #9,d0                ;d0 = line num rel to ytop (9 pixels per line)
 cmp.w .link(a6),d0
 bcc .szrs                 ;go if below bottom line printed
 add.w .ytop(a6),d0        ;d0 = absolute line num
 addq.w #5,d0              ;   = size 5+
 bra.s .szpp               ;size selected: return with size in d0

; miscellaneous messages

.szms:                     ;here if message not LBM
 move.l im_Class(a0),d0

 cmp.l #IDCMP_CLOSEWINDOW,d0  ;quit from .size if close window
 beq.s .szqt

 cmp.l #IDCMP_VANILLAKEY,d0   ;quit from .size if <Esc>
 bne .szrs
 cmp.w #$001B,im_Code(a0)
 bne .szrs                 ;else keep waiting

; quit from .size - return 0

.szqt:
 moveq #0,d0

; quit from .size - return size

.szpp:
 tst.w d0                  ;D0 = 0 / 5-31 on return
 add.w #64,a7
 move.l (a7)+,a6
 rts


; called by TLDShow from .size -  show a line with:   size (number of files)

.sizl:                     ;** show line d0 of sizes at ypos d1

 subq.w #3,d1              ;dec d1 by 3 to skip scanlines above nominal ht

 move.l a3,a6              ;a6 = TLGfiles's stack before .size/.sizl called
 move.l .szst(a6),a3       ;a3 = .size's stack when TLDShow called

 movem.l d1-d2,-(a7)
 sub.w #12,a7              ;workspace to build string

 addq.w #5,d0              ;line 0 = size 5
 move.w d0,d1
 lsl.w #1,d1               ;set d2 = number of files of size d0
 move.w 0(a3,d1.w),d2      ;a3 = stack when TLDShow called = size counts

 move.l #'    ',(a7)       ;put size
 cmp.b #10,d0
 bcs.s .nput
 move.b #'0',(a7)
.cry1:
 cmp.b #10,d0
 bcs.s .nput
 sub.b #10,d0
 addq.b #1,(a7)
 bra .cry1
.nput:
 add.b #'0',d0
 move.b d0,1(a7)

 move.l a7,a0              ;put count
 addq.l #4,a0
 lea .digi,a2
 moveq #4,d0
.digt:
 move.w (a2)+,d1
 move.b #' ',(a0)
 cmp.w d1,d2
 bcc.s .digr
 tst.w d0
 beq.s .digr
 cmp.b #' ',-1(a0)
 beq.s .nxdg
.digr:
 move.b #'0'-1,(a0)
.digk:
 addq.b #1,(a0)
 sub.w d1,d2
 bcc .digk
 add.w d1,d2
 addq.l #1,a0
.nxdg:
 dbra d0,.digt
 move.b #'(',3(a7)         ;put () around count
 move.b #')',(a0)+
 clr.b (a0)                ;null delimit

 moveq #0,d0               ;d0 = xpos
 move.l 12(a7),d1          ;d1 = ypos
 move.l d3,d2              ;d2 = wbox
 move.l 16(a7),d3          ;d3 = wint
 move.b d6,d7              ;d7 = cspace
 move.b d5,d6              ;d6 = bgpen
 move.b d4,d5              ;d5 = fgpen
 moveq #0,d4               ;d4 = flags
 bset #31,d4               ;     ascii
 bset #30,d4               ;     &...;
 move.l .upth(a6),a0       ;a0 = ucode_path  a1 already = rastport
 move.l a7,a2              ;a2 = string
 move.l .ubas(a6),a6       ;a6 = ucode.library base
 jsr _LVOTLUstring(a6)

 add.w #12,a7
 movem.l (a7)+,d1-d2
 rts

.digi: dc.w 10000,1000,100,10,1



*>>*******   Subroutine -  A glyph on the GlyphViewer clicked   ***********


Glyph:

 rts



; TLD, TLS, and TLL subroutines

 INCLUDE 'UCODE:Includes/tld_stuff.i'
 INCLUDE 'UCODE:Includes/tls_stuff.i'
 INCLUDE 'UCODE:Includes/tll_stuff.i'
