; Digital Signal Analyzer
; Written by Sobolev Vladimir from Russia, Ekaterinburg, 08-Apr-98


 bra      start
 incdir   "Sys:a/Devpac3/include/"

 include  exec/exec_lib.i
 include  exec/memory.i
 include  libraries/dos_lib.i
 include  libraries/dos.i
 include  intuition/intuition.i
 include  intuition/intuition_lib.i
 include  intuition/imageclass.i
 include  intuition/gadgetclass.i
 include  graphics/gfxbase.i
 include  graphics/graphics_lib.i
 include  libraries/asl.i
 include  libraries/asl_lib.i
 include  math/mathieeesingbas_lib.i

start:
 clr.l    dsa_file_mem
 bsr      OpenSysLib
 tst.b    d0
 beq      exit1
 bsr      OpenOtherLib
 tst.b    d0
 beq      exit2
 bsr      OpenScr
 tst.l    d0
 beq      exit3
 bsr      OpenWin
 tst.l    d0
 beq      exit4

 bsr      main

exit4:
 bsr      CloseWin
exit3:
 bsr      CloseScr
exit2:
 bsr      CloseOtherLib
exit1:
 bsr      CloseSysLib
 bsr      FreeAllMemory
 moveq.l  #0,d0
 rts

;=========================

main:
 st       Refresh_gadget        ; need gadget refresh
 st       Refresh_text          ; need text refresh
 st       Refresh_gfx           ; need gfx refresh
 sf       zoom_flag
 clr.b    BackupFile
 clr.b    BackupDrawer
 clr.w    gfx_small_step
 sf       calc_osc_pos_dis
 sf       calc_gfx_pos_dis

 move.l   #file_info_block,d0
 addq.l   #4,d0
 andi.l   #$fffffffc,d0
 move.l   d0,dsa_fib    ; get address long word aligned file info block

; bsr      GetWinSize
; bsr      ClearWorkWindow

 movea.l  dsa_win,a0
 lea      dsa_menu,a1
 CALLINT  SetMenuStrip    ; set menu to dsa_win
 tst.l    d0
 beq      ma_1


ma_2:        ; wait user action
 bsr      refresh_task
ma_2a:

 movea.l  dsa_win,a0
 move.l   wd_UserPort(a0),a0
 CALLEXEC WaitPort
 movea.l  dsa_win,a0
 move.l   wd_UserPort(a0),a0
 CALLEXEC GetMsg
 tst.l    d0
 beq      ma_2
 movea.l  d0,a1
 move.l   im_Class(a1),d0
 tst.l    d0                      ; no event ?
 beq      ma_2

 move.l   a1,-(a7)
 lea      int_msg_copy,a0
 move.w   #im_SIZEOF-1,d0

ma_2ac:
 move.b   (a1)+,(a0)+
 dbf      d0,ma_2ac

 move.l   (a7)+,a1
 CALLEXEC ReplyMsg
 lea      int_msg_copy,a1
 move.l   im_Class(a1),d0

 btst     #1,d0                   ; test NEWSIZE event
 beq      ma_c1b
 st       zoom_flag
 sf       calc_osc_pos_dis
 st       Refresh_text
 st       Refresh_gfx
 st       Refresh_gadget
 bra      ma_2

ma_c1b:
 btst     #3,d0                   ; test MOUSEBUTTONS event
 beq      ma_c1d
 cmpi.w   #SELECTDOWN,im_Code(a1) ; button press or release ?
 bne      ma_2                    ; jump if not lmb press
 move.w   im_MouseX(a1),d0
 move.w   im_MouseY(a1),d1
 bsr      select_pos
 bra      ma_2

ma_c1d:
 btst     #4,d0                   ; test MOUSEMOVE event
 beq      ma_c1c
 bra      ma_2a

ma_c1c:
 btst     #5,d0                   ; test GADGETDOWN event
 beq      ma_c1a
 move.l   im_IAddress(a1),a0
 move.w   gg_GadgetID(a0),d0
 sf       gpush_direction
 bsr      ma_gadget
 bra      ma_2

ma_c1a:
 btst     #6,d0                   ; test GADGETUP event
 beq      ma_c1
 move.l   im_IAddress(a1),a0
 move.w   gg_GadgetID(a0),d0
 st       gpush_direction
 bsr      ma_gadget
 bra      ma_2

ma_c1:
 btst     #8,d0                   ; test MENUPICK event
 beq      ma_c2
 move.w   im_Code(a1),menu_punkt
 bsr      ma_menu_pick
 tst.l    d0                      ; success=ok ? (exit ?)
 beq      ma_6                    ; if d0=0 to exit (Quit was selected in menu)
 bra      ma_2

ma_c2:
 btst     #9,d0                   ; test CLOSEWINDOW event
 beq      ma_c3
 bra      ma_6                    ; to exit

ma_c3:
 btst     #10,d0                  ; test RAWKEY event
 beq      ma_c4
 move.w   im_Code(a1),key_code
 move.w   im_Qualifier(a1),skey_code
 bsr      ma_raw_key
 bra      ma_2

ma_c4:
 bra      ma_2

ma_6:
 movea.l  dsa_win,a0
 lea      dsa_menu,a1
 CALLINT  ClearMenuStrip
ma_1:
 rts



;------------------------------------

refresh_task:
 tst.b    Refresh_gadget
 beq      reta_2b
 sf       Refresh_gadget
 bsr      GetWinSize
 bsr      AjustHGadget
 bsr      RefreshHGWorkWindow
reta_2b:

 tst.b    Refresh_text
 beq      reta_2c
 sf       Refresh_text
 bsr      ClearTextArea
 bsr      RedrawTexts
reta_2c:

 tst.b    Refresh_gfx
 beq      reta_2a
 sf       Refresh_gfx
 bsr      ClearGfxArea
 bsr      RedrawGraphics
reta_2a:
 rts



;------------------------------------

ma_gadget:
 cmpi.w   #1,d0
 bne      maga_2
 bsr      calc_cur_text_pos
 st       Refresh_text
 bra      maga_1

maga_2:
 cmpi.w   #2,d0
 bne      maga_3
 tst.l    dsa_file_mem      ; oscilograms exists ?
 beq      maga_1            ; jump if not exists
 tst.b    gpush_direction
 bne      maga_1            ; jump if gadget release
; immediate press
 bsr      ajust_field
 st       calc_osc_pos_dis
 st       Refresh_gadget
 st       Refresh_text
 st       Refresh_gfx
 bra      maga_1

maga_3:
 cmpi.w   #3,d0
 bne      maga_4
 bsr      calc_cur_gfx_pos
 st       Refresh_gfx
 bra      maga_1

maga_4:
 cmpi.w   #4,d0
 bne      maga_5
 move.l   dsa_file_mem,d0
 beq      maga_1
 tst.w    dsnw_pi03_pos
 beq      maga_1
 move.w   gfx_small_step,d1
 sub.w    d1,dsnw_pi03_pos
 bcc      maga_4a
 clr.w    dsnw_pi03_pos
maga_4a:
 st       Refresh_gadget
 st       Refresh_gfx
 bra      maga_1

maga_5:
 cmpi.w   #5,d0
 bne      maga_6
 move.l   dsa_file_mem,d0
 beq      maga_1
 cmpi.w   #$ffff,dsnw_pi03_pos
 beq      maga_1
 move.w   gfx_small_step,d1
 add.w    d1,dsnw_pi03_pos
 bcc      maga_5a
 move.w   #$ffff,dsnw_pi03_pos
maga_5a:
 st       Refresh_gadget
 st       Refresh_gfx
 bra      maga_1

maga_6:
 cmpi.w   #6,d0
 bne      maga_7
 move.l   dsa_file_mem,d0
 beq      maga_1
 move.w   kosc,d2
 subq.w   #1,d2
 cmp.w    cur_osc_pos,d2        ; last osc ?
 bcs      maga_1
 beq      maga_1
 move.w   cur_osc_pos,d1
 addq.w   #1,d1
 move.w   d1,cur_osc_pos
 cmp.w    d1,d2                 ; last osc ?
 bne      maga_6a
 move.w   #$ffff,dsnw_pi08_pos
 bra      maga_6b
maga_6a:
 swap.w   d1
 clr.w    d1
 divu.w   kosc,d1
 move.w   d1,dsnw_pi08_pos
maga_6b:
 st       calc_osc_pos_dis
 st       Refresh_gadget
 st       Refresh_text
 st       Refresh_gfx
 bra      maga_1

maga_7:
 cmpi.w   #7,d0
 bne      maga_8
 move.l   dsa_file_mem,d0
 beq      maga_1
 tst.w    cur_osc_pos         ; first osc ?
 beq      maga_1
 move.w   cur_osc_pos,d1
 subq.w   #1,d1
 move.w   d1,cur_osc_pos
 tst.w    d1                  ; first osc ?
 bne      maga_7a
 clr.w    dsnw_pi08_pos
 bra      maga_7b
maga_7a:
 swap.w   d1
 clr.w    d1
 divu.w   kosc,d1
 move.w   d1,dsnw_pi08_pos
maga_7b:
 st       calc_osc_pos_dis
 st       Refresh_gadget
 st       Refresh_text
 st       Refresh_gfx
 bra      maga_1

maga_8:
 cmpi.w   #8,d0
 bne      maga_9
 sf       calc_osc_pos_dis
 bsr      calc_cur_osc_pos
 st       Refresh_text
 st       Refresh_gfx
 bra      maga_1

maga_9:
 bra      maga_1

maga_1:
 rts


;------------------------------------

ma_raw_key:
 lea      raw_key_table,a0
 move.w   key_code,d0
 move.w   skey_code,d1

mrke_3:
 tst.l    (a0)
 beq      mrke_1
 cmp.w    (a0),d0
 bne      mrke_2
 cmp.w    2(a0),d1
 bne      mrke_2
 move.l   4(a0),a0
 jsr      (a0)
 bra      mrke_1
mrke_2:
 adda.w   #8,a0
 bra      mrke_3
mrke_1:
 moveq.l  #$ff,d0   ; not exit
 rts


;------------------------------------

ma_menu_pick:
 move.w   menu_punkt,d0
 cmpi.w   #$ffff,d0
 beq      mepi_1   ; push rmb and no select menu punkt: resume - no action
 lea      menu_jump_table,a0
mepi_2:
 move.w   (a0)+,d1
 cmp.w    #$ffff,d1
 beq      mepi_1
 movea.l  (a0)+,a1
 cmp.w    d0,d1
 bne      mepi_2
 jsr      (a1)
 rts
mepi_1:
 moveq.l  #$ff,d0   ; not exit
 rts


;------------------------------------

mn_Load:
 move.l   dsa_win,rtl_Window
 move.l   #rtl_LoadTitle,rtl_Title
 lea      BackupFile,a0
 lea      rtl_File,a1
 moveq.l  #32,d0
 bsr      CopyString1       ; restore file name
 lea      BackupDrawer,a0
 lea      rtl_Drawer,a1
 move.l   #256,d0
 bsr      CopyString1       ; restore drawer path
 clr.l    rtl_Save
 move.l   ASL_FileRequest,d0
 suba.l   a0,a0
 movea.l  _AslBase,a6
 jsr      _LVOAllocAslRequest(a6)
 tst.l    d0
 beq      mnl_1
 move.l   d0,dsa_requester
 move.l   d0,a0
 lea      req_tag_list,a1
 movea.l  _AslBase,a6
 jsr      _LVOAslRequest(a6)
 tst.l    d0
 beq      mnl_2             ; jump if user canceled

 st       calc_osc_pos_dis
 st       calc_gfx_pos_dis
 st       Refresh_text      ; refresh oscilogramm text
 st       Refresh_gfx       ; refresh oscilogramm gfx
 st       Refresh_gadget

 movea.l  dsa_file_mem,a1
 move.l   a1,d0
 beq      mnl_1a            ; memory is free
 move.l   dsa_file_size,d0
 CALLEXEC FreeMem           ; free old memory (erase old oscilogramm)
 clr.l    dsa_file_mem

mnl_1a:
 movea.l  dsa_requester,a0
 movea.l  fr_File(a0),a0
 lea      BackupFile,a1
 moveq.l  #32,d0
 bsr      CopyString1      ; save file name
 movea.l  dsa_requester,a0
 movea.l  fr_Drawer(a0),a0
 lea      BackupDrawer,a1
 move.l   #256,d0
 bsr      CopyString1      ; save drawer path
 movea.l  dsa_requester,a0
 movea.l  fr_Drawer(a0),a0
 lea      file_path,a1
 move.l   #256,d0
 bsr      CopyString1      ; copy path+file name to internal bufer
 movea.l  dsa_requester,a0
 movea.l  fr_File(a0),a0
 lea      file_path,a1
 move.l   #256,d0
 bsr      AddFileToPath

 move.l   #file_path,d1
 move.l   #1005,d2
 CALLDOS  Open
 tst.l    d0
 bne      mnl_2a
 moveq.l  #3,d0      ; message: File not open
 bsr      WinErr
 bra      mnl_2
mnl_2a:
 move.l   d0,dsa_file
 move.l   #file_path,d1
 moveq.l  #SHARED_LOCK,d2
 CALLDOS  Lock
 tst.l    d0
 bne      mnl_3a
 moveq.l  #3,d0      ; message: File not open
 bsr      WinErr
 bra      mnl_3
mnl_3a:
 move.l   d0,dsa_file_lock
 move.l   d0,d1
 move.l   dsa_fib,d2
 CALLDOS  Examine
 tst.l    d0
 bne      mnl_4a
 moveq.l  #3,d0      ; message: File not open
 bsr      WinErr
 bra      mnl_4
mnl_4a:
 movea.l  dsa_fib,a0
 move.l   fib_Size(a0),dsa_file_size
 cmpi.l   #dsah_SIZEOF,dsa_file_size
 bge      mnl_5
 moveq.l  #4,d0     ; message: This is no DSA file or file is corrupt
 bsr      WinErr    ; Window with message to screen
 bra      mnl_4
mnl_5:
 move.l   dsa_file_size,d0
 moveq.l  #1,d1     ; public
 CALLEXEC AllocMem
 tst.l    d0
 bne      mnl_6
 moveq.l  #1,d0     ; message: Low memory for load file
 bsr      WinErr
 bra      mnl_4
mnl_6:
 move.l   d0,dsa_file_mem
 move.l   dsa_file,d1
 move.l   d0,d2
 move.l   dsa_file_size,d3
 CALLDOS  Read
 cmp.l    dsa_file_size,d0
 beq      mnl_7
 moveq.l  #2,d0     ; message: Loading error
 bsr      WinErr
 bra      mnl_8
mnl_7:              ; load - o.k.
 movea.l  dsa_file_mem,a0
 cmpi.l   #'DSAF',dsah_ID(a0)
 beq      mnl_4b    ; sucesfully load, no free memory
 moveq.l  #4,d0     ; message: This is no DSA file or file is corrupt
 bsr      WinErr
 bra      mnl_8
mnl_4b:
 bsr      after_read
 bra      mnl_4

mnl_8:
 movea.l  dsa_file_mem,a1
 move.l   dsa_file_size,d0
 CALLEXEC FreeMem
 clr.l    dsa_file_mem
mnl_4:
 move.l   dsa_file_lock,d1
 CALLDOS  UnLock
mnl_3:
 move.l   dsa_file,d1
 CALLDOS  Close
mnl_2:
 movea.l  dsa_requester,a0
 movea.l  _AslBase,a6
 jsr      _LVOFreeAslRequest(a6)
mnl_1:
 moveq.l  #$ff,d0   ; no exit
 rts


;------------------------------------

mn_Save:
 tst.l    dsa_file_mem
 bne      mns_2b
 moveq.l  #6,d0      ; message: No file in memory
 bsr      WinErr
 bra      mns_2
mns_2b:
 bsr      prepare_write
 move.l   #file_path,d1
 move.l   #1006,d2         ; new file
 CALLDOS  Open
 tst.l    d0
 bne      mns_2a
 moveq.l  #5,d0      ; message: File not open for write
 bsr      WinErr
 bra      mns_2
mns_2a:
 move.l   d0,dsa_file
 move.l   d0,d1
 move.l   dsa_file_mem,d2
 move.l   dsa_file_size,d3
 CALLDOS  Write
 cmp.l    dsa_file_size,d0
 beq      mns_7
 moveq.l  #7,d0     ; message: Saving error
 bsr      WinErr
mns_7:              ; save - o.k.
 move.l   dsa_file,d1
 CALLDOS  Close
mns_2:
 moveq.l  #$ff,d0   ; no exit
 rts



;------------------------------------

mn_SaveAs:
 tst.l    dsa_file_mem
 bne      mnsa_2b
 moveq.l  #6,d0      ; message: No file in memory
 bsr      WinErr
 bra      mnsa_1
