mads 1.9.0 build 21 (16 Aug 09)
Source: C:\nes\atalan\codebase\atalan\examples/interrupts.asm
     1 = 0600			_stdbuf equ 1536
     2 = 0080			_arr equ 128
     3 = 0653			_putchr_proc_adr equ 1619
     4 = 0080			_std_print_adr__a equ _arr
     5 = 0080			_std_print_adr___10 equ _arr
     6 = 0600			_std_print_adr___11 equ _stdbuf
     7 = 0653			_std_print_adr___12 equ _putchr_proc_adr
     8 = D40A			WSYNC equ 54282
     9 = 0000			color__Black equ 0
    10 = 000F			color__White equ 15
    11 = 02C4			COLOR0 equ 708
    12 = D016			COLPF equ 53270
    13 = D01A			COLBK equ 53274
    14 = 0070			dl_command__BLANK8 equ 112
    15 = 0002			dl_command__CHR0 equ 2
    16 = 0041			dl_command__NEXT equ 65
    17 = 0230			SDLSTL equ 560
    18 = D40E			NMIEN equ 54286
    19 = 0200			VDSLST equ 512
    20 = 0224			VVBLKD equ 548
    21 = 8000			s equ 32768
    22 				   org $2e0
    23 FFFF> 02E0-02E1> 00 20	   dta a($2000)
    24 02E2			   org $2000
    25 				;### interrupts.atl(39) sdlstl = gr0
    26 2000-220D> A9 6B		   lda #<gr0
    27 2002 8D 30 02		   sta SDLSTL-0
    28 2005 A9 20		   lda #>gr0
    29 2007 8D 31 02		   sta SDLSTL-0+1
    30 				;### interrupts.atl(40) COLOR0(2) = red+8
    31 200A A9 48		   lda #72
    32 200C 8D C6 02		   sta COLOR0-0+2
    33 				;### interrupts.atl(41) COLOR0(5) = black
    34 200F A9 00		   lda #color__Black
    35 2011 8D C9 02		   sta COLOR0-0+5
    36 				;### interrupts.atl(45) s(1,1) = "Demonstration of Interrupts in ATALAN"
    37 2014 A0 01		   ldy #1
    38 2016 B9 8B 20		   lda s_lo,y
    39 2019 18			   clc
    40 201A 69 01		   adc #1
    41 201C 85 80		   sta _arr-0
    42 201E B9 A3 20		   lda s_hi,y
    43 2021 69 00		   adc #0
    44 2023 85 81		   sta _arr-0+1
    45 2025 20 F6 20		   jsr _std_print_adr
    46 2028 25 44 65 6D 6F 6E +    dta b(37),c'Demonstration of Interrupts in ATALAN'
    47 204E 00			   dta b(0)
    48 				;### interrupts.atl(49) on'vbi cycle
    49 204F A9 CF		   lda #<cycle
    50 2051 8D 24 02		   sta VVBLKD-0
    51 2054 A9 20		   lda #>cycle
    52 2056 8D 25 02		   sta VVBLKD-0+1
    53 				;### interrupts.atl(50) on'dli set_col
    54 2059 A9 BC		   lda #<set_col
    55 205B 8D 00 02		   sta VDSLST-0
    56 205E A9 20		   lda #>set_col
    57 2060 8D 01 02		   sta VDSLST-0+1
    58 2063 A9 C0		   lda #192
    59 2065 8D 0E D4		   sta NMIEN
    60 2068			_lbl4:
    61 2068 4C 68 20		   jmp _lbl4
    62 206B			gr0:
    63 				;### interrupts.atl(13) 	3 times BLANK8, 
    64 206B 70			   dta b(dl_command__BLANK8)
    65 206C 70			   dta b(dl_command__BLANK8)
    66 206D 70			   dta b(dl_command__BLANK8)
    67 				;### interrupts.atl(14) 	CHR0+LMS, s, 
    68 206E 42			   dta b(66)
    69 206F 00 80		   dta a(s)
    70 				;### interrupts.atl(15) 	2 times CHR0, 
    71 2071 02			   dta b(dl_command__CHR0)
    72 2072 02			   dta b(dl_command__CHR0)
    73 				;### interrupts.atl(16) 	CHR0+DLI, 
    74 2073 82			   dta b(130)
    75 				;### interrupts.atl(17) 	20 times CHR0, 
    76 2074 02			   dta b(dl_command__CHR0)
    77 2075 02			   dta b(dl_command__CHR0)
    78 2076 02			   dta b(dl_command__CHR0)
    79 2077 02			   dta b(dl_command__CHR0)
    80 2078 02			   dta b(dl_command__CHR0)
    81 2079 02			   dta b(dl_command__CHR0)
    82 207A 02			   dta b(dl_command__CHR0)
    83 207B 02			   dta b(dl_command__CHR0)
    84 207C 02			   dta b(dl_command__CHR0)
    85 207D 02			   dta b(dl_command__CHR0)
    86 207E 02			   dta b(dl_command__CHR0)
    87 207F 02			   dta b(dl_command__CHR0)
    88 2080 02			   dta b(dl_command__CHR0)
    89 2081 02			   dta b(dl_command__CHR0)
    90 2082 02			   dta b(dl_command__CHR0)
    91 2083 02			   dta b(dl_command__CHR0)
    92 2084 02			   dta b(dl_command__CHR0)
    93 2085 02			   dta b(dl_command__CHR0)
    94 2086 02			   dta b(dl_command__CHR0)
    95 2087 02			   dta b(dl_command__CHR0)
    96 				;### interrupts.atl(18) 	NEXT, gr0
    97 2088 41			   dta b(dl_command__NEXT)
    98 2089 6B 20		   dta a(gr0)
    99 208B 00 28 50 78 A0 C8 + s_lo:  :24 dta l(s + #*40)
   100 20A3 80 80 80 80 80 80 + s_hi:  :24 dta h(s + #*40)
   101 20BB 60			   rts
   102 20BC			set_col .proc
   103 20BC 48			   pha
   104 20BD 8A			   txa
   105 20BE 48			   pha
   106 20BF 98			   tya
   107 20C0 48			   pha
   108 				;### interrupts.atl(26) 	wait'line
   109 20C1 8D 0A D4		   sta WSYNC
   110 				;### interrupts.atl(27) 	COLPF(2) = white	
   111 20C4 A9 0F		   lda #color__White
   112 20C6 8D 18 D0		   sta COLPF-0+2
   113 20C9 68			   pla
   114 20CA A8			   tay
   115 20CB 68			   pla
   116 20CC AA			   tax
   117 20CD 68			   pla
   118 20CE 40			   rti
   119 				.endp
   120 20CF			cycle .proc
   121 				;### interrupts.atl(34) 	inc	COLOR0(5)
   122 20CF EE C9 02		   inc COLOR0+5
   123 				;### interrupts.atl(35) 	COLBK = COLOR0(5)		;as we are using deferred VBI, we must copy the color to hardware register
   124 20D2 AD C9 02		   lda COLOR0-0+5
   125 20D5 8D 1A D0		   sta COLBK
   126 20D8 4C 62 E4		   jmp $e462
   127 				.endp
   128 20DB			   icl 'C:\nes\atalan\codebase\atalan\platform\atari\atari.asm'
Source: C:\nes\atalan\codebase\atalan\platform\atari\atari.asm
     1 = 009B			_EOL_CHAR equ 155
     2
     3 20DB			_adr_putchr .proc
     4 				;Write byte to address specified by _arr and increment the address by 1.
     5 					
     6 					;Convert ASCII to ATARI character screen code
     7 					;
     8 					;The rules are following:
     9 					;0..31   +64
    10 					;32..95  -32
    11 					;96..127 0  (codes are same)
    12 					 	
    13 20DB AA				tax
    14 20DC 2A				rol 
    15 20DD 2A				rol 
    16 20DE 2A				rol 
    17 20DF 2A				rol
    18 20E0 29 03			and #3
    19 20E2 A8				tay
    20 20E3 8A				txa
    21 20E4 59 F2 20			eor tbl,y
    22 					
    23 					;write the char to specified address	
    24 20E7 A0 00			ldy #0
    25 20E9 91 80			sta (_arr),y
    26
    27 20EB E6 80			inc _arr
    28 20ED D0 02			bne skip1
    29 20EF E6 81			inc _arr+1
    30 20F1			skip1
    31 20F1 60				rts
    32
    33 20F2 40			tbl	dta b(%01000000)		;%0 00 00000		00..31	+64
    34 20F3 20					dta b(%00100000)		;%0 01 00000		32..63	-32
    35 20F4 60					dta b(%01100000)		;%0 10 00000    64..95  -32
    36 20F5 00					dta b(%00000000)		;%0 11 00000    96..127 0
    37 					
    38 				.endp
    39
    40 20F6			_out_putchr .proc
    41 				;Write character from A to output.
    42 					
    43 						tax
    44 						lda $347	;ICPUTB+1
    45 						pha
    46 						lda $346	;ICPUTB
    47 						pha
    48 						txa
    49 						rts
    50
    51 				.endp
   129 20F6			   icl 'C:\nes\atalan\codebase\atalan\processor\m6502\m6502.asm'
Source: C:\nes\atalan\codebase\atalan\processor\m6502\m6502.asm
     1 				;********************************************************
     2 				;
     3 				;  ATALAN 6502 processor definition support routines
     4 				;
     5 				;  Parts of code have been taken from Effectus library.
     6 				;
     7 				;********************************************************
     8
     9
    10 				;Noname
    11 				;651-655         028B-028F
    12 				;
    13 				;More spare bytes that you shouldn't use because future versions of the OS might use them. 
    14 				;Locations 651 and 652 are already used by version "B" as part of the interrupt handler routines.
    15
    16 				;OS registers we use as temporary:
    17 				;
    18 				;BUFRLO,BUFRHI   50,51 $32,$33
    19 				;BFENLO,BFENHI   52,53 $34,$35
    20
    21 				;ADRESS  100,101   $64,$65  A temporary storage location used by the display handler for so many things that it made my mind spin and I forgot what they were.
    22 				;MLTTMP  102,103   $66,$67  More temporary storage, with aliases OPNTMP and TOADR.
    23 				;SAVADR  104,105   $68,$69  Also know as FRMADR. Also used for temporary storage. 
    24 				;                           Also not significant enough to explain (look at the OS listing if, for some reason, you really care).
    25
    26 				;Registers used when drawing line
    27 				;ROWAC   112,113   $70,$71
    28 				;COLAC   114,115   $72,$73
    29 				;ENDPT   116,117   $74,$75
    30 				;COUNTR  126,127   $7E,$7F  COUNTR tells how many points have to be plotted before the line is finished.
    31
    32 				;
    33 = 0001			_SYS_PRINT_SIGNED = 1
    34
    35 				;_putchr_proc_adr = $653  ;+$654 
    36 = 0032			?argptr =   $32		;$33
    37 = 0034			?varptr	=	$34
    38 = 0015			?size	=	$15		;15		//$16 BUFADR
    39 						.IF _SYS_PRINT_SIGNED = 1 
    40 = 0016			?sign = $16
    41 						.ENDIF
    42 = 0038			?aux2	=	$38
    43 = 0039			?aux	=	$39
    44
    45 				;Following assigns are defined by mc6502.atl
    46
    47 = 0032			_TW1 = $32	;$33  mc6502.atl defines these labels as _TEMPW1, _TEMPW2.
    48 = 0034			_TW2 = $34  ;$35
    49 = 0015			_TW3 = $15	;$16
    50 = 0070			_TL1 = $70	;four byte register ($70-$73) defined under name _TEMPL1 in mc6502.atl		
    51
    52 				;_stdbuf    = $600		;TODO: use LINBUF ($247-$26E)  (100,101 can point to it)
    53
    54 				;Argument list:
    55 				;	0	end of list
    56 				;	1..127  Constant string of specified lenght
    57 				; 128     EOL
    58
    59 				;   7 6 5 4 3 2 1 0 
    60 				;  |0| | | | | | | |		String of length 0..127
    61 				;  |1|0|0| | | | | |    Pointer to unsigned integer of length 1..31 bytes
    62 				;  |1|0|1| | | | | |    Pointer to signed integer of length 1..31 bytes
    63
    64 				;         ---- ptr to unsigned integer ---- (7-bit set)
    65 				; 129     one byte integer reference
    66 				;	130     two byte integer reference
    67 				;	131     three byte integer eference
    68 				;	132     four byte integer reference
    69 				;         ---- ptr to signed -----  (5-bit set)
    70 				; 161     one byte
    71 				; 162     two byte
    72 				; 163     three byte
    73 				; 164     four byte
    74
    75 20F6			_std_print_adr .proc
    76
    77 20F6 A9 DB				lda #<_adr_putchr
    78 20F8 A2 20				ldx #>_adr_putchr
    79 20FA 18					clc
    80 20FB 90 00				bcc system__print
    81 						.endp
    82 						
    83 20FD			_std_print_out .proc
    84 						lda #<_out_putchr
    85 						ldx #>_out_putchr
    86 						clc											;TODO: No Jump, if we are directly before the _std_print
    87 						bcc system__print
    88 						.endp
    89
    90 				 .IF .NOT .DEF _EOL_CHAR
    91 						_EOL_CHAR equ 0
    92 				 .ENDIF
    93
    94 20FD			system__print .proc
    95 20FD 8D 53 06				sta _putchr_proc_adr 
    96 2100 8E 54 06				stx _putchr_proc_adr+1
    97 						
    98 						;... continue to _std_print
    99 				;.endp
   100 						
   101 				;_std_print	.proc
   102
   103 						;Get address of argument from stack
   104 2103 68					pla
   105 2104 85 32				sta ?argptr
   106 2106 68					pla
   107 2107 85 33				sta ?argptr+1
   108 2109 20 64 21				jsr _read_byte	;just skip next byte (that is part of return address)
   109
   110 						;Read command from input				
   111 210C			command
   112 210C 20 64 21				jsr _read_byte
   113 210F 85 15				sta ?size
   114 2111 A8					tay				; to set the flags
   115 2112 F0 4C				beq done		;command 0 means end of sequence
   116 2114 10 3E				bpl str			;1..127 constant string
   117
   118 						;Write n-byte integer variable
   119
   120 2116 29 7F				and #$7f		; zero top bit (it's always 1)
   121 2118 85 15				sta ?size
   122 211A F0 30				beq eol			;size 0 means end of line (0 byte integer would be nonsense)
   123
   124 				    ;Read address of the variable
   125
   126 211C 20 64 21				jsr _read_byte
   127 211F 85 34				sta ?varptr		
   128 2121 20 64 21				jsr _read_byte
   129 2124 85 35				sta ?varptr+1
   130
   131 						.IF _SYS_PRINT_SIGNED = 1 
   132 						;signed number has bit 5 set
   133 2126 A9 00				lda #0
   134 2128 85 16				sta ?sign
   135 						
   136 212A A5 15				lda ?size
   137 212C 29 20		    and #32		;%00100000
   138 212E F0 13		    beq unsigned
   139
   140 2130 A5 15				lda ?size	;size uses only 4 bits
   141 2132 29 1F				and #31		;%00011111
   142 2134 85 15				sta ?size
   143 				    
   144 2136 A8			    tay				;test, whether the integer is negative (i.e. top byte is negative)
   145 2137 88			    dey
   146 2138 B1 34		    lda (?varptr),y
   147 213A 10 07		    bpl unsigned
   148 						 
   149 213C C6 16		    dec ?sign				;sign = $ff  (-1)
   150 						
   151 213E A9 2D				lda #'-'
   152 2140 20 6F 21				jsr _std_putchr
   153 						
   154 2143			unsigned
   155 						.ENDIF
   156 						    
   157 2143 20 BD 21				jsr _std_bin_to_bcd
   158 2146 20 73 21				jsr _std_print_hex
   159 2149 18					clc
   160 214A 90 C0				bcc command		;jmp command
   161 214C			eol
   162 214C A9 9B				lda #_EOL_CHAR	
   163 214E 20 6F 21				jsr _std_putchr
   164 2151 18					clc
   165 2152 90 B8				bcc command		;jmp command
   166 						;Write constant string (size is 1..127, already stored)
   167 									
   168 2154			str
   169 2154 20 64 21				jsr _read_byte
   170 2157 20 6F 21				jsr _std_putchr
   171 215A C6 15				dec ?size
   172 215C D0 F6				bne str
   173 215E F0 AC				beq	command
   174 										
   175 2160			done		
   176 2160 6C 32 00				jmp (?argptr)	
   177 2163 60					rts
   178 						
   179 2164			_read_byte
   180 2164 A0 00				ldy #0
   181 2166 B1 32				lda (?argptr),y
   182 2168 E6 32				inc ?argptr
   183 216A D0 02				bne skip
   184 216C E6 33				inc ?argptr+1
   185 216E			skip
   186 216E 60					rts
   187 				.endp
   188
   189 216F			_std_putchr .proc
   190 216F 6C 53 06				jmp (_putchr_proc_adr)
   191 2172 60					rts
   192 				.endp
   193
   194
   195 2173			.proc _std_print_hex
   196 				;Print hexadecimal number of arbitrary length (?size). 
   197 				;Leading zeroes are not printed.
   198 				;In:
   199 				;	?varptr		Pointer to memory containing the number
   200 				;	?size		  Number of bytes to print
   201 				;Uses:
   202 				;	?aux
   203 				;	?aux2
   204 					
   205 2173 A5 15				lda ?size
   206 2175 85 39				sta ?aux
   207 2177 A9 00				lda #0
   208 2179 85 38				sta ?aux2		; number of non-zero digits on output
   209 217B F0 12				beq _loop
   210 217D			_outbyte
   211 217D A4 39				ldy ?aux		
   212 217F B1 34				lda (?varptr),y
   213 2181 48					pha
   214 2182 4A					lsr
   215 2183 4A					lsr
   216 2184 4A					lsr
   217 2185 4A					lsr
   218 2186 20 9D 21				jsr _write_digit
   219 					
   220 2189 68					pla
   221 218A 29 0F				and #$0f
   222 218C 20 9D 21				jsr _write_digit
   223 218F			_loop	
   224 218F C6 39				dec ?aux
   225 2191 10 EA				bpl _outbyte
   226 						
   227 						;If no character has been written, write at least one 0		
   228 2193 A5 38				lda ?aux2
   229 2195 D0 05				bne _no_empty
   230 2197 A9 30				lda #48
   231 2199 20 6F 21				jsr _std_putchr
   232 219C			_no_empty
   233 				 
   234 219C 60					rts
   235 					
   236 219D			_write_digit
   237 				;In: a 4 bit digit
   238
   239 219D AA					tax
   240 219E D0 04				bne _non_zero
   241 21A0 A5 38				lda ?aux2
   242 21A2 F0 08				beq _done		;this is zero and there has been no char before - no output
   243 21A4			_non_zero
   244 21A4 BD AD 21				lda hex,x
   245 21A7 20 6F 21				jsr _std_putchr
   246 21AA E6 38				inc ?aux2
   247 21AC			_done
   248 21AC 60					rts
   249
   250 21AD 30 31 32 33 34 35 + hex     dta c"0123456789ABCDEF"
   251
   252 				.endp
   253
   254 21BD			.proc _std_bin_to_bcd
   255 				;Convert binary number to BCD. 
   256 				;Arbitrary size (up to 127 bytes) are supported.
   257 				;In:
   258 				;	?varptr	pointer to binary number
   259 				; a   0 means unsigned number
   260 				;     $ff means signed number
   261 				;	?size	number of bytes
   262 				;Out:
   263 				;	?size	on output, returns size of resulting bcd number
   264 				;   ?varptr	on output, containg pointer to converted BCD
   265 				;Uses:
   266 				;	_stdbuf
   267 				;	?aux
   268 				;	?aux2
   269
   270 						;Compute size of resulting number 
   271 21BD A4 15				ldy ?size
   272 21BF 84 39				sty ?aux		; used to count later
   273 21C1 C8					iny				;add space to result
   274 21C2 84 15				sty ?size
   275 						
   276 						;Zero the destination buffer
   277 21C4 A9 00				lda #0
   278 21C6 99 FF 05		zero	sta _stdbuf-1,y
   279 21C9 88					dey
   280 21CA D0 FA				bne zero
   281 						
   282 						;**** We convert the number byte a time
   283 21CC F8					sed
   284 						
   285 						;?aux = varptr(?aux)
   286 21CD			bytes
   287 21CD C6 39				dec ?aux
   288 21CF A4 39				ldy ?aux
   289 21D1 B1 34				lda (?varptr),y	
   290 						.IF _SYS_PRINT_SIGNED = 1 
   291 21D3 45 16				eor ?sign
   292 						.ENDIF	
   293 21D5 85 38				sta ?aux2
   294 21D7 38					sec				;set top bit to 1
   295 21D8 B0 12				bcs loop		
   296
   297 21DA			shift_byte			
   298 21DA A2 00				ldx #0
   299 21DC A4 15				ldy ?size
   300 21DE			bcd_mul2
   301 21DE BD 00 06				lda _stdbuf,x
   302 21E1 7D 00 06				adc	_stdbuf,x			;buf2(x) = buf2(x) * 2 + carry
   303 21E4 9D 00 06				sta _stdbuf,x
   304 21E7 E8					inx
   305 21E8 88					dey								;TODO: cpx ?size
   306 21E9 D0 F3				bne bcd_mul2
   307 							
   308 21EB 18					clc
   309 21EC 26 38		loop	rol ?aux2		;divide by two, if result is 0, end
   310 21EE D0 EA				bne shift_byte		
   311 						
   312 21F0 A5 39				lda ?aux
   313 21F2 D0 D9				bne bytes
   314 					
   315 						.IF _SYS_PRINT_SIGNED = 1 
   316 						;If this is negative number, add 1
   317 						;In case sign is $ff, asl will set the C to 1, otherwise to 0	
   318 21F4 A5 16				lda ?sign
   319 21F6 0A					asl
   320 21F7 A2 00				ldx #0
   321 21F9			carry1
   322 21F9 BD 00 06				lda _stdbuf,x
   323 21FC 69 00				adc #0
   324 21FE 9D 00 06				sta _stdbuf,x
   325 2201 E8					inx
   326 2202 B0 F5				bcs carry1
   327 						.ENDIF
   328 									
   329 2204 D8					cld		
   330 						
   331 2205 A9 00				lda #<_stdbuf
   332 2207 85 34				sta ?varptr	
   333 2209 A9 06				lda #>_stdbuf
   334 220B 85 35				sta ?varptr+1	
   335 220D 60					rts
   336
   337 				.endp
   338 				 
   339 				/*
   340 				  Mul8 - 8-bit multiplication routine
   341 				  
   342 				  Original source:
   343 				  Book Atari Roots (Chapter Ten - Assembly Language Math)
   344 				  Hyperlink: http://www.atariarchives.org/roots/chapter_10.php
   345 				  
   346 				  Parameters:
   347 					  a First multiplicant
   348 					  x Second multiplicant
   349 				  Result: 
   350 						TEMPW2,TEMPW2+1	high byte of the result
   351 				*/
   351
   352
   353 220E			_sys_mul8  .proc
   354
   355 = 0032			MUL1 = _TW1
   356 = 0033			MUL2 = _TW1+1
   357 = 0034			RES  = _TW2		;_TW2+1
   358
   359 						sta MUL1			;input comes in A and X
   360 						stx MUL2
   361 						
   362 						lda #0			;RES = 0
   363 						sta RES
   364 						
   365 						ldx #8  
   366 220E			loop
   367 						lsr MUL1		;MUL1 = MUL1 / 2
   368 						bcc noadd
   369 						
   370 						clc					;RES = RES + (MUL2 * $ff)
   371 						adc MUL2	  
   372 220E			noadd 
   373 						ror @				;RES = RES / 2		(Carry is 0, when there was no add)
   374 						ror RES
   375
   376 						dex
   377 						bne loop
   378 						
   379 						sta RES+1
   380 						rts
   381
   382 						.endp
   383
   384 				/*
   385 				  Mul16 - 16-bit multiplication routine
   386 				    
   387 				  Parameters:
   388 					  _TW1 First multiplicant (we use only two bytes now)
   389 					  _TW2 Second multiplicant
   390 				  Result: 
   391 						_TL1 Result
   392 				*/
   392
   393
   394 220E			_sys_mul16  .proc
   395
   396 = 0032			MUL1 = _TW1
   397 = 0034			MUL2 = _TW2
   398 = 0070			RES  = _TL1
   399 						
   400 						lda #0      ;RES = 0;
   401 						sta RES
   402 						sta RES+1
   403 						sta RES+2
   404 						sta RES+3
   405 						
   406 						ldx #16  
   407 220E			loop
   408 						lsr MUL1+1		;MUL1 = MUL1 / 2
   409 						ror MUL1
   410 						bcc noadd
   411 						
   412 						lda RES+2			;RES = RES + (MUL2 * $ffff)  (only upper half) 
   413 						clc		
   414 						adc MUL2
   415 						sta RES+2
   416 						lda RES+3
   417 						adc MUL2+1
   418 						sta RES+3
   419 220E			noadd
   420 						ror RES+3				;RES = RES / 2		(Carry is 0, when there was no add)
   421 						ror RES+2
   422 						ror RES+1
   423 						ror RES+0
   424 						 
   425 						dex
   426 						bne loop
   427 						
   428 						rts
   429
   430 						.endp
   431 				 
   432 				/*
   433 				  Div8 - 8-bit division routine
   434 				 
   435 				  Original source:
   436 				  Book Atari Roots (Chapter Ten - Assembly Language Math)
   437 				  Hyperlink: http://www.atariarchives.org/roots/chapter_10.php
   438 				 
   439 				  Parameters:
   440 				  _TEMPW1		16-bit dividend
   441 				  a					 p1_math:  8-bit divisor
   442 				  x          number of bits of an divisir (8 max)
   443 				 
   444 				  Result:
   445 				  x STORE1: 8-bit quotient
   446 				  a STORE2: 8-bit remainder
   447 				*/
   447
   448
   449 220E			_sys_div8  .proc
   450 				  ldx #08  ; For an 8-bit divisor
   451 					
   452 220E			_sys_div
   453
   454 = 0034			divisor  = _TW2
   455 = 0035			quotient = _TW2+1
   456
   457 				  sta divisor
   458 					lda #0     				; for non-8 divis
   459 					sta quotient
   460 				  lda _TW1+1
   461 				  sec 
   462 				  sbc divisor
   463 220E			dloop 
   464 				  php  					; The loop that divides 
   465 				  rol quotient
   466 				  asl _TW1
   467 				  rol @
   468 				  plp
   469 				  bcc addit
   470 				  sbc divisor
   471 				  jmp next
   472 220E			addit 
   473 				  adc divisor
   474 220E			next  
   475 				  dex
   476 				  bne dloop
   477 				  bcs fini
   478 				  adc divisor
   479 				  clc
   480 220E			fini
   481 					tax            ; x = remainder
   482 				  lda quotient   ; a = quotient
   483 				  rol
   484 				  rts
   485 				 
   486 				  .endp
   487
   488 				/*
   489
   490 				  Square Root
   491
   492 				  Calculates the 8 bit root and 9 bit remainder of a 16 bit unsigned integer in
   493 				  Numberl/Numberh. The result is always in the range 0 to 255 and is held in
   494 				  Root, the remainder is in the range 0 to 511 and is held in Reml/Remh
   495
   496 				  partial results are held in templ/temph
   497
   498 				  Destroys A, X registers.
   499
   500 					Arguments:
   501 					
   502 					_TEMPW1  16-bit number to compute root of
   503 					
   504 					<a        Square root
   505 					<_TEMPW2  Remainder of square
   506 					
   507 				*/
   507
   508
   509 220E			_sys_sqrt16 .proc
   510
   511 = 0032			Numberl		= _TW1		; number to find square root of low byte
   512 = 0033			Numberh		= _TW1+1	; number to find square root of high byte
   513 = 0034			Reml		  = _TW2		; remainder low byte
   514 = 0035			Remh		  = _TW2+1	; remainder high byte
   515 = 0070			templ		  = _TL1		; temp partial low byte
   516 = 0071			temph		  = _TL1+1	; temp partial high byte
   517 = 0072			Root		  = _TL1+2	; square root
   518
   519 					LDA	#$00		; clear A
   520 					STA	Reml		; clear remainder low byte
   521 					STA	Remh		; clear remainder high byte
   522 					STA	Root		; clear Root
   523 					LDX	#$08		; 8 pairs of bits to do
   524 220E			Loop
   525 					ASL	Root		; Root = Root * 2
   526
   527 					ASL	Numberl		; shift highest bit of number ..
   528 					ROL	Numberh		;
   529 					ROL	Reml		; .. into remainder
   530 					ROL	Remh		;
   531
   532 					ASL	Numberl		; shift highest bit of number ..
   533 					ROL	Numberh		;
   534 					ROL	Reml		; .. into remainder
   535 					ROL	Remh		;
   536
   537 					LDA	Root		; copy Root ..
   538 					STA	templ		; .. to templ
   539 					LDA	#$00		; clear byte
   540 					STA	temph		; clear temp high byte
   541
   542 					SEC			; +1
   543 					ROL	templ		; temp = temp * 2 + 1
   544 					ROL	temph		;
   545
   546 					LDA	Remh		; get remainder high byte
   547 					CMP	temph		; comapre with partial high byte
   548 					BCC	Next		; skip sub if remainder high byte smaller
   549
   550 					BNE	Subtr		; do sub if <> (must be remainder>partial !)
   551
   552 					LDA	Reml		; get remainder low byte
   553 					CMP	templ		; comapre with partial low byte
   554 					BCC	Next		; skip sub if remainder low byte smaller
   555
   556 								; else remainder>=partial so subtract then
   557 								; and add 1 to root. carry is always set here
   558 220E			Subtr
   559 					LDA	Reml		; get remainder low byte
   560 					SBC	templ		; subtract partial low byte
   561 					STA	Reml		; save remainder low byte
   562 					LDA	Remh		; get remainder high byte
   563 					SBC	temph		; subtract partial high byte
   564 					STA	Remh		; save remainder high byte
   565
   566 					INC	Root		; increment Root
   567 220E			Next
   568 					DEX			; decrement bit pair count
   569 					BNE	Loop		; loop if not all done
   570
   571 					lda Root
   572 					
   573 					RTS
   574 				.endp
   130
