102 call div_hl_de_signed
107 call div_hl_de_signed
117 ; push result pointer
121 ; call sm_factorial(argument)
127 ; ; print it the easy way
198 rst 0 ; can't return into ccp as clobbered by stack growth
212 ; no, set up for *result =
226 ; push result pointer
230 ; call sm_factorial(argument - 1)
244 ; set *result = sm_factorial(argument - 1) * argument
250 1$: ; yes, set up for *result =
329 ; lower dispatcher, just before 0x100
333 dispatch_l5: ; pc in de
336 dispatch_l6: ; tos in de, pc in hl
341 rst 0x30 ; print stack
348 dispatch_l1: ; tos in de and hl, pc in bc
350 dispatch_l2: ; tos in hl, pc in bc
352 dispatch_l3: ; tos in de, pc in bc, h clobbered
354 dispatch_l4: ; tos in de, pc in bc, h = >esc
358 rst 0x30 ; print stack
367 call_i: ; same as imm_w, call
379 jmp_i: ; same as imm_w, jmp
383 jz_i: ; same as imm_w, jz
394 jnz_i: ; same as imm_w, jnz
417 add_isp: ; same as imm_w, add_sp
426 ld_iw: ; same as imm_w, ld_w
437 ld_isb: ; same as imm_w, ld_sb
450 ld_iub: ; same as imm_w, ld_ub
471 add_iw: ; same as imm_w, add_w
479 ;sub_iw: ; same as imm_w, sub_w
480 ; rst 8 ; ld hl,(bc)+
482 sub_xw: ; same as xchg_w, sub_w
486 sub_w: ; same as neg_w, add_w
492 eq_iw: ; same as imm_w, eq_w
505 ; middle dispatch routines
507 jmp: ; also means ret
512 adj_isp: ; same as imm_w, adj_sp
516 adj_sp: ; same as add_sp, st_sp
525 ;st_ixw: ; same as imm_w, xchg_w, st_w
526 ; rst 8 ; ld hl,(bc)+
532 st_iw: ; same as imm_w, st_w
543 st_ixb: ; same as imm_w, xchg_w, st_d
551 ; middle dispatcher, near 0x180, smaller in size
552 ; used for store-type routines that empty stack and need it to be popped
554 dispatch_mm1: ; pc in bc
556 dispatch_m0: ; pc in bc, h = >esc
561 rst 0x30 ; print stack
565 lt_iuw: ; same as imm_w, lt_iuw
568 gt_uw: ; same as xchg_w, lt_uw
581 lt_isw: ; same as imm_w, lt_isw
584 gt_sw: ; same as xchg_w, lt_sw
605 and_iw: ; same as imm_w, and_w
618 or_iw: ; same as imm_w, and_w
631 xor_iw: ; same as imm_w, and_w
691 ; upper dispatcher, after 0x200
693 dispatch_um1: ; tos in hl and de, pc in bc
696 ;dispatch_u1: ; tos in de and hl, pc in bc
698 dispatch_u2: ; tos in hl, pc in bc
700 dispatch_u3: ; tos in de, pc in bc, h clobbered
702 dispatch_u4: ; tos in de, pc in bc, h = >esc
705 rst 0x30 ; print stack
756 ;ld b,a ; for 32-bit result
759 ;ld c,a ; for 32-bit result
811 jp p,4$ ; positive dividend
814 dec hl ; reduces remainder by 1 (we inc later)
818 jr c,2$ ; negative dividend, negative divisor
820 ; negative dividend, positive divisor
828 1$: inc hl ; get into range -divisor+1..0
834 2$: ; negative dividend, negative divisor
841 3$: inc hl ; get into range divisor+1..0
847 4$: ; positive dividend
851 jr nc,divu ; positive dividend, positive divisor
853 ; positive dividend, negative divisor
872 divu: ; positive dividend, positive divisor
884 ; non-restoring division routine
886 ; de = divisor, hl:a = dividend with hl = previous remainder, a = next byte
887 ; enter at div0 with positive remainder in hl, such that hl < de
888 ; enter at div1 with negative remainder in hl, such that hl >= -de
890 ; div0/1 return a = 8-bit quotient as an odd number interpreted as -ff..ff,
891 ; by summing positive/negative place values, e.g. -80 +40 +20 -10 +8 -4 -2 +1
893 ; if entered at div0, there is a -80 and so quotient is in range -ff..-1
894 ; if entered at div1, there is a +80 and so quotient is in range 1..ff
895 ; falls out of loop after div01 with positive remainder, div11 with negative,
896 ; depending on this we should re-enter at div0 or div1, signalled by cf return
898 ; the successive quotient bytes can be concatenated into a full quotient,
899 ; but negative bytes require the next higher quotient byte to be decremented,
900 ; we know in advance if this will happen because the implied sign of the
901 ; quotient byte depends only on whether we entered at div0 or div1, hence,
902 ; before the div11 return we'll decrement to compensate for next negative byte
904 ; the decrement can also be seen as compensating for the extra add hl,de that
905 ; may be needed to make negative remainder positive before return to caller,
906 ; thus leaving quotient in a consistent state regardless of which exit taken,
907 ; remainder needs the add hl,de if cf=1 returned (equiv. return byte is even)
909 ; in the following code each sbc hl,de gets an inc a and each add hl,de gets
910 ; a dec a, guaranteeing the integrity of the division, the initial scf/rla is
911 ; needed to make the result 100 + -ff..ff or 1..1ff, so that the decrements
912 ; cannot borrow into the upcoming dividend bits also held in a, and there must
913 ; be another shift between the scf/rla and increment/decrement so that the scf
914 ; is implicitly in the 100s place, making the code awkward though it's correct
916 ; now optimized to only inc/dec a when doing zero-crossing, fix above analysis
926 div11: ; bit 1, below
932 div02: ; bit 2, above
938 div13: ; bit 3, below
944 div04: ; bit 4, above
950 div15: ; bit 5, below
956 div06: ; bit 6, above
962 div17: ; bit 7, below
980 div01: ; bit 1, above
986 div12: ; bit 2, below
992 div03: ; bit 3, above
998 div14: ; bit 4, below
1004 div05: ; bit 5, above
1010 div16: ; bit 6, below
1016 div07: ; bit 7, above
1022 div18: ; done, below
1025 ;dec a ; compensation
1029 ; divn0/1 are the same as div0/1 but carry reversed after add/subtract divisor
1030 ; this is for negative divisors where we expect carry (means no zero crossing)
1032 ; when divisor negated, remainder also negated, so we expect to do subtraction
1033 ; when remainder negative and vice versa, need to clear carry after add hl,hl
1036 divn0: ; bit 0, above
1044 divn11: ; bit 1, below
1050 divn02: ; bit 2, above
1057 divn13: ; bit 3, below
1063 divn04: ; bit 4, above
1070 divn15: ; bit 5, below
1076 divn06: ; bit 6, above
1083 divn17: ; bit 7, below
1089 divn08: ; done, above
1095 divn1: ; bit 0, below
1101 divn01: ; bit 1, above
1108 divn12: ; bit 2, below
1114 divn03: ; bit 3, above
1121 divn14: ; bit 4, below
1127 divn05: ; bit 5, above
1134 divn16: ; bit 6, below
1140 divn07: ; bit 7, above
1147 divn18: ; done, below
1150 ;dec a ; compensation
1157 .ascii '0123456789abcdef'