mnsa_2b:
 move.l   dsa_win,rtl_Window
 move.l   #rtl_SaveTitle,rtl_Title
 lea      BackupFile,a0
 lea      rtl_File,a1
 moveq.l  #32,d0
 bsr      CopyString1       ; restore file name
 lea      BackupDrawer,a0
 lea      rtl_Drawer,a1
 move.l   #256,d0
 bsr      CopyString1       ; restore drawer path
 clr.l    rtl_Save
 move.l   ASL_FileRequest,d0
 suba.l   a0,a0
 movea.l  _AslBase,a6
 jsr      _LVOAllocAslRequest(a6)
 tst.l    d0
 beq      mnsa_1
 move.l   d0,dsa_requester
 move.l   d0,a0
 lea      req_tag_list,a1
 movea.l  _AslBase,a6
 jsr      _LVOAslRequest(a6)
 tst.l    d0
 beq      mnsa_2           ; jump if user canceled

 bsr      prepare_write

 movea.l  dsa_requester,a0
 movea.l  fr_File(a0),a0
 lea      BackupFile,a1
 moveq.l  #32,d0
 bsr      CopyString1      ; save file name
 movea.l  dsa_requester,a0
 movea.l  fr_Drawer(a0),a0
 lea      BackupDrawer,a1
 move.l   #256,d0
 bsr      CopyString1      ; save drawer path
 movea.l  dsa_requester,a0
 movea.l  fr_Drawer(a0),a0
 lea      file_path,a1
 move.l   #256,d0
 bsr      CopyString1      ; copy path+file name to internal bufer
 movea.l  dsa_requester,a0
 movea.l  fr_File(a0),a0
 lea      file_path,a1
 move.l   #256,d0
 bsr      AddFileToPath

 move.l   #file_path,d1
 move.l   #1006,d2         ; new file
 CALLDOS  Open
 tst.l    d0
 bne      mnsa_2a
 moveq.l  #5,d0      ; message: File not open for write
 bsr      WinErr
 bra      mnsa_2

mnsa_2a:
 move.l   d0,dsa_file
 move.l   d0,d1
 move.l   dsa_file_mem,d2
 move.l   dsa_file_size,d3
 CALLDOS  Write
 cmp.l    dsa_file_size,d0
 beq      mnsa_7
 moveq.l  #7,d0            ; message: Saving error
 bsr      WinErr
mnsa_7:                    ; save - o.k.
 move.l   dsa_file,d1
 CALLDOS  Close
mnsa_2:
 movea.l  dsa_requester,a0
 movea.l  _AslBase,a6
 jsr      _LVOFreeAslRequest(a6)
mnsa_1:
 moveq.l  #$ff,d0   ; no exit
 rts

;------------------------------------

mn_Import:
 move.l   dsa_win,rtl_Window
 move.l   #rtl_ImportTitle,rtl_Title
 lea      BackupFile,a0
 lea      rtl_File,a1
 moveq.l  #32,d0
 bsr      CopyString1       ; restore file name
 lea      BackupDrawer,a0
 lea      rtl_Drawer,a1
 move.l   #256,d0
 bsr      CopyString1       ; restore drawer path
 clr.l    rtl_Save
 move.l   ASL_FileRequest,d0
 suba.l   a0,a0
 movea.l  _AslBase,a6
 jsr      _LVOAllocAslRequest(a6)
 tst.l    d0
 beq      mnim_1
 move.l   d0,dsa_requester
 move.l   d0,a0
 lea      req_tag_list,a1
 movea.l  _AslBase,a6
 jsr      _LVOAslRequest(a6)
 tst.l    d0
 beq      mnim_2             ; jump if user canceled

mnim_1a:
 movea.l  dsa_requester,a0
 movea.l  fr_File(a0),a0
 lea      BackupFile,a1
 moveq.l  #32,d0
 bsr      CopyString1      ; save file name
 movea.l  dsa_requester,a0
 movea.l  fr_Drawer(a0),a0
 lea      BackupDrawer,a1
 move.l   #256,d0
 bsr      CopyString1      ; save drawer path
 movea.l  dsa_requester,a0
 movea.l  fr_Drawer(a0),a0
 lea      file_path,a1
 move.l   #256,d0
 bsr      CopyString1      ; copy path+file name to internal bufer
 movea.l  dsa_requester,a0
 movea.l  fr_File(a0),a0
 lea      file_path,a1
 move.l   #256,d0
 bsr      AddFileToPath

 move.l   #file_path,d1
 move.l   #1005,d2       ; old file
 CALLDOS  Open
 tst.l    d0
 bne      mnim_2a
 moveq.l  #3,d0      ; message: File not open
 bsr      WinErr
 bra      mnim_2
mnim_2a:
 move.l   d0,dsa_file
 move.l   #file_path,d1
 moveq.l  #SHARED_LOCK,d2
 CALLDOS  Lock
 tst.l    d0
 bne      mnim_3a
 moveq.l  #3,d0      ; message: File not open
 bsr      WinErr
 bra      mnim_3
mnim_3a:
 move.l   d0,dsa_file_lock
 move.l   d0,d1
 move.l   dsa_fib,d2
 CALLDOS  Examine
 tst.l    d0
 bne      mnim_4a
 moveq.l  #3,d0      ; message: File not open
 bsr      WinErr
 bra      mnim_4
mnim_4a:
 movea.l  dsa_fib,a0
 move.l   fib_Size(a0),import_file_size
 tst.l    import_file_size
 bne      mnim_5
 moveq.l  #8,d0     ; message: Open empty file
 bsr      WinErr    ; Window with message to screen
 bra      mnim_4
mnim_5:
 move.l   import_file_size,d0
 moveq.l  #1,d1     ; public
 CALLEXEC AllocMem
 tst.l    d0
 bne      mnim_6
 moveq.l  #1,d0     ; message: Low memory for load file
 bsr      WinErr
 bra      mnim_4
mnim_6:
 move.l   d0,import_file_mem
 move.l   dsa_file,d1
 move.l   d0,d2
 move.l   import_file_size,d3
 CALLDOS  Read
 cmp.l    import_file_size,d0
 beq      mnim_7
 moveq.l  #2,d0     ; message: Loading error
 bsr      WinErr
 bra      mnim_8
mnim_7:              ; load - o.k.
 movea.l  import_file_mem,a0
 move.l   import_file_size,d0
 bsr      prepare_hst_file
 tst.l    d0
 bne      mnim_4b
 moveq.l  #9,d0     ; message: This is not PLDSHELL file or file is corrupt
 bsr      WinErr
 bra      mnim_8
mnim_4b:
 move.w   conv_osc_count,d0
 move.l   conv_osc_lenght,d1
 move.b   #2,d2                ; universal type (16 types of signal)
 bsr      make_dsa
 tst.l    d0
 beq      mnim_8

 movea.l  import_file_mem,a0
 move.l   import_file_size,d0
 bsr      hst_import

 sf       calc_osc_pos_dis
 sf       calc_gfx_pos_dis
 st       Refresh_text      ; refresh oscilogramm text
 st       Refresh_gfx       ; refresh oscilogramm gfx
 st       Refresh_gadget

mnim_8:
 movea.l  import_file_mem,a1
 move.l   import_file_size,d0
 CALLEXEC FreeMem
mnim_4:
 move.l   dsa_file_lock,d1
 CALLDOS  UnLock
mnim_3:
 move.l   dsa_file,d1
 CALLDOS  Close
mnim_2:
 movea.l  dsa_requester,a0
 movea.l  _AslBase,a6
 jsr      _LVOFreeAslRequest(a6)
mnim_1:
 moveq.l  #$ff,d0   ; no exit
 rts



;------------------------------------

mn_Export:
 clr.l    export_file_mem

 tst.l    dsa_file_mem
 bne      mnex_2b
 moveq.l  #6,d0      ; message: No file in memory
 bsr      WinErr
 bra      mnex_1
mnex_2b:

 bsr      prepare_dsa2hst
 tst.l    d0
 bne      mnex_2c
 moveq.l  #11,d0     ; message: No oscilogram for export
 bsr      WinErr
 bra      mnex_1
mnex_2c:
 move.l   export_file_size,d0
 move.l   #$10000,d1
 CALLEXEC AllocMem
 tst.l    d0
 bne      mnex_2d
 moveq.l  #10,d0     ; message: Low memory for internal buffers
 bsr      WinErr
 bra      mnex_1

mnex_2d:
 move.l   d0,export_file_mem
 bsr      dsa2hst

 move.l   dsa_win,rtl_Window
 move.l   #rtl_ExportTitle,rtl_Title
 lea      BackupFile,a0
 lea      rtl_File,a1
 moveq.l  #32,d0
 bsr      CopyString1       ; restore file name
 lea      BackupDrawer,a0
 lea      rtl_Drawer,a1
 move.l   #256,d0
 bsr      CopyString1       ; restore drawer path
 clr.l    rtl_Save
 move.l   ASL_FileRequest,d0
 suba.l   a0,a0
 movea.l  _AslBase,a6
 jsr      _LVOAllocAslRequest(a6)
 tst.l    d0
 beq      mnex_1
 move.l   d0,dsa_requester
 move.l   d0,a0
 lea      req_tag_list,a1
 movea.l  _AslBase,a6
 jsr      _LVOAslRequest(a6)
 tst.l    d0
 beq      mnex_2           ; jump if user canceled

 movea.l  dsa_requester,a0
 movea.l  fr_File(a0),a0
 lea      BackupFile,a1
 moveq.l  #32,d0
 bsr      CopyString1      ; save file name
 movea.l  dsa_requester,a0
 movea.l  fr_Drawer(a0),a0
 lea      BackupDrawer,a1
 move.l   #256,d0
 bsr      CopyString1      ; save drawer path
 movea.l  dsa_requester,a0
 movea.l  fr_Drawer(a0),a0
 lea      file_path,a1
 move.l   #256,d0
 bsr      CopyString1      ; copy path+file name to internal bufer
 movea.l  dsa_requester,a0
 movea.l  fr_File(a0),a0
 lea      file_path,a1
 move.l   #256,d0
 bsr      AddFileToPath

 move.l   #file_path,d1
 move.l   #1006,d2         ; new file
 CALLDOS  Open
 tst.l    d0
 bne      mnex_2a
 moveq.l  #5,d0      ; message: File not open for write
 bsr      WinErr
 bra      mnex_2

mnex_2a:
 move.l   d0,dsa_file
 move.l   d0,d1
 move.l   export_file_mem,d2
 move.l   export_real_size,d3
 CALLDOS  Write
 cmp.l    export_real_size,d0
 beq      mnex_7
 moveq.l  #7,d0            ; message: Saving error
 bsr      WinErr
mnex_7:                    ; save - o.k.
 move.l   dsa_file,d1
 CALLDOS  Close
mnex_2:
 movea.l  dsa_requester,a0
 movea.l  _AslBase,a6
 jsr      _LVOFreeAslRequest(a6)
mnex_1:
 tst.l    export_file_mem
 beq      mnex_1a
 move.l   export_file_mem,a1
 move.l   export_file_size,d0
 CALLEXEC FreeMem
mnex_1a:
 moveq.l  #$ff,d0   ; no exit
 rts


;------------------------------------

mn_About:
 lea      dsa_NewWinAbout,a0
 move.l   dsa_scr,nw_Screen(a0) ; install screen pointer to window structure
 CALLINT  OpenWindow         ; open About window
 move.l   d0,dsa_WinAbout
 tst.l    d0
 beq      mnab_1             ; about window not open

 movea.l  dsa_WinAbout,a0
 movea.l  wd_RPort(a0),a0    ; window RastPort
 lea      dsa_AboutText,a1   ; IntuiText structure
 moveq.l  #0,d0              ; x coord
 moveq.l  #0,d1              ; y coord
 CALLINT  PrintIText
 movea.l  dsa_WinAbout,a0
 movea.l  wd_RPort(a0),a0    ; window RastPort
 lea      dsa_AboutText2,a1  ; IntuiText structure
 moveq.l  #0,d0              ; x coord
 moveq.l  #0,d1              ; y coord
 CALLINT  PrintIText
 movea.l  dsa_WinAbout,a0
 movea.l  wd_RPort(a0),a0    ; window RastPort
 lea      dsa_AboutText3,a1  ; IntuiText structure
 moveq.l  #0,d0              ; x coord
 moveq.l  #0,d1              ; y coord
 CALLINT  PrintIText

 movea.l  dsa_WinAbout,a0
 move.l   wd_UserPort(a0),a0
 CALLEXEC WaitPort
 movea.l  dsa_WinAbout,a0
 move.l   wd_UserPort(a0),a0
 CALLEXEC GetMsg
 tst.l    d0
 beq      mnab_2
 move.l   d0,a1
 CALLEXEC ReplyMsg
mnab_2:
 movea.l  dsa_WinAbout,a0
 CALLINT  CloseWindow
 moveq.l  #$ff,d0   ; no exit
mnab_1:
 rts



;------------------------------------

mn_Quit:
 moveq.l  #0,d0     ; exit
 rts



;------------------------------------

mn_GetOsc:
 bsr      alloc_hard_buf
 tst.l    d0
 beq      mngo_1

 lea      dsa_action_init,a4
 lea      ide_cmd,a5
 CALLEXEC Supervisor

 lea      dsa_action_start,a4
 lea      ide_cmd,a5
 CALLEXEC Supervisor

 moveq.l  #10,d1
 CALLDOS  Delay           ; wait 0.2 sec

 lea      dsa_action_read,a4
 lea      ide_cmd,a5
 CALLEXEC Supervisor

 bsr      mn_MakeOsc

mngo_1:
 moveq.l  #$ff,d0     ; no exit
 rts



;--------------------------------------------------------------------------

mn_RefreshMode:
 move.l   dsa_win,a0
 move.l   #(IDCMP_MENUPICK|IDCMP_RAWKEY),d0      ; window event filter
 CALLINT  ModifyIDCMP
mnrm_1:
 movea.l  dsa_win,a0
 move.l   wd_UserPort(a0),a0
 CALLEXEC GetMsg
 tst.l    d0
 beq      mnrm_3
 movea.l  d0,a1
 move.l   im_Class(a1),d0
 tst.l    d0                      ; no event ?
 beq      mnrm_3

 move.l   d0,-(a7)
 CALLEXEC ReplyMsg
 move.l   (a7)+,d0

 btst     #8,d0                   ; test MENUPICK event
 bne      mnrm_2
 btst     #10,d0                  ; test RAWKEY event
 bne      mnrm_2

mnrm_3:
 bsr      mn_GetOsc
 bsr      refresh_task

 moveq.l  #25,d1
 CALLDOS  Delay           ; wait 0.5 sec
 bra      mnrm_1

mnrm_2:                   ; exit from autorefresh mode
 movea.l  dsa_scr,a0
 CALLINT  DisplayBeep
 moveq.l  #$ff,d0     ; no exit
 move.l   dsa_win,a0
 move.l   #default_idcmp,d0        ; window event filter
 CALLINT  ModifyIDCMP
 rts



;--------------------------------------------------------------------------

mn_InitOsc:
 lea      dsa_action_init,a4
 lea      ide_cmd,a5
 CALLEXEC Supervisor
 moveq.l  #$ff,d0     ; no exit
 rts



;--------------------------------------------------------------------------

mn_StartOsc:
 lea      dsa_action_start,a4
 lea      ide_cmd,a5
 CALLEXEC Supervisor
 moveq.l  #$ff,d0     ; no exit
 rts



;--------------------------------------------------------------------------

mn_StopOsc:
 lea      dsa_action_stop,a4
 lea      ide_cmd,a5
 CALLEXEC Supervisor
 moveq.l  #$ff,d0     ; no exit
 rts



;--------------------------------------------------------------------------

mn_MakeOsc:
 bsr      alloc_hard_buf
 tst.l    d0
 beq      mnmo_1

 moveq.l  #16,d0
 move.l   #$10000,d1
 moveq.l  #1,d2
 bsr      make_dsa   ; d0 - quant of osc; d1 - osc lenght; d2 - osc type (1,2,3)
 tst.l    d0
 beq      mnmo_1

 lea      dsa_action_read,a4
 lea      ide_cmd,a5
 CALLEXEC Supervisor

 bsr      buf_to_osc

 st       calc_osc_pos_dis
 st       calc_gfx_pos_dis
 st       Refresh_gadget
 st       Refresh_text
 st       Refresh_gfx

mnmo_1:
 moveq.l  #$ff,d0     ; no exit
 rts



;--------------------------------------------------------------------------

