   1:			;*=*=*
   2:			;	xtrsmous/cmd
   3:			;	LS-DOS driver for xtrs emulation of mouse
   4:			;
   5:			;	Copyright (c) 1998, Timothy Mann
   6:			;       $Id: xtrsmous.z80,v 1.2 2008/06/26 04:39:56 mann Exp $
   7:			;
   8:			;	This software may be copied, modified, and used for any
   9:			;	purpose without fee, provided that (1) the above copyright
  10:			;	notice is retained, and (2) modified versions are clearly
  11:			;	marked as having been modified, with the modifier's name and
  12:			;	the date included.  
  13:			;
  14:			;	Usage:
  15:			;	  xtrsmous		To load driver in high memory.
  16:			;	  xtrsmous (low) 	To load driver in low memory if possible,
  17:			;				  or in high memory if low memory is full.
  18:			;
  19:			;	The default is to use high memory because MDRAW/BAS contains a
  20:			;	PEEK in the first line of code that looks for the driver in
  21:			;	high memory; if it is in low memory, MDRAW thinks the driver
  22:			;	is not installed and exits.  If you edit this line of code to
  23:			;	remove the test, the driver will work fine in low memory.
  24:			;*=*=*
  25:			
  26:			
  27:			; ASCII chars
  28:	000A          	LF      equ     10
  29:	000D          	CR	equ	13
  30:	0003          	ETX	equ	3
  31:			
  32:			; Model 4 SVC numbers
  33:	0064          	@high   equ     100
  34:	000A          	@dsply  equ     10
  35:	0065          	@flags  equ     101
  36:	000C          	@logot  equ     12
  37:	0052          	@gtdcb  equ	82 
  38:	0053          	@gtmod	equ	83
  39:	0009          	@keyin	equ	9
  40:	0011          	@param	equ	17
  41:	0078          	@mouse	equ     120     ;unofficial value
  42:			
  43:	01F0          	svcvec	equ	100h + 2*@mouse
  44:			
  45:			; xtrs emts (byte-reversed)
  46:	29ED          	emt_mouse  equ	029edh
  47:			
  48:	3000          		org	3000h
  49:			;*=*=*
  50:			; 	Relocator for disk driver
  51:			;*=*=*
  52:	3000  116B31  	instal:	ld	de,prmtab
  53:	3003  3E11    		ld	a,@param	;Parse parameters
  54:	3005  EF      		rst	40
  55:	3006  C29530  		jp	nz,prmerr
  56:	3009  21D230  		ld      hl,hello_
  57:	300C  3E0A    		ld      a,@dsply        ;Display hello
  58:	300E  EF      		rst     40
  59:			;*=*=*
  60:			;       Check if driver already loaded
  61:			;*=*=*
  62:	300F  118131  		ld	de,modnam
  63:	3012  3E53    		ld	a,@gtmod
  64:	3014  EF      		rst	40
  65:	3015  CA9930  		jp	z,loaded	;Already loaded
  66:			;*=*=*
  67:			;	Check if OK to use low memory.
  68:			;*=*=*
  69:	3018  010000  	lparm:	ld	bc,0
  70:	301B  78      		ld	a,b
  71:	301C  B1      		or	c
  72:	301D  2828    		jr	z,usehi
  73:			;*=*=*
  74:			;       Obtain low memory driver pointer.  Bizarre API here!
  75:			;*=*=*
  76:	301F  1E4B    	        ld      e,'K'           ;Locate pointer to *KI DCB
  77:	3021  1649    		ld	d,'I'		;  via @GTDCB SVC
  78:	3023  3E52    	        ld      a,@gtdcb        
  79:	3025  EF      	        rst     40
  80:	3026  C29D30  	        jp      nz,curdl        ;No error unless KI clobbered!
  81:	3029  2B      	        dec     hl              ;Decrement to driver pointer
  82:	302A  56      	        ld      d,(hl)          ;P/u hi-order of pointer,
  83:	302B  2B      	        dec     hl              ;  decrement to and p/u
  84:	302C  5E      	        ld      e,(hl)          ;  lo-order of pointer
  85:			;*=*=*
  86:			;       Check if driver will fit into [(LCPTR), X'12FF']
  87:			;*=*=*
  88:	302D  E5      		push	hl		;Save address of pointer
  89:	302E  211F00  	        ld      hl,length	;New pointer will be
  90:	3031  19      	        add     hl,de		;  pointer + LENGTH
  91:	3032  54      		ld	d,h		;Save a copy in DE
  92:	3033  5D      		ld	e,l
  93:	3034  010113  	        ld      bc,1301h        ;If > 1300H, driver won't fit
  94:	3037  97      	        sub     a               ;Reset carry flag
  95:	3038  ED42    	        sbc     hl,bc
  96:	303A  E1      		pop	hl		;Get back address of pointer
  97:	303B  300A    	        jr      nc,usehi        ;Go if driver won't fit
  98:	303D  73      		ld	(hl),e		;Store new value of pointer
  99:	303E  23      		inc	hl
 100:	303F  72      		ld	(hl),d
 101:	3040  1B      		dec	de		;Last byte of driver goes here
 102:	3041  ED536931		ld      (newend),de
 103:	3045  1816    		jr	dorelo
 104:			;*=*=*
 105:			;       Put in high memory instead.
 106:			;*=*=*
 107:	3047  210000  	usehi:	ld      hl,0            ;Get current HIGH$
 108:	304A  45      		ld      b,l
 109:	304B  3E64    		ld      a,@high 
 110:	304D  EF      		rst     40
 111:	304E  C2A130  		jp      nz,nomem
 112:	3051  226931  		ld      (newend),hl	;Last byte of driver goes here
 113:	3054  111F00  		ld	de,length
 114:	3057  97      		sub	a		;Reset carry flag
 115:	3058  ED52    		sbc	hl,de		;Compute new HIGH$
 116:	305A  3E64    		ld      a,@high         ;Set new HIGH$ into the system
 117:	305C  EF      		rst     40
 118:			;*=*=*
 119:			;       Relocate internal references in driver.
 120:			;	HL = address for last byte of driver.
 121:			;*=*=*
 122:	305D  CDAB30  	dorelo:	call	relo
 123:			;*=*=*
 124:			;	Link to @ICNFG (must follow address relocation and precede movement)
 125:			;*=*=*
 126:	3060  3E65    		ld      a,@flags        ;Get flags pointer into IY
 127:	3062  EF      		rst     40
 128:	3063  FD7E1C  	        ld      a,(iy+28)       ;Copy current @ICNFG into LINK
 129:	3066  FD6E1D  	        ld      l,(iy+29)
 130:	3069  FD661E  	        ld      h,(iy+30)
 131:	306C  329131  		ld	(link),a
 132:	306F  229231  	        ld      (link+1),hl
 133:	3072  218E31  		ld	hl,dvrcfg	;Get relocated init address
 134:	3073          	rx01	equ	$-2
 135:	3075  FD751D  	        ld      (iy+29),l       ;Save in @ICNFG vector
 136:	3078  FD741E  	        ld      (iy+30),h
 137:	307B  FD361CC3		ld	(iy+28),0c3h	;Insert JP opcode
 138:			;*=*=*
 139:			;       Move driver into low or high memory.
 140:			;*=*=*
 141:	307F          	move:
 142:	307F  ED5B6931		ld      de,(newend)     ;Destination address
 143:	3083  219A31  		ld      hl,dvrend       ;Last byte of module
 144:	3086  011F00  		ld      bc,length       ;Length of filter
 145:	3089  EDB8    		lddr
 146:	308B  EB      		ex      de,hl
 147:	308C  23      		inc     hl              ;Bump to driver entry
 148:			;*=*=*
 149:			;	Driver is loaded; finish up.
 150:			;*=*=*
 151:	308D  CD9431  		call	dvrini		;Hook into SVC table
 152:			
 153:	3090  210000  		ld      hl,0            ;Successful completion
 154:	3093  97      		sub	a
 155:	3094  C9      		ret
 156:			
 157:			;*=*=*
 158:			;	Error vectors
 159:			;*=*=*
 160:	3095  215731  	prmerr:	ld	hl,prmerr_
 161:	3098  DD      		defb	0ddh
 162:	3099  213731  	loaded:	ld	hl,loaded_
 163:	309C  DD      		defb	0ddh
 164:	309D  210631  	curdl:	ld	hl,curdl_
 165:	30A0  DD      		defb	0ddh
 166:	30A1  211931  	nomem:  ld      hl,nomem_
 167:	30A4  3E0C    	logot:	ld	a,@logot 
 168:	30A6  EF      		rst	40
 169:	30A7  21FFFF  		ld      hl,-1            ;Unuccessful completion
 170:	30AA  C9      		ret
 171:			
 172:			;*=*=*
 173:			;       Relocate internal references in driver.
 174:			;	HL = address for last byte of driver.
 175:			;*=*=*
 176:	30AB  2A6931  	relo:	ld	hl,(newend)
 177:	30AE  FD219B31		ld      iy,reltab       ;Point to relocation tbl
 178:	30B2  119A31  		ld      de,dvrend
 179:	30B5  97      		sub     a               ;Clear carry flag
 180:	30B6  ED52    		sbc     hl,de
 181:	30B8  44      		ld      b,h             ;Move to BC
 182:	30B9  4D      		ld      c,l
 183:	30BA  FD6E00  	rloop:  ld      l,(iy)          ;Get address to change
 184:	30BD  FD6601  		ld      h,(iy+1)
 185:	30C0  7C      		ld      a,h
 186:	30C1  B5      		or      l
 187:	30C2  C8      		ret	z
 188:	30C3  5E      		ld      e,(hl)          ;P/U address
 189:	30C4  23      		inc     hl
 190:	30C5  56      		ld      d,(hl)
 191:	30C6  EB      		ex      de,hl           ;Offset it
 192:	30C7  09      		add     hl,bc
 193:	30C8  EB      		ex      de,hl
 194:	30C9  72      		ld      (hl),d          ;And put back
 195:	30CA  2B      		dec     hl
 196:	30CB  73      		ld      (hl),e
 197:	30CC  FD23    		inc     iy
 198:	30CE  FD23    		inc     iy
 199:	30D0  18E8    		jr      rloop           ;Loop till done
 200:			
 201:			;*=*=*
 202:			;	Messages and globals
 203:			;*=*=*
 204:	30D2  58545253	hello_: defb    'XTRSMOUS - Emulated mouse driver for xtrs - 9/28/98',CR
	      4D4F5553
	      202D2045
	      6D756C61
	      74656420
	      6D6F7573
	      65206472
	      69766572
	      20666F72
	      20787472
	      73202D20
	      392F3238
	      2F39380D
 205:	3106  4C532D44	curdl_:	defb	'LS-DOS is curdled!',CR
	      4F532069
	      73206375
	      72646C65
	      64210D
 206:	3119  48696768	nomem_: defb    'High memory is not available!',CR
	      206D656D
	      6F727920
	      6973206E
	      6F742061
	      7661696C
	      61626C65
	      210D
 207:	3137  4D6F7573	loaded_:defb	'Mouse driver is already loaded!',CR
	      65206472
	      69766572
	      20697320
	      616C7265
	      61647920
	      6C6F6164
	      6564210D
 208:	3157  42616420	prmerr_:defb	'Bad parameters!',CR
	      70617261
	      6D657465
	      7273210D
 209:	3167  0000    	lcptr:	defw	0
 210:	3169  0000    	newend:	defw	0
 211:			
 212:			;*=*=*
 213:			;	Parameter table
 214:			;*=*=*
 215:	316B  4C4F5720	prmtab:	defb	'LOW   '
	      2020
 216:	3171  1930    		defw	lparm+1
 217:	3173  4C202020		defb	'L     '
	      2020
 218:	3179  1930    		defw	lparm+1
 219:	317B  00      		defb	0
 220:			
 221:			;*=*=*
 222:			;	Driver
 223:			;*=*=*
 224:	317C  180D    	entry:  jr      begin           ;The driver starts with the
 225:	317E  9A31    		defw    dvrend          ;  DOS standard header
 226:	317E          	rx00	equ	$-2
 227:	3180  06      		defb    modptr-modnam   ;Length of name
 228:	3181  244D4F55	modnam:	defb    '$MOUSE'        ;Name for @GTMOD requests
	      5345
 229:	3187  0000    	modptr: defw    0               ;These pointers are unused, but 1st byte MBZ
 230:	3189  0000    		defw    0
 231:			;*=*=*
 232:			;	Do the real work using an emulator trap
 233:			;*=*=*
 234:	318B  ED29    	begin:	defw	emt_mouse
 235:	318D  C9      		ret
 236:			;*=*=*
 237:			;	Boot-time initialization
 238:			;*=*=*
 239:	318E          	dvrcfg:				;@ICNFG chains in here
 240:	318E  CD9431  		call	dvrini
 241:	318F          	rx02	equ	$-2	
 242:	3191  54696D  	link:	defb	'Tim'		;Replaced by next link in @ICNFG chain
 243:			;*=*=*
 244:			;	Hook into SVC table
 245:			;*=*=*
 246:	3194  217C31  	dvrini:	ld	hl,entry
 247:	3195          	rx03	equ	$-2
 248:	3197  22F001  		ld	(svcvec),hl
 249:	319A  C9      		ret
 250:			
 251:	319A          	dvrend  equ     $-1
 252:	001F          	length  equ     $-entry
 253:	319B  7E317330	reltab: defw    rx00,rx01,rx02,rx03,0
	      8F319531
	      0000
 254:	3000          		end     instal



Statistics:

    48	symbols
   421	bytes



Symbol Table:

@dsply         =   a     emt_mouse      =29ed     nomem           30a1     
@flags         =  65     entry           317c     nomem_          3119     
@gtdcb         =  52     etx            =   3+    prmerr          3095     
@gtmod         =  53     hello_          30d2     prmerr_         3157     
@high          =  64     instal          3000     prmtab          316b     
@keyin         =   9+    lcptr           3167+    relo            30ab     
@logot         =   c     length         =  1f     reltab          319b     
@mouse         =  78     lf             =   a+    rloop           30ba     
@param         =  11     link            3191     rx00           =317e     
begin           318b     loaded          3099     rx01           =3073     
cr             =   d     loaded_         3137     rx02           =318f     
curdl           309d     logot           30a4+    rx03           =3195     
curdl_          3106     lparm           3018     svcvec         = 1f0     
dorelo          305d     modnam          3181     usehi           3047     
dvrcfg          318e     modptr          3187     
dvrend         =319a     move            307f+    
dvrini          3194     newend          3169     
