** morse.s
** Based on a combo of MY KINGDOM FOR A RASTPORT and morsecode.s
** A program in assembly language to make morse code sending and
** random code generating routines.  Started on April 30, 1097.
** By        Peter V. Inskeep
**           6 Clearview Drive
**           Long Valley, N. J., 07853
*
**  Includes not needed if the equates are used to speed assembly
;   INCLUDE    'exec/types.i'     ;these will conflict with the 
;   INCLUDE    'exec/io.i'
;   INCLUDE    'intuition/intuition.i'  ;equates below
;   INCLUDE    'outfile.equ'
useoutfile  equ  1  ;equ 1 if you are not using outfile.equ
useincludes equ  1  ;equ 1 if you are not using any includes at all
   XREF   _LVOGetMsg
   XREF   _LVOReplyMsg
   XREF   _LVOSetMenuStrip
   XREF   _LVOClearMenuStrip
   XREF   _LVOPrintIText
   XREF   _LVOClearScreen
   XREF   _LVODrawBorder
   XREF   _LVOOpenWindow
   XREF   _LVOCloseWindow
   XREF   _LVOAddDevice     ;exec function
   XREF   _LVOOpenDevice    ;exec function
   XREF   _LVOCloseDevice
   XREF   _LVORemDevice
   xref   _LVOOpenLibrary
   xref   _LVOCloseLibrary
   xref   _LVOOpen
   xref   _LVOWaitForChar
   xref   _LVOExecute
   xref   _LVOClose
   xref   _LVOInput
   xref   _LVOOutput
   xref   _LVOInput
   xref   _LVOOutput                 
   xref   _LVODoIO
   xref   _LVOSendIO
   xref   _LVOAbortIO
   xref   _LVOCheckIO
   xref   _LVOAddGadget
   XREF   _LVOAllocMem
   XREF   _LVOFreeMem

***  Outfile.equ equates - items defined in outfile.equ only
***  do not use these if using outfile.equ, but do if using include
   IFEQ  1-useoutfile  ;IF NOT EQUAL ZERO THEN THESE ARE NOT USED
AbsExecBase    equ $4
MEMF_PUBLIC  EQU  $01
MEMF_CHIP  EQU  $02
MEMF_FAST  EQU  $04
MEMF_CLEAR  EQU  $10000
  ENDC
***   DMA CHIP ADDRESSES - FROM THE HARDWARE MANUAL
***   NOT CURRENTLY IN INCLUDE OR OUTFILE.EQU SO ALWAYS USE  
Chipadr        equ $dff000      ;base address of chip
DMAconw        equ Chipadr+$96  ;DMA control write register
Aud0Lc         equ Chipadr+$a0  ;Channel 0 waveform sample location
Aud0Len        equ Chipadr+$a4  ;Channel 0 waveform sample length
Aud0per        equ Chipadr+$a6  ;channel 0 period
Aud0vol        equ Chipadr+$a8  ;channel 0 volume
Aud1Lc         equ Chipadr+$b0  ;Channel 1 waveform sample location
Aud1Len        equ Chipadr+$b4  ;Channel 1 waveform sample length
Aud1per        equ Chipadr+$b6  ;channel 1 period
Aud1vol        equ Chipadr+$b8  ;channel 1 volume
Setclr         equ $08000       ;DMA SEETCLR bit
OffDMA         equ 0            ;Disable DMA
Aud0en         equ $01          ;enable/disable Channel 0
Aud1en         equ $02          ;Enable/disable Channel 1
DMAen          equ $0200        ;Enable DMA
ALT0           equ $b0          ;type ALT-0 to go to a random number

**  INCLUDE EQUATES FROM EITHER INCLUDE OR OUTFILE.EQU
**  Do not use these [set not =] if using include or outfile.equ
   IFEQ  1-useincludes  ;IF NOT ZERO THEN WILL NOT BE EQUATED
wd_RPort   equ  $32
wd_FirstGadget  equ  $3e
wd_Size    equ  $7c
ig_ImageData  equ  $0a
ig_SIZEOF  EQU  $14
wd_UserPort   equ   $56
nw_FirstGadget equ  $12
im_Class   equ   $14
im_Code    equ   $18
im_MouseX  equ   $20
im_MouseY  equ   $22
im_Seconds equ   $24
im_Micros  equ   $28
MP_SIGBIT   equ   $0f
MENUENABLED   equ   $01
MIDRAWN   equ   $100
ITEMTEXT   equ   $02
ITEMENABLED   equ   $10
WBENCHSCREEN   equ   $01
HIGHCOMP   equ   $40
WINDOWSIZING   equ   $01
WINDOWDRAG   equ   $02
WINDOWDEPTH   equ   $04
WINDOWCLOSE   equ   $08
SMART_REFRESH   equ   $00
ACTIVATE   equ   $1000
GIMMEZEROZERO   equ   $400
VANILLAKEY    EQU  $00200000    ;SEE OPENWINDOW IN INTUITION REF MANL
FOLLOWMOUSE  EQU   $0008
CHECKIT  EQU $00000001
COMMSEQ  EQU $0004
MENUTOGGLE   EQU  $0008
CMD_READ  EQU  $02
CMD_WRITE  EQU $03
MN_SIZE  EQU   $99
IO_DEVICE  EQU   $14
IO_UNIT    EQU   $18
IO_COMMAND  EQU  $1C
IO_FLAGS   EQU   $1E
IO_ERROR   EQU   $1F
IO_ACTUAL  EQU   $20
IO_LENGTH  EQU   $24
IO_DATA    EQU   $28
IO_OFFSET  EQU   $2C
IOSTD_SIZE  EQU  $30
pi_SIZEOF   EQU  $16
pi_Flags    EQU  $00
pi_HorizPot EQU  $02
pi_VertPot  EQU  $04
pi_HorizBody  EQU  $06
pi_VertBody   EQU  $08
pi_HPotRes  EQU  $0e
pi_VPotRes  EQU  $10
AUTOKNOB   EQU  $01
FREEHORIZ  EQU  $02
FREEVERT   EQU  $04
KNOBHIT    EQU  $0100
KNOBHMIN   EQU  6
KNOBVMIN   EQU  4
gg_NextGadget equ  $00
gg_LeftEdge   equ  $04
gg_TopEdge    equ  $06
gg_Width      equ  $08
gg_Height     equ  $0a
gg_Flags      equ  $0c
gg_Activation  equ  $0e
gg_GadgetType  equ  $10
gg_GadgetRender equ  $12
gg_SelectRender  equ  $16
gg_GadgetText  equ  $1a
gg_MutualExclude  equ  $1e
gg_SpecialInfo   equ  $22
gg_GadgetID    equ  $26
gg_UserData    equ  $28
gg_SIZEOF    equ  $1c
RELVERIFY  EQU  $01
RIGHTBORDER  EQU  $10
BOTTOMBORDER  EQU  $80
PROPGADGET  EQU  $03
GZZGADGET  EQU  $2000
CLOSEWINDOW  EQU  $0200
GADGETUP  EQU  $40
MENUPICK  EQU  $0100
GRELRIGHT  EQU  $10
GRELHEIGHT  EQU  $40
GRELWIDTH  EQU  $20
GRELBOTTOM  EQU  $08
GADGIMAGE  EQU  $04
GADGHIMAGE  EQU  $02
GADGHCOMP  EQU  $00
RP_JAM1  EQU  $00
RP_JAM2  EQU  $01

   ENDC