alloc_hard_buf:
 moveq.l  #$ff,d0
 tst.l    hard_buf_mem
 bne      ahbu_1

 move.l   #$20000,d0
 moveq.l  #0,d1
 CALLEXEC AllocMem
 tst.l    d0
 bne      ahbu_2

 moveq.l  #10,d0
 bsr      WinErr
 moveq.l  #0,d0
 bra      ahbu_1

ahbu_2:
 move.l   d0,hard_buf_mem
 moveq.l  #$ff,d0

ahbu_1:
 rts



;--------------------------------------------------------------------------

buf_to_osc:
 moveq.l  #0,d1

btos_4:
 move.w   d1,regr_curosc
 clr.l    regr_curc

 move.w   d1,d0
 bsr      GetOscTextAdr
 move.b   #1,(a0)+
 move.b   #'o',(a0)+
 move.b   #'s',(a0)+
 move.b   #'c',(a0)+
 move.b   #'_',(a0)+
 cmp.b    #10,d0
 bcs      btos_4a
 addq.b   #7,d0
btos_4a:
 add.b    #'0',d0
 move.b   d0,(a0)+
 clr.b    (a0)

 move.l   d1,-(a7)
 bsr      GetOscGfxAdr
 move.l   (a7)+,d1
 
 move.l   hard_buf_mem,a1
 move.l   #($1000-1),d0
btos_5:
 move.w   #16-1,d4
btos_11:
 moveq.l  #0,d3
 rol.w    (a1)+
 bcc      btos_10
 moveq.l  #1,d3
btos_10:
 rol.w    d2
 andi.w   #$fffe,d2
 or.w     d3,d2
 dbf      d4,btos_11

 move.w   d2,(a0)+
 dbf      d0,btos_5

 addq.w   #1,d1
 cmpi.w   #16,d1
 bne      btos_4
 rts



;--------------------------------------------------------------------------
; not conflict ide action

ide_cmd:
 move.w   #$2700,sr        ; disable interrupt in supervisor state
 nop

 move.b   $da2018,d0
 nop
 move.b   d0,ide_mode      ; backup old value
 ori.b    #$10,d0
 move.b   d0,$da2018       ; slave select
 nop

 jsr      (a4)

 move.b   ide_mode,d0
 andi.b   #$ef,d0
 move.b   d0,$da2018       ; restore master hdd mode
 nop
 rte



;--------------------------------------------------------------------------

dsa_action_init:
 bsr      dsa_action_stop
 move.b   $da2004,d0       ; initial device
 nop
 rts



;--------------------------------------------------------------------------

dsa_action_start:
 move.b   $da2008,d0       ; start
 nop
 rts



;--------------------------------------------------------------------------

dsa_action_stop:
 move.b   $da200c,d0       ; stop
 nop
 rts



;--------------------------------------------------------------------------

dsa_action_read:
 bsr      dsa_action_stop
 move.b   $da2010,d0       ; counter reset
 nop
 lea      $da2000,a0
 move.l   hard_buf_mem,a1
 move.l   #($800-1),d0
dare_1:
 move.l   (a0),(a1)+       ; in any amiga one .l ide access -> two .w access ;-)
 move.l   (a0),(a1)+
 move.l   (a0),(a1)+
 move.l   (a0),(a1)+
 move.l   (a0),(a1)+
 move.l   (a0),(a1)+
 move.l   (a0),(a1)+
 move.l   (a0),(a1)+
 move.l   (a0),(a1)+
 move.l   (a0),(a1)+
 move.l   (a0),(a1)+
 move.l   (a0),(a1)+
 move.l   (a0),(a1)+
 move.l   (a0),(a1)+
 move.l   (a0),(a1)+
 move.l   (a0),(a1)+
 dbf      d0,dare_1
 rts



;--------------------------------------------------------------------------

select_pos:
 bsr      select_text_pos
 bsr      select_gfx_pos
 rts



;--------------------------------------------------------------------------

select_text_pos:
 tst.l    dsa_file_mem
 beq      setp_1
 move.l   dsa_file_mem,a0

 move.w   d0,d2
 sub.w    point_x,d2
 bmi      setp_1
 cmp.w    point_sx1,d2
 bcc      setp_1

 move.w   d1,d3
 sub.w    point_y,d3
 bmi      setp_1
 move.w   point_sy,d5
 and.w    #$fff8,d5       ; /8 *8
 cmp.w    d5,d3
 bcc      setp_1          ; jump if y-point_y >= point_sy & $fff8

 lsr.w    #3,d3           ; /8 (/vertical size)
 add.w    cur_osc_pos,d3
 cmp.w    max_osc_size,d3
 bcc      setp_1

 move.w   d3,dsah_LinCurOsc(a0)
 st       Refresh_text
 st       Refresh_gfx

setp_1:
 rts



;--------------------------------------------------------------------------

select_gfx_pos:
 tst.l    dsa_file_mem
 beq      segp_1
 move.l   dsa_file_mem,a0

 move.w   d0,d2
 sub.w    point_x,d2
 bmi      segp_1
 sub.w    point_sx1,d2
 bmi      segp_1
 move.w   point_sx2,d4
 cmp.w    d4,d2
 bcc      segp_1          ; jump if x-(point_x+point_sx1) >= point_sx2

 move.w   d1,d3
 sub.w    point_y,d3
 bmi      segp_1
 move.w   point_sy,d5
 and.w    #$fff8,d5       ; /8 *8
 cmp.w    d5,d3
 bcc      segp_1          ; jump if y-point_y >= point_sy & $fff8

 ext.l    d2
 divu.w   dsah_CurZoomPix(a0),d2
 ext.l    d2
 add.l    cur_gfx_pos,d2
 cmp.l    max_gfx_size,d2
 bcc      segp_1

 lsr.w    #3,d3           ; /8 (/vertical size)
 add.w    cur_osc_pos,d3
 cmp.w    max_osc_size,d3
 bcc      segp_1

 move.l   d2,dsah_LinCurC(a0)
 move.w   d3,dsah_LinCurOsc(a0)
 st       Refresh_text
 st       Refresh_gfx

segp_1:
 rts



;--------------------------------------------------------------------------

rk_zoom_outx2:
 tst.l    dsa_file_mem
 beq      rkzox2_1
 move.l   dsa_file_mem,a0
 cmpi.w   #1,dsah_CurZoomStp(a0)
 beq      rkzox2_2
 move.w   dsah_CurZoomStp(a0),d0
 lsr.w    #1,d0
 bne      rkzox2_4
 moveq.l  #1,d0
rkzox2_4:
 move.w   d0,dsah_CurZoomStp(a0)
 bra      rkzox2_3
rkzox2_2:
 cmpi.w   #128,dsah_CurZoomPix(a0)
 bge      rkzox2_1
 move.w   dsah_CurZoomPix(a0),d0
 lsl.w    #1,d0
 move.w   d0,dsah_CurZoomPix(a0)
rkzox2_3:
 st       Refresh_gadget
 st       Refresh_gfx
rkzox2_1:
 rts



;--------------------------------------------------------------------------

rk_zoom_out:
 tst.l    dsa_file_mem
 beq      rkzo_1
 move.l   dsa_file_mem,a0
 cmpi.w   #1,dsah_CurZoomStp(a0)
 beq      rkzo_2
 subi.w   #1,dsah_CurZoomStp(a0)
 bra      rkzo_3
rkzo_2:
 cmpi.w   #128,dsah_CurZoomPix(a0)
 bge      rkzo_1
 addi.w   #1,dsah_CurZoomPix(a0)
rkzo_3:
 st       Refresh_gadget
 st       Refresh_gfx
rkzo_1:
 rts



;--------------------------------------------------------------------------

rk_zoom_inx2:
 tst.l    dsa_file_mem
 beq      rkzix2_1
 move.l   dsa_file_mem,a0
 cmpi.w   #1,dsah_CurZoomPix(a0)
 bne      rkzix2_2
 cmpi.w   #128,dsah_CurZoomStp(a0)
 bge      rkzix2_1
 move.w   dsah_CurZoomStp(a0),d0
 lsl.w    #1,d0
 move.w   d0,dsah_CurZoomStp(a0)
 bra      rkzix2_3
rkzix2_2:
 move.w   dsah_CurZoomPix(a0),d0
 lsr.w    #1,d0
 bne      rkzix2_4
 moveq.l  #1,d0
rkzix2_4:
 move.w   d0,dsah_CurZoomPix(a0)
rkzix2_3:
 st       Refresh_gadget
 st       Refresh_gfx
rkzix2_1:
 rts



;--------------------------------------------------------------------------

rk_zoom_in:
 tst.l    dsa_file_mem
 beq      rkzi_1
 move.l   dsa_file_mem,a0
 cmpi.w   #1,dsah_CurZoomPix(a0)
 bne      rkzi_2
 cmpi.w   #128,dsah_CurZoomStp(a0)
 bge      rkzi_1
 addi.w   #1,dsah_CurZoomStp(a0)
 bra      rkzi_3
rkzi_2:
 subi.w   #1,dsah_CurZoomPix(a0)
rkzi_3:
 st       Refresh_gadget
 st       Refresh_gfx
rkzi_1:
 rts



;--------------------------------------------------------------------------

rk_osc_up:
 tst.l    dsa_file_mem
 beq      rkou_1

 move.l   dsa_file_mem,a0
 move.w   dsah_LinCurOsc(a0),d0
 beq      rkou_1
 subq.w   #1,d0
 move.w   d0,regr_curosc
 clr.l    regr_curc
 bsr      GetOscTextAdr
 move.l   a0,osc1_header
 move.b   (a0),osc1_type
 bsr      GetOscSize
 move.l   d0,osc1_len        ; in bytes
 bsr      GetOscGfxAdr  ; output: a0 - current data byte address; d0 - oscilogram type; d1 - current bit of current data byte (type 1 or 2)
 move.l   a0,osc1_data

 move.l   dsa_file_mem,a0
 move.w   dsah_LinCurOsc(a0),d0
 move.w   d0,regr_curosc
 clr.l    regr_curc
 bsr      GetOscTextAdr
 move.l   a0,osc2_header
 move.b   (a0),osc2_type
 bsr      GetOscSize
 move.l   d0,osc2_len        ; in bytes
 bsr      GetOscGfxAdr  ; output: a0 - current data byte address; d0 - oscilogram type; d1 - current bit of current data byte (type 1 or 2)
 move.l   a0,osc2_data

 bsr      swap_two_split_osc

 move.l   dsa_file_mem,a0
 subi.w   #1,dsah_LinCurOsc(a0)

 move.w   dsah_LinCurOsc(a0),d0
 cmp.w    cur_osc_pos,d0
 bcc      rkou_1
 moveq.l  #7,d0
 bsr      ma_gadget     ; up scroll osc

rkou_1:
 rts



;--------------------------------------------------------------------------

rk_osc_down:
 tst.l    dsa_file_mem
 beq      rkod_1

 move.l   dsa_file_mem,a0
 move.w   dsah_LinCurOsc(a0),d0
 addq.w   #1,d0
 cmp.w    dsah_OscQuant(a0),d0
 bcc      rkod_1                 ; jump if current osc - last osc
 subq.w   #1,d0
 move.w   d0,regr_curosc
 clr.l    regr_curc
 bsr      GetOscTextAdr
 move.l   a0,osc1_header
 move.b   (a0),osc1_type
 bsr      GetOscSize
 move.l   d0,osc1_len        ; in bytes
 bsr      GetOscGfxAdr  ; output: a0 - current data byte address; d0 - oscilogram type; d1 - current bit of current data byte (type 1 or 2)
 move.l   a0,osc1_data

 move.l   dsa_file_mem,a0
 move.w   dsah_LinCurOsc(a0),d0
 addq.w   #1,d0
 move.w   d0,regr_curosc
 clr.l    regr_curc
 bsr      GetOscTextAdr
 move.l   a0,osc2_header
 move.b   (a0),osc2_type
 bsr      GetOscSize
 move.l   d0,osc2_len        ; in bytes
 bsr      GetOscGfxAdr  ; output: a0 - current data byte address; d0 - oscilogram type; d1 - current bit of current data byte (type 1 or 2)
 move.l   a0,osc2_data

 bsr      swap_two_split_osc

 move.l   dsa_file_mem,a0
 addi.w   #1,dsah_LinCurOsc(a0)

 move.w   dsah_LinCurOsc(a0),d0
 move.w   cur_osc_pos,d1
 add.w    frame_osc_size,d1
 cmp.w    d1,d0
 bcs      rkou_1
 moveq.l  #6,d0
 bsr      ma_gadget     ; down scroll osc

rkod_1:
 rts



;--------------------------------------------------------------------------

rk_left_arrow:
 tst.l    dsa_file_mem
 beq      rkla_1

 move.l   dsa_file_mem,a0
 tst.l    dsah_LinCurC(a0)
 beq      rkla_1
 subi.l   #1,dsah_LinCurC(a0)
 st       Refresh_gadget
 st       Refresh_gfx

 move.l   dsah_LinCurC(a0),d0
 cmp.l    cur_gfx_pos,d0
 bcc      rkla_1

 moveq.l  #4,d0
 bsr      ma_gadget     ; left scroll osc
rkla_1:
 rts



;--------------------------------------------------------------------------

rk_right_arrow:
 tst.l    dsa_file_mem
 beq      rkra_1

 move.l   dsa_file_mem,a0
 move.l   dsah_LinCurC(a0),d0
 addq.l   #1,d0
 cmp.l    dsah_OscLen(a0),d0
 bcc      rkra_1                 ; jump if current vector - last vector
 addi.l   #1,dsah_LinCurC(a0)
 st       Refresh_gadget
 st       Refresh_gfx

 move.l   dsah_LinCurC(a0),d0
 move.l   cur_gfx_pos,d1
 add.l    frame_gfx_size,d1
 cmp.l    d1,d0
 bcs      rkra_1

 moveq.l  #5,d0
 bsr      ma_gadget     ; right scroll osc
rkra_1:
 rts



;--------------------------------------------------------------------------

rk_up_arrow:
 tst.l    dsa_file_mem
 beq      rkua_1

 move.l   dsa_file_mem,a0
 move.w   dsah_LinCurOsc(a0),d0
 beq      rkua_1

 subi.w   #1,dsah_LinCurOsc(a0)
 st       Refresh_gadget
 st       Refresh_text
 st       Refresh_gfx

 move.w   dsah_LinCurOsc(a0),d0
 cmp.w    cur_osc_pos,d0
 bcc      rkua_1
 moveq.l  #7,d0
 bsr      ma_gadget     ; up scroll osc

rkua_1:
 rts


;--------------------------------------------------------------------------

rk_down_arrow:
 tst.l    dsa_file_mem
 beq      rkda_1

 move.l   dsa_file_mem,a0
 move.w   dsah_LinCurOsc(a0),d0
 addq.w   #1,d0
 cmp.w    dsah_OscQuant(a0),d0
 bcc      rkda_1                 ; jump if current osc - last osc

 addi.w   #1,dsah_LinCurOsc(a0)
 st       Refresh_gadget
 st       Refresh_text
 st       Refresh_gfx

 move.w   dsah_LinCurOsc(a0),d0
 move.w   cur_osc_pos,d1
 add.w    frame_osc_size,d1
 cmp.w    d1,d0
 bcs      rkou_1
 moveq.l  #6,d0
 bsr      ma_gadget     ; down scroll osc

rkda_1:
 rts



;--------------------------------------------------------------------------

swap_two_split_osc:
 tst.b    osc1_type
 beq      swto_7
 tst.b    osc2_type
 beq      swto_7

 move.l   osc1_len,d0
 moveq.l  #0,d1
 CALLEXEC AllocMem
 bne      swto_2
 moveq.l  #10,d0
 bsr      WinErr
 bra      swto_1
swto_2:
 move.l   d0,a1
 move.l   d0,d1          ; backup memory pointer
 move.l   osc1_len,d0
 move.l   osc1_data,a0

swto_3:
 move.b   (a0)+,(a1)+    ; copy osc1 to temp buffer
 subq.l   #1,d0
 bne      swto_3

 move.l   osc2_data,a0
 move.l   osc2_len,d0
 move.l   osc1_data,a1

swto_4:
 move.b   (a0)+,(a1)+    ; copy osc2 to osc1
 subq.l   #1,d0
 bne      swto_4

 move.l   d1,a0
 move.l   osc1_len,d0

swto_5:
 move.b   (a0)+,(a1)+    ; copy temp buffer to osc2
 subq.l   #1,d0
 bne      swto_5

 move.l   d1,a1
 move.l   osc1_len,d0
 CALLEXEC FreeMem

swto_7:
 move.l   osc1_header,a0
 move.l   osc2_header,a1
 moveq.l  #(dsah_SIZEOF-1),d0

