1 eÿadi4.s
\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\10\ 2.define Adi4
8 ! This subroutine adds two fourbyte integers, which are on the stack.
9 ! The addresses are initiated by the subroutine Addsub.
10 ! Also the loopvariable (register X) is initiated by that routine.
11 ! The result is pushed back onto the stack
15 jsr Addsub ! initiate addresses
17 1: lda (ADDR+2),y ! get byte first operand
18 adc (ADDR),y ! add to byte second operand
19 sta (ADDR+2),y ! push on real stack
22 bne 1b ! do it 4 times
26 cmi.s
\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0Õ
\ 1.define Cmi
33 ! This subroutine compares on two integers.
34 ! If T is pushed first and than S, the routine will return:
41 jsr Sbi2 ! subtract operands (T - S)
57 hcmi4.s
\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0"
\ 3.define Cmi4
64 ! This subroutine compares on fourbyte integers.
65 ! If T is pushed first and than S, the routine will return:
72 jsr Sbi4 ! subtract operands (T - S)
73 jsr Pop ! get result (lowbyte, lowbyte+1)
74 stx ARTH ! store lowbyte
75 sta ARTH+1 ! store lowbyte+1
76 jsr Pop ! get result (lowbyte+2, lowbyte+3)
82 1: cmp #0 ! test lowbyte+3 on zero
84 cpx #0 ! test lowbyte+2 on zero
87 cmp ARTH+1 ! test lowbyte+1 on zero
89 cmp ARTH ! test lowbyte on zero
99 sbi4.s
\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0_
\ 1.define Sbi4
106 ! This subroutine subtracts two fourbyte signed integers.
110 jsr Addsub ! initiate addresses
112 1: lda (ADDR+2),y ! get lowbyte+y first operand
113 sbc (ADDR),y ! subtract lowbyte+y second operand
114 sta (ADDR+2),y ! put on stack lowbyte+y result
121 waddsub.s
\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\82\ 2.define Addsub
128 ! This subroutine is used by the fourbyte addition and subtraction
130 ! It puts the address of the second operand into
131 ! the zeropage locations ADDR and ADDR+1
132 ! The address of the first operand is put into
133 ! zeropage locations ADDR+2 and ADDR+3.
139 sta ADDR ! address of second operand (lowbyte)
142 sta ADDR+2 ! address of first operand (lowbyte)
144 sta ADDR+1 ! address of second operand (highbyte)
146 sta ADDR+3 ! address of first operand (highbyte)
149 ldx #0x0FC ! do it 4 times
153 cmu4.s
\0s
\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0«
\ 3.define Cmu4
160 ! This subroutine compares two unsigned fourbyte integers.
161 ! If T is first pushed and than S the routine will return:
172 jsr Sdo ! store S in zeropage ARTH - ARTH+3
175 jsr Sdo ! store T in zeropage ARTH+4 - ARTH+7
178 bcc 3f ! S (lowbyte+3) < T (lowbyte+3)
179 bne 2f ! S (lowbyte+3) < T (lowbyte+3)
182 bcc 3f ! S (lowbyte+2) < T (lowbyte+2)
183 bne 2f ! S (lowbyte+2) < T (lowbyte+2)
186 bcc 3f ! S (lowbyte+1) < T (lowbyte+1)
187 bne 2f ! S (lowbyte+1) < T (lowbyte+1)
190 bcc 3f ! S (lowbyte+0) < T (lowbyte+0)
191 bne 2f ! S (lowbyte+0) < T (lowbyte+0)
198 3: lda #0x0FF ! S < T
203 \0dum_float.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0«
\ 2.define Adf4
234 ! Dummy floating point package for 6500
235 ! every EM floating point instruction results in an
236 ! "Illegal EM instruction" trap.
267 odvi4.s
\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0K
\ 1.define Dvi4
274 ! This subroutine performs a fourbyte signed division.
275 ! For more details see dvi.s
276 ! The only difference is that zeropage locations are twice as big.
292 dvu4.s
\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\07
\ 2.define Dvu4
299 ! This subroutine performs an unsigned division on fourbyte
300 ! integers. For more details see dvi.s
301 ! The only difference is that zeropage locations are twice as big.
306 sty UNSIGN ! it is unsigned
312 sta ARTH+3 ! divisor in ARTH - ARTH+3
318 sta ARTH+7 ! dividend in ARTH+4 - ARTH+7
325 jmp Push ! store result
328 rlar.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0R
\ 2.define Lar
335 ! This subroutine performs the LAR instruction.
336 ! For details see rapport IR-81.
340 jsr Aar ! get object address
341 ldy NBYTES+1 ! the size of the object (highbyte)
343 ldy NBYTES ! the size of the object (lowbyte)
345 bne 1f ! object size is one byte
346 jsr Loi1 ! get object
347 jmp Push ! push on the stack
349 bne 1f ! object size is a word
351 jmp Push ! push on the stack
353 bne 2f ! object size is four bytes
355 2: jmp Loil ! get object
358 lol.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0(
\ 1.define Lol
365 ! This subroutine loads a local in registerpair AX which
366 ! offset from the localbase is to big.
370 jsr Locaddr ! get the address of local
372 lda (ADDR),y ! get lowbyte
375 lda (ADDR),y ! get highbyte
379 los.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0Y
\ 2.define Los
386 ! This subroutine perfoms the LOS instruction.
387 ! For detail see rapport IR-81.
394 bne 1f ! the size is one
395 jsr Pop ! get address
396 jsr Loi1 ! push it on the stack
399 bne 2f ! the size is two
400 jsr Pop ! get address
401 jsr Loi ! push it on the stack
404 bne 3f ! the size is four
405 jsr Pop ! get address
406 jmp Ldi ! push it on the stack
407 3: sta ARTH+1 ! the size is greater than four
410 jsr Pop ! get address
411 jmp Loil ! push it on the stack
415 loil.s
\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0í
\ 1.define Loil
422 ! This subroutine pushes an object of size greater than four bytes
427 sta ADDR+1 ! source address (lowbyte)
428 stx ADDR ! source address (highbyte)
433 sta ADDR+2 ! destination address (lowbyte)
434 sta SP+2 ! new stackpointer
437 sta ADDR+3 ! destination address (highbyte)
438 sta SP+1 ! new stackpointer
440 jmp Blmnp ! do the move
443 Aloi1.s
\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\08
\ 1.define Loi1
450 ! This routine loads a one byte object in registerpair AX.
454 stx ADDR ! address of byte (lowbyte)
455 sta ADDR+1 ! address of byte (highbyte)
457 lda (ADDR),y ! load byte
458 tax ! store byte in X
459 tya ! clear highbyte of AX
463 loi.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0}
\ 1.define Loi, Lext
469 ! This subroutine performs an indirect load on a word of two bytes.
470 ! Lext is used when the address is already in zeropage.
474 stx ADDR ! address of object (lowbyte)
475 sta ADDR+1 ! address of object (highbyte)
478 lda (ADDR),y ! get lowbyte
481 lda (ADDR),y ! get highbyte
485 amli4.s
\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0ý
\ 1.define Mli4
492 ! This subroutine multiplies two signed fourbyte integers
493 ! For more detail see mli.s
494 ! The only difference is that zeropage locations are twice as big.
505 sta ARTH+3 ! multiplier
511 sta ARTH+7 ! multiplicand
523 emlu.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\1d\ 1.define Mlu2
530 ! This subroutine multiplies two unsigned fourbyte intergers.
531 ! For more details see mli.s
536 sta ARTH+1 ! multiplier
539 sta ARTH+3 ! multiplicand
545 jmlu4.s
\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0«
\ 1.define Mlu4
552 ! This subroutine multiplies two fourbyte unsigned integers.
553 ! For more details see mli.s
554 ! The only difference is that zeropage locations are twice as big.
565 sta ARTH+3 ! multiplier
571 sta ARTH+7 ! multiplicand
575 mul4.s
\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\19\ 4.define Mul4
582 ! This subroutine multiplies two fourbyte signed integers.
583 ! For more details see mli.s
584 ! The only difference is that zeropage locations are twice as big.
596 sta ARTH+15 ! clear accumulator
600 beq 2f ! multiplying by zero: no addition
617 ror ARTH ! shift multiplier
625 ror ARTH+8 ! shift accumulator
627 beq 3f ! it's unsigned: so no shift in of signbit
646 \0rmi.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0$
\ 2.define Rmi2
653 ! This subroutine returns the remainder of a twobyte signed division.
654 ! The sign of the result is as specified in the emtest.
659 sty NBYTES ! for the sign of the result
661 sta ARTH+1 ! first operand
664 sta ARTH+3 ! second operand
666 sty UNSIGN ! its signed arithmetic
669 ror ARTH+4 ! result must be shifted one time
673 beq 1f ! result must be positive
678 rmi4.s
\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0ä
\ 1.define Rmi4
685 ! This subroutine returns the remainder of a fourbyte division.
690 sty NBYTES ! for the sign of the result
692 sty UNSIGN ! it is signed arithmetic
697 ror ARTH+8 ! result must be shifted one time
699 beq 1f ! result is positive
711 div4.s
\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0~
\ 2.define Div4
718 ! This subroutine performs a signed divide on two fourbyte integers.
719 ! For more detail see dvi.s
720 ! The only difference is that zeropage locations are twice as big.
730 sta ARTH+3 ! divisor in ARTH - ARTH+3
737 sty SIGN ! it's signed
743 sta ARTH+7 ! dividend in ARTH+4 - ARTH+7
757 rmu.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0y
\ 1.define Rmu2
764 ! This subroutine returns the remainder of an twobyte unsigned
770 sta ARTH+1 ! first operand
773 sta ARTH+3 ! second operand
775 sty UNSIGN ! it unsigned
778 ror ARTH+4 ! shift result one time
784 dvi.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\07
\ 6.define Dvi2, Div, Duv
791 ! The subroutine Dvi2 performs a signed division.
792 ! Its operands are on the stack.
793 ! The subroutine Div performs also a signed division, ecxept that
794 ! its operand are already in zeropage.
795 ! The subroutine Duv performs a n unsigned division.
796 ! For an explanation of the algoritm used see
797 ! A. S. Tanenbaum's Structered Computer Organisation. 1976
802 sta ARTH+1 ! store divisor
805 sta ARTH+3 ! store dividend
807 sty UNSIGN ! used for result sign
812 bpl 1f ! if divisor is negative
813 ldx ARTH ! make it positive
820 bpl 1f ! if dividend is negative
821 ldx ARTH+2 ! make it positive
825 eor #1 ! excusive or with sign of divisor
839 bcc 1f ! no subtraction
840 bne 2f ! divisor goes into dividend
843 bcc 1f ! no subtraction
844 2: sec ! divisor goes into dividend
850 sta ARTH+5 ! subtract divisor from dividend
852 rol ARTH+2 ! a subtraction so shift in a 1
854 1: asl ARTH+2 ! no subtraction so shift in a 0
857 rol ARTH+5 ! shift dividend
862 ldy UNSIGN ! is it an unsigned division
864 ldy SIGN ! is the result negative
871 \0rmu4.s
\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\ 1\ 2.define Rmu4
878 ! This subroutine returns the remainder of a fourbyte unsigned
884 sty UNSIGN ! its unsigned
890 sta ARTH+3 ! second operand
896 sta ARTH+7 ! first operand
901 ror ARTH+8 ! shift result one time
910 oduv4.s
\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\84\ 3.define Duv4
917 ! This subroutine performs an unsigned division on two fourbyte
919 ! For more details see dvi.s
920 ! The only difference is that zeropage locations are twice as big.
981 ngi4.s
\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0½
\ 1.define Ngi4
988 ! This subroutine takes a fourbyte interger and negates it.
989 ! For more details see ngi2.s
997 eor #0x0FF ! one's complement lowbyte+y
1006 sta (ADDR),y ! lowbyte+y
1010 sta (ADDR),y ! (lowbyte+y)+0
1016 drtt.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\84\ 1.define Rtt
1023 ! This subroutine performs the return from trap.
1028 jsr Ret ! restore old stackpointer and localbase
1029 jsr Pop ! remove trapnumber
1032 stx hol0 ! restore linenumber
1035 stx hol0+4 ! restore filename pointer
1038 jsr Sdi ! restore return area
1042 ret.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0À
\ 3.define Ret
1049 ! This subroutine stores the returnvalue in the return area.
1050 ! This area is in zeropage.
1051 ! The size of the object to be returned is in zeropage location
1053 ! It also restores the localbases and the stackpointer of the
1054 ! invoking procedure.
1058 sty RETSIZE ! save returnsize
1059 beq 1f ! the return size is zero
1060 lda #0 ! address of returnvalue area (highbyte)
1061 ldx #RETURN ! address of returnvalue area (lowbyte)
1064 jsr Sti ! store word
1067 jsr Sdi ! store fourbyte word
1068 1: ldx LB ! get old stackpointer (lowbyte)
1070 lda LB+1 ! get old stackpointer (highbyte)
1076 1: jsr Pop ! get old localbase
1077 stx LB ! localbase (lowbyte)
1078 sta LB+1 ! localbase (highbyte)
1083 sta LBl ! second localbase (lowbyte)
1086 sta LBl+1 ! second localbase (highbyte)
1090 sar.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0.
\ 2.define Sar
1097 ! This subroutine performs the SAR instruction.
1098 ! For details see rapport IR-81.
1102 jsr Aar ! get object address
1103 ldy NBYTES+1 ! the size of the object (highbyte)
1105 ldy NBYTES ! the size of the object (lowbyte)
1107 bne 1f ! object size is one byte
1108 jmp Sti1 ! put it in array
1110 bne 1f ! object size is two bytes
1111 jmp Sti ! put it in array
1113 bne 2f ! object size is fourbytes
1114 jmp Sdi ! put it in array
1115 2: jmp Stil ! put it in array
1118 aar.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0¤
\ 2.define Aar
1125 ! This subroutine gets the address of the array element
1129 stx ADDR ! address of descriptor (lowbyte)
1130 sta ADDR+1 ! address of descriptor (highbyte)
1132 lda (ADDR),y ! lowerbound (lowbyte)
1135 lda (ADDR),y ! lowerbound (highbyte)
1136 jsr Sbi2 ! index - lowerbound
1139 lda (ADDR),y ! objectsize (lowbyte)
1143 lda (ADDR),y ! objectsize (highbyte)
1146 cpx #1 ! objectsize = 1 then return
1147 bne 5f ! arrayaddress + index
1150 5: jsr Mli2 ! objectsize > 1 then return
1151 jmp Adi2 ! arrayaddress + index * objectsize
1154 adi.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0â
\ 1.define Adi2
1161 ! This subroutine adds two twobyte integers.
1162 ! The first operand is on the top of the stack, the second operand
1163 ! is in the AX registerpair.
1164 ! The result is returned in registerpair AX.
1168 sta ARTH+1 ! second operand (highbyte)
1169 stx ARTH ! second operand (lowbyte)
1170 jsr Pop ! get first operand
1174 adc ARTH ! add lowbytes
1177 adc ARTH+1 ! add the highbytes
1181 sbi.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0Ú
\ 1.define Sbi2
1188 ! This subroutine subtracts two twobyte signed integers
1189 ! and returnes the result in registerpair AX.
1193 stx ARTH ! save second operand (lowbyte)
1194 sta ARTH+1 ! save second operand (highbyte)
1198 txa ! get first operand (lowbyte)
1199 sbc ARTH ! subtract second operand (lowbyte)
1202 pla ! get first operand (highbyte)
1203 sbc ARTH+1 ! subtract second operand (highbyte)
1207 mli.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0ã
\ 4.define Mli2, Mlinp, Mul
1214 ! The subroutine Mli2 multiplies two signed integers. The integers
1215 ! are popped from the stack.
1216 ! The subroutine Mlinp expects the two integer to be in zeropage.
1217 ! While the subroutine Mul an unsigned multiply subroutine is.
1218 ! For the algoritme see A. S. Tanenbaum
1219 ! Structured Computer Organisation. 1976.
1229 sty UNSIGN ! it's signed
1231 bpl 3f ! multiplier negative so:
1233 jsr Ngi2 ! negate multiplier
1238 jsr Ngi2 ! negate multiplicand
1246 sta ARTH+7 ! clear accumulator
1250 beq 2f ! multiplying by zero: no addition
1259 ror ARTH ! shift multiplier
1263 ror ARTH+4 ! shift accumulator
1265 beq 3f ! unsigned multiply: so no shift in of signbit
1281 vngi.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0Z
\ 1.define Ngi2
1288 ! This subroutine negates the integer in registerpair AX.
1289 ! The negation is a one's complement plus one.
1293 eor #0x0FF ! one's complement A
1296 eor #0x0FF ! one's complement X
1300 iny ! increment A if neccesairy
1305 set.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\r\ 3.define Set
1312 ! This subroutine creates a set of n (n <= 256) bytes.
1313 ! In this set a certain bit, which number is in registerpair AX,
1314 ! is set. The rest is zero.
1318 stx ARTH ! save bitnumber (lowbyte)
1319 sta ARTH+1 ! save bitnumber (highbyte)
1320 jsr Zer ! create n zerobytes
1322 and #0x07 ! n mod 8 (bitnumber in byte)
1327 1: asl a ! set bit (n mod 8)
1332 1: lsr ARTH+1 ! shiftright n 3 times (= n div 8)
1333 ror ARTH ! this is the bytenumber
1336 ldy ARTH ! load bytenumber
1339 stx ADDR ! address of set (lowbyte)
1340 sta ADDR+1 ! address of set (highbyte)
1341 lda ARTH+2 ! get bit
1342 sta (ADDR),y ! store byte with bit on
1346 1zer.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0.
\ 1.define Zer
1353 ! This subroutine puts n (n <=256) zero bytes on top of
1355 ! The number of bytes minus one is in Y.
1360 lsr a ! number of bytes div 2
1365 2: jsr Push ! push two bytes
1371 stl.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0.
\ 1.define Stl
1378 ! This subroutine performs the storage of a local which offset
1383 jsr Locaddr ! get the local address
1384 jsr Pop ! get the word
1386 sta (ADDR),y ! store highbyte
1389 sta (ADDR),y ! store lowbyte
1393 sts.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0c
\ 2.define Sts
1400 ! This subroutine stores indirect a number of bytes.
1401 ! The number of bytes is in the registerpair AX.
1406 bne 3f ! number of bytes > 255
1408 bne 1f ! onebyte storage
1409 jsr Pop ! get the address
1410 jmp Sti1 ! store the byte
1412 bne 2f ! twobyte storage
1413 jsr Pop ! get the address
1414 jmp Sti ! store the word
1416 bne 3f ! fourbyte storage
1417 jsr Pop ! get the address
1418 jmp Sdi ! store the double word
1419 3: sta ARTH+1 ! objectsize > 4
1422 jsr Pop ! get address
1423 jmp Stil ! store the object
1426 msdl.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0¨
\ 1.define Sdi, Sdo
1433 ! The subroutine Sdi takes a fourbyte word and stores it
1434 ! at the address in registerpair AX.
1435 ! If the address is in zeropage, Sdo is used.
1439 stx ADDR ! address (lowbyte)
1440 sta ADDR+1 ! address (highbyte)
1446 sta (ADDR),y ! store lowbyte
1449 sta (ADDR),y ! store highbyte
1456 sti.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0/
\ 2.define Sti, Sext, Stii
1463 ! The subroutine Sti stores an twobyte word at the address which
1464 ! is in registerpair AX.
1465 ! The subroutine Sext is used when the address is already in
1467 ! The subroutine Stii is used when the address is in zeropage
1468 ! and the registerpair AX contains the word.
1472 stx ADDR ! address of word (lowbyte)
1473 sta ADDR+1 ! address of word (highbyte)
1478 sta (ADDR),y ! store highbyte
1481 sta (ADDR),y ! store lowbyte
1485 rstil.s
\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0¼
\ 2.define Stil
1492 ! This subroutine stores indirect a block of bytes if
1493 ! the number of bytes is greater than four.
1494 ! The destination address is in registerpair AX.
1495 ! The lowbyte of the number of bytes is in Y,
1496 ! the highbyte is in zeropage location NBYTES+1.
1500 sta ADDR+3 ! destination address (highbyte)
1501 stx ADDR+2 ! destination address (lowbyte)
1502 sty NBYTES ! number of bytes (lowbyte)
1505 sta ADDR ! source address (lowbyte)
1507 sta SP+2 ! new stackpointer (lowbyte)
1509 sta ADDR+1 ! source address (highbyte)
1511 sta SP+1 ! new stackpointer (highbyte)
1513 jmp Blmnp ! do the move
1516 blm.s
\0\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0×
\ 3.define Blm, Blmnp
1523 ! This subroutine copies bytes from one place in memory to
1524 ! another. The source address is in registerpair AX and is stored
1525 ! in zeropage locations ADDR and ADDR+1.
1526 ! The destination address is popped from the stack and stored in
1527 ! zeropage locations ADDR+2 and ADDR+3.
1528 ! The number of bytes to be copied is in register Y (lowbyte) and
1529 ! zeropage location NBYTES+1 (highbyte).
1530 ! The subroutine Blmnp is used when the source and destination
1531 ! addresses are already in zeropage.
1535 stx ADDR+2 ! source address (lowbyte)
1536 sta ADDR+3 ! source address (highbyte)
1538 stx ADDR ! destination address (lowbyte)
1539 sta ADDR+1 ! destination address (highbyte)
1542 lda (ADDR),y ! get source byte
1543 sta (ADDR+2),y ! copy to destination
1546 dec ADDR+1 ! 256 bytes copied
1547 dec ADDR+3 ! decrement source and destination address
1550 bne 1b ! do it n times
1554 sti1.s
\0at.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0D
\ 1.define Sti1
1561 ! This subroutine stores an onebyte wordfractional at the address
1562 ! which is in registerpair AX.
1566 stx ADDR ! address of byte (lowbyte)
1567 sta ADDR+1 ! address of byte (highbyte)
1571 sta (ADDR),y ! store byte
1575 test2.s
\0t.s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0~
\ 1.define Test2
1582 ! This subroutine tests if the value on top of the stack is 2.
1583 ! It is used if the size is on top of the stack.
1584 ! The word which is to be handled is returned in registerpair AX.
1589 bne 1f ! value > 255
1599 testFFh.s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\85\ 1.define TestFFh
1606 ! This subroutine tests if the value on top of the stack is <= 256.
1607 ! It is used if the istruction argument is on top of the stack.
1608 ! The value is saved in Y.
1613 bpl 1f ! value > 256
1617 bne 1f ! value is zero
1627 trap.s
\0.s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0ø
\a.define Trap
1634 ! This subroutine performs the trap instruction.
1643 lda IGNMASK ! get bitmask (lowbyte)
1645 lda IGNMASK+1 ! get bitmask (highbyte)
1647 ror ARTH ! shiftright bitmask n times
1653 pla ! clear hardware_stack
1655 3: pla ! clear hardware_stack
1662 bne 1f ! ERRPROC <> 0 (highbyte)
1664 bne 1f ! ERRPROC <> 0 (lowbyte)
1668 jsr Ldi ! save return area
1671 jsr Push ! save filename pointer
1674 jsr Push ! save linenumber
1676 sta ADDR ! address of errorhandler (lowbyte)
1678 sta ADDR+1 ! address of errorhandler (highbyte)
1680 sta ERRPROC ! reset ERRPROC (lowbyte)
1681 sta ERRPROC+1 ! reset ERRPROC (highbyte)
1684 jmp (ADDR) ! proceed with errorhandler
1761 ldi.s
\0\0.s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0Þ
\ 1.define Ldi, Ldo
1768 ! The subroutine Ldi pushes a four byte object onto the stack.
1769 ! The address is in registerpair AX.
1770 ! If the address is already in zeropage Ldo is used.
1774 stx ADDR ! address of object (lowbyte)
1775 sta ADDR+1 ! address of object (highbyte)
1778 1: lda (ADDR),y ! get lowbyte
1781 lda (ADDR),y ! get highbyte
1784 jsr Push ! do the push
1786 bpl 1b ! perform 2 times
1790 data.s
\0.s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0Í
\ 2.define EARRAY,ERANGE,ESET,EIOVFL
1791 .define ECONV,ESTACK
1792 .define EHEAP,EODDZ,ECASE
1793 .define EBADMON,EBADLIN,EBADGTO
1800 ! This file contains the global data used by the trap routine.
1806 .asciz "Array bound error\n\r"
1808 .asciz "Range bound error\n\r"
1810 .asciz "Set bound error\n\r"
1812 .asciz "Integer overflow\n\r"
1814 .asciz "Conversion error\n\r"
1816 .asciz "Stack overflow\n\r"
1818 .asciz "Heap overflow\n\r"
1820 .asciz "Illegal size argument\n\r"
1822 .asciz "Case error\n\r"
1824 .asciz "Bad monitor call\n\r"
1826 .asciz "Argument of LIN to high\n\r"
1828 .asciz "GTO descriptor error\n\r"
1831 lzri.s
\0\0.s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\83\ 1.define Zrl, Zro
1838 ! The subroutine Zrl makes a local zero which offset is to big.
1839 ! The offset of the local is in registerpair AX.
1840 ! The subroutine Zro is used if the address is already in zeropage.
1844 jsr Locaddr ! get address of local
1848 sta (ADDR),y ! lowbyte = 0
1850 sta (ADDR),y ! highbyte = 0
1854 tlocaddr.s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0s
\ 1.define Locaddr
1861 ! This routine gets the address of a local which offset is to big.
1862 ! The offset is in registerpair AX.
1869 adc LB ! localbase + offset (lowbyte)
1870 sta ADDR ! address (lowbyte)
1872 adc LB+1 ! localbase + offset (highbyte)
1873 sta ADDR+1 ! address (highbyte)
1877 band.s
\0r.s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\96\ 3.define And
1884 ! This subroutine performs the logical and on two groups of
1885 ! atmost 254 bytes. The number of bytes is in register Y.
1886 ! The two groups are on the stack.
1887 ! First the value of the stackpointer is saved in zeropage
1888 ! locations ADDR, ADDR+1. Then an offset of Y is added
1889 ! and stored in ADDR+2, ADDR+3.
1890 ! The result is pushed back on the stack.
1895 sta ADDR+1 ! address of first group (lowbyte)
1897 sta ADDR ! address of first group (highbyte)
1901 sta SP+2 ! new stackpointer (lowbyte)
1902 sta ADDR+2 ! stackpointer + Y (lowbyte)
1905 sta SP+1 ! new stackpointer (highbyte)
1906 sta ADDR+3 ! stackpointer + Y (highbyte)
1908 lda (ADDR),y ! get byte first group
1909 and (ADDR+2),y ! perform logical and with second group
1910 sta (ADDR+2),y ! push result on real_stack
1912 bne 1b ! do it n times
1916 asp.s
\0r.s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0Ë
\ 1.define Asp
1923 ! This subroutine adds an offset to the stackpointer,
1924 ! e.g. after the return from a procedurecall.
1925 ! The offset is in registerpair AX, and is added to the
1933 adc SP+2 ! add adjustment (lowbyte)
1934 sta SP+2 ! new stackpointer (lowbyte)
1936 adc SP+1 ! add adjustment (highbyte)
1937 sta SP+1 ! get stackpointer (highbyte)
1941 cii.s
\0r.s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\96\ 4.define Cii
1948 ! This subroutine converts integers to integers.
1949 ! Convertions of integers with the same source size as destination
1950 ! size aren't done, there just return the source.
1951 ! A convertion from 4 bytes to 2 bytes just strips the two
1952 ! most significant bytes.
1953 ! A convertion from 2 bytes to 4 bytes tests the sign of the
1954 ! source so that sign extentension takes place if neccesairy.
1959 beq Cii_2 ! a conversion from ? to 2
1960 jsr Pop ! a conversion from 4 to ?
1962 beq 8f ! a conversion 4 to 4 (skip)
1964 tay ! save A for sign test
1968 tya ! test on negative
1969 bmi 1f ! negative means sign extension
1970 lda #0 ! no sign extension here
1973 1: lda #0x0FF ! sign extension here
1975 2: jsr Push ! push twobyte integer
1980 Cii_2: ! a conversion from 2 to ?
1983 beq 8f ! a conversion from 2 to 2 (skip)
1984 jsr Pop ! a conversion from 4 to 2
1988 jsr Pop ! strip most significant bytes
1992 jmp Push ! push result
1996 cms.s
\0r.s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0þ
\ 3.define Cms
2003 ! This subroutine compares two groups of bytes, bit for bit.
2004 ! The groups can consist of 2 or 4 bytes. This number is in
2006 ! The address of the first group is stored in zeropage locations
2007 ! ADDR and ADDR+1, the address of the second group in ADDR+2 and ADDR+3
2008 ! The routine returns a 0 on equality, a 1 otherwise.
2015 sta ADDR ! address of first group (lowbyte)
2016 stx ADDR+1 ! address of second group (highbyte)
2021 sta ADDR+2 ! address of second group (lowbyte)
2024 sta ADDR+3 ! address of second group (highbyte)
2029 sta SP+2 ! new stackpointer (lowbyte)
2032 sta SP+1 ! new stackpointer (highbyte)
2034 lda (ADDR),y ! get byte first group
2035 cmp (ADDR+2),y ! compare bit for bit with byte second group
2039 lda #0 ! both groups are equal
2042 2: lda #0 ! there is a difference between the groups
2047 cmu.s
\0r.s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\13\ 2.define Cmu2
2054 ! This subroutine compares two unsigned twobyte integers.
2055 ! If T is the first pushed and than S, the routine will return:
2061 stx EXG ! S (lowbyte)
2062 sta EXG+1 ! S (highbyte)
2065 beq 2f ! S (highbyte) = T (highbyte)
2070 1: lda #0xFF ! S < T
2082 dcom.s
\0r.s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0¸
\ 1.define Com
2089 ! This subroutine performs a one complement on
2090 ! a group of atmost 254 bytes (number in register Y).
2091 ! This group is on the top of the stack.
2096 sta ADDR+1 ! address (highbyte) of first byte
2098 sta ADDR ! address (lowbyte) of first byte
2101 eor #0x0FF ! one complement
2104 bne 1b ! do it n times
2108 csa.s
\0r.s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\07
\ 6.define Csa
2115 ! This subroutine performs the case jump by indexing.
2116 ! The zeropage locations ADDR, ADDR+1 contain the address of
2117 ! the case descriptor which also is the address of the
2119 ! The zeropage locations ADDR+2, ADDR+3 contain the address of the
2120 ! indextable which is the casedescriptor + 6.
2123 stx ADDR ! address of descriptor (lowbyte)
2124 sta ADDR+1 ! address of descriptor (highbyte)
2129 sta ADDR+2 ! address of index table (lowbyte)
2132 sta ADDR+3 ! address of index table (highbyte)
2133 jsr Pop ! fetch index
2134 pha ! subtract lowerbound
2139 sta ARTH ! lowerbound (lowbyte)
2143 sta ARTH+1 ! lowerbound (highbyte)
2144 bmi 1f ! index < lowerbound
2148 bcc 1f ! index (highbyte) > upperbound - lowerbound
2149 bne 2f ! index (highbyte) <= upperbound - lowerbound
2153 bcc 1f ! index (lowbyte) > upperbound - lowerbound
2155 rol ARTH+1 ! index * 2
2159 sta ADDR+2 ! address of pointer (lowbyte)
2162 sta ADDR+3 ! address of pointer (highbyte)
2164 lda (ADDR+2),y ! jump address (lowbyte)
2167 lda (ADDR+2),y ! jump address (highbyte)
2171 3: stx ADDR ! pointer <> 0
2173 jmp (ADDR) ! jump to address
2174 1: ldy #0 ! pointer = 0
2175 lda (ADDR),y ! get default pointer (lowbyte)
2178 lda (ADDR),y ! get default pointer (highbyte)
2181 bne 3b ! default pointer <> 0
2184 rcsb.s
\0r.s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0"
\ 5.define Csb
2191 ! This subroutine performs the case jump by searching the table.
2192 ! The zeropage locations ADDR, ADDR+1 contain the address of the
2193 ! case descriptor, which also is the address of the default pointer.
2194 ! The zeropage locations ADDR+2, ADDR+3 are used to address the jump
2199 stx ADDR ! address of descriptor (lowbyte)
2200 sta ADDR+1 ! address of descriptor (highbyte)
2204 lda (ADDR),y ! number of entries (lowbyte)
2207 stx ARTH ! index (lowbyte)
2208 sta ARTH+1 ! index (highbyte)
2215 sta ADDR+2 ! pointer (lowbyte)
2219 sta ADDR+3 ! pointer (highbyte)
2223 bne 3f ! pointer (lowbyte) <> index (lowbyte)
2227 bne 3f ! pointer (highbyte) <> index (highbyte)
2229 lda (ADDR+2),y ! jump address (lowbyte)
2232 lda (ADDR+2),y ! jump address (highbyte)
2237 lda (ADDR),y ! default pointer (lowbyte)
2240 lda (ADDR),y ! default pointer (highbyte)
2242 4: bne 1f ! pointer (lowbyte) <> 0
2244 bne 1f ! pointer (highbyte) <> 0
2245 beq 5b ! get default pointer
2251 dup.s
\0r.s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\9a\ 2.define Dup
2258 ! This subroutine duplicate's the top n (in register Y) bytes.
2260 ! The duplicating takes place as follows.
2261 ! The registerpair is filled with the bytes at stackpointer + N
2262 ! and stackpopinter + N-1.
2263 ! These two bytes then are pushed onto the stack.
2264 ! Next the offset N is decremented and the next two byte are taken
2265 ! care off. Until N = 0.
2271 stx ADDR ! address of group (lowbyte)
2272 sta ADDR+1 ! address of group (highbyte)
2274 lda (ADDR),y ! get lowbyte
2277 lda (ADDR),y ! get highbyte
2280 jsr Push ! push them
2286 dvu.s
\0r.s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0û
\0.define Dvu2
2293 ! This subroutine performs a twobyte unsigned division
2294 ! For more details see dvi.s.
2308 texg.s
\0r.s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0[
\ 3.define Exg
2315 ! This subroutine exchanges two groups of bytes on the top of the
2316 ! stack. The groups may consist of atmost 255 bytes.
2317 ! This number is in register Y.
2318 ! The exchange is from ADDR, ADDR+1 to ADDR+2, ADDR+3
2324 stx ADDR ! address of first group (lowbyte)
2325 sta ADDR+1 ! address of first group (highbyte)
2326 sty Ytmp ! save number of bytes to be exchanged
2330 sta ADDR+2 ! address of second group (lowbyte)
2333 sta ADDR+3 ! address of second group (highbyte)
2335 lda (ADDR),y ! get byte from first group
2336 pha ! temporary save
2337 lda (ADDR+2),y ! get byte from second group
2338 sta (ADDR),y ! store in first group
2339 pla ! get temporary saved byte
2340 sta (ADDR+2),y ! store in second group
2342 bne 1b ! perform n times
2346 exg2.s
\0.s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0è
\ 1.define Exg2
2353 ! This subroutine exchanges two words on top of the stack.
2354 ! The top word of the stack is really in the AX registerpair.
2355 ! So this word is exchanged with the top of the real stack.
2362 jsr Pop ! get top real stack
2364 sta EXG+1 ! save top of real stack
2368 jsr Push ! push on real stack
2370 lda EXG+1 ! get new A
2374 gto.s
\0\0.s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0¬
\ 5.define Gto
2381 ! This subroutine performs the non_local goto.
2382 ! The address of the descriptor is stored in zeropage locations
2384 ! Since there are two stacks (hardware_stack and the real_stack),
2385 ! the stackpointer of the hard_stack is resetted by searching the
2386 ! new localbase in the real_stack while adjusting the hardware_stack.
2390 stx ADDR ! address of descripto (lowbyte)
2391 sta ADDR+1 ! address of descriptor (highbyte)
2393 pla ! __gto return address.
2395 lda (ADDR),y ! new localbase (lowbyte)
2399 lda (ADDR),y ! new localbase (highbyte)
2404 beq 2f ! goto within same procedure
2406 lda (LB),y ! get localbase (lowbyte)
2409 lda (LB),y ! get localbase (highbyte)
2413 beq 2f ! found localbase
2414 3: stx LB ! temporary save of localbase
2417 pla ! hardware_stack
2419 2: sta LB+1 ! store localbase (highbyte)
2421 stx LB ! store localbase (lowbyte)
2425 sta LBl ! localbase - 240 (lowbyte)
2428 sta LBl+1 ! localbase - 240 (highbyte)
2430 lda (ADDR),y ! new stackpointer (highbyte)
2433 lda (ADDR),y ! new stackpointer (lowbyte)
2436 lda (ADDR),y ! jump address (highbyte)
2439 lda (ADDR),y ! jump address (lowbyte)
2441 jmp (ADDR+2) ! jump to address
2444 indir.s
\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0Z
\ 1.define Indir
2451 ! This subroutine performs an indirect procedurecall.
2452 ! This must be done this way since the jump instruction
2453 ! is the only one which can indirect change the programcounter.
2454 ! The address of the function must be in zeropage loactions
2462 inn.s
\0s
\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\9c\ 4.define Inn
2469 ! This subroutine checks if a certain bit is set in a set
2470 ! of n bytes on top of the stack.
2474 stx ARTH ! save bit number (lowbyte)
2475 sta ARTH+1 ! save bit number (highbyte)
2478 lda #0 ! bit number is negative
2479 sta ARTH+2 ! make it zero
2482 and #0x07 ! get bit number mod 8
2485 cpx #0 ! bit number = 0
2486 beq 2f ! no shifting to right place
2487 1: asl a ! shift left until bit is in place
2490 2: sta ARTH+2 ! bit is one in place
2492 1: lsr ARTH+1 ! shift left 3 times bit number (highbyte)
2493 ror ARTH ! shift left 3 times bit number (lowbyte)
2494 dex ! this is bit number div 8
2495 bne 1b ! which is byte number
2498 stx ADDR ! address of the set (lowbyte)
2499 sta ADDR+1 ! address of the set (highbyte)
2504 2: clc ! remove the set
2506 sta SP+2 ! new stackpointer (lowbyte)
2509 sta SP+1 ! new stackpointer (highbyte)
2511 lda (ADDR),y ! load the byte in A
2512 bit ARTH+2 ! test bit
2514 3: lda #0 ! bit is zero
2517 1: lda #0 ! bit is one
2522 ior.s
\0s
\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0ñ
\ 2.define Ior
2529 ! This subroutine performs the logical inclusive or on two
2530 ! groups of bytes. The groups may consist of atmost 254 bytes.
2531 ! The two groups are on the stack.
2535 sta ADDR+1 ! address of the first group (highbyte)
2537 sta ADDR ! address of the first group (lowbyte)
2541 sta SP+2 ! new stackpointer (lowbyte)
2542 sta ADDR+2 ! address of second group (lowbyte)
2545 sta SP+1 ! new stackpointer (highbyte)
2546 sta ADDR+3 ! address of second group (highbyte)
2548 lda (ADDR),y ! get byte first group
2549 ora (ADDR+2),y ! inclusive or with byte second group
2550 sta (ADDR+2),y ! restore result on stack
2552 bne 1b ! perform n times
2556 lcs.s
\0s
\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\82\ 1.define Lcs
2563 ! This subroutine creates space for locals on procedure entry
2564 ! by lowering the stackpointer.
2568 sta ARTH ! number of locals (lowbyte)
2569 stx ARTH+1 ! number of locals (highbyte)
2573 sta SP+2 ! new stackpointer (lowbyte)
2576 sta SP+1 ! new stackpointer (highbyte)
2580 lxa1.s
\0\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0;
\ 1.define Lxa1
2587 ! This subroutine loads the address of AB zero static levels back.
2590 ldy LB+1 ! load address of localbase (highbyte)
2591 ldx LB ! load address of localbase (lowbyte)
2593 inx ! argumentbase = localbase + 2
2600 )lxa2.s
\0\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\04
\ 2.define Lxa2
2607 ! This subroutine load the address of AB n (255 >= n > 0) static levels
2613 sta ADDR ! address of localbase (lowbyte)
2615 sta ADDR+1 ! address of localbase (highbyte)
2617 lda (ADDR),y ! static level LB (lowbyte)
2620 lda (ADDR),y ! static level LB (highbyte)
2621 sta ADDR+1 ! static level LB (highbyte)
2623 sta ADDR ! static level LB (lowbyte)
2629 inx ! argumentbase = localbase + 2
2637 lxl.s
\0\0\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0ý
\ 1.define Lxl
2644 ! This subroutine loads LB n (255 => n > 0) static levels back.
2649 sta ADDR ! address of localbase (lowbyte)
2651 sta ADDR+1 ! address of localbase (highbyte)
2653 lda (ADDR),y ! get localbase (lowbyte) 1 level back
2656 lda (ADDR),y ! get localbase (highbyte) 1 level back
2657 sta ADDR+1 ! new localbase (highbyte)
2659 sta ADDR ! new localbase (lowbyte)
2667 npro.s
\0\0\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0Ý
\ 2.define Pro
2674 ! This routine is called at the entry of a procedure.
2675 ! It saves the localbase of the invoking procedure, and sets the
2676 ! new localbase to the present value of the stackpointer.
2677 ! It then initializes the second localbase by subtracting
2678 ! BASE from the real one.
2682 ldx LB ! get localbase (lowbyte)
2683 lda LB+1 ! get localbase (highbyte)
2684 jsr Push ! push localbase onto the stack
2685 ldx SP+2 ! get stackpointer (lowbyte)
2686 lda SP+1 ! get stackpointer (highbyte)
2687 stx LB ! new localbase (lowbyte)
2688 sta LB+1 ! new localbse (highbyte)
2693 sta LBl ! second localbase (lowbyte)
2696 sta LBl+1 ! second localbase (highbyte)
2700 frol.s
\0\0\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0ü
\ 1.define Rol
2707 ! This subroutine rotates left an integer n times
2708 ! N is in register X.
2709 ! The result is returned in registerpair AX.
2716 jmp Pop ! zero rotate return input
2717 1: tay ! Y contains number of rotates
2719 stx Ytmp ! save lowbyte
2721 rol Ytmp ! rotate lowbyte
2722 rol a ! rotate highbyte
2724 inc Ytmp ! put carry in rightmost bit
2727 ldx Ytmp ! store lowbyte in X
2731 rol4.s
\0\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0Ü
\ 1.define Rol4
2738 ! This subroutine rotates left a fourbyte integer n times.
2739 ! N is in register X.
2744 bne 1f ! a zero rotate skip
2756 rol ARTH+3 ! rotate left
2758 inc ARTH ! put carry in rightmost bit
2769 ror.s
\0\0\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0÷
\ 1.define Ror
2776 ! This subroutine rotates right a integer twobyte word.
2777 ! The number of rotates is in X.
2778 ! The result is returned in registerpair AX.
2783 bne 1f ! a zero rotate just return input
2787 stx Ytmp ! save lowbyte
2789 ror a ! rotate highbyte
2790 ror Ytmp ! rotate lowbyte
2792 ora #0x80 ! put carry in leftmost bit
2795 ldx Ytmp ! get lowbyte
2799 tror4.s
\0\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\1e\ 2.define Ror4
2806 ! This subroutine rotates right a fourbyte word.
2807 ! The number of rotates is in X.
2812 bne 1f ! a zero rotate skip
2821 2: lsr ARTH+3 ! rotate word
2826 lda #0x80 ! put carry in leftmost bit
2836 jmp Push ! push result onto the stack
2839 sli.s
\0\0\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0£
\ 1.define Sli2
2846 ! This subroutine shifts a signed or unsigned interger to the
2848 ! N is in register X.
2849 ! The returned value is in registerpair AX.
2855 jmp Pop ! zero shift, return input
2857 jsr Pop ! get integer
2858 stx Ytmp ! save lowbyte
2863 ldx Ytmp ! get lowbyte
2867 Asli4.s
\0\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0@
\ 2.define Sli4
2874 ! This subroutine shift a signed or unsigned fourbyte integer
2875 ! n times left. N is in register X.
2880 beq 9f ! zero shift, return input
2881 lda SP+2 ! the shifting is done on the stack
2882 sta ADDR ! address of integer (lowbyte)
2884 sta ADDR+1 ! address of integer (highbyte)
2901 sta (ADDR),y ! shift left
2907 sri.s
\0\0\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\13\ 3.define Sri2, Sru2
2914 ! The subroutine Sri2 shifts a signed integer n times right.
2915 ! In the case of a negative integer there is signextension.
2916 ! The subroutine Sru2 shifts right an unsigned integer.
2917 ! The returned value is in registerpair AX.
2923 jmp Pop ! zero shift, return input
2925 jsr Pop ! get integer
2926 stx Ytmp ! save lowbyte
2927 jmp 2f ! shift unsigned
2931 jmp Pop ! zero shift, return input
2933 jsr Pop ! get integer
2934 stx Ytmp ! save lowbyte
2936 bmi 1f ! negative signextended shift
2938 ror Ytmp ! shift not signextended
2941 ldx Ytmp ! get lowbyte
2943 1: sec ! shift signextended
2948 ldx Ytmp ! get lowbyte
2952 dsri4.s
\0\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\95\ 2.define Sri4, Sru4
2959 ! The subroutine Sri4 shifts a signed fourbyte integer to the
2961 ! N is in register X.
2962 ! The subroutine Sru4 shifts an unsigned fourbyte integer to the
3009 2teq.s
\0\0\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0O
\ 1.define Teq
3016 ! This subroutine test if the value in registerpair AX is zero
3018 ! The returned value, a 1 or a 0, is in AX.
3024 2: lda #0 ! AX is zero
3029 lda #0 ! AX is nonzero
3035 tge.s
\0\0\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0$
\ 1.define Tge
3042 ! This subroutine test if the value in registerpair AX is
3043 ! greater than or equal to zero.
3044 ! The result is returned in AX.
3058 tgt.s
\0\0\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0a
\ 1.define Tgt
3065 ! This subroutine tests if the value in registerpair AX is
3066 ! greater than zero.
3067 ! The value returned is in AX.
3084 2tle.s
\0\0\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0k
\ 1.define Tle
3091 ! This subroutine tests if the value in registerpair AX is
3092 ! less than or equal to zero.
3093 ! The value returned is in AX.
3111 ttlt.s
\0\0\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\15\ 1.define Tlt
3118 ! This subroutine tests if the value in registerpair AX is
3120 ! The value returned is in AX.
3134 tne.s
\0\0\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\04
\ 1.define Tne
3141 ! This subroutine tests if the value in registerpair AX is
3142 ! not equal to zero.
3143 ! The value returned is in AX.
3159 xor.s
\0\0\0s
\0s
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0Æ
\ 2.define Xor
3166 ! This subroutine performs the exclusive or on two groups of bytes.
3167 ! The groups consists of atmost 254 bytes.
3168 ! The result is on top of the stack.
3173 sta ADDR+1 ! address of first group (lowbyte)
3175 sta ADDR ! address of first group (highbyte)
3179 sta SP+2 ! new stackpointer (lowbyte)
3180 sta ADDR+2 ! address of second group (lowbyte)
3183 sta SP+1 ! new stackpointer (highbyte)
3184 sta ADDR+3 ! address of second group (highbyte)
3186 lda (ADDR),y ! get byte first group
3187 eor (ADDR+2),y ! exclusive or with byte second group
3188 sta (ADDR+2),y ! restore result