***  Program equates not defined in Include or Outfile.equ
maxspeed   equ  $a00
maxstring      equ 1000    ;max string size
linelen        equ 54      ;set to typed line length
Count          equ $ffff        ;counter for delay timer
bufferlen      equ 400  ;keyboard buffer length not more than #keybuf
gwide   equ   22  ;how wide the gadget box is ( -GRELWIDTH)
ghigh   equ  -40  ;how high the gadget box is (-GRELHEIGHT
gleft   equ  -22  ;where the left edge of the box is (-GRELRIGHT)
gtop    equ   15  ; -40  ;where the top of the box is (-GRELBOTTOM)
g1wide  equ  400
g1high  equ   12      ; -15
g1left  equ   100
g1top    equ  -13
** The following macro added by P.V.Inskeep, on 30,May,1987, to
** accomodate the need to copy a structure size into a program
** being written, and to consume the correct number of BYTES!
  IFND  MYSTRUCT	
MYSTRUCT    MACRO     ;mystructname,mystructendaddr
\1          ds.b      \2
        ENDM
  ENDC
tart:
   jsr    getmem  ;allocate some chim memory
   jsr    inits   ;set up some chip mem pointers
***   Open the Intuition Library ***
   movea.l    #IntuitionName,a1     ;ask for intuition.library
   clr.l      d0                    ;accept any version 0 or greater
   movea.l    AbsExecBase,a6       ;the one fixed location in Amiga
   jsr        _LVOOpenLibrary(a6)   ;assembly language programming
   move.l     d0,IntuitionLibrary   ;store the pointer here
   beq        Abort      ;if zero then open failed so we go away
** Open graphics - need for clear screen
   movea.l    #GraphicsName,a1     ;ask for the graphics.library
   clr.l      d0                   ;any version
   movea.l    AbsExecBase,a6
   jsr        _LVOOpenLibrary(a6)
   move.l     d0,GraphicsLibrary   ;store the pointer here
   beq        Abort
***   Open our simple window
   movea.l    #newwindow,a0
   movea.l    IntuitionLibrary,a6
   jsr        _LVOOpenWindow(a6)
   move.l     d0,MyWindow        ;pointer to newly opened window
   beq        Abort              ;the rastport pointer is located
   movea.l    MyWindow,a0        ;at an address which is offset from
   movea.l    wd_RPort(a0),a1    ;the window pointer by the value of
   move.l     a1,myrport         ;wd_RPort, which is hex $32

** Initializations - nothing works unless these are initialized before
** being used in the various routines.
   move.l    #1,randflag  ;set random for keyboard input
   move.l    #0,codecntr  ;zero out code counter
   move.l    #0,kbcntr    ;zero out keyboard counter
   move.l    #keybuf,kbptr     ;the current keyboard buffer position
   move.l    #keybuf,codeptr   ;the current code char position
   move.l    #keybuf,d0     
   add.l     #bufferlen,d0      ;get to end of keybuf
   move.l    d0,kbendptr  ;the end of keybuf
   move.l    #mymenu,menupoint   ;initialize pointer to menu structure
   move.l    #menuitemone,firstmenuitem    ;init 1st menuitem pointer
   move.l    #firstitemtext,itemonetext    ;init 1st item intuitext struct
   move.l    #fititle,fitext               ;init title in 1st menu item
   move.l    #menuitemtwo,menuitemone      ;init the second menu item
   move.l    #seconditemtext,itemtwotext   ;and its text
   move.l    #sititle,sitext
   move.l    #menuitem3,menuitemtwo      ;init third menu item
   move.l    #thirditemtext,item3text    ;and its text
   move.l    #tititle,titext
   move.l    #onelinelist,oneline1    ;init drawline border coordinates
   move.l    #onecharbuf,onecharptr   ;for writing one char
   move.l    #5,ranword   ;for random char generator spacing
   lea       buffer,a1    ;initialize the buffer
   move.l    a1,bufptr    ;pointer
** Set the Menu Strip
   movea.l   MyWindow,a0    ;pointers to window and to menu structure
   movea.l   menupoint,a1   ;needed to call SetMenuStrip
   movea.l   IntuitionLibrary,a6
   jsr       _LVOSetMenuStrip(a6)

IntroMessage:
   jsr   welcomssg  ;see if the messages work
   move.l  #200,d0   ;this is a short pause routine to let
                      ;the user read the intro message
   jsr   pause      ;time to read the screen
   jsr   setmessage     ;set up the message center
   bra      openconsole
*****  We went to the openconsole routine *****
   cnop   0,4
;try the IORequest block structure here  KEEP THIS 4/10/87
   MYSTRUCT  myio,IOSTD_SIZE
   cnop 0,4

** Open Console.Device
** Start by init the iodata field to a pointer to  MyWindow
**   The open console device fills in all the rest.
**   for the specific commands.  see int. manual pg 174
openconsole:
;initialize to call adddevice
   move.l   #myio,a0   ;the reserved block pointer is ioreqptr
   move.l   a0,ioreqptr   ;set up a ioblock pointer
   move.l   MyWindow,d1   ;get the window pointer
   move.l   d1,IO_DATA(a0)  ;put the window ptr in IO_DATA
   move.l   #wd_Size,IO_LENGTH(a0)   ;poke size of a window structure
;add device
   movea.l  ioreqptr,a1   ;pointer to the io request block
   movea.l  AbsExecBase,a6
   jsr      _LVOAddDevice(a6)  
**open device
   movea.l  #consolename,a0    ;console.device any other not do anything
   move.l   #0,d0   ;unit number
   movea.l  ioreqptr,a1   ;IORequest block structure i built
   move.l   #0,d1  ;flags dont know what to put
   movea.l  AbsExecBase,a6
   jsr      _LVOOpenDevice(a6)  ;returns 0 if success, error if not
   move.l   d0,consoleflag  ;keeps track of successful console open   
   tst.l    d0    ;zero is success, not zero is error number
   beq      success
   move.l   #consolefail,IntuMsg  ;open console failed mssg
   move.w   #200,offsetleft     ;print the message in the
   move.w   #175,offsettop       ;middle of the screen
   jsr      printthis
   bra      close1
success:
  move.l  #iobuffer,d4  ;load a zero term mssg to print
   jsr  conwrite   ;a short success message
   tst.l    d0     ;zero is success
   bne      close1
   bra  passover  ;pass over the morse gadget initializations
closeconsole:
   movea.l  ioreqptr,a1
   movea.l  AbsExecBase,a6
   jsr      _LVOCloseDevice(a6)
   rts
** put the message pointer in d4, with zero terminated
conwrite:
   movea.l  ioreqptr,a0   ;pointer to iorequestblock structure
   move.l  #-1,IO_LENGTH(A0)  ;use -1 only if text null terminated.
;   otherwise, load iolength with buffer text length
   move.l  d4,IO_DATA(A0)
   move.w  #CMD_WRITE,IO_COMMAND(a0)    ;WORD LENGTH
   movea.l a0,a1    ;iorequestblock structure
   movea.l AbsExecBase,a6
   jsr     _LVODoIO(a6)
   rts
conread:
   movea.l  ioreqptr,a0 
   move.l  #10,IO_LENGTH(a0)   ;read a maximum of ten chars.
   move.w  #CMD_READ,IO_COMMAND(a0)   ;set up the read command
   move.l  a0,a1
   move.l  bufptr,IO_DATA(a0)  ;fill the buffer from dos
   movea.l AbsExecBase,a6
   jsr     _LVODoIO(a6)
   rts
**  Write one char in kbptr to the screen
conwone:
   movea.l  ioreqptr,a1   ;pointer to iorequestblock structure
   move.l   #1,IO_LENGTH(a1)  ;use 1 to write one character
   move.l   kbptr,IO_DATA(a1)
   move.w   #CMD_WRITE,IO_COMMAND(a1)    ;WORD LENGTH
   movea.l  AbsExecBase,a6
   jsr      _LVOSendIO(a6)
   rts
** Read one char fm keyboard (kbptr) 
conrone:
   movea.l  ioreqptr,a1  ;get ioreqblock base pointer
   move.l   #1,IO_LENGTH(a1)   ;read 1 char
   move.w   #CMD_READ,IO_COMMAND(a1)   ;set the read command
   move.l   kbptr,IO_DATA(a1)  ;pointer where to store char
   movea.l  AbsExecBase,a6     ;needs base ptr in a1
   jsr      _LVOSendIO(a6)
   rts
** gets a char if there is one in keyboard, and writes it
conchar:
   clr.l    d4   ;sending a dot or dash
   movea.l  ioreqptr,a0
   move.w   30(a0),d4  ;bit 6 of #30 in iorequest block will be 
   btst     #14,d4   ;1 if a char is available in read, otherwise
   beq      1$      ;it will be zero
   jsr    conrone   ;conchar is used in element to get a char while
   jsr   conwone    ;there was a char
   jsr   addkeyst   ;increment keyboard buffer ptr
1$  rts
getmem:   ;for image and audio
    move.l   #imagebytes,d0   ;#sizepubmem,d0
    move.l   #(MEMF_CHIP!MEMF_PUBLIC),d1   ;!MEMF_CLEAR),d1
    movea.l  AbsExecBase,a6
    jsr      _LVOAllocMem(a6)
    tst.l    d0   ;a ptr to the memoryblock or 0 if error
    beq      Abort
    move.l   d0,memblock   ;ptr to reserved memory block
    move.l   d0,a0   ;ptr to reserved mem block
    clr.l    d0    ;set up dbra register
    move.l   #imagebytes,d0   ;#sizepubmem,d0   ;how many iterations
    sub.l    #1,d0   ;goes to minus 1
    lea.l    theimage,a1   ;ptr to beginning of initial data
1$  move.b   (a1)+,(a0)+   ;move data from begin to memblock
    dbra     d0,1$  ;loop until all copied
;image2 - pitch - transformation
    move.l   #pitchbytes,d0   ;#sizepubmem,d0
    move.l   #(MEMF_CHIP!MEMF_PUBLIC),d1   ;!MEMF_CLEAR),d1
    movea.l  AbsExecBase,a6
    jsr      _LVOAllocMem(a6)
    tst.l    d0   ;a ptr to the memoryblock or 0 if error
    beq      Abort
    move.l   d0,pitchblock   ;ptr to reserved memory block
    move.l   d0,a0   ;ptr to reserved mem block
    clr.l    d0    ;set up dbra register
    move.l   #pitchbytes,d0   ;#sizepubmem,d0   ;how many iterations
    sub.l    #1,d0   ;goes to minus 1
    lea.l    pitchimage,a1   ;ptr to beginning of initial data
3$  move.b   (a1)+,(a0)+   ;move data from begin to memblock
    dbra     d0,3$  ;loop until all copied
    ;now the audio block moves to chip memory
    move.l   #sizeaudio,d0
    move.l   #(MEMF_CHIP!MEMF_PUBLIC),d1   ;!MEMF_CLEAR),d1
    movea.l  AbsExecBase,a6
    jsr      _LVOAllocMem(a6)
    tst.l    d0   ;a ptr to the memoryblock or 0 if error
    beq      Abort
    move.l   d0,audioblock   ;ptr to reserved memory block
    move.l   d0,a0   ;ptr to reserved mem block
    clr.l    d0    ;set up dbra register
    move.l   #sizeaudio,d0   ;how many iterations
    sub.l    #1,d0   ;goes to minus 1
    lea.l    Wavesample,a1   ;ptr to beginning of initial data
2$  move.b   (a1)+,(a0)+   ;move data from begin to memblock
    dbra     d0,2$  ;loop until all copied
    rts    
*  Initialize the variables
inits:
   lea       image1,a0   ;gadget1 image structure ptr
   movea.l   memblock,a1  ;ptr to gadget knob image data
   move.l    a1,ig_ImageData(a0)  ;initialize image1 data ptr
   lea       image2,a0
   movea.l   pitchblock,a1
   move.l    a1,ig_ImageData(a0)  ;init image2 data ptr
   lea       prop1,a0
   clr.l     d0
   move.w    pi_VertPot(a0),d0
   move.l    d0,elmdelay
   move.l    d0,dashdelay
   lea       prop2,a0
   clr.l     d0
   move.w   pi_HorizPot(a0),d0   ;frequency  ;also word length
   divu     #40,d0     ;divide down by 40
   move.w   d0,frequency  ;store the new frequency
   jsr   sound
   rts
passover:
   jsr   sound    ;initialize the sound
   jsr   ChanneL0 ;make a noise
   move.l   #testmsg,d4
   jsr   conwrite  ;print a message
   tst.l  d0
   bne    close1   ;if it fails
   jsr    zerokeybuf   ;fill keybuf with zeros
   jsr    conrone   ;read once to set to #14 bit  
;   jsr   testhex
   bra   ponder3
keytest:
   jsr    conchar     ;is there a char at keyboard
   jsr    codetable   ;see if there is a char to send
   bra    ponder3     ;loop back and do it again
zerokeybuf:
   move.l    #keybuf,a0  ;start of keyboard buffer
   clr.l     d1
   move.l    #bufferlen,d1    ;one less than buffer length
   sub.l     #1,d1           
1$   move.b   #0,(a0)+   ;zero fill
   dbra      d1,1$   ;decrement and branch
   rts

** The main routine for the menuitem selection.
** The Message Reading SubRoutine **
ponder3:
   jsr     getmessage  ;go see if there is a message to read
   tst.l   d0    ;returns zero if none
   beq     ponder5     ;return if no message
   clr.l   d0  ;myclass contains the idcmp message upon [ponder4]
   move.l  myclass,d0    ;return from getmessage
   cmp.w   #MENUPICK,d0  ;was a menu picked
   beq     whichmenu     ;if so, then go find out which menu item
   cmp.w   #CLOSEWINDOW,d0   ;or was it the closewindow gadget?
   beq     close1        ;if so, go close everything out
   cmp.w   #GADGETUP,D0  ;or was the gadget hit to change speed
   beq     chgspeed      ;change the delay loop values 
ponder5    bra  keytest  ;forever2  ;no message

** Which Menu Item was selected?
whichmenu:
   clr.l   d0  ;mycode shows which menu item was selected
   move.w   mycode,d0  ;mycode is word, not longword
**  The next instructions masks mycode to isolate the six middle bits
**  which contain the item number, and then compare it to item 1
   and.w    #%0000011111100000,d0   ;15-11=sub; 10-5=item; 4-0=menu
   cmp.w    #%0000000000000000,d0    ;0 is the 1st item #
   beq      itemnr1    ;the 1st menu item was picked
   cmp.w    #%0000000000100000,d0    ;1 is the 2nd item #
   beq      itemnr2    ;the 2nd menu item was picked
   cmp.w    #%0000000001000000,d0    ;10 is the 3rd item #
   beq      itemnr3    ;the 3rd item was picked
   jsr      erase      ;erase rectangle bounded by above
   move.l   #playmouse,IntuMsg    ;if not either of the above
   move.w   #280,offsetleft       ;print the message play with
   move.w   #5,offsettop         ;your mouse
   jsr      printthis  ;prints string pointed to by IntuMsg
   bra      ponder5    ;loop back to the beginning
itemnr1:  ;send faster
   jsr      erase
   move.l   #pickitem1,IntuMsg  ;random;first item picked so
   move.w   #270,offsetleft     ;print the message on the
   move.w   #5,offsettop       ;right side of the screen
   jsr      printthis
   jsr      meitem1    ;send faster
   bra      ponder5
itemnr2:               ;send slower
   jsr      erase
   move.l   #pickitem2,IntuMsg  ;random;first item picked so
   move.w   #270,offsetleft          ;print the message on the
   move.w   #5,offsettop            ;right side of the screen
   jsr      printthis
   jsr      meitem2     ;send slower
   bra      ponder5
itemnr3:                ;switch random
   jsr      erase
   move.l   #pickitem3,IntuMsg    ;second item picked so
   move.w   #270,offsetleft       ;print the message in the
   move.w   #5,offsettop         ;middle of the screen
   jsr      printthis
   jsr      meitem3   ;switch random on/off
   bra      ponder5   ;use the same exit point

**  Random Number Generator - Uses MICROS **
random:
    clr.l    d4
    jsr      GETRANDOM  ;a random nr 0-9 in d0
    asl      #4,d0  ;shift left 3 to max 127
    move.l   d0,d4  ;store
    jsr      GETRANDOM  ;get another
    add.l    d4,d0  ;combine them
    add.l    #65,d0   ;at least an "a"
    and.l    #$7f,d0
    cmp.l    #64,d0  ;decimal 42
    ble      random    
    cmp.l    #124,d0
    bge      random
    cmp.l    #97,d0
    bge      1$
    cmp.l    #63,d0
    bge      random
1$  cmp.l    lastrandom,d0
    beq      random   ;if they are the same dont use it
    jsr      aspace  ;see if time for a space
    move.l   d0,-(sp)
    lea      onecharbuf,a0
    move.l   a0,d4
    move.b   d0,(a0) 
    jsr      conwrite  ;write it out
    move.l   (sp)+,d0  ;get the character back
    move.l   d0,lastrandom  ;store for comparison
    rts   

GETRANDOM:
   JSR   onerandom    ;make a random number fm 0 to 9
   moveq    #0,d0      ;clear d0 long
   MOVE.B   CELL1,D0   ;get the random # always in cell1
   RTS      ;to from whence it came
** GENERATE RANDOM #'S FROM TRANSACTOR, MAY, 1987 
** MUST INITIALIZE WITH 21 RANDOM SINGLE DIGIT NUMBERS <10
onerandom:
   moveq    #0,d0
   moveq    #0,d1
   moveq    #0,d2
   MOVE.B   CELL21,D0
   ADD.B    CELL2,D0
   CMP.B    #10,D0
   blt      TEMP
   SUB.B    #10,D0
TEMP  MOVE.B  D0,TMP
   movea.l   #CBASE+21,a0
   movea.l   #CBASE+22,a1
   move.l    #19,D1
LOOP  move.b  -(A0),-(a1)        ;d2
    dbra    d1,LOOP
    move.b  TMP,CELL1  ;THIS IS THE RANDOM DIGIT FROM 0 TO 9
    rts
aspace:
    move.l  ranword,d5  ;what's in ranword
    tst.l   d5   ;if zero, then reseed
    beq     1$
    sub.l   #1,ranword  ;if not, reduce and return
2$  rts
1$  jsr     GETRANDOM  ;reseed the ranword
    move.l  d0,ranword
    move.l  #32,d0   ;put a space in the character generator
    bra     2$
    
* CLEAR THE SCREEN**
clear:
   move.l   #longnull,IntuMsg    ;this prints a null message
   move.w   #0,offsetleft      ;in the top left corner of the
   move.w   #0,offsettop       ;screen so we can set the 'cursor'
   jsr      printthis          ;for the call to ClearScreen
   movea.l  myrport,a1         ;this windows rastport
   movea.l  GraphicsLibrary,a6   ;the graphics.library
   jsr      _LVOClearScreen(a6)  ;clears from the 'cursor' or pen
   move.w   #10,offsetleft     ;position to the end of the rastport
   move.w   #0,offsettop      ;or end of the window
   rts
setmessage:
   movea.l  MyWindow,a0   ;pointer to my window
   movea.l  wd_UserPort(a0),a0  ;pointer to our window's userport
   move.l   a0,userport         ;save it
   move.l   a0,a1   ;IntuiMessage apprs to be false not needed
   move.l   a1,intuimessage     ;with our userport (and window)
   rts
getmessage:
   clr.l    d4               ;need this for junk
   movea.l  userport,a0      ;get userport pointer for call to GetMsg
   movea.l  AbsExecBase,a6  ;GetMsg is exec.lib, not intuition.lib
   jsr      _LVOGetMsg(a6)
   tst.l    d0               ;returns null if no message
   beq      getmssg1         ;escape if null
   move.l   d0,idcmpmessage  ;pointer to this message structure needed
   movea.l  idcmpmessage,a0  ;for address indirect with displacement
   move.l   im_Class(a0),myclass  ;which ICDMP flag ie., MENUPICK
   move.w   im_Code(a0),mycode    ;word-which menu item # 0,1,etc.
   move.w   im_MouseX(a0),mousex  ;mouse x & y coordinates if
   move.w   im_MouseY(a0),mousey  ;FOLLOWMOUSE flag is set in window
   move.l   im_Seconds(a0),seconds  ;these are here in case you want to
   move.l   im_Micros(a0),micros    ;use them for random # or timing
   movea.l  idcmpmessage,a1  ;we want to reply to this message, which
   movea.l  AbsExecBase,a6  ;is pointed to by idcmpmessage, so that
   jsr      _LVOReplyMsg(a6) ;messages don't pile up
   move.l   idcmpmessage,d0  ;if d0 not 0 then return with message
getmssg1    rts

** Intuition Message
welcomssg:
   move.w   #10,offsettop
   move.w   #50,offsetleft
   move.l   #line1,IntuMsg    ;get pointer for first line to be
   bsr      lineprint    ;printed
   move.l   #line2,IntuMsg   ;second line
   bsr   lineprint
   move.l   #line3,IntuMsg
   bsr   lineprint
   move.l   #line4,IntuMsg
   bsr   lineprint
   move.l   #line5,IntuMsg
   bsr   lineprint
   move.l   #line6,IntuMsg
   bsr   lineprint
   move.l   #line7,IntuMsg
   bsr   lineprint
   rts
lineprint   add.w    #20,offsettop
   jsr      printthis
   rts

** the following will print what is in "IntuMsg"
printthis:
   movea.l   #0,a0   ;clear these else doesn't work
   movea.l  #0,a1
   clr.l    d0
   clr.l    d1
   movea.l  myrport,a0           ;pointer to rastport struct
   movea.l  #intuitext,a1        ;pointer to intuitext struct
   move.w   offsetleft,d0        ;leftedge offset
   move.w   offsettop,d1         ;top edge offset
   movea.l  IntuitionLibrary,a6  ;set library pointer
   jsr      _LVOPrintIText(a6)   ;call print
   rts

** Pause routine expects delay value in d0, with constant 10000
pause:
   move.l   #10000,d1
   move.l   d0,d2       ;put outter loop value in d2
pause1   move.l  d1,d3  ;inner loop value in d3
pause2      nop
   dbra     d3,pause2   ;decrease inner loop till minus 1
   dbra     d2,pause1   ;same for outter loop
   rts                  ;all done

** ERASE Part of Screen Routine - Fills a rectangle with the  **
** background color.  The rectangle is bounded by the starting
** and ending x,y coordinates (top left & bottom right)
** Start x pos in d0, end x pos in d1, both y pos' in d2
** Start at the bottom of the rectangleand draw lines in
** the background color up to the top of the screen
erase:
   move.w   #00,d0
   move.w   #599,d1
   move.w   #15,d2
   move.w   d0,stx         ;starting x position
   move.w   d1,endx        ;ending x position
   move.w   d2,sty         ;starting y position
   move.w   d2,endy        ;ending y position
grids1   jsr  drawline     ;draw one horizontal line a pixel high
   subi.w   #1,sty         ;reduce y position
   subi.w   #1,endy        ;reduce y position
   dbra     d2,grids1      ;go back and draw another line
   rts

**  call this subroutine to draw a single line from coordinates
**  stx,sty to endx,endy - initialize those values before calling
**  the subroutine by move.w   #nn,stx etc
drawline:
   movea.l  myrport,a0       ;pointer to our rastport
   movea.l  #oneline,a1      ;pointer to border structure
   move.l   #0,d0            ;offsets-left & top
   move.l   #0,d1
   move.l   IntuitionLibrary,a6
   jsr      _LVODrawBorder(a6)
   rts    

***   Close the intuition window only ***
windowclose  movea.l   MyWindow,a0
   movea.l  IntuitionLibrary,a6
   jsr      _LVOCloseWindow(a6)      ;now close the window
   rts

*  Exit program
close1:
   move.l   consoleflag,d0
   tst.l    d0
   bne      close2
   jsr closeconsole
close2:
close    clr.l    d0
***   Close out and be gone  ***
bailout:
   jsr   clear  ;clear the screen
   move.w   #200,offsetleft  ;position a goodbye message
   move.w   #50,offsettop
   move.l   #goodbye,IntuMsg
   jsr      printthis
   move.l   #100,d0 
   jsr      pause           
   movea.l   MyWindow,a0    ;clear the menu strip to
   movea.l  IntuitionLibrary,a6      ;avoid conflicts when the
   jsr      _LVOClearMenuStrip(a6)   ;program is ended
bailout1    movea.l   MyWindow,a0
   movea.l  IntuitionLibrary,a6
   jsr      _LVOCloseWindow(a6)      ;now close the window
Abort:
  clr.l     d0
  rts                  ;all done, program has ended

**   The Code Table
**   code element to be sent is in d0
codetable:
   jsr    getcodechar   ;get the next char fm keybuf
   cmpi.b   #0,d0
   beq      codet3  ;leave if char zero      
   cmpi.b   #32,d0   ;is it a space? if so, skip code
   beq      endword
   movea.l  #alphacode,a0     ;get table pointer
   clr.l    d1                ;clr counter
   move.b   (a0),d1           ;set count at # of chars in table
   adda.l   #1,a0             ;move up to beginning of table
codet1   cmp.b    0(a0,d1),d0       ;index into table d1 bytes & compare
   beq      codet2            ;char found
   dbra     d1,codet1         ;decrement counter & try again
   bra      codet3            ;exit-no match found
codet2   move.b   d1,ltrcode        ;save the letter code number
   jmp      findltr           ;get the letter
codet4:
   bne      codet3
   move.l   d0,-(sp)        ;save char
   move.l   #linelen,carreturn
   move.l   (sp)+,d0        ;restore char
codet3    rts   ;to keytest and start again

endword:
   clr.l   d0
   move.b  wordspce,d0       ;set up dbra loop
endword1  jsr     element    ;basic element spacing
   dbra    d0,endword1
   jmp     codet4            ;go update the line counter

findltr  move.b   ltrcode,d0  ;get the number back
   add.b    d0,d0             ;double it
   movea.l  #dotdash,a0       ;get table base
   move.b   0(a0,d0),d1       ;the length of the code elements
   subq.b   #1,d1             ;dec by one for dbra ending in -1
   addq.b   #1,d0             ;up addr to code description
   move.b   0(a0,d0),d2       ;get the morse letter
nextelm  btst     d1,d2       ;if bit 1 then dash
   bne.s    dash
dot   jsr   sndon       ;turn on the sound
   jsr      element     ;sound one dot element
elmstart jsr   sndoff   ;turn sound off
   jsr   noelement      ;char space
elmdone  dbra     d1,nextelm  ;if not -1 then get next element
endchar  clr.l    d1
   move.b   charspce,d1       ;do the character space-3 elms
endchar1 jsr   element        ;make space rem to make charspce one
   dbra     d1,endchar1       ;less than desired spaceing.
   jmp      codet4            ;all done-get next character
dash  jsr   sndon
   jsr      dashelement ;this is longer by the weighting ratio
   jmp      elmstart    ;the dash is done

***  KeyBuffer Maintainence routine. Does not alter d0 ***
addkeyst:
   add.l   #1,kbptr
   add.l   #1,kbcntr ;increment the keyboard counter
   move.l  kbendptr,d4   ;set up a compare
   cmp.l   kbptr,d4   ;is ptr less?
   bgt     1$     ;d4 is > kbptr so branch
   move.l  #keybuf,kbptr  ;reset to the beginnng
1$  rts

** This gets a char and increments codeptr
getcodechar:
   clr.l   d1
   clr.l   d0
   move.l  randflag,d1
   tst.l   d1     ;if zero, then fetch code from random routine
   beq    random  ;this will send random code until menu changed
   move.l  codecntr,d1  ;see that code does not get ahead of keyboard
   cmp.l   kbcntr,d1    ;is d0 bigger, then dont send anything
   bge     1$           ;just return until keyboard catches up
   clr.l   d0
   movea.l  codeptr,a0   ;set up indirect to get char to send
   move.b  (a0),d0    ;get the char
   add.l   #1,codeptr  ;increment before testing
   add.l   #1,codecntr  ;increment the code counter
   move.l  kbendptr,d4     ;are we at the end of the buffer
   move.l  codeptr,d5
   cmp.l   d5,d4 
   bgt     1$     ;branch if d4 > codeptr
   move.l  #keybuf,codeptr   ;reset to the beginning
1$  rts    ;returns with char in d0, & pointer incremented

** Chage Speed With Proportional Gadget **
chgspeed:
    clr.l    d0  ;cuz we're going from word to long
    clr.l    d1
    lea.l    prop1,a0   ;get the prop struct base ptr
    move.w   pi_VertPot(a0),d0   ;must be word length
    divu     #2,d0   ;cut it down
    move.w   #maxspeed,d1
    add.w    d0,d1
    move.l   d1,elmdelay  ;do the dot
    move.l   d1,dashdelay  ;do the dash
    lea.l    prop2,a0   ;get pitch prop struct base ptr
    clr.l    d0
    move.w   pi_HorizPot(a0),d0   ;frequency  ;also word length
    divu     #40,d0     ;divide down by 40
    move.w   d0,frequency  ;store the new frequency
    jsr   sound
;tell the screen that we did this
   jsr      erase
   clr.l    d0
   move.w   frequency,d0
   jsr      printhex
   move.l   #hexprint,IntuMsg 
   move.w   #270,offsetleft   
   move.w   #5,offsettop      
   jsr      printthis
   bra      ponder5    

** Independant Menu Picks **
** send faster
meitem1:
   subi.l   #1,elmdelay1  ;menu item says go faster
   subi.l   #3,dashdelay1
   beq    meitem2       ;unless we get to zero
   rts
**  send slower
meitem2:          ;send slower
   addi.l   #1,elmdelay1   ;menu says go slower
   addi.l   #3,dashdelay1
   rts
**  switch random = 0  keyboard = 1
meitem3:
   tst.l   randflag    ;what is current state?
   beq.s   1$    ;its zero, so we want to make it one
   move.l   #0,randflag  ;it was one, so make it zero
2$  rts
1$  move.l   #1,randflag  ;make it one
   move.l   codeptr,d4   ;reprint remaining keyboard buffer
   jsr   conwrite
   bra   2$    ;exit at one place     

sound:
    movea.l audioblock,a2  ;Find address of waveform sample data
    move.l  a2,Aud0Lc      ;set waveform location channel 0
    move.l  a2,Aud1Lc      ;set waveform location channel 1
* Length = number of WORDS (not bytes) in waveform sample
    move.w  #16,Aud0Len    ;Set sample length channel 0
    move.w  #16,Aud1Len    ;set sample length channel 1
* volume can go up to 64
    move.w  #64,Aud0vol    ;Set channel 0 volume at maximum
    move.w  #64,Aud1vol    ;Set Channel 1 volume at maximum
    move.w  frequency,d0   ;bigger period higher sound
    move.w  d0,Aud0per     ;reset channel 0 period
;    add.w   d0,d0          ;make a different pitch
    move.w  d0,Aud1per     ;set channel 1 period
    rts
ChanneL0:
    move.w  #(Setclr+DMAen+Aud0en),DMAconw     ;enable channel 0
    bsr Timedelay                              ;delay
    move.w  #(OffDMA+Aud0en),DMAconw           ;disable channel 0
ChanneL1:
    move.w  #(Setclr+DMAen+Aud1en),DMAconw     ;enable channel 1
    bsr Timedelay                              ;delay
    move.w  #(OffDMA+Aud1en),DMAconw           ;disable channel 1
    rts
sndon:
   move.w  #(Setclr+DMAen+Aud1en),DMAconw     ;turn sound on
   move.w  #(Setclr+DMAen+Aud0en),DMAconw     ;ch 0 & 1
   rts
sndoff:
   move.w  #(OffDMA+Aud1en),DMAconw   ;turn sound off
   move.w  #(OffDMA+Aud0en),DMAconw   ;ch 0 & 1
   rts
noelement   movem.l  d0-d4/a0-a4,-(sp)    ;save the registers
   jsr    conchar    ;get a key      
   clr.l    d1
   move.l   elmdelay1,d1   ;set up a double # time delay loop
2$  clr.l    d0
   move.l   elmdelay,d0    ;with delay & delay1 with delay
3$  nop
   dbra     d0,3$    ;as the largest #
   dbra     d1,2$
   movem.l  (sp)+,d0-d4/a0-a4
   rts
element   movem.l  d0-d4/a0-a4,-(sp)    ;save the registers
   jsr    conchar
   clr.l    d1
   move.l   elmdelay1,d1   ;set up a double # time delay loop
element2  clr.l    d0
   move.l   elmdelay,d0    ;with delay & delay1 with delay
element3  nop
   dbra     d0,element3    ;as the largest #
   dbra     d1,element2
   movem.l  (sp)+,d0-d4/a0-a4
   rts
dashelement  movem.l   d0-d4/a0-a4,-(sp)    ;save the registers
   clr.l    d1
   move.l   dashdelay1,d1
dashelm2  clr.l    d0
   move.l   dashdelay,d0
dashelm3  nop
   dbra     d0,dashelm3
   dbra     d1,dashelm2
   movem.l  (sp)+,d0-d4/a0-a4
   rts
Timedelay:
   movem.l   d0-d1,-(sp)
   move.w #12,d0
*   move.l d1,-(a7)
   subq.w #1,d0
1$   move.w #Count,d1
2$  nop
   dbra d1,2$
   dbra d0,1$
*   move.l (a7)+,d1
   movem.l   (sp)+,d0-d1
   rts

printhex:
;prints a 16-bit hex number using d0 and hexfield
   clr.l   d1  ;nibble holder
   clr.l   d2  ;downcounter
   moveq   #3,d2
   lea.l   hexfield,a0
   lea.l   hexlist,a1
   bra     1$
2$ sub.l   #1,d2
   asr.l   #4,d0  ;shift to next nibble 
1$ move.l  d0,d1  ;move it 
   andi.l  #$0f,d1  ;what is the nibble
   move.b  0(a1,d1.l),d1  ;get the ascii equivalent
   move.b  d1,0(a0,d2.l)  ;put it in the hexfield
   tst.l   d2
   beq     3$
   bra     2$
3$ rts
testhex:
   jsr      erase
   move.l   elmdelay,d0
   jsr      printhex
   move.l   #hexprint,IntuMsg  ;random;first item picked so
   move.w   #210,offsetleft     ;print the message on the
   move.w   #5,offsettop       ;right side of the screen
   jsr      printthis
   rts
yestheend:
      
   SECTION     data,DATA

CBASE    DC.B     9
CELL1    DC.B     4
CELL2    DC.B     7,2,5,8,3,6,1,0,2,8,4,6,9,5,1,0,7,5,2
CELL21   DC.B     3
TMP      DC.B     0,0,0,0
         CNOP     0,4

;dosname  dc.b     'dos.library',0
;conname  dc.b     'raw:10/120/620/80/MORSE CODE - NO2D - 1987',0
;   cnop  0,4
hexlist  dc.b  '0123456789abcdef',0
consolename  dc.b  'console.device',0
IntuitionName   dc.b  'intuition.library',0
GraphicsName    dc.b  'graphics.library',0
    cnop   0,4    ;this is used to allign following stuff on a
**  long word address. If not done disaster can strike

menuflags   EQU   MENUENABLED!MIDRAWN   ;FROM INTUITION MENU STRUCTURE
itemflags   EQU   ITEMTEXT!ITEMENABLED!HIGHCOMP!COMMSEQ
item3flags  EQU   ITEMTEXT!ITEMENABLED!HIGHCOMP!CHECKIT!COMMSEQ!MENUTOGGLE
MyGadgets   EQU   WINDOWSIZING!WINDOWDRAG!WINDOWDEPTH!WINDOWCLOSE
MyFeatures  EQU   SMART_REFRESH!ACTIVATE!GIMMEZEROZERO   ;!VANILLAKEY
MyFlags     EQU   MyGadgets!MyFeatures
gadgrel     EQU   GRELRIGHT!GRELHEIGHT   ; !GRELBOTTOM
gadg1rel    EQU   GRELHEIGHT!GRELBOTTOM
gadgflags   EQU   GADGHIMAGE!GADGIMAGE
gadg1flags  EQU   GADGHIMAGE!GADGIMAGE
gadgtype    EQU   PROPGADGET!GZZGADGET
propflags   EQU   FREEVERT!KNOBHIT      ;!FREEHORIZ  !AUTOKNOB
prop1flags  EQU   KNOBHIT!FREEHORIZ           ;!AUTOKNOB
menupick    EQU   MENUPICK
MyTitle:    dc.b  ' NO2D MORSE CODE ',0   ;the title of our window
iobuffer    dc.b  ' The iobuffer has opened successfully.',10,13,0
menutitle   dc.b  'Morse Menu',0      ;null term string
fititle     dc.b  'Send Faster',0    ;first item in menu
sititle     dc.b  'Send Slower',0   ;second item in menu
tititle     dc.b  'Send Random',0   ;third menu item
offsetleft  dc.w  0
offsettop   dc.w  0
frequency   dc.w  600
      cnop   0,4

**  MENU and MENU ITEM STRUCTURES
mymenu:
   dc.l  0    ;menu pointer
   dc.w  0,0,150,100  ;leftedge,topedge,width,height
   dc.w  MIDRAWN!MENUENABLED  ;menuflags MENUENABLED & MIDRAWN
   dc.l  menutitle    ;pointer to title string
firstmenuitem  dc.l  0   ;pointer to first menu item (menuitemone)
   dc.w   0,0,0,0     ;for the jazz-beat (who knows what that means)

** The first menu item structure **
menuitemone  dc.l  0     ;pointer to second menuitem
   dc.w  0,0,130,11      ;left,top,width,height of select box
   dc.w   itemflags      ;see flags set above
   dc.l   0              ;mutual exclude null=no item excluded
itemonetext   dc.l   0   ;pointer to intuitext struct for item text
   dc.l   0              ;pointer to highlight alternate image/text
   dc.b   70,0     ;set if COMMSEQ flag is set & a kluge byte 'f'
   dc.l   0       ;subitem if any
   dc.w   0       ;next selected item in drag 'mi_NextSelect'
** remember to initialize all of these things
firstitemtext:
   dc.b  0,1,4,0  ;pens drawmode & kluge
   dc.w  0,0      ;leftedge,topedge
   dc.l  0        ;textfont null = default
fitext  dc.l  0   ;textpointer
   dc.l  0        ;pointer to next intuitext struct

** The second menu item structure **
menuitemtwo  dc.l  0  ;pointer to third menuitem
   dc.w  3,15,130,11  ;left,top,width,height of select box
   dc.w   itemflags   ;see flags set above
   dc.l   0           ;mutual exclude null=no item excluded
itemtwotext   dc.l   0   ;aptr to intuitext struct for this item text
   dc.l   0              ;aptr to highlight alternate image/text
   dc.b   83,0     ;set if COMMSEQ flag is set & a kluge byte 's'
   dc.l   0       ;subitem if any
   dc.w   0       ;next selected item in drag 'mi_NextSelect'
** remember to initialize all of these things
seconditemtext:
   dc.b  0,1,4,0  ;pens drawmode & kluge
   dc.w  0,0      ;leftedge,topedge
   dc.l  0        ;textfont null = default
sitext  dc.l  0   ;textpointer
   dc.l  0        ;pointer to next intuitext struct
   cnop  0,4

** The third menu item structure **
menuitem3  dc.l  0     ;pointer to second menuitem
   dc.w  3,30,150,11   ;left,top,width,height of select box
   dc.w   item3flags   ;see flags set above
   dc.l   0            ;mutual exclude null=no item excluded
item3text   dc.l   0   ;pointer to intuitext struct for item text
   dc.l   0            ;pointer to highlight alternate image/text
   dc.b   65,0     ;set only if COMMSEQ flag is set & a kluge byte
   dc.l   0       ;subitem if any
   dc.w   0       ;next selected item in drag 'mi_NextSelect'
** remember to initialize all of these things
thirditemtext:
   dc.b  0,1,4,0  ;pens drawmode & kluge
   dc.w  12,0      ;leftedge,topedge
   dc.l  0        ;textfont null = default
titext  dc.l  0   ;textpointer
   dc.l  0        ;pointer to next intuitext struct

**  An IntuiText Structure.  Use this to do the "printthis"
**  routine, with pointer to message in IntuMsg
intuitext:
  dc.b  1,1,2,0   ;FT & bk pen, drawmode, kluge
  dc.w  0,0       ;leftedge topedge
  dc.l  0         ;textfont normal if 0
IntuMsg  dc.l  0  ;pointer to null terminated text to be printed
  dc.l  0         ;next intuitext structure-null if none`
   cnop   0,4

line1  dc.b  'Welcome to the Morse Code Practice Program.',0
line2  dc.b  'It is designed to help you improve your Morse Code',0
line3  dc.b  'sending and receiving speed, with the hope that it',0
line4  dc.b  'will encourage you to get your amatuer radio license',0
line5  dc.b  'or to upgrade.  This is written in Assembly Language,',0
line6  dc.b  'and free distribution is encouraged.',0
line7  dc.b  'by Peter V. Inskeep, NO2D  --  72017,1211.',0
goodbye     dc.b  'GOOD BYE NOW!',0
pickgadget  dc.b  'Gadget Picked',0
pickitem1   dc.b  'Send Faster',0
pickitem2   dc.b  'Send Slower',0
pickitem3   dc.b  'Switch Code Source',0
playmouse   dc.b  'Playing with your Mouse?',0
consolefail dc.b  'Console.Device Failed to Open',0
consoleopen dc.b  'Console Opened Successfully',0
gottamsg   dc.b   'I got a message',0
;bitresult  dc.b   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  ;one extra for null
   cnop  0,4
longnull   dc.b   32,0,0,0,0
   cnop  0,4
hexprint   dc.b   '$ '
hexfield   dc.b   'fedc',0  ;five bytes, four used zero ends it
   cnop  0,4
** A border structure to support the erase routine.
 oneline:
  dc.w  0,0    ;left & top offsets
  dc.b  0,0    ;1,2 forground and background pens
  dc.b  0      ;jam1 drawing modes
  dc.b  2      ;number of xy coordinates to be drawn
oneline1  dc.l  0    ;where the coordinates are (onelinelist)
  dc.l  0      ;next border structure-null if none
A   cnop   0,4
onelinelist:
stx   dc.w  1    ;stuff these with the line starting and ending
sty   dc.w  1    ;coordinates for each line you want to draw
endx  dc.w  1    ;then call the border subroutine with the
endy  dc.w  1    ;oneline border structure address
   cnop    0,4
************** Gadget Rendering Section  **************************;  
g1txt   dc.b   'Slow',0
g2txt   dc.b   'Fast',0

g2itxt:
   dc.b   1   ft pen
   dc.b   0   bk pen
   dc.b   RP_JAM1  draw mode
   dc.w   0     left edge  ;where the word Fast will print relative
   dc.w   150         top edge  ;to the top left of gadget box 
   dc.l   0   font ptr 0=default
   dc.l   g2txt  text ptr   "Fast"
   dc.l   0      ptr to next text struct
g1itxt:
   dc.b   1   ft pen
   dc.b   0   bk pen
   dc.b   RP_JAM1  draw mode
   dc.w   0    left edge  ;where the word Slow will print
   dc.w   -10   top edge
   dc.l   0   font ptr 0=default
   dc.l   g1txt  text ptr  "Slow"
   dc.l   g2itxt   ;0      ptr to next text struct

g1xy:  ;coordinated for drawing the box x first, then y
   dc.w   10,10
   dc.w   10,50
   dc.w   100,50
   dc.w   100,10
   dc.w   10,10

border1:
   dc.w   200   ;leftedge
   dc.w   40   ;topedge
   dc.b   1   ;frontpen
   dc.b   2   ;backpen
   dc.b   RP_JAM1   ;drawmode
   dc.b   5   ;count of xy pairs
   dc.l   g1xy  ;vector coordinate pairs rel to lefttop
   dc.l   0
   cnop   0,4
image2:
   dc.w   0,0,64,11,1
   dc.l   0   ;image data pointer
   dc.b   1,0
   dc.l   0
   cnop   0,4
image1:
   dc.w   0    ;left
   dc.w   0    ;top
   dc.w   16   ;no. of pixels wide 
   dc.w   14   ;no. of rows high
   dc.w   1    ;bitplane depth 1 or 2 for what I am doing use 1
im1addr   dc.l   0   ;testimage
   dc.b   1    ;PlanePick
   dc.b   0    ;PlaneOnOff
   dc.l   0    ;next image
prop2:
   dc.w   prop1flags 
   dc.w   $3000 ;pi_HorizPot  
   dc.w   $0   
   dc.w   $800   
   dc.w   $0   
   dc.w   20      
   dc.w   20      
   dc.w   500     
   dc.w   500     
   dc.w   0   ;g1left   
   dc.w   0   ;g1top    
prop1:
   dc.w   propflags    ;flags  00
   dc.w   0       ;pi_HorizPot  02
   dc.w   $6000   ;pi_VertPot   04  ;code speed for propgadget
   dc.w   $0      ;pi_HorizBody the portion of the total that will  06
   dc.w   $400    ;pi_VertBody show in the gadget window  08
   dc.w   20      ;pi_CWidth  0a
   dc.w   20      ;pi_CHeight  0c
   dc.w   500     ;pi_HPotRes  0e
   dc.w   500     ;pi_VPotRes  10
   dc.w   gleft   ;pi_LeftBorder  12
   dc.w   gtop    ;pi_TopBorder  14
gadget2:
   dc.l   0        ;ptr to next gadget in list
   dc.w   g1left    ;left edge of gadget relative or absolute
   dc.w   g1top     ;top edge of gadget relative or absolute
   dc.w   g1wide    ;width of the gadget itself
   dc.w   g1high    ;height of the gadget
   dc.w   gadg1flags!gadg1rel   ;flags
   dc.w   RELVERIFY!BOTTOMBORDER    ;!TOPBORDER ;activation
   dc.w   PROPGADGET!GZZGADGET   ;gadget type  (03) & ($2000)
   dc.l   image2   ;ptr- border, image, or none(0)
   dc.l   0   ;select render alternate border, image
   dc.l   0   ;g1itxt   ;gadget text if any
   dc.l   0   ;mutual exclude
   dc.l   prop2   ;special info for prop, string and interger gadgets
   dc.w   1   ;user defined gadget id field
   dc.l   0   ;pointer to user data

gadget1:
   dc.l   gadget2        ;ptr to next gadget in list
   dc.w   gleft    ;left edge of gadget relative or absolute
   dc.w   gtop     ;top edge of gadget relative or absolute
   dc.w   gwide    ;width of the gadget itself
   dc.w   ghigh    ;height of the gadget
   dc.w   gadgflags!gadgrel   ;flags
   dc.w   RELVERIFY!RIGHTBORDER    ;!TOPBORDER ;activation
   dc.w   PROPGADGET!GZZGADGET   ;gadget type  (03) & ($2000)
   dc.l   image1   ;ptr- border, image, or none(0)
   dc.l   0   ;select render alternate border, image
   dc.l   0   ;g1itxt   ;gadget text if any
   dc.l   0   ;mutual exclude
   dc.l   prop1   ;special info for prop, string and interger gadgets
   dc.w   1   ;user defined gadget id field
   dc.l   0   ;pointer to user data
   
**  A NEW WINDOW STRUCTURE - GADGETUP ADDED 8/27/87  **
newwindow:
  dc.w  0,0,640,200   ;Left,Top,Width,Height
  dc.b  0,1           ;DetailPen, BlockPen
  dc.l  CLOSEWINDOW!MENUPICK!GADGETUP         ;!FOLLOWMOUSE;IDCMFlags
  dc.l  MyFlags       ;Flags-described above
  dc.l  gadget1       ;gadget pointer load yours here 
  dc.l  0             ;CheckMark    Default
  dc.l  MyTitle       ;Title-see above
  dc.l  0             ;Screen: 0=Default
  dc.l  0             ;BitMap   Default
  dc.w  50,50,640,200 ;Minwidth,height;Maxwidth,height
  dc.w  WBENCHSCREEN  ;Type- customscreen is more work
  cnop   0,4
onecharbuf  dc.b  0,0,0,0,0,0,0,0  ;buffer for onechar (onecharptr)
   cnop   0,4
testmsg  dc.b  'MORSE CODE TEST PROGRAM',13,10
         dc.b  'by Peter Inskeep - NO2D',13,10
         dc.b  'Dated January 10, 1987',13,10,13,10
  dc.b  'Type lower case characters on the keyboard.  Each',13,10
  dc.b  'character should print on the screen and its morse',13,10
  dc.b  'code will sound through both speakers.',13,10,10
  dc.b  'Use the Prop Gadgets at the right edge and the bottom of',13,10
  dc.b  'the window to change sending speed and pitch.',13,10,10
  dc.b  'Or, use the Menu to send faster or slower,',13,10
  dc.b  'or to switch between keyboard and random sending.',13,10,10
  dc.b  'Have FUN and Learn.',13,10,0

endline   dc.b  13,10,0
decitable   dc.w   10000,1000,100,10
testbuff dc.b  '0',13,10,0
;ConsoleDeviceName:
;  dc.b  'console.device',0
;NotFound:
;  dc.b  13,10,'No char-match found',13,10,0
;  cnop   0,4

** Timing counters for dot and dash sound elements
elmdelay    dc.l  $0500
elmdelay1   dc.l  $0002
dashdelay   dc.l  $0500
dashdelay1  dc.l  $0006
charspce    dc.b  2
wordspce    dc.b  7
dashlen     dc.b  2         ;we may not need this if we use dashdelay

alphacode:
  dc.b  43            ;44 chars in table [0-43]
  dc.b  '?.,-/=\;'    ;8 char ;=(._._.) \(..._._) ;(_..._)
  dc.b  '0987654321'  ;10 char
  dc.b  'jqyzxcpbvflowgdkurhsmnaite',0  ;26 char
dotdash:
  dc.b  6,%00001100   ; ?
  dc.b  6,%00010101   ; .
  dc.b  6,%00110011   ; ,
  dc.b  5,%00010001   ; -
  dc.b  5,%00010010   ; /
  dc.b  5,%00001010   ; =  .-.-.
  dc.b  6,%00000101   ; \  ...-.-
  dc.b  5,%00010001   ; ;  -...-
  dc.b  5,%00011111   ; 0
  dc.b  5,%00011110   ; 9
  dc.b  5,%00011100   ; 8
  dc.b  5,%00011000   ; 7
  dc.b  5,%00010000   ; 6
  dc.b  5,%00000000   ; 5
  dc.b  5,%00000001   ; 4
  dc.b  5,%00000011   ; 3
  dc.b  5,%00000111   ; 2
  dc.b  5,%00001111   ; 1
  dc.b  4,%00000111   ; j
  dc.b  4,%00001101   ; q
  dc.b  4,%00001011   ; y
  dc.b  4,%00001100   ; z
  dc.b  4,%00001001   ; x
  dc.b  4,%00001010   ; c
  dc.b  4,%00000110   ; p
  dc.b  4,%00001000   ; b
  dc.b  4,%00000001   ; v
  dc.b  4,%00000010   ; f
  dc.b  4,%00000100   ; l
  dc.b  3,%00000111   ; o
  dc.b  3,%00000011   ; w
  dc.b  3,%00000110   ; g
  dc.b  3,%00000100   ; d
  dc.b  3,%00000101   ; k
  dc.b  3,%00000001   ; u
  dc.b  3,%00000010   ; r
  dc.b  4,%00000000   ; h
  dc.b  3,%00000000   ; s
  dc.b  2,%00000011   ; m
  dc.b  2,%00000010   ; n
  dc.b  2,%00000001   ; a
  dc.b  2,%00000000   ; i
  dc.b  1,%00000001   ; t
  dc.b  1,%00000000   ; e
   cnop   0,4  
  SECTION   IMAGEDATA,DATA
beginpubmem:  
theimage:
   dc.w   %1111111111111111
   dc.w   %1100000000000011
   dc.w   %1100001111100011
   dc.w   %1100010000010011
   dc.w   %1100010000000011
   dc.w   %1100001111100011
   dc.w   %1100000000010011
   dc.w   %1100000000010011
   dc.w   %1100010000010011
   dc.w   %1100001111100011
   dc.w   %1100000000000011
   dc.w   %1100000000000011
   dc.w   %1100000000000011
   dc.w   %1111111111111111
imagebytes  equ *-beginpubmem
pitchimage:
 dc.w  %1111111111111111,%1111111111111111,%1111111111111111,%1111111111111111
 dc.w  %1100000000000000,%0000000000000000,%0000000000000000,%0000000000000011
 dc.w  %1100111110000111,%1111100001111111,%1110000001111000,%0001100000110011
 dc.w  %1100110001100000,%1100000000000110,%0000000011000110,%0001100000110011
 dc.w  %1100110001100000,%1100000000000110,%0000000110000000,%0001100000110011
 dc.w  %1100111110000000,%1100000000000110,%0000000110000000,%0001111111110011
 dc.w  %1100110000000000,%1100000000000110,%0000000110000000,%0001100000110011
 dc.w  %1100110000000000,%1100000000000110,%0000000011000110,%0001100000110011
 dc.w  %1100110000000111,%1111100000000110,%0000000001111000,%0001100000110011
 dc.w  %1100000000000000,%0000000000000000,%0000000000000000,%0000000000000011
 dc.w  %1111111111111111,%1111111111111111,%1111111111111111,%1111111111111111
pitchbytes  equ *-pitchimage
   dcb.w   50,1
sizepubmem equ *-beginpubmem
   cnop 0,4
beginaudio:  
Wavesample:
        dc.b 0,32,64,96,120,120,120,120,120,120,120,120
        dc.b 90,64,32,0,-32,-64,-90,-120,-120,-120
        dc.b -120,-120,-120,-120,-120,-120,-96,-64,-32,0
sizeaudio  equ *-beginaudio
  SECTION   mem,BSS
IntuitionLibrary   ds.l  1   ;keep address of Intuition here
GraphicsLibrary    ds.l  1   ;keep address of Graphics here
DeviceLibrary      ds.l  1
DosLibrary    ds.l  1   ;DOS Library pointer
decinumber    ds.l  1   ;number to become decimal string
readbufptr    ds.l  1   ;for conread a 0 term string 
readbuffer    ds.l  100 ;storage for readbufptr
onecharptr    ds.l  1   ;pointer for one character write buffer
bufptr        ds.l  1   ;a general buffer pointer
buffer        ds.l  20  ;a one screen line buffer
handle        ds.l  1   ;console file read handle
prtbuff       ds.l  25  ;buffer for special print (end in 0)
prtptr        ds.l  1   :pointer for the spec.print buffer
outfile       ds.l  1   ;pointer for output(a6) call
codecntr      ds.l  1   ;counter for code sending
kbcntr        ds.l  1   ;counter for keyboard usage (with codecntr)
ltrcode       ds.l  1   ;store letter number here
carreturn     ds.l  1   ;holds carriage return in linelen
MyWindow      ds.l  1   ;address of the structure describing our window
mywdsize      ds.l  1   ;size of the window 
bucket        ds.l  1   ;a place to dump things
intuimessage  ds.l  1   ;pointer to IntuiMessage message structure
userport      ds.l  1   ;pointer to wd_UserPort structure
myclass       ds.l  1   ;ICDMP Class or equal to flag ie., MENUPICK
menupoint     ds.l  1   ;pointer to menu structure
idcmpmessage  ds.l  1   ;the message class reported by intuimessage
myrport     ds.l   1   ;this windows rastport
seconds     ds.l   1   ;seconds in IntuiMessage
micros      ds.l   1   ;microseconds in IntuiMessage
keybuf      ds.l  bufferlen    ;keystroke buffer 
kbptr       ds.l   1   ;keybuf current position pointer
kbendptr    ds.l   1   ;end of keybuf pointer
codeptr     ds.l   1   ;code sending current position (not same as kbptr)
prtachar    ds.l   1   ;need byte, but try this instead
randflag    ds.l   1   ;random flag 1=keyboard 0=random
consoleflag  ds.l  1   ;flag for success opening console 0=success
ioreadbuffer   ds.l   20 ;read buffer 80 characters max
iowritbuf   ds.l   1   ;one char write buffer, but longword
ioreadbuf   ds.l   1   ;one char read buffer, but longword
ioreqptr    ds.l   1   ;pointer to io request block
;mygadptr   ds.l   1   ;ptr to regular gadget structure
;mypropptr  ds.l   1   ;pointer to proportional gadget info structure
ranword     ds.l   1   ;a cntr for random word space
memblock    ds.l   1   ;pointer to image data in memory
pitchblock  ds.l   1   ;ptr to pitch image data
audioblock  ds.l   1   ;ptr to audio data block
lastrandom  ds.l   1   ;store the last random # here
mousex      ds.w   1   ;x mouse coordinate
mousey      ds.w   1   ;y mouse coordinate
mycode      ds.w   1   ;for things line menu# ie, 0,1,2,3, etc.
infrequency   ds.w   1   ;holds sound frequency fm horizpot

   END    