swto_6:
 move.b   (a0),d1
 move.b   (a1),(a0)+
 move.b   d1,(a1)+
 dbf      d0,swto_6

 st       Refresh_gadget
 st       Refresh_text
 st       Refresh_gfx

swto_1:
 rts



;--------------------------------------------------------------------------

GetOscSize:
 movem.l  d1/a0,-(a7)
 move.l   dsa_file_mem,a0
 move.l   a0,d0
 beq      gosi_1
 move.l   dsah_OscLen(a0),d1
 move.w   regr_curosc,d0
 bsr      GetOscTextAdr
 moveq.l  #0,d0
 tst.b    (a0)         ; empty osc ?
 beq      gosi_1
 cmpi.b   #1,(a0)      ; digital osc ?
 beq      gosi_11
 cmpi.b   #2,(a0)      ; universal osc ?
 beq      gosi_12
 cmpi.b   #3,(a0)      ; analog osc ?
 beq      gosi_1

gosi_11:
 move.l   d1,d0
 lsr.l    #3,d0
 andi.l   #$7,d1
 beq      gosi_1
 addq.l   #1,d0
 bra      gosi_1

gosi_12:
 move.l   d1,d0
 lsr.l    #1,d0
 andi.l   #$1,d1
 beq      gosi_1
 addq.l   #1,d0
 bra      gosi_1

gosi_13:
 move.l   d1,d0
 add.l    d1,d0

gosi_1:
 movem.l  (a7)+,d1/a0
 rts



;--------------------------------------------------------------------------

after_read:
 move.l   a0,-(a7)
 move.l   dsa_file_mem,a0
 move.w   dsah_CurOsc(a0),cur_osc_pos
 move.l   dsah_CurC(a0),cur_gfx_pos

 bsr      calc_max_gfx_size
 bsr      calc_frame_gfx_size
 bsr      calc_kgfx

 bsr      calc_max_osc_size
 bsr      calc_frame_osc_size
 bsr      calc_kosc

 moveq.l  #0,d0                 ; default gfx gadget pos
 move.l   kgfx,d1
 beq      afre_1
 move.l   d1,d0
 move.l   _MathieeesingbasBase,a6
 jsr      _LVOIEEESPFlt(a6)        ; d0->d0.ieee
 move.l   d0,-(a7)
 move.l   cur_gfx_pos,d0
 move.l   _MathieeesingbasBase,a6
 jsr      _LVOIEEESPFlt(a6)        ; d0->d0.ieee
 move.l   d0,-(a7)
 move.l   #$00010000,d0
 move.l   _MathieeesingbasBase,a6
 jsr      _LVOIEEESPFlt(a6)        ; d0->d0.ieee
 move.l   (a7)+,d1
 move.l   _MathieeesingbasBase,a6
 jsr      _LVOIEEESPMul(a6)        ; d0->d0.ieee
 move.l   (a7)+,d1
 move.l   _MathieeesingbasBase,a6
 jsr      _LVOIEEESPDiv(a6)        ; d0.ieee=d0.ieee/d1.ieee
 move.l   _MathieeesingbasBase,a6
 jsr      _LVOIEEESPFix(a6)        ; d0.ieee->d0
 cmpi.l   #$10000,d0
 bcs      afre_1
 move.w   #$ffff,d0
afre_1:
 move.w   d0,dsnw_pi03_pos

 moveq.l  #0,d0
 tst.w    kosc
 beq      afre_2
 move.w   cur_osc_pos,d0
 swap.w   d0                       ; lsl.l #16,d0
 divu.w   kosc,d0
afre_2:
 move.w   d0,dsnw_pi08_pos

 clr.w    cur_text_pos
 clr.w    dsnw_pi01_pos

 move.l   (a7)+,a0
 rts



;--------------------------------------------------------------------------

prepare_write:
 move.l   a0,-(a7)
 move.l   dsa_file_mem,a0
 move.w   cur_osc_pos,dsah_CurOsc(a0)
 move.l   cur_gfx_pos,dsah_CurC(a0)
 move.l   (a7)+,a0
 rts



;--------------------------------------------------------------------------

GetWinSize:
 move.l   #$4000,d4          ; (point_sx1*65536)/(point_sx1+point_sx2)=0.25
 move.l   dsa_file_mem,d0
 beq      gwsi_1
 move.l   d0,a1
 move.w   dsah_TextGfxZoom(a1),d4
gwsi_1:

 move.l   dsa_win,a0
 move.w   #8,point_x         ; left, top point x-coordinate
 move.w   #12,point_y        ; left, top point y-coordinate
 move.w   #32,point_sx1      ; minimum text field x-size
 move.w   #64,point_sx2      ; minimum graphic field x-size
 move.w   #32+64,point_sx    ; minimum summary work area x-size
 move.w   #40,point_sy       ; minimum work area y-size
 move.w   #18,point_sxb      ; gadget width
 move.w   #10,point_syb      ; gadget height

 move.w   wd_Width(a0),d0
 sub.w    point_x,d0         ; left window gadget width
 bmi      gwsi_3             ; jump if low width
 sub.w    point_sxb,d0             ; right window gadget width
 bmi      gwsi_3             ; jump if low width
 cmp.w    point_sx,d0        ; check for minimum width work area
 blt      gwsi_3             ; jump if current window x-size < minimum
 move.w   d0,point_sx        ; set new width
 cmpi.w   #$1000,d4
 bcs      gwsi_3
 cmpi.w   #$c000,d4
 bcs      gwsi_4
 move.w   #$c000,d4
 bra      gwsi_6
gwsi_3:
 move.w   #$1000,d4          ; set default sx1/sx2 at small width
gwsi_6:
 move.l   dsa_file_mem,d0
 beq      gwsi_4
 move.l   d0,a1
 move.w   d4,dsah_TextGfxZoom(a1)
gwsi_4:

 move.w   point_sx,d0
 mulu     d0,d4              ; calc text width
 swap.w   d4                 ; analog lsr.l #16,d4
 move.w   d4,point_sx1
 sub.w    d4,d0              ; calc graphics width
 move.w   d0,point_sx2

 move.w   wd_Height(a0),d1
 sub.w    point_y,d1         ; up window border
 bmi      gwsi_5             ; jump if low height
 sub.w    point_syb,d1       ; down window gadget height
 bmi      gwsi_5             ; jump if low height
 cmp.w    point_sy,d1        ; check for minimum width work area
 blt      gwsi_5             ; jump if current window x-size < minimum
 move.w   d1,point_sy
gwsi_5:

 rts



;---------------------------------------------------------------

ajust_field:
 move.l   dsa_win,a0
 move.l   #(IDCMP_MOUSEMOVE|IDCMP_MOUSEBUTTONS|IDCMP_GADGETUP),d0      ; window event filter
 CALLINT  ModifyIDCMP

ajfi_2:
 movea.l  dsa_win,a0
 move.l   wd_UserPort(a0),a0
 CALLEXEC WaitPort
 movea.l  dsa_win,a0
 move.l   wd_UserPort(a0),a0
 CALLEXEC GetMsg
 tst.l    d0
 beq      ajfi_2
 movea.l  d0,a1
 move.l   im_Class(a1),d0
 tst.l    d0                      ; no event ?
 beq      ajfi_2

 move.l   a1,-(a7)
 lea      int_msg_copy,a0
 move.w   #im_SIZEOF-1,d0

ajfi_6:
 move.b   (a1)+,(a0)+
 dbf      d0,ajfi_6

 move.l   (a7)+,a1
 CALLEXEC ReplyMsg
 lea      int_msg_copy,a1
 move.l   im_Class(a1),d0

 btst     #3,d0                   ; test MOUSEBUTTONS event
 bne      ajfi_1
 btst     #6,d0                   ; test GADGETUP event
 bne      ajfi_1
 btst     #4,d0                   ; test MOUSEMOVE event
 beq      ajfi_2

 move.w   im_MouseX(a1),d0
 bmi      ajfi_3
 cmp.w    point_x,d0
 beq      ajfi_3
 bcs      ajfi_3                  ; jump if im_MouseX < point_x
 move.w   point_x,d1
 add.w    point_sx,d1
 cmp.w    d1,d0
 bcc      ajfi_4
 move.w   d0,d2
 sub.w    point_x,d2              ; d2=x-point_x (new point_sx1)
 move.w   d1,d3
 sub.w    d0,d3                   ; d3=point_x+point_sx-x (new point_sx2)
 add.w    d2,d3
 swap.w   d2                      ; d2<<16
 clr.w    d2
 divu.w   d3,d2
 cmpi.w   #$1000,d2
 bcs      ajfi_3
 cmpi.w   #$c000,d2
 bcc      ajfi_4
 bra      ajfi_5
ajfi_3:
 move.w   #$1000,d2
 bra      ajfi_5
ajfi_4:
 move.w   #$c000,d2
ajfi_5:
 move.l   dsa_file_mem,a0
 move.w   d2,dsah_TextGfxZoom(a0)  ; save new relation

 bsr      GetWinSize
 bsr      AjustHGadget
 bsr      RefreshHGWorkWindow
 bra      ajfi_2

ajfi_1:
 bsr      GetWinSize
 bsr      AjustHGadget
 bsr      RefreshHGWorkWindow

 move.l   dsa_win,a0
 move.l   #default_idcmp,d0        ; window event filter
 CALLINT  ModifyIDCMP
 rts



;---------------------------------------------------------------

AjustHGadget:
 bsr      correct_zoom_cur_osc
 bsr      calc_max_text_size
 bsr      calc_frame_text_size
 bsr      calc_ktext
 bsr      calc_cur_text_pos

 bsr      calc_max_gfx_size
 bsr      calc_frame_gfx_size
 bsr      calc_kgfx
 bsr      calc_cur_gfx_pos

 bsr      calc_max_osc_size
 bsr      calc_frame_osc_size
 bsr      calc_kosc
 bsr      calc_cur_osc_pos

 move.l   dsa_win,a1

 lea      dsnw_g01,a0
 move.w   point_x,d0
 move.w   d0,gg_LeftEdge(a0)
 move.w   point_sx1,d0
 subq.w   #4,d0
 move.w   d0,gg_Width(a0)

 moveq.l  #$ff,d0             ; default gadget size
 move.w   max_text_size,d1
 beq      ajhg_1
 cmp.w    frame_text_size,d1
 bcs      ajhg_1              ; jump if real size < frame size
 moveq.l  #0,d0
 move.w   frame_text_size,d0
 mulu.w   #$ffff,d0
 divu     max_text_size,d0
ajhg_1:
 move.w   d0,dsnw_pi01_step


 lea      dsnw_g02,a0
 move.w   point_x,d0
 add.w    point_sx1,d0
 subq.w   #2,d0
 move.w   d0,gg_LeftEdge(a0)
 move.w   #8,gg_Width(a0)


 lea      dsnw_g03,a0
 move.w   point_x,d0
 add.w    point_sx1,d0
 addq.w   #4,d0
 move.w   d0,gg_LeftEdge(a0)
 move.w   point_sx2,d0
 subq.w   #4,d0
 sub.w    point_sxb,d0
 sub.w    point_sxb,d0
 move.w   d0,gg_Width(a0)

 moveq.l  #$ff,d0             ; default gadget size
 move.l   max_gfx_size,d1
 beq      ajhg_2
 cmp.l    frame_gfx_size,d1
 bcs      ajhg_2              ; jump if real size < frame size
 movem.l  a0/a1,-(a7)
 move.l   frame_gfx_size,d0
 mulu.w   #$ffff,d0
 andi.l   #$7fffffff,d0
 move.l   _MathieeesingbasBase,a6
 jsr      _LVOIEEESPFlt(a6)        ; d0->d0.ieee
 move.l   d0,-(a7)
 move.l   max_gfx_size,d0
 andi.l   #$7fffffff,d0
 move.l   _MathieeesingbasBase,a6
 jsr      _LVOIEEESPFlt(a6)
 move.l   d0,d1
 move.l   (a7)+,d0
 move.l   _MathieeesingbasBase,a6
 jsr      _LVOIEEESPDiv(a6)        ; d0.ieee=d0.ieee/d1.ieee
 move.l   _MathieeesingbasBase,a6
 jsr      _LVOIEEESPFix(a6)        ; d0.ieee->d0
 movem.l  (a7)+,a0/a1
ajhg_2:
 move.w   d0,dsnw_pi03_step
 lsr.w    #3,d0                    ; /8
 tst.w    d0
 bne      ajhg_4
 moveq.l  #1,d0
ajhg_4:
 move.w   d0,gfx_small_step


 moveq.l  #$ff,d0             ; default gadget size
 move.w   max_osc_size,d1
 beq      ajhg_3
 cmp.w    frame_osc_size,d1
 bcs      ajhg_3              ; jump if real size < frame size
 moveq.l  #0,d0
 move.w   frame_osc_size,d0
 mulu.w   #$ffff,d0
 divu     max_osc_size,d0
ajhg_3:
 move.w   d0,dsnw_pi08_step

 rts



;--------------------------------------------------------------

correct_zoom_cur_osc:
 move.l   d0,-(a7)
 tst.b    zoom_flag
 beq      czco_1
 sf       zoom_flag
 tst.l    dsa_file_mem
 beq      czco_1
 move.w   cur_osc_pos,d0
 add.w    frame_osc_size,d0
 cmp.w    max_osc_size,d0
 bcs      czco_1
 move.w   max_osc_size,d0
 sub.w    frame_osc_size,d0
 bpl      czco_2
 moveq.l  #0,d0
czco_2:
 move.w   d0,cur_osc_pos
czco_1:
 move.l   (a7)+,d0
 rts



;--------------------------------------------------------------

calc_max_text_size:
 movem.l  d0-d2/a0/a1,-(a7)
 moveq.l  #0,d1                   ; default max text size
 movea.l  dsa_file_mem,a0
 move.l   a0,d0
 beq      cmts_1                  ; jump if no oscilogram file in memory
 moveq.l  #0,d0                   ; clear current oscilogram counter

cmts_2:
 movea.l  dsa_file_mem,a0
 cmp.w    dsah_OscQuant(a0),d0
 beq      cmts_1                  ; jump if last osc or no osc
 bsr      GetOscTextAdr
 tst.b    (a0)+                   ; empty text line ?
 beq      cmts_3                  ; if yes - jump to next line
 move.l   a0,a1

cmts_4:
 tst.b    (a1)+
 bne      cmts_4

 suba.l   a0,a1
 move.l   a1,d2
 subq.l   #1,d2
 cmpi.l   #30,d2         ; string lenght > 30 symbols ?
 bcs      cmts_5
 moveq.l  #30,d2
cmts_5:
 cmp.w    d2,d1          ; compare current lenght (d2) and max lenght (d1)
 bcc      cmts_3         ; jump if current lenght <= max lenght
 move.w   d2,d1          ; install new max lenght

cmts_3:
 addq.l   #1,d0
 bra      cmts_2

cmts_1:
 move.w   d1,max_text_size
 movem.l  (a7)+,d0-d2/a0/a1
 rts



;--------------------------------------------------------------

calc_frame_text_size:
 move.l   d0,-(a7)
 move.w   point_sx1,d0
 lsr.w    #3,d0
 move.w   d0,frame_text_size
 move.l   (a7)+,d0
 rts



;--------------------------------------------------------------

calc_ktext:
 move.l   d0,-(a7)
 move.w   max_text_size,d0
 sub.w    frame_text_size,d0
 bpl      cakt_1
 clr.w    d0
cakt_1:
 addq.w   #1,d0
 move.w   d0,ktext
 move.l   (a7)+,d0
 rts



;--------------------------------------------------------------

calc_cur_text_pos:
 move.l   d0,-(a7)
 moveq.l  #0,d0
 move.w   ktext,d0
 mulu.w   dsnw_pi01_pos,d0
 swap.w   d0                      ; lsr.l    #16,d0
 move.w   d0,cur_text_pos
 move.l   (a7)+,d0
 rts



;--------------------------------------------------------------

calc_max_gfx_size:
 movem.l  d0/d1/a0,-(a7)
 clr.l    max_gfx_size
 move.l   dsa_file_mem,a0
 move.l   a0,d0
 beq      cmgs_1
 move.l   dsah_OscLen(a0),max_gfx_size
cmgs_1:
 movem.l  (a7)+,d0/d1/a0
 rts



;--------------------------------------------------------------

calc_frame_gfx_size:
 movem.l  d0/a0,-(a7)
 moveq.l  #0,d0
 move.w   point_sx2,d0
 lsr.l    #1,d0                       ; /2 (2-default CurZoomPiz)
 move.l   d0,frame_gfx_size
 move.l   dsa_file_mem,a0
 move.l   a0,d0
 beq      cfgs_1
 tst.w    dsah_CurZoomPix(a0)
 beq      cfgs_1
 moveq.l  #0,d0
 move.w   point_sx2,d0
 divu.w   dsah_CurZoomPix(a0),d0      ; calc frame_gfx_size in periods
 andi.l   #$0000ffff,d0
 move.l   d0,frame_gfx_size
