;The following program demonstrates a solution to a problem given in class
;
;It allows the user to put three initials in the upper left hand corner of
;the screen with input coming from a joystick or paddle
;
;Essentially, the user can move the joystick or paddle to the right or left
;which will cause the letters of the alphabet to be rotated upon the screen.
;When the computer displays the desired letter, the user selects it by pressing
;the button on the joystick or paddle
;
;
;			    **********************
;			    *			 *
;			    *	JOYSTICK-STAR	 *
;			    *			 *
;			    * mini-wordprocessor *
;			    *	 version 1.0	 *
;			    *	      by	 *
;			    *			 *
;			    *	 Nathan Hull	 *
;			    *			 *
;			    **********************
;
	 xor   dx,dx	      ;blank screen
         mov   al,' '
	 mov   cx,2000
	 mov   bl,07h
	 call  paint
;

	 call  joystar	      ;insert this call anywhere in your program desired
;
	 int   20h	      ;return to DOS
;
;the following routine puts three characters in the upper left-hand corner
;of the screen. It could be easily expanded
;
joystar: push  dx
	 xor   dx,dx	      ;zero out dx register - set col and row = 0
joyloop: call  dischr	      ;put one character on the screen
	 inc   dl	      ;go to next column
	 cmp   dl,3	      ;stop after 3 characters
	 jb    joyloop
	 pop   dx
	 ret
;
;This routine puts a single character in the DOS color on the screen
;in row dh, column dl
;
normc	 equ   07h	      ;grey on black (DOS color)
red	 equ   04h	      ;red on black
joydir	 db    ?	      ;direction to go thru alphabet
;				   -1 = backwards
;                                   0 = don't change
;				   +1 = forwards
curchr	 db    ?	      ;current character displayed
;
dischr:  push  ax
	 push  bx
	 push  cx
	 push  dx
         mov   curchr,'A'     ;start with an A
	 mov   bl,red	      ; and write it out in red on black
disloop: call  wrtchr	      ;write single char in current color at curr loc
	 call  delay	      ;always nice to be able to see it
chkbutn: mov   ah,0	      ;look at top button
	 int   60h	      ;call dewar paddle/joystick routine
	 or    al,al	      ;check high order bit : button pressed if = 1
	 js    gotchr	      ;stop look if button is pressed
	 call  getdir	      ; else find which direction joystick is pressed
	 cmp   joydir,0       ;check for joystick in middle position
	 je    chkbutn	      ; if it is, jump to check for fire button
	 call  getchr	      ;   else, get the next character to display
	 jmp   disloop
gotchr:  mov   bl,normc       ;rewrite final character in DOS color
	 call  wrtchr
	 pop   dx
	 pop   cx
	 pop   bx
	 pop   ax
	 ret
;
;
;
; routine to write a single character
;	 input:  (bl)	      color
;		 (dh, dl)     row and column
;		 (curchr)     character to write
;
wrtchr:  push  ax
	 push  cx
	 mov   cx,1	      ;write only one character
	 mov   al,curchr      ;character to write is the current one
	 call  paint
	 pop   cx
	 pop   ax
	 ret
;
;
;
; routine to find the direction to joystick is pointing
;  the result is placed in joydir = -1 if joystick = 0 thru 34
;				  =  0 if joystick = 35 thru 44
;				  = +1 if joystick = 45 thru 79
;
getdir:  push  ax
	 mov   ah,0	      ;select horizontal axis
	 int   60h	      ;call dewar joystick routine
	 and   al,7fh	      ;strip off high order bit
	 cmp   al,34	      ;is joystick pointing left?
	 jbe   left
	 cmp   al,44	      ;is joystick in the center (neutral) position?
	 jbe   center
	 mov   joydir,+1      ;else joystick is pointing to right: set dir
	 jmp   dirfin	      ;jump to return
left:	 mov   joydir,-1      ;joystick pointing left: set dir
	 jmp   dirfin
center:  mov   joydir,0       ;joystick in neutral position: set dir
dirfin:  pop   ax
	 ret
;
;
;
; this routine finds the next ASCII character to display and places
; it in curchr.  It uses joydir to detemine which direction to move
; in the alphabet.  Notice that only the lower and upper case letters,
; and the character 'space' are used.
;
getchr:  push  ax
	 mov   al,curchr      ;move in the old character
         cmp   al,' '         ;is the old  character a space?
	 je    space	      ; if so, handle it separately
	 add   al,joydir      ;   else, find next character in ASCII sequence
         cmp   al,'A'         ;have we gone lower than an A?
	 jae   lowchk	      ;if not, check lower case
         mov   al,' '         ;if so, set next char to a space
	 jmp   chrfin	      ;jump to return
lowchk:  cmp   al,'z'         ;have we gone higher than a low case z?
	 jbe   midchk	      ;if not, check for characters between alphabets
         mov   al,' '         ;if so, set next char to a space
	 jmp   chrfin	      ;jump to return
midchk:  cmp   al,'Z'         ;check end of upper alphabet
	 jbe   chrfin	      ;new character is A thru Z
         cmp   al,'a'         ;check begin of lower alphabet
	 jae   chrfin	      ;new character is a thru z
	 cmp   joydir,0       ;else new character is between alphabets
	 jle   Z	      ;signed comparison:
;				if joydir = -1
;                                then going from 'a' to 'Z'
         mov   al,'a'         ;    else going from 'Z' to 'a'
	 jmp   chrfin	      ;jump to return
Z:       mov   al,'Z'         ;new character is Z
	 jmp   chrfin	      ;jump to return
space:	 cmp   joydir,0       ;signed comparison:
	 jge   A	      ; if joydir = +1
;                                then going from space to 'A'
         mov   al,'z'         ;   else gong from space to 'z'
	 jmp   chrfin	      ;jump to return
A:       mov   al,'A'         ;new characters is A
chrfin:  mov   curchr,al
	 pop   ax
	 ret
;
;
;
; the following three routines are from the game program:
;
delay:	 push  dx	      ;save registers
	 mov   dh,25	      ;get cursor off screen area (cleaner appearence)
	 mov   dl,0
	 call  setpos
	 mov   dx,40000       ;set delay constant
delay1:  dec   dx	      ;decrement delay counter
	 jnz   delay1	      ;loop till delay is complete
	 pop   dx	      ;restore registers
	 ret
;
;
;
;routine to set cursor position
;
;	 (dh, dl)	      cursor line, column
;	 call setpos
;
setpos:  push  ax	      ;save registers
	 push  bx
	 mov   bh,0	      ;set cursor on page 0
	 mov   ah,2
	 int   10h
	 pop   bx	      ;restore registers
	 pop   ax
	 ret
;
;
;
; routine to paint characters on screen
;
;	 (dh, dl)	      line, column of start of area to paint
;	 (cx)		      number of characters to paint
;	 (bl)		      required color
;	 (al)		      ASCII character code
;	 call paint
;
paint:	 push  ax	      ;save registers
	 push  bx
	 cmp   cx,0	      ;skip if no chars to paint
	 je    paint1
	 call  setpos	      ;set cursor psitin
	 mov   bh,0	      ;write the characters on page 0
	 mov   ah,9
	 int   10h
paint1:  pop   bx	      ;restore registers
	 pop   ax
	 ret
;
;
	 end