cfgs_1:
 movem.l  (a7)+,d0/a0
 rts



;--------------------------------------------------------------

calc_kgfx:
 move.l   d0,-(a7)
 move.l   max_gfx_size,d0
 sub.l    frame_gfx_size,d0
 bpl      cakg_1
 clr.l    d0
cakg_1:
 addq.l   #1,d0
 move.l   d0,kgfx
 move.l   (a7)+,d0
 rts


;--------------------------------------------------------------

calc_cur_gfx_pos:
 movem.l  d0/d1,-(a7)
 tst.b    calc_gfx_pos_dis
 bne      ccgp_2
 moveq.l  #0,d0
 move.w   dsnw_pi03_pos,d0           ; read horiz scroll slider position
 move.l   d0,d1
 mulu.w   kgfx+2,d0                  ; mult. low part
 mulu.w   kgfx,d1                    ; mult. high part
 clr.w    d0
 swap.w   d0                         ; lsl.l #16,d1
 add.l    d0,d1                      ; (16*32)>>16
 btst     #31,d1
 beq      ccgp_1                     ; jump if no overflow
 move.l   #$7fffffff,d1              ; overflow
ccgp_1:
 move.l   d1,cur_gfx_pos
ccgp_2:
 sf       calc_gfx_pos_dis
 movem.l  (a7)+,d0/d1
 rts



;--------------------------------------------------------------

calc_max_osc_size:
 movem.l  d0/a0,-(a7)
 clr.w    max_osc_size
 move.l   dsa_file_mem,a0
 move.l   a0,d0
 beq      cmos_1
 move.w   dsah_OscQuant(a0),max_osc_size
cmos_1:
 movem.l  (a7)+,d0/a0
 rts



;--------------------------------------------------------------

calc_frame_osc_size:
 move.l   d0,-(a7)
 move.w   point_sy,d0
 lsr.w    #3,d0                   ; d0/8
 move.w   d0,frame_osc_size
 move.l   (a7)+,d0
 rts



;--------------------------------------------------------------

calc_kosc:
 move.l   d0,-(a7)
 move.w   max_osc_size,d0
 sub.w    frame_osc_size,d0
 bpl      cako_1
 clr.w    d0
cako_1:
 addq.w   #1,d0
 move.w   d0,kosc
 move.l   (a7)+,d0
 rts


;--------------------------------------------------------------

calc_cur_osc_pos:
 move.l   d0,-(a7)
 tst.b    calc_osc_pos_dis
 bne      ccop_1
 moveq.l  #0,d0
 move.w   kosc,d0
 mulu.w   dsnw_pi08_pos,d0        ; read vert scroll slider position
 swap.w   d0                      ; lsr.l    #16,d0
 move.w   d0,cur_osc_pos
ccop_1:
 move.l   (a7)+,d0
 rts



;--------------------------------------------------------------

RefreshHGWorkWindow:
 move.l   dsa_win,a0
 CALLINT  RefreshWindowFrame
 lea      dsnw_g01,a0
 move.l   dsa_win,a1
 suba.l   a2,a2
 CALLINT  RefreshGadgets
 rts



;-------------------------------------------------------------

ClearTextArea:
 move.l   dsa_win,a0
 move.l   wd_RPort(a0),a1
 moveq.l  #RP_JAM2,d0             ; set fill pen mode
 CALLGRAF SetDrMd

 move.l   dsa_win,a0
 move.l   wd_RPort(a0),a1
 moveq.l  #0,d0                   ; set pen to background color
 CALLGRAF SetAPen

 move.l   dsa_win,a0
 move.l   wd_RPort(a0),a1
 move.w   point_x,d0
 move.w   point_y,d1
 move.w   point_sx1,d2
 move.w   point_sy,d3
 add.w    d0,d2
 add.w    d1,d3
 subq.w   #1,d2
 subq.w   #1,d3
 CALLGRAF RectFill                ; fill rectangle of text area
 rts



;-------------------------------------------------------------

ClearGfxArea:
 move.l   dsa_win,a0
 move.l   wd_RPort(a0),a1
 moveq.l  #RP_JAM2,d0             ; set fill pen mode
 CALLGRAF SetDrMd

 move.l   dsa_win,a0
 move.l   wd_RPort(a0),a1
 moveq.l  #0,d0                   ; set pen to background color
 CALLGRAF SetAPen

 move.l   dsa_win,a0
 move.l   wd_RPort(a0),a1
 move.w   point_x,d0
 add.w    point_sx1,d0
 move.w   point_y,d1
 move.w   point_sx2,d2
 move.w   point_sy,d3
 add.w    d0,d2
 add.w    d1,d3
 subq.w   #1,d2
 subq.w   #1,d3
 CALLGRAF RectFill                ; fill rectangle of text area
 rts



;-------------------------------------------------------------

fill_rect:
 movem.l  d0-d4/a0-a1,-(a7)
 move.l   dsa_win,a0
 move.l   wd_RPort(a0),a1
 moveq.l  #RP_JAM2,d0             ; set fill pen mode
 CALLGRAF SetDrMd

 move.l   dsa_win,a0
 move.l   wd_RPort(a0),a1
 move.l   $10(a7),d0               ; set pen to background color
 CALLGRAF SetAPen

 move.l   dsa_win,a0
 move.l   wd_RPort(a0),a1
 move.l   (a7),d0
 move.l   4(a7),d1
 move.l   8(a7),d2
 move.l   $c(a7),d3
 add.w    d0,d2
 add.w    d1,d3
 subq.w   #1,d2
 subq.w   #1,d3
 CALLGRAF RectFill                ; fill rectangle of text area
 movem.l  (a7)+,d0-d4/a0/a1
 rts



;-------------------------------------------------------------

RedrawTexts:
 movea.l  dsa_file_mem,a0
 move.l   a0,d0
 beq      rete_2                  ; jump if no oscilogram file in memory
 move.w   frame_osc_size,d1
 beq      rete_2
 move.w   cur_osc_pos,d0
 move.w   #0,d2                   ; offset relative point_y

rete_1:
 cmp.w    dsah_OscQuant(a0),d0    ; check - current oscilogram exist ?
 bge      rete_2                  ; jump if no
 cmp.w    point_sy,d2             ; check - end of window for current oscilogram
 bge      rete_2                  ; jump if no space for current oscilogram
 movem.l  d0-d2/a0,-(a7)

 bsr      GetOscTextAdr
 tst.b    (a0)+                   ; empty text line ?
 beq      rete_3
 tst.w    frame_text_size
 beq      rete_3                  ; jump if no space for visual symbols
 move.w   cur_text_pos,d0
 beq      rete_1a

rete_2a:
 tst.b    (a0)+                   ; dependet from slider
 beq      rete_3
 subq.w   #1,d0
 bne      rete_2a

rete_1a:
 lea      dsatt_t,a1              ; set destination string address
 move.w   frame_text_size,d0      ; max. - 31 symbol
 ext.l    d0
 bsr      CopyString1

 move.l   dsa_file_mem,a2
 movea.l  dsa_win,a0
 movea.l  wd_RPort(a0),a0         ; window RastPort
 lea      dsa_TempText,a1         ; IntuiText structure

 move.b   custom_text_pen,(a1)
 move.l   (a7),d3                 ; restore d0 from stack
 cmp.w    dsah_LinCurOsc(a2),d3
 bne      rete_1b
 move.b   select_text_pen,(a1)
rete_1b:

 move.w   point_x,d0              ; x coord
 move.w   point_y,d1              ; y coord
 add.w    d2,d1                   ; + offset y coord
 CALLINT  PrintIText
rete_3:
 movem.l  (a7)+,d0-d2/a0
 addq.w   #1,d0                   ; next oscilogram
 addq.w   #8,d2                   ; increment vertical text offset
 subq.w   #1,d1                   ; decrement quantity oscilogram counter
 bne      rete_1
rete_2:
 rts

;-------------------------

GetOscTextAdr:
 move.l   d0,-(a7)
 movea.l  dsa_file_mem,a0
 adda.l   #dsah_SIZEOF,a0
 lsl.w    #5,d0                   ; *32 (oscilogram name field size)
 adda.w   d0,a0
 move.l   (a7)+,d0
 rts

;-------------------------

RedrawGraphics:
 movea.l  dsa_file_mem,a0
 move.l   a0,d0
 beq      regr_2                  ; jump if no oscilogram file in memory
 move.w   frame_osc_size,d1
 beq      regr_2
 move.w   cur_osc_pos,d0
 move.w   #0,d2                   ; offset relative point_y

regr_1:
 cmp.w    dsah_OscQuant(a0),d0    ; check - current oscilogram exist ?
 bge      regr_2                  ; jump if no
 cmp.w    point_sy,d2             ; check - end of window for current oscilogram
 bge      regr_2                  ; jump if no space for current oscilogram
 movem.l  d0-d2/a0,-(a7)
 move.w   d0,regr_curosc
 move.w   d2,regr_vert_offset
 move.l   cur_gfx_pos,regr_curc   ; current cycle

 bsr      GetOscGfxAdr            ; return: a0-address d0.b-type d1.b - bit num
 tst.b    d0                      ; empty graphics pointer ?
 beq      regr_3

 move.l   a0,regr_dataadr
 move.b   d0,regr_type
 move.b   d1,regr_bitnum          ; 7..0 (type 1) or 7,3 (type 2)

 move.w   point_x,d0
 add.w    point_sx1,d0            ; add size of text field
 move.w   d0,regr_x               ; set x coord of current symbol (_|)

 move.w   point_y,d0
 add.w    regr_vert_offset,d0     ; add vertical y offset (d2)
 move.w   d0,regr_y               ; set y coord of current symbol

 movea.l  dsa_file_mem,a0
 move.w   dsah_CurZoomPix(a0),regr_sx   ; set width of current symbol
 move.w   dsah_CurZoomStp(a0),regr_stp
 move.w   #7,regr_sy                    ; set maximum height of current symbol
 move.b   #2,regr_oldval                ; default: no jump
 clr.w    regr_oldlev                   ; default: zero analog level

 move.w   regr_x,d0
 move.w   regr_y,d1
 move.w   point_sx2,d2
 subq.w   #1,d2
 move.w   regr_sy,d3
 moveq.l  #0,d4
 move.b   gfx_bg_pen,d4
 bsr      fill_rect

regr_4:                           ; begin horizontal line cycle
 bsr      GetOscData              ; return: a0-pointer to pixel array for draw

regr_5:
 move.b   (a0)+,d0                ; test end of symbol sequence
 beq      regr_3                  ; jump to end of symbol sequence (line)
 cmp.b    #1,d0                   ; test end of current symbol
 beq      regr_4                  ; jump to next symbol

 movea.l  dsa_win,a1
 movea.l  wd_RPort(a1),a1         ; window RastPort
 move.b   (a0)+,d0
 move.l   a0,-(a7)
 CALLGRAF SetAPen                 ; set color pen of line
 movea.l  (a7)+,a0                ; restore old a0 value

 movea.l  dsa_win,a1
 movea.l  wd_RPort(a1),a1         ; window RastPort
 move.w   (a0)+,d0
 move.w   (a0)+,d1
 move.l   a0,-(a7)
 CALLGRAF Move                    ; set graphics pen to first coord
 movea.l  (a7)+,a0                ; restore old a0 value

 movea.l  dsa_win,a1
 movea.l  wd_RPort(a1),a1         ; window RastPort
 move.w   (a0)+,d0
 move.w   (a0)+,d1
 move.l   a0,-(a7)
 CALLGRAF Draw                    ; draw element
 movea.l  (a7)+,a0
 bra      regr_5

regr_3:
 movem.l  (a7)+,d0-d2/a0
 addq.w   #1,d0                   ; next oscilogram
 addq.w   #8,d2                   ; increment vertical text offset
 subq.w   #1,d1                   ; decrement quantity oscilogram counter
 bne      regr_1
regr_2:
 rts

;----------------------------------------------
;
; line:             ---- 2 Elements in Symbol1
;                  / /
;         ------  / /  ---------
;              |<- /   |       |
;              ---------       ----
;              ^^^^^^^^
;              Symbol1 ^^^^^^^^
;                       Symbol2
;
;----------------------------------------------

; get pen and coords current symbol and test end of line
; generate data array of pen and coords

GetOscData:
 lea      regr_buf,a0
 movea.l  dsa_file_mem,a1
 clr.b    (a0)                    ; default action: end of symbol sequence

 move.l   dsah_OscLen(a1),d0
 cmp.l    regr_curc,d0            ; current symbol is the last ?
 ble      geod1                   ; jump if yes

 move.w   point_x,d0
 add.w    point_sx1,d0
 add.w    point_sx2,d0
 cmp.w    regr_x,d0               ; current symbol out of screen ?
 ble      geod1                   ; jump if yes

 move.w   regr_x,d1
 sub.w    d1,d0                   ; calc real max. width for current symbol
 cmp.w    regr_sx,d0              ; current max. width > real max. width ?
 bgt      geod4                   ; jump if no
 move.w   d0,regr_sx              ; set width size
geod4:

 move.l   dsa_file_mem,a2
 move.l   dsah_LinCurC(a2),d2
 cmp.l    regr_curc,d2            ; select line on current symbol ?
 bne      geod_4a
 move.w   dsah_LinCurOsc(a2),d2
 moveq.l  #0,d4
 cmp.w    regr_curosc,d2          ; select osc on current osc ?
 bne      geod_4b
 moveq.l  #1,d4
geod_4b:

 move.w   regr_sx,d2
 moveq.l  #1,d3                   ; offset=1
 cmp.w    #3,d2
 bcs      geod_4c
 move.w   d2,d3
 lsr.w    #1,d3                   ; offset=element_width/2
geod_4c:
 add.w    regr_x,d3

 move.b   #2,(a0)+                ; flag - current coord present
 move.b   mark_vert_pen,(a0)+
 move.w   d3,(a0)+                ; draw vertical line
 move.w   regr_y,(a0)+
 move.w   d3,(a0)+
 move.w   regr_y,d0
 add.w    regr_sy,d0
 move.w   d0,(a0)+

 tst.b    d4
 beq      geod_4a

 move.b   #2,(a0)+                ; flag - current coord present
 move.b   mark_vert_sel_pen,(a0)+
 move.w   d3,(a0)+                ; draw osc-select vertical line
 move.w   regr_y,(a0)+
 move.w   d3,(a0)+
 move.w   regr_y,d0
 add.w    regr_sy,d0
 subq.w   #1,d0
 move.w   d0,(a0)+

geod_4a:
 cmp.b    #2,regr_type            ; 4 bit value (16 different format of signal)
 beq      geod2
 cmp.b    #3,regr_type            ; 16 bit analog signal
 beq      geod3
 cmp.b    #1,regr_type            ; two level digital signal (0 and 1 value only)
 bne      geod1

; type 1 - two level digital output

 movea.l  regr_dataadr,a2
 move.b   regr_bitnum,d0
 moveq.l  #0,d1
 btst     d0,(a2)
 beq      geod5
 moveq.l  #1,d1
geod5:
 cmp.b    #2,regr_oldval          ; first oscilogram ?
 beq      geod6                   ; no level to level vertical line
 cmp.b    regr_oldval,d1          ; different old and current signal level ?
 beq      geod6                   ; no level to level vertical line

 move.b   #2,(a0)+                ; flag - current coord present
 move.b   jump_dig_pen,(a0)+
 move.w   regr_x,(a0)+            ; draw vertical line
 move.w   regr_y,(a0)+
 move.w   regr_x,(a0)+
 move.w   regr_y,d0
 add.w    regr_sy,d0
 subq.w   #1,d0
 move.w   d0,(a0)+

geod6:
 move.b   d1,regr_oldval          ; store current value

 move.b   #2,(a0)+                ; flag - current symbol present
 move.b   dig_pen,(a0)+
 move.w   regr_x,(a0)+
 move.w   regr_y,d0
 tst.b    d1
 bne      geod7                   ; jump if high signal level
 add.w    regr_sy,d0
 subq.w   #1,d0
geod7:
 move.w   d0,d2
 move.w   d0,(a0)+
 move.w   regr_x,d0
 add.w    regr_sx,d0
 subq.w   #1,d0
 move.w   d0,(a0)+
 move.w   d2,(a0)+
 move.b   #1,(a0)                 ; flag - go to next symbol

 move.w   regr_stp,d1             ; set counter for increment address
geod9:                            ; increment address cycle
 move.b   regr_bitnum,d0
 subq.b   #1,d0
 bpl      geod8                   ; jump if no byte limit
 lea      regr_dataadr,a0
 addq.l   #1,(a0)                 ; increment data pointer
 moveq.l  #7,d0                   ; set bit pointer to msb
geod8:
 move.b   d0,regr_bitnum
 subq.w   #1,d1
 bne      geod9

 move.w   regr_stp,d0
 ext.l    d0
 lea      regr_curc,a0
 add.l    d0,(a0)                 ; increment current cycle value
 move.w   regr_sx,d0
 add.w    d0,regr_x               ; increment x-coord
 bra      geod1

; type 2 - 16 diferent signal in 4 bit data

geod2:
 movea.l  regr_dataadr,a2
 move.b   (a2),d0
 move.b   d0,d1
 andi.b   #$0f,d1
 cmpi.b   #7,regr_bitnum
 bne      geod10
 move.b   d0,d1
 lsr.b    #4,d1
geod10:
 lea      sig_array,a2
 move.b   d1,d0
 ext.w    d0
 lsl.w    #4,d0
 adda.w   d0,a2                   ; get pointer to signal

 move.b   sm_JumpDetect(a2),d1
 cmp.b    #2,d1                   ; not jumped symbol ?
 beq      geod11                  ; no level to level vertical line
 cmpi.b   #2,regr_oldval
 beq      geod11
 cmp.b    regr_oldval,d1          ; different old and current signal level ?
 beq      geod11                  ; no level to level vertical line

 move.b   #2,(a0)+                ; flag - current element present
 move.b   sm_JumpPen(a2),(a0)+
 move.w   regr_x,(a0)+            ; draw vertical line
 move.w   regr_y,(a0)+
 move.w   regr_x,(a0)+
 move.w   regr_y,d0
 add.w    regr_sy,d0
 subq.w   #1,d0
 move.w   d0,(a0)+

geod11:
 move.b   d1,regr_oldval          ; store current jump flag value
 tst.b    sm_LinQuant(a2)
 beq      geod12

 move.b   #2,(a0)+                ; flag - current element present
 move.b   sm_Lin1Pen(a2),(a0)+
 move.w   sm_Lin1Val(a2),d2
 move.w   regr_sy,d3
 subq.w   #1,d3
 mulu.w   d3,d2
 divu     #$ffff,d2               ; get real level in pixels
 move.w   regr_x,(a0)+
 move.w   regr_y,d0
 add.w    regr_sy,d0
 subq.w   #1,d0
 sub.w    d2,d0
 move.w   d0,(a0)+
 move.w   regr_x,d2
 add.w    regr_sx,d2
 subq.w   #1,d2
 move.w   d2,(a0)+
 move.w   d0,(a0)+
 move.b   #1,(a0)                 ; flag - go to next symbol

 cmp.b    #1,sm_LinQuant(a2)      ; one level elements ?
 beq      geod12

 move.b   #2,(a0)+                ; flag - current coord present
 move.b   sm_Lin2Pen(a2),(a0)+
 move.w   sm_Lin2Val(a2),d2
 mulu.w   d3,d2
 divu     #$ffff,d2               ; get real level in pixels
 move.w   regr_x,(a0)+
 move.w   regr_y,d0
 add.w    regr_sy,d0
 subq.w   #1,d0
 sub.w    d2,d0
 move.w   d0,(a0)+
 move.w   regr_x,d2
 add.w    regr_sx,d2
 subq.w   #1,d2
 move.w   d2,(a0)+
 move.w   d0,(a0)+
 move.b   #1,(a0)                 ; flag - go to next symbol

geod12:
 move.w   regr_stp,d1             ; set counter for increment address
geod13:                           ; increment address cycle
 move.b   regr_bitnum,d0
 subq.b   #4,d0
 bpl      geod14                  ; jump if no byte limit
 lea      regr_dataadr,a0
 addq.l   #1,(a0)                 ; increment data pointer
 moveq.l  #7,d0                   ; set bit pointer to msb
geod14:
 move.b   d0,regr_bitnum
 subq.w   #1,d1
 bne      geod13

 move.w   regr_stp,d0
 ext.l    d0
 lea      regr_curc,a0
 add.l    d0,(a0)                 ; increment current cycle value
 move.w   regr_sx,d0
 add.w    d0,regr_x               ; increment x-coord
 bra      geod1

; type 3 - analog 16 bit signal

geod3:
 move.b   #2,(a0)+                ; flag - current element present
 move.b   analog_pen,(a0)+
 move.w   regr_oldlev,d0          ; read old analog level value
 ext.l    d0
 move.w   regr_sy,d1
 subq.w   #1,d1
 divu     d1,d0                   ; get real level in pixels
 move.w   d0,d2
 move.w   regr_x,(a0)+
 move.w   regr_y,d0
 add.w    regr_sy,d0
 subq.w   #1,d0
 sub.w    d2,d0
 move.w   d0,(a0)+

 move.w   regr_x,d2
 add.w    regr_sx,d2
 subq.w   #1,d2
 move.w   d2,(a0)+
 movea.l  regr_dataadr,a2
 move.b   (a2)+,d0                ; read high byte of signal level
 lsl.w    #8,d0
 move.b   (a2)+,d0                ; read low byte of signal level
 ext.l    d0
 move.w   regr_sy,d1
 subq.w   #1,d1
 divu     d1,d0                   ; get real level in pixels
 move.w   d0,d2
 move.w   regr_y,d0
 add.w    regr_sy,d0
 subq.w   #1,d0
 sub.w    d2,d0
 move.w   d0,(a0)+
 move.b   #1,(a0)                 ; flag - go to next symbol

 move.w   regr_stp,d1             ; set counter for increment address
geod15:
 lea      regr_dataadr,a0
 addq.l   #2,(a0)                 ; increment data pointer
 subq.w   #1,d1
 bne      geod15

 move.w   regr_stp,d0
 ext.l    d0
 lea      regr_curc,a0
 add.l    d0,(a0)                 ; increment current cycle value
 move.w   regr_sx,d0
 add.w    d0,regr_x               ; increment x-coord
 bra      geod1

geod1:
 lea      regr_buf,a0
 rts



;-------------------------
; output:
; a0 - current data byte address
; d0 - oscilogram type
; d1 - current bit of current data byte (need in type 1 and 2)

GetOscGfxAdr:
 movem.l  d2-d6/a1/a2,-(a7)
 movea.l  dsa_file_mem,a0
 moveq.l  #0,d0
 move.w   dsah_OscQuant(a0),d2
 beq      goga_4                  ; jump if no oscilogram
 move.l   dsah_OscLen(a0),d3
 beq      goga_4                  ; jump if zero oscilogram cycles
 adda.w   #dsah_SIZEOF,a0
 movea.l  a0,a2                   ; set header pointer
 lsl.w    #5,d2
 adda.w   d2,a0
 moveq.l  #0,d5                   ; first oscilogram
 move.w   regr_curosc,d2          ; destination oscilogram number

goga_8:                           ; begin of oscilogram cycle
 movea.l  a0,a1                   ; backup old pointer value
 move.b   (a2),d0                 ; get oscilogram type
 tst.b    d0
 beq      goga_5                  ; jump if empty line (zero lenght)
 cmp.b    #1,d0                   ; digital signal (2 bit) ?
 beq      goga_1
 cmp.b    #2,d0                   ; mix signal (4 bit) ?
 beq      goga_2
 cmp.b    #3,d0                   ; analog signal (16 bit) ?
 beq      goga_3
goga_5:
 moveq.l  #0,d0
 bra      goga_4                  ; jump to empty line (not known signal type)

goga_1:
 move.l   d3,d4
 lsr.l    #3,d4
 add.l    d4,a0
 moveq.l  #7,d1
 and.l    d3,d1
 beq      goga_6
 adda.w   #1,a0                   ; get next addres if bit(s) used
 bra      goga_6

goga_2:
 move.l   d3,d4
 lsr.l    #1,d4
 add.l    d4,a0
 moveq.l  #1,d1
 and.l    d3,d1
 beq      goga_6
 adda.w   #1,a0                   ; get next addres if bit(s) used
 bra      goga_6

goga_3:
 move.l   d3,d4
 lsl.l    #1,d4
 add.l    d4,a0
 bra      goga_6

goga_6:
 moveq.l  #1,d4
 move.l   a0,d6
 and.l    d6,d4
 beq      goga_7                  ; jump if even address
 adda.w   #1,a0                   ; get even address
goga_7:
 move.w   d5,d4
 addq.w   #1,d5                   ; increment oscilogram number
 adda.w   #32,a2                  ; increment header lenght to text pointer
 cmp.w    d2,d4
 bne      goga_8
 movea.l  a1,a0                   ; restore pointer to destination oscilogram

; calculate data offset relative current oscilogram cycle
 move.l   regr_curc,d3
 cmpi.b   #1,d0
 beq      goga_11
 cmpi.b   #2,d0
 beq      goga_12
 cmpi.b   #3,d0
 beq      goga_13
 bra      goga_4

goga_11:
 move.l   d3,d4
 lsr.l    #3,d4
 add.l    d4,a0
 move.l   d3,d1
 and.l    #7,d1
 eor.l    #7,d1
 bra      goga_4

goga_12:
 move.l   d3,d4
 lsr.l    #1,d4
 add.l    d4,a0
 moveq.l  #7,d1
 move.l   d3,d4
 andi.l   #1,d4
 beq      goga_4
 moveq.l  #3,d1
 bra      goga_4

goga_13:
 move.l   d3,d4
 lsl.l    #1,d4
 add.l    d4,a0
 bra      goga_4

goga_4:
 movem.l  (a7)+,d2-d6/a1/a2
 rts


;--------------------------------------------------------------------------

prepare_dsa2hst:
 movem.l  d1-d4/a0,-(a7)
 moveq.l  #0,d0
 moveq.l  #0,d1             ; osc for convert count
prdh_3:
 move.l   dsa_file_mem,a0
 cmp.w    dsah_OscQuant(a0),d0
 beq      prdh_1
 bsr      GetOscTextAdr
 cmpi.b   #1,(a0)
 beq      prdh_2
 cmpi.b   #2,(a0)
 beq      prdh_2
 addq.w   #1,d0
 bra      prdh_3
prdh_2:
 addq.w   #1,d0
 addq.w   #1,d1
 bra      prdh_3
prdh_1:
 moveq.l  #0,d0
 tst.w    d1
 beq      prdh_4     ; jump if not osc for export
 bsr      calc_max_text_size
 move.l   dsa_file_mem,a0
 move.l   dsah_OscLen(a0),d2
 move.l   d1,d3
 lsl.l    #6,d3      ; osc*64
 add.l    #64,d3
 move.l   d1,d4
 addq.l   #4,d4
 mulu.w   max_text_size,d4
 add.l    d4,d3      ; +[(4+osc)*(max(osc))]
 move.l   d4,export_real_size
 move.l   d4,export_text_size
 add.l    d1,d3      ; +osc
 addq.l   #6,d3
 move.l   d1,d4
 addq.l   #4,d4
 move.w   d1,export_osc
 moveq.l  #0,d1
prdh_5:
 add.l    d2,d1      ; +[(osc+4)*osc_len]
 subq.l   #1,d4
 bne      prdh_5
 add.l    d1,export_real_size
 move.l   d1,export_gfx_size
 add.l    d1,d3
 move.l   d3,export_file_size
 moveq.l  #$ff,d0
prdh_4:
 movem.l  (a7)+,d1-d4/a0
 rts



;--------------------------------------------------------------------------

dsa2hst:
 movem.l  d1-d4/a0,-(a7)

 move.l   export_file_mem,a0
 move.l   export_file_size,d0
 move.b   #' ',d1
dshs_6:
 move.b   d1,(a0)+
 subq.l   #1,d0
 bne      dshs_6

 moveq.l  #0,d0
 moveq.l  #1,d1                ; current export cycle
 move.l   export_file_mem,a1
dshs_3:
 move.l   dsa_file_mem,a0
 cmp.w    dsah_OscQuant(a0),d0
 beq      dshs_1
 bsr      GetOscTextAdr
 cmpi.b   #1,(a0)
 beq      dshs_2
 cmpi.b   #2,(a0)
 beq      dshs_2
 addq.w   #1,d0
 bra      dshs_3
dshs_2:
 move.b   #';',(a1)+
 move.b   #' ',(a1)+
 move.b   #'p',(a1)+
 move.b   #'o',(a1)+
 move.b   #'s',(a1)+
 move.b   #'i',(a1)+
 move.b   #'t',(a1)+
 move.b   #'i',(a1)+
 move.b   #'o',(a1)+
 move.b   #'n',(a1)+
 move.b   #' ',(a1)+
 addi.l   #11,export_real_size
 sf       d3                    ; reset first non-zero-digit value flag
 move.l   d1,d2

 divu.w   #10000,d2
 tst.w    d2
 bne      dshs_c5x
 tst.b    d3
 beq      dshs_c4
dshs_c5x:
 st       d3
 move.b   d2,d4
 add.b    #'0',d4
 move.b   d4,(a1)+
 addi.l   #1,export_real_size

dshs_c4:
 swap.w   d2
 ext.l    d2
 divu.w   #1000,d2
 tst.w    d2
 bne      dshs_c4x
 tst.b    d3
 beq      dshs_c3
dshs_c4x:
 st       d3
 move.b   d2,d4
 add.b    #'0',d4
 move.b   d4,(a1)+
 addi.l   #1,export_real_size

dshs_c3:
 swap.w   d2
 ext.l    d2
 divu.w   #100,d2
 tst.w    d2
 bne      dshs_c3x
 tst.b    d3
 beq      dshs_c2
dshs_c3x:
 st       d3
 move.b   d2,d4
 add.b    #'0',d4
 move.b   d4,(a1)+
 addi.l   #1,export_real_size

dshs_c2:
 swap.w   d2
 ext.l    d2
 divu.w   #10,d2
 tst.w    d2
 bne      dshs_c2x
 tst.b    d3
 beq      dshs_c1
dshs_c2x:
 st       d3
 move.b   d2,d4
 add.b    #'0',d4
 move.b   d4,(a1)+
 addi.l   #1,export_real_size

dshs_c1:
 swap.w   d2
 move.b   d2,d4
 add.b    #'0',d4
 move.b   d4,(a1)+
 addi.l   #1,export_real_size

 move.b   #' ',(a1)+
 move.b   #'"',(a1)+
 addi.l   #2,export_real_size

 adda.w   #1,a0
dshs_5:
 move.b   (a0)+,d2
 beq      dshs_4
 move.b   d2,(a1)+
 addi.l   #1,export_real_size
 bra      dshs_5
dshs_4:

 move.b   #'"',(a1)+
 move.b   #' ',(a1)+
 move.b   #'S',(a1)+
 move.b   #$0d,(a1)+
 move.b   #$0a,(a1)+
 addi.l   #5,export_real_size
 addq.w   #1,d0
 addq.w   #1,d1
 bra      dshs_3

; user info
dshs_1:
 move.b   #';',(a1)+
 move.b   #' ',(a1)+
 move.b   #$0d,(a1)+
 move.b   #$0a,(a1)+
 addi.l   #4,export_real_size

 moveq.l  #0,d0
 moveq.l  #0,d1                ; current_export_cycle-1
 move.l   a1,a2

dshs_13:
 move.l   dsa_file_mem,a0
 cmp.w    dsah_OscQuant(a0),d0
 beq      dshs_11
 bsr      GetOscTextAdr
 cmpi.b   #1,(a0)
 beq      dshs_12
 cmpi.b   #2,(a0)
 beq      dshs_12
 addq.w   #1,d0
 bra      dshs_13

dshs_12:
 adda.w   #1,a0
 moveq.l  #0,d2
 move.w   export_osc,d2
 move.l   a2,a1
dshs_14:
 move.b   (a0)+,d3
 beq      dshs_13a
 move.b   #';',(a1)+
 move.b   #' ',(a1)+
 move.b   d3,(a1,d1.w)
 adda.l   d2,a1
 move.b   #$0d,(a1)+
 move.b   #$0a,(a1)+
 bra      dshs_14

dshs_13a:
 addq.w   #1,d0
 addq.w   #1,d1
 bra      dshs_13

dshs_11:
 move.l   a2,a1
 adda.l   export_text_size,a1

 move.b   #';',(a1)+
 move.b   #' ',(a1)+
 move.b   #$0d,(a1)+
 move.b   #$0a,(a1)+
 move.b   #';',(a1)+
 move.b   #' ',(a1)+
 addi.l   #6,export_real_size

; gfx-vectors data
 move.w   export_osc,d0
dshs_20
 move.b   #'-',(a1)+
 addi.l   #1,export_real_size
 dbf      d0,dshs_20

 move.b   #$0d,(a1)+
 move.b   #$0a,(a1)+
 addi.l   #2,export_real_size

 moveq.l  #0,d0
 moveq.l  #0,d1    ; export_osc_number-1
 move.l   a1,a2

dshs_23:
 move.l   dsa_file_mem,a0
 move.l   dsah_OscLen(a0),d3
 cmp.w    dsah_OscQuant(a0),d0
 beq      dshs_21
 bsr      GetOscTextAdr
 cmpi.b   #1,(a0)
 beq      dshs_22
 cmpi.b   #2,(a0)
 beq      dshs_22
 addq.w   #1,d0
 bra      dshs_23

dshs_22:
 movem.l  d0/d1,-(a7)
 move.w   d0,regr_curosc
 clr.l    regr_curc
 bsr      GetOscGfxAdr  ; output: a0 - current data byte address; d0 - oscilogram type; d1 - current bit of current data byte (type 1 or 2)
 moveq.l  #0,d2
 move.w   export_osc,d2
 move.l   a2,a1

dshs_24:
 tst.l    d3
 beq      dshs_25
 cmpi.b   #1,d0        ; digital osc
 bne      dshs_26      ; jump if universal osc

; digital osc
 move.b   (a0),d5
 moveq.l  #'L',d4
 btst     d1,d5
 beq      dshs_28
 moveq.l  #'H',d4
dshs_28:
 subq.b   #1,d1
 bpl      dshs_27
 adda.w   #1,a0
 moveq.l  #7,d1
 bra      dshs_27

; universal osc
dshs_26:
 move.b   (a0),d5
 cmp.b    #7,d1
 bne      dshs_29
 lsr.b    #4,d5
 moveq.l  #3,d1
 bra      dshs_31
dshs_29:
 adda.w   #1,a0
 moveq.l  #7,d1
dshs_31:
 and.b    #$0f,d5
 moveq.l  #'L',d4
 tst.b    d5
 beq      dshs_30
 moveq.l  #'H',d4
 cmp.b    #1,d5
 beq      dshs_30
 moveq.l  #'0',d4
 cmp.b    #2,d5
 beq      dshs_30
 moveq.l  #'1',d4
 cmp.b    #3,d5
 beq      dshs_30
 moveq.l  #'Z',d4
 cmp.b    #4,d5
 beq      dshs_30
 moveq.l  #'X',d4
dshs_30:
 bra      dshs_27

dshs_27:
 move.b   #';',(a1)+
 move.b   #' ',(a1)+
 move.l   4(a7),d5      ; restore export osc sequence number
 move.b   d4,(a1,d5.w)
 adda.l   d2,a1
 move.b   #$0d,(a1)+
 move.b   #$0a,(a1)+
 subq.l   #1,d3
 bra      dshs_24

dshs_25:
 movem.l  (a7)+,d0/d1
 addq.w   #1,d0
 addq.w   #1,d1
 bra      dshs_23

dshs_21:
 movem.l  (a7)+,d1-d4/a0
 rts



;--------------------------------------------------------------------------
; a0 - address of hst file; d0 - lenght

prepare_hst_file:
 movem.l  d1/a0,-(a7)
 move.l   d0,check_size
 clr.w    conv_osc_count

prhf_3:
 bsr      search_comment
 tst.b    d0
 beq      prhf_1
 bsr      get_type
 tst.b    d0
 beq      prhf_2
 cmpi.b   #1,d0
 bne      prhf_2       ; jump if end of signal definition
 bsr      get_number
 tst.l    d0
 beq      prhf_2
 subq.l   #1,d0
 cmp.w    conv_osc_count,d0
 bne      prhf_2
 addi.w   #1,conv_osc_count
 bmi      prhf_1       ; jump if osc > $7fff
 bsr      get_text
 tst.l    d0
 beq      prhf_1
 bra      prhf_3

prhf_2:
 tst.l    check_size
 beq      prhf_1
 bmi      prhf_1
 tst.w    conv_osc_count
 beq      prhf_1
 bsr      get_text
 tst.l    d0
 beq      prhf_1

prhf_4:
 move.b   (a0)+,d0
 subi.l   #1,check_size
 beq      prhf_1
 bmi      prhf_1
 cmp.b    #$21,d0
 bcs      prhf_4
 cmpi.b   #'-',d0
 bne      prhf_4
 cmpi.b   #$20,-2(a0)
 bne      prhf_4
 cmpi.b   #';',-3(a0)
 bne      prhf_4
 cmpi.b   #10,-4(a0)
 bne      prhf_4
 move.w   conv_osc_count,d0 
 
prhf_5:
 subi.l   #1,check_size
 beq      prhf_1
 bmi      prhf_1
 cmpi.b   #'-',(a0)+
 bne      prhf_4
 subq.w   #1,d0
 bne      prhf_5

 bsr      get_text
 tst.l    d0
 beq      prhf_1
 clr.l    conv_osc_lenght

prhf_11:
 move.b   (a0),d0
 cmpi.b   #$20,d0
 bcc      prhf_11a
 adda.w   #1,a0
 subi.l   #1,check_size
 beq      prhf_9
 bmi      prhf_9
 bra      prhf_11

prhf_11a:
 subi.l   #2,check_size
 beq      prhf_9
 bmi      prhf_9             ; jump to err if end of file
 adda.w   #2,a0
 move.w   conv_osc_count,d1

prhf_8:                  ; check all signals
 subi.l   #1,check_size
 beq      prhf_1
 bmi      prhf_1             ; jump to err if end of file
 move.b   (a0)+,d0
 cmpi.b   #'0',d0
 beq      prhf_7
 cmpi.b   #'1',d0
 beq      prhf_7
 cmpi.b   #'L',d0
 beq      prhf_7
 cmpi.b   #'l',d0
 beq      prhf_6
 cmpi.b   #'H',d0
 beq      prhf_7
 cmpi.b   #'h',d0
 beq      prhf_6
 cmpi.b   #'X',d0
 beq      prhf_7
 cmpi.b   #'x',d0
 beq      prhf_6
 cmpi.b   #'Z',d0
 beq      prhf_7
 cmpi.b   #'z',d0
 beq      prhf_6
 cmpi.b   #' ',d0
 beq      prhf_7a
 bra      prhf_1          ; unknown signal type
prhf_6:
 bclr     #5,d0           ; upper case
 move.b   d1,-1(a0)
prhf_7:
 subq.l   #1,d1
prhf_7a:
 tst.w    d1
 bne      prhf_8
 addi.l   #1,conv_osc_lenght
 bmi      prhf_1          ; jump if osc lenght > $7fffffff
 bra      prhf_11

prhf_9:
 tst.l    conv_osc_lenght
 beq      prhf_1
 moveq.l  #$ff,d0         ; check and calculate - o.k.
 bra      prhf_12

prhf_1:
 moveq.l  #0,d0           ; check and calculate - failed
prhf_12:
 movem.l  (a7)+,d1/a0
 rts



;--------------------------------------------------------------------------

hst_import:
 movem.l  d0-d5/a0-a2,-(a7)
 move.l   d0,check_size
 clr.w    d5             ; oscilogram counter

hsim_3:
 bsr      search_comment
 bsr      get_type
 tst.b    d0
 beq      hsim_4       ; jump if end of signal defenition
 cmpi.b   #1,d0
 bne      hsim_4       ; jump if end of signal definition
 bsr      get_number
 tst.l    d0
 beq      hsim_4
 subq.l   #1,d0
 cmp.w    d5,d0
 bne      hsim_4
 bsr      get_text
 move.l   d0,a1
 move.w   d5,d0
 move.l   a0,-(a7)
 bsr      GetOscTextAdr
 move.b   #2,(a0)+
 sf       d1            ; flag exists of '"'
 clr.b    d2            ; current lenght of signal name

hsim_3d:
 move.b   (a1)+,d0
 cmpi.b   #$20,d0
 bcs      hsim_3a
 cmpi.b   #'"',d0
 beq      hsim_3b
 cmpi.b   #$20,d0
 beq      hsim_3c
hsim_3e:
 addq.b   #1,d2
 cmpi.b   #30,d2
 beq      hsim_3a
 move.b   d0,(a0)+
 bra      hsim_3d
hsim_3b:
 tst.b    d1
 bne      hsim_3a
 st       d1
 bra      hsim_3d
hsim_3c:
 tst.b    d1
 bne      hsim_3e 

hsim_3a:
 clr.b    (a0)+
 move.l   (a7)+,a0
 addq.w   #1,d5
 bra      hsim_3

hsim_4:
 move.b   (a0)+,d0
 cmp.b    #$21,d0
 bcs      hsim_4
 cmpi.b   #'-',d0
 bne      hsim_4
 cmpi.b   #$20,-2(a0)
 bne      hsim_4
 cmpi.b   #';',-3(a0)
 bne      hsim_4
 cmpi.b   #10,-4(a0)
 bne      hsim_4
 
 move.l   dsa_file_mem,a2
 move.w   dsah_OscQuant(a2),d0 

hsim_5:
 cmpi.b   #'-',(a0)+
 bne      hsim_4
 subq.w   #1,d0
 bne      hsim_5

 move.l   a0,a1            ; backup pointer to hst data
 moveq.l  #-1,d5           ; first oscilogram number-1

hsim_11:
 addq.w   #1,d5
 move.l   dsa_file_mem,a0
 cmp.w    dsah_OscQuant(a0),d5
 beq      hsim_9
 move.w   d5,regr_curosc
 clr.l    regr_curc
 bsr      GetOscGfxAdr   ; output: a0 - current data byte address; d0 - oscilogram type; d1 - current bit of current data byte (need in type 1 and 2)
 move.l   a0,a2          ; a2 pointed to osc data
 move.l   dsa_file_mem,a0
 move.l   dsah_OscLen(a0),d4
 move.l   a1,a0

hsim_11a:
 move.b   (a0)+,d0
 cmpi.b   #10,d0
 bne      hsim_11a

 adda.w   #2,a0          ; skip first two row
 move.w   d5,d0

hsim_11b:
 tst.w    d0
 beq      hsim_11c
hsim_11d:
 cmpi.b   #' ',(a0)+     ; skip empty row
 beq      hsim_11d
 subq.w   #1,d0
 bra      hsim_11b

hsim_11c:
 move.b   (a0)+,d2
 cmp.b    #' ',d2        ; skip empty row
 beq      hsim_11c
 moveq.l  #2,d3          ; input, low ?
 cmpi.b   #'0',d2
 beq      hsim_7
 moveq.l  #3,d3          ; input, high ?
 cmpi.b   #'1',d2
 beq      hsim_7
 moveq.l  #0,d3          ; output, low ?
 cmpi.b   #'L',d2
 beq      hsim_7
 moveq.l  #1,d3          ; output, high ?
 cmpi.b   #'H',d2
 beq      hsim_7
 moveq.l  #4,d3          ; z-state ?
 cmpi.b   #'Z',d2
 beq      hsim_7
 moveq.l  #5,d3          ; unknown input state ?     ; X
hsim_7:
 cmpi.b   #7,d1
 beq      hsim_7a
 or.b     d3,(a2)+       ; fill low part of byte
 moveq.l  #7,d1
 bra      hsim_7b
hsim_7a:
 lsl.b    #4,d3
 move.b   d3,(a2)        ; fill high part of byte
 moveq.l  #3,d1
hsim_7b:
 subq.l   #1,d4
 bne      hsim_11a
 bra      hsim_11

hsim_9:
 movem.l  (a7)+,d0-d5/a0-a2
 rts



;--------------------------------------------------------------------------
; d0 - quant of osc; d1 - osc lenght; d2 - osc type (1,2,3)

make_dsa:
 movem.l  d1-d4/a0/a1,-(a7)
 movem.l  d0-d2,-(a7)
 movea.l  dsa_file_mem,a1
 move.l   a1,d0
 beq      mads_5            ; memory is free
 move.l   dsa_file_size,d0
 CALLEXEC FreeMem           ; free old memory (erase old oscilogramm)
 clr.l    dsa_file_mem
mads_5:
 movem.l  (a7)+,d0-d2

 move.l   #dsah_SIZEOF,d3
 moveq.l  #0,d4
 move.w   d0,d4
 lsl.l    #5,d4             ; *32 names field
 add.l    d4,d3

 movem.l  d0-d2,-(a7)
 cmpi.b   #1,d2
 beq      mads_1
 cmpi.b   #2,d2
 beq      mads_2
 bra      mads_3

mads_1:
 move.l   d1,d2
 lsr.l    #3,d2             ; /8
 andi.l   #$f,d1
 beq      mads_4
 addq.l   #2,d2             ; word align
 bra      mads_4
 
mads_2:
 move.l   d1,d2
 lsr.l    #1,d2             ; /2
 andi.l   #3,d1
 beq      mads_4
 addq.l   #2,d2             ; word align
 bra      mads_4

mads_3:
 move.l   d1,d2
 add.l    d1,d2             ; *2
 bra      mads_4

mads_4:
 tst.w    d0
 beq      mads_6
 add.l    d2,d3
 subq.w   #1,d0
 bra      mads_4

mads_6:
 move.l   d3,dsa_file_size
 move.l   d3,d0
 move.l   #$10001,d1         ; public, clear
 CALLEXEC AllocMem
 tst.l    d0
 bne      mads_7
 movem.l  (a7)+,d0-d2
 moveq.l  #10,d0             ; message: Low memory for internal buffers
 bsr      WinErr
 bra      mads_8

mads_7:
 move.l   d0,dsa_file_mem
 move.l   d0,a0
 movem.l  (a7)+,d0-d2
 move.l   #'DSAF',dsah_ID(a0)
 move.l   d1,dsah_OscLen(a0)
 move.w   #$3000,dsah_TextGfxZoom(a0)
 move.w   d0,dsah_OscQuant(a0)
 move.w   #2,dsah_CurZoomPix(a0)    ; quant. pixel in one cycle
 move.w   #1,dsah_CurZoomStp(a0)    ; step for "x" in array (1..32767)
 clr.l    dsah_CurC(a0)
 clr.w    dsah_CurOsc(a0)
 clr.l    dsah_LinCurC(a0)
 clr.w    dsah_LinCurOsc(a0)
 clr.w    dsah_Version(a0)
 clr.w    dsah_Reserved1(a0)
 moveq.l  #$ff,d0              ; o.k.
 bra      mads_9

mads_8:
 moveq.l  #0,d0                ; failed
mads_9:
 movem.l  (a7)+,d1-d4/a0/a1
 rts



;=========================


WinErr:
 move.l   d0,-(a7)
 lea      dsa_NewWinErr,a0
 move.l   dsa_scr,nw_Screen(a0)   ; install screen pointer to window structure
 CALLINT  OpenWindow              ; open Err window
 move.l   (a7)+,d2
 move.l   d0,dsa_WinErr
 tst.l    d0
 beq      wier_1                  ; Err window not open

 lea      dsa_ErrTextPointers,a0  ; error codes, pointers to text
wier_3:
 move.l   (a0)+,d0                ; load error code
 move.l   (a0)+,d1                ; load pointer to text
 tst.l    d0                      ; last error code ?
 beq      wier_2
 cmp.l    d0,d2              ; compare current error code with loaded error code
 bne      wier_3
wier_2:
 move.l   d1,erit_TextString      ; selected pointer to IText structure
 movea.l  dsa_WinErr,a0
 movea.l  wd_RPort(a0),a0         ; window RastPort
 lea      erit_IText,a1
 moveq.l  #0,d0                   ; x coord
 moveq.l  #0,d1                   ; y coord
 CALLINT  PrintIText

 movea.l  dsa_WinErr,a0
 move.l   wd_UserPort(a0),a0
 CALLEXEC WaitPort
 movea.l  dsa_WinErr,a0
 move.l   wd_UserPort(a0),a0
 CALLEXEC GetMsg
 tst.l    d0
 beq      wier_4
 move.l   d0,a1
 CALLEXEC ReplyMsg
wier_4:
 movea.l  dsa_WinErr,a0
 CALLINT  CloseWindow
wier_1:
 rts



;-----------------------

FreeAllMemory:
 movea.l  dsa_file_mem,a1
 move.l   a1,d0
 beq      fram_1            ; memory already freed
 move.l   dsa_file_size,d0
 CALLEXEC FreeMem           ; free old memory
fram_1:

 move.l   hard_buf_mem,a1
 move.l   a1,d0
 beq      fram_2
 move.l   #$20000,d0
 CALLEXEC FreeMem
fram_2:

 rts



;-----------------------

CopyString1:
; a0 - source string (xx..xx,0)
; a1 - destination string (xx..xx,0)
; d0 - maximum lenght of destination string
 movem.l  d0/a0/a1,-(a7)
 tst.l    d0
 beq      cost1_1
cost1_2:
 move.b   (a0)+,(a1)+
 beq      cost1_1
 subq.l   #1,d0
 bne      cost1_2
 clr.b    (a1)
cost1_1:
 movem.l  (a7)+,d0/a0/a1
 rts

;------------------------

AddFileToPath:
; a0 - source path string (xx..xx,0)
; a1 - destination file string (xx..xx,0)
; d0 - maximum lenght of destination string
 tst.l    d0
 beq      aftp_1
 tst.b    (a1)
 beq      aftp_4    ; no path (only file)
aftp_2:
 tst.b    (a1)      ; check end of destination string
 beq      aftp_3
 adda.l   #1,a1
 subq.l   #1,d0
 beq      aftp_1
 bra      aftp_2
aftp_3:
 cmpi.b   #':',-1(a1)
 beq      aftp_4
 cmpi.b   #'/',-1(a1)
 beq      aftp_4
 move.b   #'/',(a1)+
 subq.l   #1,d0
 beq      aftp_1
aftp_4:
 move.b   (a0)+,(a1)+
 beq      aftp_1
 subq.l   #1,d0
 bne      aftp_4
aftp_1:
 rts



;------------------------

OpenWin:
 lea      dsa_newwin,a0
 lea      dsa_newwin_tag_list,a1
; lea      dnwst,a0
; lea      dnwtl,a1
 move.l   dsa_scr,nw_Screen(a0)
; move.l   dsa_scr,scr_pnt
 CALLINT  OpenWindowTagList
 move.l   d0,dsa_win
 rts



;-------------------------

CloseWin:
 move.l   dsa_win,d0
 beq      clwi_1
 movea.l  d0,a0
 CALLINT  CloseWindow
clwi_1:
 rts



;-------------------------

OpenScr:
 lea      dsa_newscr,a0
 lea      dsa_newscr_tag_list,a1
 CALLINT  OpenScreenTagList
 move.l   d0,dsa_scr

 move.l   d0,a0
 CALLINT  GetScreenDrawInfo
 move.l   d0,dsa_scdri

; move.l   dsa_scdri,dsnw_tlim02_dri
 suba.l   a0,a0
 lea      imageclass_name,a1
 lea      dsnw_tlim02,a2
 CALLINT  NewObjectA          ; create new Image for "left-arrow" gadget
 move.l   d0,dsnw_im02

; move.l   dsa_scdri,dsnw_tlims02_dri
 suba.l   a0,a0
 lea      imageclass_name,a1
 lea      dsnw_tlims02,a2
 CALLINT  NewObjectA          ; create new Image for "left-arrow" gadget
 move.l   d0,dsnw_ims02

 move.l   dsa_scdri,dsnw_tlim04_dri
 suba.l   a0,a0
 lea      sysiclass_name,a1
 lea      dsnw_tlim04,a2
 CALLINT  NewObjectA          ; create new Image for "left-arrow" gadget
 move.l   d0,dsnw_im04
 move.l   d0,dsnw_ims04

 move.l   dsa_scdri,dsnw_tlim05_dri
 suba.l   a0,a0
 lea      sysiclass_name,a1
 lea      dsnw_tlim05,a2
 CALLINT  NewObjectA          ; create new Image for "right-arrow" gadget
 move.l   d0,dsnw_im05
 move.l   d0,dsnw_ims05

 move.l   dsa_scdri,dsnw_tlim06_dri
 suba.l   a0,a0
 lea      sysiclass_name,a1
 lea      dsnw_tlim06,a2
 CALLINT  NewObjectA          ; create new Image for "down-arrow" gadget
 move.l   d0,dsnw_im06
 move.l   d0,dsnw_ims06

 move.l   dsa_scdri,dsnw_tlim07_dri
 suba.l   a0,a0
 lea      sysiclass_name,a1
 lea      dsnw_tlim07,a2
 CALLINT  NewObjectA          ; create new Image for "up-arrow" gadget
 move.l   d0,dsnw_im07
 move.l   d0,dsnw_ims07

 move.l   dsa_scr,a0
 move.l   dsa_scdri,a1
 CALLINT  FreeScreenDrawInfo

 rts



;-------------------------

CloseScr:
 move.l   dsnw_im07,a0
 CALLINT  DisposeObject

 move.l   dsnw_im06,a0
 CALLINT  DisposeObject

 move.l   dsnw_im05,a0
 CALLINT  DisposeObject

 move.l   dsnw_im04,a0
 CALLINT  DisposeObject

 move.l   dsnw_im02,a0
 CALLINT  DisposeObject

 move.l   dsnw_ims02,a0
 CALLINT  DisposeObject

 move.l   dsa_scr,d0
 beq      clsc_1
 movea.l  d0,a0
 CALLINT  CloseScreen
clsc_1:
 rts



;-------------------------

OpenSysLib:
 clr.l    _DOSBase
 clr.l    _IntuitionBase
 clr.l    _GfxBase

 lea      dosname,a1
 moveq    #0,d0
 CALLEXEC OpenLibrary
 tst.l    d0
 beq      opsl_1
 move.l   d0,_DOSBase

 lea      intname(pc),a1
 moveq    #0,d0
 CALLEXEC OpenLibrary
 tst.l    d0
 beq      opsl_1
 move.l   d0,_IntuitionBase

 lea      grafname,a1
 moveq    #0,d0
 CALLEXEC OpenLibrary
 tst.l    d0
 beq      opsl_1
 move.l   d0,_GfxBase

 moveq.l  #$ff,d0   ; ok
 rts
opsl_1:
 rts



;-----------------------

OpenOtherLib:
 clr.l    _AslBase

 lea      aslname,a1
 moveq    #0,d0
 CALLEXEC OpenLibrary
 tst.l    d0
 beq      opol_1
 move.l   d0,_AslBase

 clr.l    _MathieeesingbasBase

 lea      mathieeesingbasname,a1
 moveq    #0,d0
 CALLEXEC OpenLibrary
 tst.l    d0
 beq      opol_1
 move.l   d0,_MathieeesingbasBase

 moveq.l  #$ff,d0   ; ok
 rts
opol_1:
 rts



;-----------------------

CloseSysLib:
 move.l   _DOSBase,d0
 beq      clsl_1
 move.l   d0,a1
 CALLEXEC CloseLibrary

clsl_1:
 move.l   _IntuitionBase,d0
 beq      clsl_2
 move.l   d0,a1
 CALLEXEC CloseLibrary

clsl_2:
 move.l   _GfxBase,d0
 beq      clsl_3
 move.l   d0,a1
 CALLEXEC CloseLibrary
clsl_3:
 rts



;-----------------------

CloseOtherLib:
 move.l   _AslBase,d0
 beq      clol_1
 move.l   d0,a1
 CALLEXEC CloseLibrary
clol_1:

 move.l   _MathieeesingbasBase,d0
 beq      clol_2
 move.l   d0,a1
 CALLEXEC CloseLibrary
clol_2:
 rts



;-----------------------------------------------------------
; find $0a,';' sequence

search_comment:
 move.l   d1,-(a7)
seco_3:
 subi.l   #1,check_size
 beq      seco_1
 bmi      seco_1
 move.b   (a0)+,d1
 cmpi.b   #';',d1
 bne      seco_3
 moveq.l  #$ff,d0
 bra      seco_2
seco_1:
 moveq.l  #0,d0
seco_2:
 move.l   (a7)+,d1
 rts
 


;-----------------------------------------------------------

get_type:
 movem.l  d1-d6/a1/a2,-(a7)
gety_2:
 move.b   (a0),d2          ; to current word
 cmpi.b   #$21,d2
 bcc      gety_1
 adda.w   #1,a0
 subi.l   #1,check_size
 beq      gety_15
 bmi      gety_15
 bra      gety_2
gety_1:

 lea      type_list(pc),a1
 moveq.l  #0,d0            ; error type
 moveq.l  #0,d1            ; begin type for cycle

gety_9:
 move.l   a0,a2            ; reload a2 (pointer to search word)
 move.l   check_size,d6
 move.b   (a1),d2          ; end of type_list ?
 beq      gety_3

gety_7:
 move.b   (a1)+,d2         ; read type_list bytes
 seq      d4
 move.b   (a2)+,d3         ; read search byte
 subq.l   #1,d6
 beq      gety_15
 bmi      gety_15
 cmpi.b   #$21,d3
 scs      d5
 and.b    d4,d5
 bne      gety_5           ; jump if equ lenght and bytes
 tst.b    d4
 bne      gety_12          ; jump if end of current type_list itim
 tst.b    d5
 bne      gety_8           ; jump if end of searched word
 cmpi.b   #'A',d3
 bcs      gety_6           ; jump if symbol < 'A'
 cmpi.b   #('Z'+1),d3
 bcc      gety_6           ; jump if symbol > 'Z'
 bset     #5,d3            ; 'X'->'x'
gety_6:
 cmp.b    d2,d3
 beq      gety_7

gety_8:
 move.b   (a1)+,d2         ; wait next type_list item
 bne      gety_8
gety_12:
 addq.l   #1,d1            ; next word in type_list
 bra      gety_9

gety_5:
 move.l   d1,d0            ; founded !

gety_3:
 move.b   (a0),d2

gety_10:                   ; pointer to next item
 move.b   (a0),d2
 cmpi.b   #$21,d2
 bcs      gety_11
 adda.w   #1,a0
 subi.l   #1,check_size
 beq      gety_15
 bmi      gety_15
 bra      gety_10
gety_15:
 moveq.l  #0,d0            ; failed - end of input buffer
gety_11:
 movem.l  (a7)+,d1-d6/a1/a2
 rts



;-------------------------------------------------------------

get_text:
 move.l   d2,-(a7)
gete_1:                   ; pointer to current item
 move.b   (a0),d2
 cmpi.b   #10,d2
 beq      gete_2
 cmpi.b   #$21,d2
 bcc      gete_2
 adda.w   #1,a0
 subi.l   #1,check_size
 beq      gete_4
 bmi      gete_4
 bra      gete_1
gete_2:
 move.l   a0,d0
gete_3:                   ; pointer to next item in new line
 subi.l   #1,check_size
 beq      gete_4
 bmi      gete_4
 move.b   (a0)+,d2
 cmpi.b   #10,d2
 bne      gete_3
 bra      gete_5
gete_4:
 moveq.l  #0,d0           ; fail
gete_5:
 move.l   (a7)+,d2
 rts



;-------------------------------------------------------------

get_number:
 movem.l  d1-d6/a1/a2,-(a7)
genu_1:                   ; pointer to item
 move.b   (a0),d2
 cmpi.b   #$21,d2
 bcc      genu_2
 adda.w   #1,a0
 subi.l   #1,check_size
 beq      genu_15
 bmi      genu_15
 bra      genu_1
genu_2:
 moveq.l  #0,d1           ; set positive value flag
 moveq.l  #0,d3           ; decimal mode
; move.b   (a0),d2
; cmpi.b   #'-',d2
; bne      genu_3
; st       d1              ; set negative value flag
; adda.w   #1,a0
; subi.l   #1,check_size
; beq      genu_15
; bmi      genu_15

;genu_3:
; move.b   (a0),d2
; cmpi.b   #'$',d2
; bne      genu_4
; moveq.l  #1,d3           ; hex mode
; adda.w   #1,a0
; subi.l   #1,check_size
; beq      genu_15
; bmi      genu_15
; bra      genu_5

;genu_4:
; move.b   (a0),d2
; cmpi.b   #'%',d2
; bne      genu_5
; moveq.l  #2,d3            ; binary mode
; adda.w   #1,a0
; subi.l   #1,check_size
; beq      genu_15
; bmi      genu_15

genu_5:
 moveq.l  #0,d4            ; pointer in digit_buf to first (high) digit
 moveq.l  #0,d5            ; d5=0 flag zero digits
 lea      digit_buf(pc),a1


genu_7:                    ; begin of scan cycle
 move.b   (a0),d2
 cmpi.b   #$21,d2
 bcs      genu_8           ; jump if end of word
 tst.b    d5
 bne      genu_6
 adda.w   #1,a0
 subi.l   #1,check_size
 beq      genu_15
 bmi      genu_15
 cmpi.b   #'0',d2
 beq      genu_7           ; first 0 (in left part) not use
 suba.w   #1,a0
 addi.l   #1,check_size

genu_6:
 tst.b    d3
 beq      genu_d10
 cmpi.b   #1,d3
 beq      genu_d16
 bra      genu_d2

genu_d10:
 cmpi.w   #10,d4           ; >9.999.999.999 ?
 beq      genu_8
 cmp.b    #'0',d2
 bcs      genu_8
 cmp.b    #('9'+1),d2
 bcc      genu_8
genu_d10_1:
 st       d5
 subi.b   #'0',d2
 move.b   d2,(a1,d4.w)
 addq.w   #1,d4
 adda.w   #1,a0
 subi.l   #1,check_size
 beq      genu_15
 bmi      genu_15
 bra      genu_7

genu_d16:
 cmpi.w   #8,d4
 beq      genu_8
 cmp.b    #'0',d2
 bcs      genu_8
 cmp.b    #('9'+1),d2
 bcs      genu_d10_1
 cmp.b    #'A',d2
 bcs      genu_8
 cmp.b    #('F'+1),d2
 bcs      genu_d16_1
 cmp.b    #'a',d2
 bcs      genu_8
 cmp.b    #('f'+1),d2
 bcc      genu_8
 bclr     #5,d2           ; 'a'->'A'
genu_d16_1:
 subi.b   #('A'-'9'-1),d2
 bra      genu_d10_1

genu_d2
 cmpi.w   #32,d4
 beq      genu_5
 cmp.b    #'0',d2
 beq      genu_d10_1
 cmp.b    #'1',d2
 beq      genu_d10_1
 bra      genu_8

digit_buf:
 dc.b     0,0,0,0,0,0,0,0
 dc.b     0,0,0,0,0,0,0,0
 dc.b     0,0,0,0,0,0,0,0
 dc.b     0,0,0,0,0,0,0,0

genu_8:                   ; pointer to next item
genu_9:
 move.b   (a0),d2
 cmpi.b   #$21,d2
 bcs      genu_10
 adda.w   #1,a0
 subi.l   #1,check_size
 beq      genu_15
 bmi      genu_15
 bra      genu_9

genu_10:
 moveq.l  #0,d0
 lea      dec_table(pc),a2

genu_11:                  ; begin of calculate cycle
 tst.b    d4
 beq      genu_12         ; jump if zero value or error->zero value
 tst.b    d3
 beq      genu_c10        ; jump to calculate decimal value
 cmpi.b   #1,d3
 beq      genu_c16
 bra      genu_c2

genu_c10:
 moveq.l  #0,d2
 move.b   -1(a1,d4.w),d2
 mulu     (a2)+,d2
 mulu     (a2)+,d2
 move.w   (a2)+,d6
 beq      genu_c10_1
 lsl.l    d6,d2
genu_c10_1:
 add.l    d2,d0
 subq.w   #1,d4
 bra      genu_11

genu_c16:
 moveq.l  #0,d2
 move.b   (a1)+,d2
 lsl.l    #4,d0
 or.l     d2,d0
 subq.w   #1,d4
 bra      genu_11

genu_c2:
 moveq.l  #0,d2
 move.b   (a1)+,d2
 lsl.l    #1,d0
 or.l     d2,d0
 subq.w   #1,d4
 bra      genu_11

dec_table:
; value=digit * x1 * x2 * (2^x3)
;         x1    x2    x3
 dc.w     1,1,0          ;             *1
 dc.w     10,1,0         ;            *10
 dc.w     100,1,0        ;           *100
 dc.w     1000,1,0       ;         *1.000
 dc.w     625,1,4        ;        *10.000
 dc.w     3125,1,5       ;       *100.000
 dc.w     3125,5,6       ;     *1.000.000
 dc.w     3125,50,6      ;    *10.000.000
 dc.w     3125,500,6     ;   *100.000.000
 dc.w     3125,5000,6    ; *1.000.000.000

genu_12:
 tst.b    d1
 beq      genu_13         ; jump if positive value
 not.l    d0
 addq.l   #1,d0
 bra      genu_13
genu_15:
 moveq.l  #0,d0           ; zero if end of input buffer
genu_13:
 movem.l  (a7)+,d1-d6/a1/a2
 rts



;--------------------------------------------------------------
;
;x1:
; addi.l   #1,$130
;x1a:
; move.w   $dff006,$dff182
; btst     #6,$bfe001
; bne      x1a
; rts



;--------------------------------------------------------------
;
;x2:
; addq.l   #1,$134
;x2a:
; move.w   $dff006,$dff182
; btst     #7,$bfe001
; bne      x2a
; rts


 include  Box0:a/dsa/dsa.inc
