├── go_plot ├── .gitignore ├── results ├── omult7.png ├── omult8.png ├── omult9.png ├── omult11.png ├── omult9_with_0.5_bias.png ├── results_mult1.json ├── results_mult16.json ├── results_mult2.json ├── results_mult22.json ├── results_mult3.json ├── results_mult5.json ├── results_mult7.json ├── results_mult8.json ├── results_mult82.json ├── results_mult9.json ├── results_omult7.json ├── results_omult9.json ├── results_mult10.json ├── results_mult11.json ├── results_mult12.json ├── results_mult13.json ├── results_mult14.json ├── results_mult15.json ├── results_mult17.json ├── results_mult18.json ├── results_mult19.json ├── results_mult20.json ├── results_mult21.json ├── results_mult23.json ├── results_mult24.json ├── results_mult25.json ├── results_mult26.json ├── results_mult27.json ├── results_mult28.json ├── results_mult29.json ├── results_mult30.json ├── results_mult31.json ├── results_mult32.json ├── results_mult33.json ├── results_mult34.json ├── results_mult35.json ├── results_mult36.json ├── results_mult37.json ├── results_mult38.json ├── results_mult39.json ├── results_mult4.json ├── results_mult40.json ├── results_mult41.json ├── results_mult42.json ├── results_mult43.json ├── results_mult44.json ├── results_mult45.json ├── results_mult46.json ├── results_mult47.json ├── results_mult48.json ├── results_mult49.json ├── results_mult50.json ├── results_mult51.json ├── results_mult52.json ├── results_mult53.json ├── results_mult54.json ├── results_mult55.json ├── results_mult56.json ├── results_mult57.json ├── results_mult58.json ├── results_mult59.json ├── results_mult6.json ├── results_mult60.json ├── results_mult61.json ├── results_mult62.json ├── results_mult63.json ├── results_mult64.json ├── results_mult65.json ├── results_mult66.json ├── results_mult67.json ├── results_mult68.json ├── results_mult69.json ├── results_mult70.json ├── results_mult71.json ├── results_mult72.json ├── results_mult73.json ├── results_mult74.json ├── results_mult75.json ├── results_mult76.json ├── results_mult77.json ├── results_mult78.json ├── results_mult79.json ├── results_mult80.json ├── results_mult81.json ├── results_mult83.json ├── results_mult84.json ├── results_mult85.json ├── results_mult86.json ├── results_mult87.json ├── results_mult88.json ├── results_mult89.json ├── results_omult1.json ├── results_omult10.json ├── results_omult11.json ├── results_omult12.json ├── results_omult13.json ├── results_omult14.json ├── results_omult15.json ├── results_omult16.json ├── results_omult17.json ├── results_omult2.json ├── results_omult25.json ├── results_omult26.json ├── results_omult27.json ├── results_omult28.json ├── results_omult29.json ├── results_omult3.json ├── results_omult30.json ├── results_omult32.json ├── results_omult4.json ├── results_omult5.json ├── results_omult6.json ├── results_omult8.json ├── results_smult1.json ├── results_smult10.json ├── results_smult11.json ├── results_smult2.json ├── results_smult3.json ├── results_smult4.json ├── results_smult5.json ├── results_smult6.json ├── results_smult7.json ├── results_smult8.json ├── results_smult9.json ├── results_omult18.json ├── results_omult19.json ├── results_omult20.json ├── results_omult21.json ├── results_omult22.json ├── results_omult23.json ├── results_omult24.json ├── results_omult31.json └── results_smult12.json ├── source └── disassembler.h └── tests ├── mult11.a ├── mult9.a ├── omult3.a ├── mult70.a ├── mult43.a ├── omult12.a ├── omult1.a ├── mult75.a ├── mult68.a ├── omult25.a ├── mult78.a ├── mult71.a ├── mult47.a ├── mult19.a ├── omult26.a ├── mult46.a ├── mult72.a ├── mult17.a ├── smult6.a ├── mult35.a ├── mult77.a ├── omult2.a ├── mult21.a ├── mult40.a ├── omult17.a ├── mult73.a ├── mult76.a ├── mult23.a ├── mult79.a ├── omult27.a ├── mult57.a ├── mult25.a ├── smult5.a ├── mult27.a ├── mult3.a ├── omult10.a ├── mult14.a ├── mult8.a ├── omult29.a ├── mult49.a ├── omult28.a ├── mult24.a ├── mult82.a ├── mult1.a ├── mult39.a ├── mult83.a ├── omult14.a ├── mult20.a ├── omult25.c ├── omult26.c ├── omult2.c ├── mult20.c ├── mult26.c ├── mult32.c ├── mult34.c ├── mult37.c ├── mult40.c ├── mult43.c ├── mult47.c ├── mult6.c ├── mult77.c ├── omult16.a ├── mult79.c ├── mult82.c ├── mult83.c ├── omult3.c ├── mult9.c ├── mult10.a ├── mult28.a ├── mult11.c ├── mult76.c ├── mult19.c ├── mult21.c ├── mult35.c ├── mult44.c ├── mult75.c ├── mult78.c ├── omult12.c ├── mult18.a ├── mult5.c ├── mult7.a ├── mult28.c ├── mult29.c ├── mult87.c ├── mult10.c ├── mult12.c ├── mult16.c ├── mult17.c ├── mult18.c ├── mult25.c ├── mult39.c ├── mult80.c ├── mult81.c ├── mult13.c ├── mult74.a ├── omult27.c ├── mult22.c ├── mult23.c ├── mult27.c ├── mult38.c ├── mult57.c ├── mult44.a ├── mult72.c ├── mult14.c ├── mult7.c ├── mult8.c ├── mult24.c ├── mult26.a ├── mult30.c ├── mult48.a ├── omult29.c ├── mult67.a ├── mult70.c ├── mult71.c ├── omult24.a ├── mult30.a ├── mult37.a ├── mult68.c ├── omult1.c ├── omult17.c ├── mult12.a ├── mult1.c ├── mult2.c ├── mult3.c ├── mult4.c ├── mult41.c ├── mult42.c ├── mult45.c ├── mult46.c ├── mult50.c └── mult51.c /go_plot: -------------------------------------------------------------------------------- 1 | python3 plotter/plotter.py 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/** 2 | source/6502.* 3 | *.csv 4 | *.bbprojectd/* 5 | -------------------------------------------------------------------------------- /results/omult7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TobyLobster/multiply_test/HEAD/results/omult7.png -------------------------------------------------------------------------------- /results/omult8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TobyLobster/multiply_test/HEAD/results/omult8.png -------------------------------------------------------------------------------- /results/omult9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TobyLobster/multiply_test/HEAD/results/omult9.png -------------------------------------------------------------------------------- /results/omult11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TobyLobster/multiply_test/HEAD/results/omult11.png -------------------------------------------------------------------------------- /results/omult9_with_0.5_bias.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TobyLobster/multiply_test/HEAD/results/omult9_with_0.5_bias.png -------------------------------------------------------------------------------- /source/disassembler.h: -------------------------------------------------------------------------------- 1 | 2 | struct disassembler_context { 3 | char *pc; 4 | char output[256]; 5 | }; 6 | 7 | extern struct disassembler_context disassembler; 8 | extern void disassemble_next(); -------------------------------------------------------------------------------- /results/results_mult1.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult1", 4 | "bytes": "38", 5 | "AverageCycles": "751.00", 6 | "MinCycles": "623", 7 | "MaxCycles": "879" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult16.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult16", 4 | "bytes": "574", 5 | "AverageCycles": "67.48", 6 | "MinCycles": "56", 7 | "MaxCycles": "79" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult2.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult2", 4 | "bytes": "33", 5 | "AverageCycles": "578.00", 6 | "MinCycles": "442", 7 | "MaxCycles": "714" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult22.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult22", 4 | "bytes": "562", 5 | "AverageCycles": "74.48", 6 | "MinCycles": "70", 7 | "MaxCycles": "79" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult3.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult3", 4 | "bytes": "36", 5 | "AverageCycles": "711.00", 6 | "MinCycles": "575", 7 | "MaxCycles": "847" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult5.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult5", 4 | "bytes": "834", 5 | "AverageCycles": "92.01", 6 | "MinCycles": "92", 7 | "MaxCycles": "96" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult7.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult7", 4 | "bytes": "36", 5 | "AverageCycles": "133.53", 6 | "MinCycles": "13", 7 | "MaxCycles": "142" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult8.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult8", 4 | "bytes": "29", 5 | "AverageCycles": "153.45", 6 | "MinCycles": "13", 7 | "MaxCycles": "162" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult82.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult82", 4 | "bytes": "827", 5 | "AverageCycles": "67.24", 6 | "MinCycles": "64", 7 | "MaxCycles": "71" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult9.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult9", 4 | "bytes": "17", 5 | "AverageCycles": "162.00", 6 | "MinCycles": "146", 7 | "MaxCycles": "178" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult7.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult7", 4 | "bytes": "802", 5 | "AverageCycles": "46.72", 6 | "MinCycles": "14", 7 | "MaxCycles": "47" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult9.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult9", 4 | "bytes": "780", 5 | "AverageCycles": "22.97", 6 | "MinCycles": "22", 7 | "MaxCycles": "23" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult10.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult10", 4 | "bytes": "27", 5 | "AverageCycles": "221.08", 6 | "MinCycles": "25", 7 | "MaxCycles": "297" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult11.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult11", 4 | "bytes": "17", 5 | "AverageCycles": "162.00", 6 | "MinCycles": "146", 7 | "MaxCycles": "178" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult12.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult12", 4 | "bytes": "71", 5 | "AverageCycles": "108.64", 6 | "MinCycles": "16", 7 | "MaxCycles": "118" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult13.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult13", 4 | "bytes": "1075", 5 | "AverageCycles": "54.00", 6 | "MinCycles": "51", 7 | "MaxCycles": "57" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult14.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult14", 4 | "bytes": "2077", 5 | "AverageCycles": "45.99", 6 | "MinCycles": "44", 7 | "MaxCycles": "48" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult15.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult15", 4 | "bytes": "2180", 5 | "AverageCycles": "204.60", 6 | "MinCycles": "196", 7 | "MaxCycles": "216" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult17.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult17", 4 | "bytes": "28", 5 | "AverageCycles": "150.47", 6 | "MinCycles": "16", 7 | "MaxCycles": "159" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult18.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult18", 4 | "bytes": "72", 5 | "AverageCycles": "109.63", 6 | "MinCycles": "16", 7 | "MaxCycles": "118" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult19.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult19", 4 | "bytes": "18", 5 | "AverageCycles": "185.00", 6 | "MinCycles": "169", 7 | "MaxCycles": "201" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult20.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult20", 4 | "bytes": "27", 5 | "AverageCycles": "244.00", 6 | "MinCycles": "212", 7 | "MaxCycles": "276" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult21.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult21", 4 | "bytes": "18", 5 | "AverageCycles": "150.00", 6 | "MinCycles": "134", 7 | "MaxCycles": "166" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult23.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult23", 4 | "bytes": "21", 5 | "AverageCycles": "153.00", 6 | "MinCycles": "137", 7 | "MaxCycles": "169" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult24.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult24", 4 | "bytes": "70", 5 | "AverageCycles": "110.63", 6 | "MinCycles": "16", 7 | "MaxCycles": "120" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult25.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult25", 4 | "bytes": "28", 5 | "AverageCycles": "243.00", 6 | "MinCycles": "175", 7 | "MaxCycles": "311" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult26.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult26", 4 | "bytes": "47", 5 | "AverageCycles": "278.14", 6 | "MinCycles": "23", 7 | "MaxCycles": "409" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult27.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult27", 4 | "bytes": "1312", 5 | "AverageCycles": "46.49", 6 | "MinCycles": "44", 7 | "MaxCycles": "49" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult28.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult28", 4 | "bytes": "27", 5 | "AverageCycles": "130.00", 6 | "MinCycles": "114", 7 | "MaxCycles": "146" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult29.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult29", 4 | "bytes": "43", 5 | "AverageCycles": "120.00", 6 | "MinCycles": "104", 7 | "MaxCycles": "136" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult30.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult30", 4 | "bytes": "74", 5 | "AverageCycles": "114.00", 6 | "MinCycles": "98", 7 | "MaxCycles": "130" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult31.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult31", 4 | "bytes": "2219", 5 | "AverageCycles": "238.07", 6 | "MinCycles": "228", 7 | "MaxCycles": "254" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult32.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult32", 4 | "bytes": "592", 5 | "AverageCycles": "117.14", 6 | "MinCycles": "117", 7 | "MaxCycles": "120" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult33.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult33", 4 | "bytes": "1276", 5 | "AverageCycles": "609.86", 6 | "MinCycles": "574", 7 | "MaxCycles": "646" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult34.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult34", 4 | "bytes": "36", 5 | "AverageCycles": "280.00", 6 | "MinCycles": "204", 7 | "MaxCycles": "356" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult35.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult35", 4 | "bytes": "20", 5 | "AverageCycles": "188.00", 6 | "MinCycles": "172", 7 | "MaxCycles": "204" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult36.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult36", 4 | "bytes": "55", 5 | "AverageCycles": "957.01", 6 | "MinCycles": "711", 7 | "MaxCycles": "1236" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult37.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult37", 4 | "bytes": "35", 5 | "AverageCycles": "278.00", 6 | "MinCycles": "202", 7 | "MaxCycles": "354" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult38.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult38", 4 | "bytes": "1345", 5 | "AverageCycles": "97.00", 6 | "MinCycles": "97", 7 | "MaxCycles": "97" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult39.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult39", 4 | "bytes": "69", 5 | "AverageCycles": "107.00", 6 | "MinCycles": "91", 7 | "MaxCycles": "123" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult4.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult4", 4 | "bytes": "137", 5 | "AverageCycles": "567.00", 6 | "MinCycles": "505", 7 | "MaxCycles": "629" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult40.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult40", 4 | "bytes": "35", 5 | "AverageCycles": "278.00", 6 | "MinCycles": "202", 7 | "MaxCycles": "354" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult41.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult41", 4 | "bytes": "1149", 5 | "AverageCycles": "350.00", 6 | "MinCycles": "338", 7 | "MaxCycles": "362" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult42.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult42", 4 | "bytes": "647", 5 | "AverageCycles": "403.83", 6 | "MinCycles": "369", 7 | "MaxCycles": "442" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult43.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult43", 4 | "bytes": "26", 5 | "AverageCycles": "208.90", 6 | "MinCycles": "175", 7 | "MaxCycles": "259" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult44.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult44", 4 | "bytes": "69", 5 | "AverageCycles": "109.00", 6 | "MinCycles": "93", 7 | "MaxCycles": "125" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult45.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult45", 4 | "bytes": "38", 5 | "AverageCycles": "695.00", 6 | "MinCycles": "543", 7 | "MaxCycles": "847" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult46.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult46", 4 | "bytes": "40", 5 | "AverageCycles": "655.00", 6 | "MinCycles": "503", 7 | "MaxCycles": "807" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult47.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult47", 4 | "bytes": "20", 5 | "AverageCycles": "175.00", 6 | "MinCycles": "159", 7 | "MaxCycles": "191" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult48.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult48", 4 | "bytes": "69", 5 | "AverageCycles": "707.11", 6 | "MinCycles": "328", 7 | "MaxCycles": "860" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult49.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult49", 4 | "bytes": "43", 5 | "AverageCycles": "703.00", 6 | "MinCycles": "551", 7 | "MaxCycles": "855" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult50.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult50", 4 | "bytes": "55", 5 | "AverageCycles": "534.00", 6 | "MinCycles": "398", 7 | "MaxCycles": "670" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult51.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult51", 4 | "bytes": "69", 5 | "AverageCycles": "524.00", 6 | "MinCycles": "388", 7 | "MaxCycles": "660" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult52.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult52", 4 | "bytes": "75", 5 | "AverageCycles": "519.00", 6 | "MinCycles": "383", 7 | "MaxCycles": "655" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult53.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult53", 4 | "bytes": "95", 5 | "AverageCycles": "514.00", 6 | "MinCycles": "378", 7 | "MaxCycles": "650" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult54.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult54", 4 | "bytes": "192", 5 | "AverageCycles": "497.00", 6 | "MinCycles": "361", 7 | "MaxCycles": "633" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult55.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult55", 4 | "bytes": "344", 5 | "AverageCycles": "483.50", 6 | "MinCycles": "348", 7 | "MaxCycles": "619" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult56.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult56", 4 | "bytes": "1210", 5 | "AverageCycles": "259.96", 6 | "MinCycles": "250", 7 | "MaxCycles": "270" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult57.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult57", 4 | "bytes": "1058", 5 | "AverageCycles": "48.49", 6 | "MinCycles": "46", 7 | "MaxCycles": "51" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult58.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult58", 4 | "bytes": "772", 5 | "AverageCycles": "365.03", 6 | "MinCycles": "357", 7 | "MaxCycles": "373" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult59.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult59", 4 | "bytes": "67", 5 | "AverageCycles": "553.99", 6 | "MinCycles": "36", 7 | "MaxCycles": "690" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult6.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult6", 4 | "bytes": "620", 5 | "AverageCycles": "137.21", 6 | "MinCycles": "114", 7 | "MaxCycles": "161" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult60.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult60", 4 | "bytes": "39", 5 | "AverageCycles": "527.00", 6 | "MinCycles": "375", 7 | "MaxCycles": "679" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult61.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult61", 4 | "bytes": "57", 5 | "AverageCycles": "482.00", 6 | "MinCycles": "346", 7 | "MaxCycles": "618" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult62.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult62", 4 | "bytes": "93", 5 | "AverageCycles": "442.00", 6 | "MinCycles": "306", 7 | "MaxCycles": "578" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult63.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult63", 4 | "bytes": "165", 5 | "AverageCycles": "422.00", 6 | "MinCycles": "286", 7 | "MaxCycles": "558" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult64.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult64", 4 | "bytes": "279", 5 | "AverageCycles": "386.00", 6 | "MinCycles": "260", 7 | "MaxCycles": "512" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult65.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult65", 4 | "bytes": "1061", 5 | "AverageCycles": "47.49", 6 | "MinCycles": "45", 7 | "MaxCycles": "50" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult66.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult66", 4 | "bytes": "1580", 5 | "AverageCycles": "45.49", 6 | "MinCycles": "44", 7 | "MaxCycles": "47" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult67.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult67", 4 | "bytes": "37", 5 | "AverageCycles": "633.00", 6 | "MinCycles": "481", 7 | "MaxCycles": "785" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult68.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult68", 4 | "bytes": "20", 5 | "AverageCycles": "188.00", 6 | "MinCycles": "172", 7 | "MaxCycles": "204" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult69.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult69", 4 | "bytes": "65", 5 | "AverageCycles": "946.52", 6 | "MinCycles": "746", 7 | "MaxCycles": "1207" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult70.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult70", 4 | "bytes": "31", 5 | "AverageCycles": "1987.11", 6 | "MinCycles": "20", 7 | "MaxCycles": "4860" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult71.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult71", 4 | "bytes": "41", 5 | "AverageCycles": "1572.91", 6 | "MinCycles": "22", 7 | "MaxCycles": "5125" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult72.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult72", 4 | "bytes": "16", 5 | "AverageCycles": "1544.56", 6 | "MinCycles": "19", 7 | "MaxCycles": "3838" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult73.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult73", 4 | "bytes": "28", 5 | "AverageCycles": "1174.08", 6 | "MinCycles": "30", 7 | "MaxCycles": "3854" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult74.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult74", 4 | "bytes": "86", 5 | "AverageCycles": "1358.00", 6 | "MinCycles": "638", 7 | "MaxCycles": "2078" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult75.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult75", 4 | "bytes": "24", 5 | "AverageCycles": "205.90", 6 | "MinCycles": "172", 7 | "MaxCycles": "256" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult76.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult76", 4 | "bytes": "18", 5 | "AverageCycles": "185.00", 6 | "MinCycles": "169", 7 | "MaxCycles": "201" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult77.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult77", 4 | "bytes": "43", 5 | "AverageCycles": "288.00", 6 | "MinCycles": "199", 7 | "MaxCycles": "377" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult78.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult78", 4 | "bytes": "20", 5 | "AverageCycles": "188.00", 6 | "MinCycles": "172", 7 | "MaxCycles": "204" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult79.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult79", 4 | "bytes": "39", 5 | "AverageCycles": "399.00", 6 | "MinCycles": "399", 7 | "MaxCycles": "399" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult80.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult80", 4 | "bytes": "325", 5 | "AverageCycles": "110.00", 6 | "MinCycles": "110", 7 | "MaxCycles": "110" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult81.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult81", 4 | "bytes": "26", 5 | "AverageCycles": "199.00", 6 | "MinCycles": "163", 7 | "MaxCycles": "235" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult83.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult83", 4 | "bytes": "1079", 5 | "AverageCycles": "56.00", 6 | "MinCycles": "54", 7 | "MaxCycles": "58" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult84.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult84", 4 | "bytes": "1199", 5 | "AverageCycles": "253.92", 6 | "MinCycles": "243", 7 | "MaxCycles": "267" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult85.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult85", 4 | "bytes": "38", 5 | "AverageCycles": "540.50", 6 | "MinCycles": "412", 7 | "MaxCycles": "669" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult86.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult86", 4 | "bytes": "2170", 5 | "AverageCycles": "187.07", 6 | "MinCycles": "177", 7 | "MaxCycles": "203" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult87.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult87", 4 | "bytes": "630", 5 | "AverageCycles": "174.00", 6 | "MinCycles": "174", 7 | "MaxCycles": "174" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult88.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult88", 4 | "bytes": "36", 5 | "AverageCycles": "1231.00", 6 | "MinCycles": "943", 7 | "MaxCycles": "1519" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_mult89.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "mult89", 4 | "bytes": "175", 5 | "AverageCycles": "492.95", 6 | "MinCycles": "426", 7 | "MaxCycles": "557" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult1.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult1", 4 | "bytes": "33", 5 | "AverageCycles": "649.00", 6 | "MinCycles": "19", 7 | "MaxCycles": "803" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult10.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult10", 4 | "bytes": "50", 5 | "AverageCycles": "909.00", 6 | "MinCycles": "57", 7 | "MaxCycles": "1215" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult11.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult11", 4 | "bytes": "547", 5 | "AverageCycles": "43.00", 6 | "MinCycles": "40", 7 | "MaxCycles": "46" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult12.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult12", 4 | "bytes": "27", 5 | "AverageCycles": "181.04", 6 | "MinCycles": "42", 7 | "MaxCycles": "239" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult13.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult13", 4 | "bytes": "179", 5 | "AverageCycles": "202.01", 6 | "MinCycles": "20", 7 | "MaxCycles": "261" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult14.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult14", 4 | "bytes": "43", 5 | "AverageCycles": "575.00", 6 | "MinCycles": "431", 7 | "MaxCycles": "719" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult15.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult15", 4 | "bytes": "47", 5 | "AverageCycles": "390.00", 6 | "MinCycles": "306", 7 | "MaxCycles": "474" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult16.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult16", 4 | "bytes": "33", 5 | "AverageCycles": "223.69", 6 | "MinCycles": "43", 7 | "MaxCycles": "795" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult17.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult17", 4 | "bytes": "34", 5 | "AverageCycles": "267.00", 6 | "MinCycles": "175", 7 | "MaxCycles": "359" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult2.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult2", 4 | "bytes": "16", 5 | "AverageCycles": "145.00", 6 | "MinCycles": "129", 7 | "MaxCycles": "161" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult25.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult25", 4 | "bytes": "16", 5 | "AverageCycles": "60.00", 6 | "MinCycles": "54", 7 | "MaxCycles": "66" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult26.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult26", 4 | "bytes": "16", 5 | "AverageCycles": "145.00", 6 | "MinCycles": "129", 7 | "MaxCycles": "161" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult27.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult27", 4 | "bytes": "22", 5 | "AverageCycles": "444.00", 6 | "MinCycles": "412", 7 | "MaxCycles": "476" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult28.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult28", 4 | "bytes": "24", 5 | "AverageCycles": "897.00", 6 | "MinCycles": "849", 7 | "MaxCycles": "945" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult29.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult29", 4 | "bytes": "34", 5 | "AverageCycles": "267.00", 6 | "MinCycles": "175", 7 | "MaxCycles": "359" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult3.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult3", 4 | "bytes": "24", 5 | "AverageCycles": "128.00", 6 | "MinCycles": "120", 7 | "MaxCycles": "136" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult30.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult30", 4 | "bytes": "40", 5 | "AverageCycles": "310.00", 6 | "MinCycles": "218", 7 | "MaxCycles": "402" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult32.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult32", 4 | "bytes": "2144", 5 | "AverageCycles": "138.35", 6 | "MinCycles": "29", 7 | "MaxCycles": "143" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult4.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult4", 4 | "bytes": "70", 5 | "AverageCycles": "686.88", 6 | "MinCycles": "36", 7 | "MaxCycles": "715" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult5.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult5", 4 | "bytes": "196", 5 | "AverageCycles": "492.96", 6 | "MinCycles": "417", 7 | "MaxCycles": "559" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult6.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult6", 4 | "bytes": "38", 5 | "AverageCycles": "153.46", 6 | "MinCycles": "82", 7 | "MaxCycles": "846" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult8.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult8", 4 | "bytes": "1075", 5 | "AverageCycles": "49.20", 6 | "MinCycles": "14", 7 | "MaxCycles": "50" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_smult1.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "smult1", 4 | "bytes": "2095", 5 | "AverageCycles": "62.99", 6 | "MinCycles": "56", 7 | "MaxCycles": "70" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_smult10.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "smult10", 4 | "bytes": "2082", 5 | "AverageCycles": "53.99", 6 | "MinCycles": "52", 7 | "MaxCycles": "56" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_smult11.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "smult11", 4 | "bytes": "2338", 5 | "AverageCycles": "51.99", 6 | "MinCycles": "50", 7 | "MaxCycles": "54" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_smult2.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "smult2", 4 | "bytes": "49", 5 | "AverageCycles": "329.67", 6 | "MinCycles": "14", 7 | "MaxCycles": "373" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_smult3.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "smult3", 4 | "bytes": "2253", 5 | "AverageCycles": "277.57", 6 | "MinCycles": "250", 7 | "MaxCycles": "311" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_smult4.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "smult4", 4 | "bytes": "67", 5 | "AverageCycles": "242.52", 6 | "MinCycles": "212", 7 | "MaxCycles": "265" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_smult5.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "smult5", 4 | "bytes": "35", 5 | "AverageCycles": "180.50", 6 | "MinCycles": "160", 7 | "MaxCycles": "201" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_smult6.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "smult6", 4 | "bytes": "39", 5 | "AverageCycles": "158.00", 6 | "MinCycles": "138", 7 | "MaxCycles": "178" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_smult7.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "smult7", 4 | "bytes": "1400", 5 | "AverageCycles": "88.50", 6 | "MinCycles": "42", 7 | "MaxCycles": "101" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_smult8.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "smult8", 4 | "bytes": "1068", 5 | "AverageCycles": "62.99", 6 | "MinCycles": "56", 7 | "MaxCycles": "70" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_smult9.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "smult9", 4 | "bytes": "81", 5 | "AverageCycles": "570.00", 6 | "MinCycles": "399", 7 | "MaxCycles": "741" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult18.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult18", 4 | "bytes": "76", 5 | "AverageCycles": "2036.00", 6 | "MinCycles": "1468", 7 | "MaxCycles": "2604" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult19.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult19", 4 | "bytes": "48", 5 | "AverageCycles": "2169.00", 6 | "MinCycles": "1861", 7 | "MaxCycles": "2477" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult20.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult20", 4 | "bytes": "66", 5 | "AverageCycles": "2741.00", 6 | "MinCycles": "2299", 7 | "MaxCycles": "3251" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult21.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult21", 4 | "bytes": "49", 5 | "AverageCycles": "1014.00", 6 | "MinCycles": "706", 7 | "MaxCycles": "1322" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult22.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult22", 4 | "bytes": "59", 5 | "AverageCycles": "1653.00", 6 | "MinCycles": "1172", 7 | "MaxCycles": "2171" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult23.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult23", 4 | "bytes": "76", 5 | "AverageCycles": "4405.00", 6 | "MinCycles": "2962", 7 | "MaxCycles": "6070" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult24.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult24", 4 | "bytes": "61", 5 | "AverageCycles": "1356.94", 6 | "MinCycles": "102", 7 | "MaxCycles": "1707" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_omult31.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "omult31", 4 | "bytes": "2162", 5 | "AverageCycles": "168.90", 6 | "MinCycles": "161", 7 | "MaxCycles": "181" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /results/results_smult12.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": { 3 | "title": "smult12", 4 | "bytes": "2210", 5 | "AverageCycles": "234.57", 6 | "MinCycles": "207", 7 | "MaxCycles": "268" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/mult11.a: -------------------------------------------------------------------------------- 1 | ; mult11.a 2 | ; from codebase64 by Graham: https://www.codebase64.org/doku.php?id=base:short_8bit_multiplication_16bit_product 3 | ; 4 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 5 | ; Average cycles: 162 6 | ; 17 bytes 7 | 8 | 9 | FAC1 = $02 10 | FAC2 = $03 11 | 12 | * = $0200 13 | 14 | ; Multiply FAC1 * FAC2 15 | ; 16 | ; On Exit: 17 | ; A (high byte) 18 | ; FAC1 (low byte) 19 | mult 20 | lda #0 21 | ldx #8 22 | clc 23 | m0 24 | bcc m1 25 | clc 26 | adc FAC2 27 | m1 28 | ror 29 | ror FAC1 30 | dex 31 | bpl m0 32 | rts 33 | -------------------------------------------------------------------------------- /tests/mult9.a: -------------------------------------------------------------------------------- 1 | ; mult9 2 | ; from The Fridge: http://www.ffd2.com/fridge/math/mult-div8.s 3 | ; 4 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 5 | ; Average cycles: 162 6 | ; 17 bytes 7 | 8 | 9 | aux = $02 10 | acc = $03 11 | ; ext = $04 12 | 13 | * = $0200 14 | 15 | ; Multiply acc * aux 16 | ; 17 | ; On Exit: 18 | ; acc (low byte) 19 | ; A (high byte) 20 | mult 21 | lda #0 22 | ldy #9 ; loop counter 23 | clc 24 | - 25 | ror 26 | ror acc 27 | bcc + 28 | clc ; decrement aux above to remove CLC 29 | adc aux 30 | + 31 | dey 32 | bne - 33 | ; sta ext 34 | rts 35 | -------------------------------------------------------------------------------- /tests/omult3.a: -------------------------------------------------------------------------------- 1 | ; omult3.a 2 | ; from the original cassette and disc versions of Elite, https://www.bbcelite.com/cassette/main/subroutine/fmltu.html 3 | ; 4 | ; 8 bit x 8 bit unsigned multiply, 8 bit partial result (high byte) 5 | ; Average cycles: 128.00 6 | ; 24 bytes 7 | 8 | 9 | P = $02 10 | Q = $03 11 | 12 | * = $0200 13 | 14 | ; multiply A * Q 15 | ; On Exit: 16 | ; A (high byte) 17 | FMLTU 18 | eor #%11111111 19 | sec 20 | ror 21 | sta P 22 | lda #0 23 | MUL3 24 | bcs MU7 25 | adc Q 26 | ror 27 | lsr P 28 | bne MUL3 29 | rts 30 | 31 | MU7 32 | lsr 33 | lsr P 34 | bne MUL3 35 | rts 36 | -------------------------------------------------------------------------------- /tests/mult70.a: -------------------------------------------------------------------------------- 1 | ; mult70.a 2 | ; from https://archive.org/details/Compute_s_Machine_Language_Routines_for_the_Commodore_64_and_128/page/357/mode/2up 3 | ; 4 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 5 | ; Average cycles: 1987.11 6 | ; 31 bytes 7 | 8 | b1 = $02 9 | b2 = $03 10 | total = $04 ; 2 bytes 11 | 12 | * = $0200 13 | 14 | mulad1 15 | lda #0 16 | sta total 17 | sta total+1 18 | 19 | ldx b1 20 | beq mulend 21 | clc 22 | lda b2 23 | beq mulend 24 | mullop 25 | dex 26 | beq mulstr 27 | clc 28 | adc b2 29 | bcc mullop 30 | 31 | inc total+1 32 | jmp mullop 33 | 34 | mulstr 35 | sta total 36 | mulend 37 | rts 38 | -------------------------------------------------------------------------------- /tests/mult43.a: -------------------------------------------------------------------------------- 1 | ; mult43.a 2 | ; from https://archive.org/details/6502-assembly-language-programming/page/n251/mode/2up 3 | ; from the book "6502 assembly language programming" by Lance A. Leventhal 4 | ; 5 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 6 | ; Average cycles: 208.9 7 | ; 26 bytes 8 | 9 | 10 | factorA = $02 11 | factorB = $03 12 | prod_low = $04 13 | prod_high = $05 14 | 15 | * = $0200 16 | 17 | mult 18 | lda #0 19 | sta prod_high 20 | ldx #8 21 | shift 22 | asl 23 | rol prod_high 24 | asl factorB 25 | bcc chcnt 26 | clc 27 | adc factorA 28 | bcc chcnt 29 | inc prod_high 30 | chcnt 31 | dex 32 | bne shift 33 | sta prod_low 34 | rts 35 | -------------------------------------------------------------------------------- /tests/omult12.a: -------------------------------------------------------------------------------- 1 | ; omult12.a 2 | ; from 'Gateway to Apshai' for the Atari 8-bit family, http://bringerp.free.fr/RE/Gta/downloads.php5 3 | ; optimised to remove use of 'result' 4 | ; 5 | ; 8 bit x 8 bit unsigned multiply, 8 bit result (low byte) 6 | ; Average cycles: 181.04 7 | ; 27 bytes 8 | 9 | localA = $02 10 | localX = $03 11 | result = $04 12 | 13 | * = $0200 14 | 15 | mulAbyX 16 | stx localX 17 | cmp localX 18 | bcc + 19 | sta localX 20 | txa 21 | 22 | + 23 | sta localA 24 | lda #0 25 | ; sta result 26 | 27 | - 28 | lsr localA 29 | php 30 | bcc + 31 | ; lda result 32 | clc 33 | adc localX 34 | ; sta result 35 | 36 | + 37 | asl localX 38 | plp 39 | bne - 40 | ; lda result 41 | rts 42 | -------------------------------------------------------------------------------- /tests/omult1.a: -------------------------------------------------------------------------------- 1 | ; omult1.a 2 | ; from Programming the 65816 by David Eyes (1986), https://archive.org/details/0893037893ProgrammingThe65816/page/n295/mode/2up?q=multiply 3 | ; 4 | ; Only returns the lower 16 bits of the result. 5 | ; 6 | ; 16 bit x 16 bit unsigned multiply, lower 16 bit result 7 | ; Average cycles: 649.00 8 | ; 33 bytes 9 | 10 | 11 | mcand1 = $02 12 | mcand2 = $04 13 | 14 | * = $0200 15 | 16 | mult 17 | ldx #0 18 | ldy #0 19 | mult1 20 | lda mcand1 21 | ora mcand1+1 22 | beq done 23 | lsr mcand1+1 24 | ror mcand1 25 | bcc mult2 26 | clc 27 | tya 28 | adc mcand2 29 | tay 30 | txa 31 | adc mcand2+1 32 | tax 33 | mult2 34 | asl mcand2 35 | rol mcand2+1 36 | jmp mult1 37 | done 38 | rts 39 | -------------------------------------------------------------------------------- /tests/mult75.a: -------------------------------------------------------------------------------- 1 | ; mult75.a 2 | ; from 'Practical Microcomputer Programming' by Walter J Weller (1980) 3 | ; bugs fixed 4 | ; 5 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 6 | ; Average cycles: 205.90 7 | ; 24 bytes 8 | 9 | 10 | * = $0200 11 | 12 | mplr = $02 13 | mcnd = $03 14 | hiprod = $04 15 | 16 | ; On Entry: 17 | ; mplr: multiplier 18 | ; mcnd: multiplicand 19 | ; On Exit: 20 | ; (A, hiprod): product 21 | mpy 22 | lda #0 ; BUGFIX: added 23 | sta hiprod ; BUGFIX: added 24 | ldy #8 25 | mpy1 26 | asl 27 | rol hiprod 28 | asl mplr 29 | bcc mpy2 30 | clc ; BUGFIX: added 31 | adc mcnd 32 | bcc mpy2 33 | inc hiprod 34 | mpy2 35 | dey 36 | bne mpy1 37 | ; sta loprod 38 | rts 39 | -------------------------------------------------------------------------------- /tests/mult68.a: -------------------------------------------------------------------------------- 1 | ; mult68.a 2 | ; from Programming The 6502 by Rodnay Zaks (1983) p84 https://archive.org/details/Programming_the_6502_OCR/page/n89/mode/2up 3 | ; 4 | ; 8 bit x 8bit unsigned multiply, 16 bit result 5 | ; Average cycles: 188.00 6 | ; 20 bytes 7 | 8 | c = $02 ; multiplier 9 | d = $03 ; multiplicand 10 | b = $04 ; temp 11 | 12 | * = $0200 13 | 14 | ; 8 bit x 8bit unsigned multiply, 16 bit result 15 | ; 16 | ; On Entry: 17 | ; c: multiplier 18 | ; d: multiplicand 19 | ; On Exit: 20 | ; (b, A): product 21 | mult 22 | lda #0 23 | sta b 24 | ldx #8 25 | loop 26 | lsr c 27 | bcc noadd 28 | clc 29 | adc d 30 | noadd 31 | ror ; not lsr, as seen in some editions 32 | ror b 33 | dex 34 | bne loop 35 | rts 36 | -------------------------------------------------------------------------------- /tests/omult25.a: -------------------------------------------------------------------------------- 1 | ; omult25.a 2 | ; from Starship Command at $1e69: http://www.level7.org.uk/miscellany/starship-command-disassembly.txt 3 | ; 4 | ; 3 bit x 8 bit unsigned multiply, 8 bit result (high bits) 5 | ; Average cycles: 60.00 6 | ; 16 bytes 7 | 8 | sine = $02 ; multiplicand (3 bits) 9 | radius = $03 ; multiplier (8 bits) 10 | 11 | * = $0200 12 | 13 | ; 3 bit x 8 bit unsigned multiply, 8 bit result 14 | ; 15 | ; On Entry: 16 | ; sine: 3 bit multiplicand 17 | ; radius: 8 bit multiplier 18 | ; On Exit: 19 | ; A: product 20 | mult 21 | ldx #3 ; 3-bit multiplication of sine by radius 22 | lda #0 23 | loop_over_bits_of_sine 24 | lsr sine 25 | bcc sine_bit_unset 26 | clc 27 | adc radius 28 | sine_bit_unset 29 | ror 30 | dex 31 | bne loop_over_bits_of_sine 32 | rts 33 | -------------------------------------------------------------------------------- /tests/mult78.a: -------------------------------------------------------------------------------- 1 | ; mult78.a 2 | ; from 'Commodore 128 assembly language programming' by Mark Andrews (1986) https://archive.org/details/Commodore_128_Assembly_Language_Programming/page/n165/mode/2up 3 | ; I swapped names of prodh and prodl to avoid confusion 4 | ; 5 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 6 | ; Average cycles: 188.00 7 | ; 20 bytes 8 | 9 | mpr = $02 10 | mpd = $03 11 | prodl = $04 12 | 13 | * = $0200 14 | 15 | ; 8 bit unsigned multiply, 16 bit result 16 | ; 17 | ; On Entry: 18 | ; mpr: multiplier 19 | ; mpd: multiplicand 20 | ; On Exit: 21 | ; (A, prodl): product 22 | mult 23 | lda #0 24 | sta prodl 25 | ldx #8 26 | loop 27 | lsr mpr 28 | bcc noadd 29 | clc 30 | adc mpd 31 | noadd 32 | ror 33 | ror prodl 34 | dex 35 | bne loop 36 | ; sta prodh 37 | rts 38 | -------------------------------------------------------------------------------- /tests/mult71.a: -------------------------------------------------------------------------------- 1 | ; mult71.a 2 | ; from https://archive.org/details/Compute_s_Machine_Language_Routines_for_the_Commodore_64_and_128/page/359/mode/2up 3 | ; 4 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 5 | ; Average cycles: 1572.91 6 | ; 41 bytes 7 | 8 | b1 = $02 ; must be adjacent to each other 9 | b2 = $03 ; must be adjacent to each other 10 | total = $04 ; 2 bytes 11 | 12 | * = $0200 13 | 14 | mulad2 15 | lda #0 16 | sta total 17 | sta total+1 18 | 19 | tay 20 | ldx b2 21 | beq mulend 22 | cpx b1 23 | bcc goahead 24 | ldx b1 25 | beq mulend 26 | ldy #1 27 | 28 | goahead 29 | lda b1,y 30 | loop 31 | dex 32 | beq mulstr 33 | clc 34 | adc b1,y 35 | bcc loop 36 | inc total+1 37 | jmp loop 38 | mulstr 39 | sta total 40 | mulend 41 | rts 42 | -------------------------------------------------------------------------------- /tests/mult47.a: -------------------------------------------------------------------------------- 1 | ; mult47.a 2 | ; from Neil Parker: https://llx.com/Neil/a2/mult.html 3 | ; 4 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 5 | ; Average cycles: 175.00 6 | ; 20 bytes 7 | 8 | 9 | num1 = $02 ; 1 byte 10 | num2 = $03 ; 1 byte 11 | result = $04 ; 2 bytes 12 | 13 | * = $0200 14 | 15 | ; result = num1 * num2 16 | mult 17 | lda #$80 ; Preload sentinel bit into RESULT 18 | sta result 19 | asl ; Initialize RESULT hi byte to 0 20 | l1 21 | lsr num2 ; Get low bit of NUM2 22 | bcc l2 ; 0 or 1? 23 | clc ; If 1, add NUM1 24 | adc num1 25 | l2 26 | ror ; "Stairstep" shift (catching carry from add) 27 | ror result 28 | bcc l1 ; When sentinel falls off into carry, we're done 29 | sta result+1 30 | rts 31 | -------------------------------------------------------------------------------- /tests/mult19.a: -------------------------------------------------------------------------------- 1 | ; mult19.a 2 | ; from Australian Personal Computer, Aug 1984: https://archive.org/details/apc_1984_08/page/115/mode/2up?q=6502+multiplication 3 | ; also from Neil Parker: https://www.llx.com/Neil/a2/mult.html 4 | ; 5 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 6 | ; Average cycles: 185 7 | ; 18 bytes 8 | 9 | 10 | NUM1 = $02 11 | NUM2 = $03 12 | RESULT = $04 13 | 14 | * = $0200 15 | 16 | ; calculate NUM1 * NUM2 17 | ; Result in A (high byte) and RESULT (low byte) 18 | mult 19 | lda #0 ; Initialize RESULT to 0 20 | ldx #8 ; There are 8 bits in NUM2 21 | L1 22 | lsr NUM2 ; Get low bit of NUM2 23 | bcc L2 ; 0 or 1? 24 | clc ; If 1, add NUM1 25 | adc NUM1 26 | L2 27 | ror ; "Stairstep" shift (catching carry from add) 28 | ror RESULT 29 | dex 30 | bne L1 31 | rts 32 | -------------------------------------------------------------------------------- /tests/omult26.a: -------------------------------------------------------------------------------- 1 | ; omult26.a 2 | ; from Starship Command at 0x0fc3: http://www.level7.org.uk/miscellany/starship-command-disassembly.txt 3 | ; 4 | ; 8 bit x 8 bit unsigned multiply, 8 bit result (high byte) 5 | ; Average cycles: 145.00 6 | ; 16 bytes 7 | 8 | multiplicand = $02 ; 9 | multiplier = $03 ; 10 | 11 | * = $0200 12 | 13 | ; 8 bit x 8 bit unsigned multiply, 8 bit result (high byte) 14 | ; 15 | ; On Entry: 16 | ; multiplicand: 8 bit 17 | ; multiplier: 8 bit multiplier 18 | ; On Exit: 19 | ; A: product 20 | mult 21 | lda #0 22 | ldx #8 ; 8-bit multiplication of input by multiplier 23 | loop_over_bits_of_multiplier 24 | lsr multiplier 25 | bcc multiplier_bit_unset 26 | clc 27 | adc multiplicand 28 | multiplier_bit_unset 29 | ror 30 | dex 31 | bne loop_over_bits_of_multiplier 32 | rts 33 | -------------------------------------------------------------------------------- /tests/mult46.a: -------------------------------------------------------------------------------- 1 | ; mult46.a 2 | ; from 'Apple Programmers Handbook', by Paul Irwin (1984) https://archive.org/details/sams-apple-programmers-handbook/page/220/mode/2up?q=multiply 3 | ; 4 | ; 16 bit x 16 bit unsigned multiply, 32 bit result 5 | ; Average cycles: 655.00 6 | ; 40 bytes 7 | 8 | 9 | result = $02 ; 4 bytes 10 | xvalue = $02 ; 2 bytes 11 | bconst = $04 ; 2 bytes 12 | mmod = $06 ; 2 bytes 13 | 14 | * = $0200 15 | 16 | mult 17 | lda #0 18 | sta bconst 19 | sta bconst+1 20 | ldx #16 21 | clc 22 | rol bconst 23 | rol bconst+1 24 | mult1 25 | ror bconst+1 26 | ror bconst 27 | ror xvalue+1 28 | ror xvalue 29 | bcc mult2 30 | clc 31 | lda bconst 32 | adc mmod 33 | sta bconst 34 | lda bconst+1 35 | adc mmod+1 36 | sta bconst+1 37 | mult2 38 | dex 39 | bpl mult1 40 | rts 41 | -------------------------------------------------------------------------------- /tests/mult72.a: -------------------------------------------------------------------------------- 1 | ; mult72.a 2 | ; from TobyLobster 3 | ; 4 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 5 | ; Average cycles: 1544.56 6 | ; 16 bytes 7 | 8 | * = $0200 9 | 10 | ; Small, slow 8 bit multiply, 16 bit result, using repeated addition! 11 | ; On Entry: 12 | ; multiplier: (1 byte) 13 | ; X: multiplicand 14 | ; On Exit: 15 | ; (A, Y): product 16 | mult 17 | lda #0 ; product low 18 | tay ; product high 19 | inx ; increment multiplicand 20 | -- 21 | clc 22 | - 23 | dex ; decrement 24 | beq + ; branch if we are done 25 | multiplier = *+1 26 | adc #0 ; add multiplier (self modifying code) 27 | bcc - ; loop back if no carry 28 | iny ; increment high byte of product 29 | bcs -- ; always loop back 30 | + 31 | rts ; 32 | -------------------------------------------------------------------------------- /tests/mult17.a: -------------------------------------------------------------------------------- 1 | ; mult17.a 2 | ; from Elite: https://www.bbcelite.com/cassette/main/subroutine/mu11.html 3 | ; tweaked to handle X=0 on input 4 | ; 5 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 6 | ; Average cycles: 150.47 7 | ; 28 bytes 8 | 9 | 10 | T = $02 11 | P = $03 12 | 13 | * = $0200 14 | 15 | ; *************************************************************************************** 16 | ; 8 bit multiply 17 | ; 18 | ; On Entry: 19 | ; A: multiplier 20 | ; P: multiplicand 21 | ; On Exit: 22 | ; A: high byte of product 23 | ; P: low byte of product 24 | mult 25 | cpx #0 26 | beq zero ; Special case: handle X=0 separately 27 | 28 | dex 29 | stx T 30 | lda #0 31 | ldx #8 32 | lsr P 33 | loop 34 | bcc + 35 | adc T 36 | + 37 | ror 38 | ror P 39 | dex 40 | bne loop 41 | rts 42 | 43 | zero 44 | txa 45 | sta P 46 | rts 47 | -------------------------------------------------------------------------------- /tests/smult6.a: -------------------------------------------------------------------------------- 1 | ; smult6.a 2 | ; from EDN magazine (5th Sept 1979), article by Arch D Robison https://archive.org/details/edn-1979_09_05/page/118/mode/2up 3 | ; 4 | ; 8 bit x 8 bit signed multiply, 16 bit result 5 | ; Average cycles: 158.00 6 | ; 39 bytes 7 | 8 | plier = $02 9 | cand = $03 10 | prol = $04 11 | 12 | * = $0200 13 | 14 | ; On Entry: 15 | ; A: multiplier 16 | ; cand: multiplicand 17 | ; On Exit: 18 | ; A: high byte of product 19 | ; Y: low byte 20 | mpy 21 | sta plier 22 | lsr 23 | sta prol 24 | lda #0 25 | ldy #7 26 | test 27 | bcc shift 28 | clc 29 | adc cand 30 | shift 31 | ror 32 | ror prol 33 | dey 34 | bne test 35 | bcc adjust 36 | sbc cand 37 | ror 38 | eor #$80 39 | rol 40 | adjust 41 | ror 42 | ror prol 43 | ldy cand 44 | bpl exit 45 | sec 46 | sbc plier 47 | exit 48 | rts 49 | -------------------------------------------------------------------------------- /tests/mult35.a: -------------------------------------------------------------------------------- 1 | ; mult35.a 2 | ; from 'Atari Roots' by Mark Andrews (1984) p173: https://archive.org/details/ataribooks-atari-roots/page/n173/mode/2up 3 | ; also available at https://www.atariarchives.org/roots/chapter_10.php 4 | ; 5 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 6 | ; Average cycles: 188.00 7 | ; 20 bytes 8 | 9 | 10 | mpr = $02 11 | mpd = $03 12 | prodl = $04 13 | ; prodh = $05 14 | 15 | *=$0200 16 | 17 | ; *************************************************************************************** 18 | ; On Entry: 19 | ; mpr: multiplier 20 | ; mpd: multiplicand 21 | ; On Exit: 22 | ; prodl: low byte of product 23 | ; A: high byte of product 24 | values 25 | lda #0 26 | sta prodl 27 | ldx #8 28 | loop 29 | lsr mpr 30 | bcc noadd 31 | clc 32 | adc mpd 33 | noadd 34 | ror 35 | ror prodl 36 | dex 37 | bne loop 38 | ; sta prodh 39 | rts 40 | -------------------------------------------------------------------------------- /tests/mult77.a: -------------------------------------------------------------------------------- 1 | ; mult77.a 2 | ; from 'Instrumentation of a Savonius wind turbine' by Samuel Martin Babb (1979) https://archive.org/details/instrumentationo00babb/page/108/mode/2up 3 | ; 4 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 5 | ; Average cycles: 288.00 6 | ; 43 bytes 7 | 8 | mul1 = $02 ; multiplier 9 | mul1h = $03 ; temp 10 | mul2 = $04 ; multiplicand 11 | lowmp = $05 ; product (low) 12 | highmp = $06 ; product (high) 13 | 14 | * = $0200 15 | 16 | mult 17 | lda #0 18 | sta highmp 19 | sta lowmp 20 | sta mul1h 21 | tax 22 | lsr mul2 23 | bcs run 24 | itiso 25 | cpx #7 26 | beq don 27 | inx 28 | asl mul1 29 | rol mul1h 30 | lsr mul2 31 | bcc itiso 32 | run 33 | lda mul1 34 | clc 35 | adc lowmp 36 | sta lowmp 37 | lda mul1h 38 | adc highmp 39 | sta highmp 40 | jmp itiso 41 | don 42 | rts 43 | -------------------------------------------------------------------------------- /tests/omult2.a: -------------------------------------------------------------------------------- 1 | ; omult2.a 2 | ; from The BBC Micro Compendium by Jeremy Ruston: https://archive.org/details/BBCMicroCompendium/page/38/mode/2up 3 | ; also found in 'Nightshade' for the BBC Micro, http://level7.org.uk/miscellany/nightshade-disassembly.txt (see multiply_A_and_X) 4 | ; 5 | ; 8 bit x 8 bit unsigned multiply, low 8 bit result 6 | ; Average cycles: 145 7 | ; 16 bytes 8 | 9 | * = $0200 10 | 11 | n1 = $02 12 | n2 = $03 13 | 14 | ; A = n1 * n2 15 | multiply 16 | ldx #8 ; Set up loop 17 | lda #0 ; Zero answer 18 | start 19 | asl ; Multiply answer 20 | asl n1 ; Copy bit 7 to carry 21 | bcc no_add ; If the bit was zero, skip addition 22 | clc ; Clear carry for addition 23 | adc n2 ; Add into answer 24 | no_add 25 | dex ; Check for end of loop 26 | bne start 27 | ; sta ans ; Store answer 28 | rts 29 | -------------------------------------------------------------------------------- /tests/mult21.a: -------------------------------------------------------------------------------- 1 | ; mult21.a 2 | ; from 'Machine Code for the Atmos and Oric-I', Bruce Smith (1984): https://archive.org/details/shiva-machine-code-for-the-atmos-and-oric-i/page/78/mode/2up 3 | ; also from Niels Möller: https://www.lysator.liu.se/~nisse/misc/6502-mul.html 4 | ; 5 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 6 | ; Average cycles: 150 7 | ; 18 bytes 8 | 9 | 10 | factor1 = $02 11 | factor2 = $03 12 | 13 | * = $0200 14 | 15 | ; *************************************************************************************** 16 | ; On Entry: 17 | ; factor1: multiplier 18 | ; factor2: multiplicand 19 | ; On Exit: 20 | ; factor1: low byte of product 21 | ; A: high byte of product 22 | mult 23 | lda #0 24 | ldx #8 25 | lsr factor1 26 | loop 27 | bcc no_add 28 | clc 29 | adc factor2 30 | no_add 31 | ror 32 | ror factor1 33 | dex 34 | bne loop 35 | ; sta factor2 36 | rts 37 | -------------------------------------------------------------------------------- /tests/mult40.a: -------------------------------------------------------------------------------- 1 | ; mult40.a 2 | ; from https://gitlab.riscosopen.org/RiscOS/Sources/Apps/Diversions/Meteors/-/blob/master/Srce6502/MetSrc 3 | ; from 'Meteors' for the BBC Micro 4 | ; 5 | ; 8 bit x 8bit unsigned multiply, 16 bit result 6 | ; Average cycles: 278 7 | ; 35 bytes 8 | 9 | 10 | _a = $02 ; two bytes 11 | _x = $04 12 | _y = $05 ; two bytes 13 | 14 | * = $0200 15 | 16 | ; *************************************************************************************** 17 | ; On Entry: 18 | ; _x: multiplier 19 | ; _y: multiplicand 20 | ; On Exit: 21 | ; _a: low byte of product 22 | ; _a+1: high byte of product 23 | mult 24 | lda #0 25 | sta _y+1 26 | sta _a 27 | sta _a+1 28 | ldy #8 29 | mloop 30 | lsr _x 31 | bcc noadd 32 | clc 33 | lda _a 34 | adc _y 35 | sta _a 36 | lda _a+1 37 | adc _y+1 38 | sta _a+1 39 | noadd 40 | asl _y 41 | rol _y+1 42 | dey 43 | bne mloop 44 | rts 45 | -------------------------------------------------------------------------------- /tests/omult17.a: -------------------------------------------------------------------------------- 1 | ; omult17.a 2 | ; from 'How to program microcomputers' by William T Barden (1977): https://archive.org/details/howtoprogrammicr00bard/page/192/mode/2up 3 | ; 4 | ; 16 bit x 8 bit unsigned multiply, 16 bit result (2 low bytes) (NOTE: MSB order!) 5 | ; Average cycles: 267.00 6 | ; 34 bytes 7 | 8 | 9 | mcand = $02 ; 2 bytes (high byte is first) 10 | res = $04 ; 2 bytes (high byte is first) 11 | 12 | * = $0200 13 | 14 | ; On Entry: 15 | ; A: multiplier 16 | ; mcand: multiplicand (2 bytes, high byte first) 17 | ; On Exit: 18 | ; (res+1, res): product (high byte first) 19 | unspm 20 | ;pha 21 | ldx #0 22 | stx res 23 | stx res+1 24 | ;pla 25 | ldx #8 26 | loop 27 | ;clc 28 | asl res+1 29 | rol res 30 | asl 31 | bcc noc1 32 | tay 33 | lda res+1 34 | clc 35 | adc mcand+1 36 | sta res+1 37 | lda res 38 | adc mcand 39 | sta res 40 | tya 41 | noc1 42 | dex 43 | bne loop 44 | rts 45 | -------------------------------------------------------------------------------- /tests/mult73.a: -------------------------------------------------------------------------------- 1 | ; mult73.a 2 | ; from TobyLobster 3 | ; 4 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 5 | ; Average cycles: 1174.08 6 | ; 28 bytes 7 | 8 | * = $0200 9 | 10 | ; Slow(!) small multiply, using repeated addition! 11 | ; On Entry: 12 | ; A: multiplier 13 | ; X: multiplicand 14 | ; On Exit: 15 | ; (A, Y): product 16 | mult 17 | sta multiplier 18 | ; if X>=multiplier then swap X and multiplier 19 | cpx multiplier 20 | bcc + 21 | stx multiplier 22 | tax 23 | + 24 | 25 | lda #0 ; product low 26 | tay ; product high 27 | inx ; increment multiplicand 28 | -- 29 | clc 30 | - 31 | dex ; decrement 32 | beq + ; branch if we are done 33 | multiplier = *+1 34 | adc #0 ; add multiplier (self modifying code) 35 | bcc - ; loop back if no carry 36 | iny ; increment high byte of product 37 | bcs -- ; always loop back 38 | + 39 | rts ; 40 | -------------------------------------------------------------------------------- /tests/mult76.a: -------------------------------------------------------------------------------- 1 | ; mult76.a 2 | ; from 'Microcomputing' Magazine (June 1981) article by Leo Scanlon https://archive.org/details/kilobaudmagazine-1981-06/page/n109/mode/2up 3 | ; see also 'Beyond Basic' by Richard Freeman (1983) https://archive.org/details/bbcbb/page/120/mode/2up 4 | ; see also 'Microprocessors : essentials, components and systems' by R Meadows (1983) https://archive.org/details/microprocessorse0000mead/page/240/mode/2up 5 | ; 6 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 7 | ; Average cycles: 185.00 8 | ; 18 bytes 9 | 10 | 11 | multiplicand = $02 12 | multiplier = $03 13 | resultlow = $04 14 | ; resulthigh = $05 15 | 16 | * = $0200 17 | 18 | ; Multiply multiplier * multiplicand 19 | ; 20 | ; On Exit: 21 | ; (resultlow, resulthigh): product 22 | mult 23 | lda #0 24 | ldx #8 25 | next 26 | lsr multiplier 27 | bcc rot 28 | clc 29 | adc multiplicand 30 | rot 31 | ror 32 | ror resultlow 33 | dex 34 | bne next 35 | ; sta resulthigh 36 | rts 37 | -------------------------------------------------------------------------------- /tests/mult23.a: -------------------------------------------------------------------------------- 1 | ; mult23.a 2 | ; 'tepples' from https://www.nesdev.org/wiki/8-bit_Multiply 3 | ; 4 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 5 | ; Average cycles: 153 6 | ; 21 bytes 7 | 8 | 9 | prodlo = $02 10 | factor2 = $03 11 | 12 | * = $0200 13 | 14 | ; On Entry: 15 | ; A: multiplier 16 | ; Y: multiplicand 17 | ; On Exit: 18 | ; A: high byte of product 19 | ; prodlo: low byte of product 20 | ; X: preserved 21 | mult 22 | ; Factor 1 is stored in the lower bits of prodlo; the low byte of 23 | ; the product is stored in the upper bits. 24 | lsr ; prime the carry bit for the loop 25 | sta prodlo 26 | sty factor2 27 | lda #0 28 | ldy #8 29 | loop 30 | ; At the start of the loop, one bit of prodlo has already been 31 | ; shifted out into the carry. 32 | bcc noadd 33 | clc 34 | adc factor2 35 | noadd 36 | ror 37 | ror prodlo ; pull another bit out for the next iteration 38 | dey ; inc/dec don't modify carry; only shifts and adds do 39 | bne loop 40 | rts 41 | -------------------------------------------------------------------------------- /tests/mult79.a: -------------------------------------------------------------------------------- 1 | ; mult79.a 2 | ; from a NASA Report (1981) https://archive.org/details/NASA_NTRS_Archive_19820015020/page/n65/mode/2up 3 | ; 4 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 5 | ; Average cycles: 399.00 6 | ; 39 bytes 7 | 8 | 9 | mplr = $02 10 | mpcnd = $03 11 | prodl = $04 12 | prodh = $05 13 | temp = $06 14 | 15 | * = $0200 16 | 17 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 18 | ; 19 | ; No branches based on data are allowed in this routine, I think so it can be run 20 | ; simultaneously across multiple processors and they all finish at exactly the same time. 21 | ; 22 | ; On Entry: 23 | ; mplr: multiplier 24 | ; mpcnd: multiplicand 25 | ; On Exit: 26 | ; (prodl, prodh): 16 bit product 27 | mult 28 | lda #0 29 | sta prodl 30 | sta prodh 31 | ldx #8 32 | loop 33 | asl prodl 34 | rol prodh 35 | asl mplr 36 | lda #0 37 | sbc #0 38 | eor #$ff 39 | and mpcnd 40 | sta temp 41 | clc 42 | adc prodl 43 | sta prodl 44 | lda prodh 45 | adc #0 46 | sta prodh 47 | dex 48 | bne loop 49 | end 50 | rts 51 | -------------------------------------------------------------------------------- /tests/omult27.a: -------------------------------------------------------------------------------- 1 | ; omult27.a 2 | ; from Starship Command at 0x0fa8 (and $10be): http://www.level7.org.uk/miscellany/starship-command-disassembly.txt 3 | ; 4 | ; 16 bit x 8 bit unsigned multiply, 16 bit result (high bytes) 5 | ; Average cycles: 444.00 6 | ; 22 bytes 7 | 8 | input_fraction = $02 ; 9 | input_pixels = $03 ; 10 | multiplier = $04 ; 11 | output_low = $05 ; 12 | output_high = $06 ; 13 | 14 | * = $0200 15 | 16 | ; 16 bit x 8 bit unsigned multiply, 16 bit result (high bytes) 17 | ; 18 | ; On Entry: 19 | ; (input_fraction, input_pixels): 16 bit multiplicand 20 | ; multiplier: 8 bits 21 | ; On Exit: 22 | ; (output_fraction, output_pixels): 16 bit product 23 | mult 24 | lda #0 25 | ldx #16 ; 16-bit multiplication of input by multiplier 26 | loop_over_bits_of_input 27 | lsr input_pixels 28 | ror input_fraction 29 | bcc input_bit_unset 30 | clc 31 | adc multiplier 32 | input_bit_unset 33 | ror 34 | ror output_low 35 | dex 36 | bne loop_over_bits_of_input 37 | sta output_high 38 | rts 39 | -------------------------------------------------------------------------------- /tests/mult57.a: -------------------------------------------------------------------------------- 1 | ; mult57.a 2 | ; from https://sites.google.com/site/h2obsession/programming/6502 3 | ; alternative smaller memory version (see mult27.a) 4 | ; 5 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 6 | ; Average cycles: 48.49 7 | ; 1058 bytes 8 | 9 | 10 | * = $0200 11 | 12 | prod_low = $02 13 | 14 | ; Tables must be aligned with page boundary 15 | sqrLow 16 | !for i, 0, 511 { 17 | !byte <((i*i)/4) 18 | } 19 | 20 | sqrHigh 21 | !for i, 0, 511 { 22 | !byte >((i*i)/4) 23 | } 24 | 25 | ; *************************************************************************************** 26 | ; On Entry: 27 | ; A = multiplicand 28 | ; X = multiplier 29 | ; On Exit: 30 | ; prod_low: low byte of product 31 | ; A: high byte of product 32 | mult 33 | sta getLow+1 34 | sta getHigh+1 35 | 36 | stx temp1 37 | sec 38 | temp1 = *+1 39 | sbc #0 40 | bcs doMult 41 | sbc #0 42 | eor #255 43 | doMult 44 | tay 45 | getLow 46 | lda sqrLow,x 47 | sbc sqrLow,y 48 | sta prod_low 49 | getHigh 50 | lda sqrHigh,x 51 | sbc sqrHigh,y 52 | rts 53 | -------------------------------------------------------------------------------- /tests/mult25.a: -------------------------------------------------------------------------------- 1 | ; mult25.a 2 | ; 'Bregalad' from https://www.nesdev.org/wiki/8-bit_Multiply 3 | ; bug fixed and tweaked input and output parameter passing 4 | ; 5 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 6 | ; Average cycles: 243 7 | ; 28 bytes 8 | 9 | 10 | Factor = $02 11 | Res = $03 12 | Res2 = $04 13 | 14 | * = $0200 15 | 16 | ; *************************************************************************************** 17 | ; On Entry: 18 | ; A: multiplier 19 | ; Factor: multiplicand 20 | ; On Exit: 21 | ; Res: low byte of product 22 | ; Res2: high byte of product 23 | ; X: preserved 24 | mult 25 | ; sty Factor ; Store input factor 26 | ldy #0 27 | sty Res 28 | sty Res2 ; Clear result 29 | ldy #8 ; Number of shifts needed 30 | - 31 | lsr ; Shift right input number 32 | bcc + ; Check if bit is set 33 | pha 34 | lda Res2 35 | clc 36 | adc Factor 37 | sta Res2 ; If so add number to result 38 | pla 39 | + 40 | ror Res2 ; Shift result right BUG FIX: ror NOT lsr 41 | ror Res 42 | dey 43 | bne - 44 | ; lda Res 45 | ; ldy Res2 46 | rts 47 | -------------------------------------------------------------------------------- /tests/smult5.a: -------------------------------------------------------------------------------- 1 | ; smult5 2 | ; based on mult9, adjusted by TobyLobster for signed multiply 3 | ; 4 | ; 8 bit x 8 bit signed multiply, 16 bit result 5 | ; Average cycles: 180.50 6 | ; 35 bytes 7 | 8 | 9 | aux = $02 10 | acc = $03 11 | ; ext = $04 12 | 13 | * = $0200 14 | 15 | ; ---------------------------------------------------------------------------- 16 | ; Multiply acc x aux (signed) 17 | ; 18 | ; On Exit: 19 | ; acc (low byte) 20 | ; A (high byte) 21 | smult 22 | ; Step 0: Remember acc 23 | ldx acc 24 | 25 | ; Step 1: Unsigned multiply acc * aux 26 | ; (see mult9) 27 | ; 28 | ; On Exit: 29 | ; acc (low byte) 30 | ; A (high byte) 31 | lda #0 32 | ldy #9 ; loop counter 33 | clc 34 | - 35 | ror 36 | ror acc 37 | bcc + 38 | clc ; decrement aux above to remove CLC 39 | adc aux 40 | + 41 | dey 42 | bne - 43 | 44 | ; Step 2: apply sign (See C=Hacking16 for details). 45 | cpx #$80 46 | bcc + 47 | sbc aux 48 | + 49 | bit aux 50 | bpl + 51 | stx temp 52 | sec 53 | temp = * + 1 54 | sbc #0 55 | + 56 | rts 57 | -------------------------------------------------------------------------------- /tests/mult27.a: -------------------------------------------------------------------------------- 1 | ; mult27.a 2 | ; from https://sites.google.com/site/h2obsession/programming/6502 3 | ; tweaked slightly 4 | ; 5 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 6 | ; Average cycles: 46.49 7 | ; 1312 bytes 8 | 9 | temp = $02 10 | 11 | * = $0200 12 | 13 | ; Tables must be aligned with page boundary 14 | sqrLow 15 | !for i, 0, 511 { 16 | !byte <((i*i)/4) 17 | } 18 | 19 | sqrHigh 20 | !for i, 0, 511 { 21 | !byte >((i*i)/4) 22 | } 23 | 24 | idTab 25 | !for i, 0, 255 { 26 | !byte i 27 | } 28 | 29 | ; *************************************************************************************** 30 | ; On Entry: 31 | ; A = multiplicand 32 | ; X = multiplier 33 | ; On Exit: 34 | ; temp: low byte of product 35 | ; A: high byte of product 36 | mult 37 | sta getLow+1 38 | sta getHigh+1 39 | sec 40 | sbc idTab,x 41 | bcs doMult 42 | sbc #0 43 | eor #255 44 | doMult 45 | tay 46 | getLow 47 | lda sqrLow,x 48 | sbc sqrLow,y 49 | sta temp 50 | getHigh 51 | lda sqrHigh,x 52 | sbc sqrHigh,y 53 | ; tax 54 | ;temp = *+1 55 | ; lda #0 56 | rts 57 | -------------------------------------------------------------------------------- /tests/mult3.a: -------------------------------------------------------------------------------- 1 | ; mult3.a 2 | ; from Neil Parker: https://llx.com/Neil/a2/mult.html 3 | ; 4 | ; 16 bit x 16 bit unsigned multiply, 32 bit result 5 | ; Average cycles: 711 6 | ; 36 bytes 7 | 8 | 9 | num1 = $02 ; 2 bytes 10 | num2 = $04 ; 2 bytes 11 | result = $06 ; 4 bytes 12 | 13 | * = $0200 14 | 15 | ; result = num1 * num2 16 | mult 17 | lda #0 ; initialize result to 0 18 | sta result+2 ; 19 | ldx #16 ; there are 16 bits in num2 20 | loop 21 | lsr num2+1 ; get low bit of num2 22 | ror num2 ; 23 | bcc + ; 0 or 1? 24 | tay ; if 1, add num1 (high byte of result is in a) 25 | clc ; 26 | lda num1 ; 27 | adc result+2 ; 28 | sta result+2 ; 29 | tya ; 30 | adc num1+1 ; 31 | + 32 | ror ; "stairstep" shift 33 | ror result+2 ; 34 | ror result+1 ; 35 | ror result ; 36 | dex ; 37 | bne loop ; 38 | 39 | sta result+3 ; 40 | rts ; 41 | -------------------------------------------------------------------------------- /tests/omult10.a: -------------------------------------------------------------------------------- 1 | ; omult10.a 2 | ; from the BBC BASIC ROM at $9d83, https://archive.org/details/BBCMicroCompendium/page/364/mode/2up 3 | ; 4 | ; 16 bit x 32 bit unsigned multiply, 32 bit result 5 | ; Average cycles: 909.00 6 | ; 50 bytes 7 | 8 | 9 | factorA = $02 ; 2 bytes 10 | factorB = $04 ; 4 bytes 11 | product2 = $08 ; 1 byte 12 | product3 = $09 ; 1 byte 13 | 14 | * = $0200 15 | 16 | ; On Entry: 17 | ; factorA=multiplier (2 bytes) 18 | ; factorB=multiplicand (4 bytes) 19 | ; On Exit: 20 | ; (Y, X, product2, product3) is the 32 bit product 21 | 22 | mult 23 | ldy #0 24 | ldx #0 25 | sty product2 26 | sty product3 27 | - 28 | lsr factorA+1 29 | ror factorA 30 | bcc + 31 | 32 | clc 33 | tya 34 | adc factorB 35 | tay 36 | txa 37 | adc factorB+1 38 | tax 39 | lda product2 40 | adc factorB+2 41 | sta product2 42 | lda product3 43 | adc factorB+3 44 | sta product3 45 | 46 | + 47 | asl factorB 48 | rol factorB+1 49 | rol factorB+2 50 | rol factorB+3 51 | 52 | lda factorA 53 | ora factorA+1 54 | bne - 55 | rts 56 | -------------------------------------------------------------------------------- /tests/mult14.a: -------------------------------------------------------------------------------- 1 | ; mult14.a 2 | ; from codebase64 by JackAsser/Instinct: https://codebase64.org/doku.php?id=base:seriously_fast_multiplication 3 | ; 4 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 5 | ; Average cycles: 45.99 6 | ; 2077 bytes 7 | 8 | 9 | PRODUCT = $03 10 | 11 | * = $200 12 | 13 | ; Tables must be aligned to page boundary 14 | square1_low 15 | !for i, 0, 511 { 16 | !byte <((i*i)/4) 17 | } 18 | square1_high 19 | !for i, 0, 511 { 20 | !byte >((i*i)/4) 21 | } 22 | 23 | square2_low 24 | !for i, 0, 511 { 25 | !byte <(((i-255)*(i-255))/4) 26 | } 27 | square2_high 28 | !for i, 0, 511 { 29 | !byte >(((i-255)*(i-255))/4) 30 | } 31 | 32 | ; ---------------------------------------------------------------------------------- 33 | ; multiplies A*X 34 | ; result is in Y (low byte) and A (high byte) 35 | mult 36 | sta sm1 37 | sta sm3 38 | eor #$ff 39 | sta sm2 40 | sta sm4 41 | 42 | sec 43 | sm1 = * + 1 44 | lda square1_low,x 45 | sm2 = * + 1 46 | sbc square2_low,x 47 | tay 48 | sm3 = * + 1 49 | lda square1_high,x 50 | sm4 = * + 1 51 | sbc square2_high,x 52 | rts 53 | -------------------------------------------------------------------------------- /tests/mult8.a: -------------------------------------------------------------------------------- 1 | ; mult8.a 2 | ; from Apple Assembly Line, January 1986: FAST.8X8.SLYE at http://www.txbobsc.com/aal/1986/aal8601.html#a5 3 | ; 4 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 5 | ; Average cycles: 153.52 6 | ; 29 bytes 7 | 8 | 9 | multiplicand = $02 10 | multiplier = $03 11 | 12 | * = $0200 13 | 14 | ; *************************************************************************************** 15 | ; multiply A*X 16 | ; returns product: X is the low byte, A is the high byte 17 | mult 18 | cpx #0 ; 19 | beq zero ; a*0=0 20 | dex ; decrement multiplicand to avoid the clc before 'adc multiplicand' 21 | stx multiplicand ; 22 | lsr ; prepare first bit 23 | sta multiplier ; 24 | lda #0 ; 25 | ldx #8 ; 26 | loop 27 | bcc skip ; no add 28 | adc multiplicand ; 29 | skip 30 | ror ; 31 | ror multiplier ; 32 | dex ; 33 | bne loop ; 34 | ldx multiplier ; 35 | rts ; 36 | zero 37 | txa ; a = 0 38 | rts ; 39 | -------------------------------------------------------------------------------- /tests/omult29.a: -------------------------------------------------------------------------------- 1 | ; omult29.a 2 | ; from 'Splitting the Atom (The Acorn Recommended Advanced User Guide)' by J.R. Stevenson and John C. Rockett: https://site.acornatom.nl/boeken/splitting-the-atom.pdf 3 | ; 4 | ; 16 bit x 8 bit unsigned multiply, 16 bit result (low bytes) 5 | ; Average cycles: 267.00 6 | ; 34 bytes 7 | 8 | * = $0200 9 | 10 | M = $02 ; multiplicand 2 bytes 11 | R = $04 ; result 2 bytes 12 | 13 | 14 | ; On Entry: 15 | ; A: multiplier 16 | ; M: multiplicand 17 | ; On Exit: 18 | ; (R, R+1): product 19 | JJ0 20 | ; pha 21 | ldx #0 ; 22 | stx R ; [OPTIMISATION: used X to avoid 'pha' and 'pla'] 23 | stx R+1 ; 24 | ; pla 25 | ldx #8 26 | JJ1 27 | ;clc ; [OPTIMISATION: replace 'clc:rol R' with 'asl R'] 28 | asl R ; 29 | rol R+1 30 | asl 31 | bcc JJ2 32 | ;pha 33 | tay ; [OPTIMISATION: use Y to remember A instead of stack] 34 | clc 35 | lda R 36 | adc M 37 | sta R 38 | lda R+1 39 | adc M+1 40 | sta R+1 41 | ;pla 42 | tya ; [OPTIMISATION: use Y to remember A instead of stack] 43 | JJ2 44 | dex 45 | bne JJ1 46 | rts 47 | -------------------------------------------------------------------------------- /tests/mult49.a: -------------------------------------------------------------------------------- 1 | ; mult49.a 2 | ; from Micro 6502 Journal Issue 31 (Dec 1980) p71-74, https://archive.org/details/micro-6502-journal-31/page/n73/mode/2up 3 | ; bug fixed 4 | ; removed shortcut to 8x16 multiply (resulting in slightly faster and smaller code) 5 | ; 6 | ; 16 bit x 16 bit unsigned multiply, 32 bit result 7 | ; Average cycles: 703 8 | ; 43 bytes 9 | 10 | 11 | * = $0200 12 | 13 | acl = $02 14 | ach = $03 15 | xtndl = $04 16 | xtndh = $05 17 | auxl = $06 18 | auxh = $07 19 | 20 | ; 16 x 16 bit unsigned multiply 21 | ; 22 | ; On Entry: 23 | ; auxl/h: 16 bit multiplier 24 | ; X (low),Y (high): 16 bit multiplicand 25 | ; On Exit: 26 | ; acl, ach, xtndl, xtndh: 32 bit product 27 | mult16x 28 | lda #$10 29 | multi 30 | sty auxl 31 | stx auxh 32 | tay 33 | lda #0 34 | sta xtndl 35 | sta xtndh 36 | mul3x 37 | lda acl 38 | lsr 39 | bcc mul4x ; Bug fix - original listing was missing this line! 40 | lda xtndl 41 | clc 42 | adc auxl 43 | sta xtndl 44 | lda xtndh 45 | adc auxh 46 | sta xtndh 47 | mul4x 48 | ror xtndh 49 | ror xtndl 50 | ror ach 51 | ror acl 52 | dey 53 | bne mul3x 54 | rts 55 | -------------------------------------------------------------------------------- /tests/omult28.a: -------------------------------------------------------------------------------- 1 | ; omult28.a 2 | ; from Starship Command at $1095: http://www.level7.org.uk/miscellany/starship-command-disassembly.txt 3 | ; 4 | ; 24 bit x 8 bit unsigned multiply, 24 bit result (high bytes) 5 | ; Average cycles: 897.00 6 | ; 24 bytes 7 | 8 | * = $0200 9 | 10 | multiplier = $02 11 | input_fraction = $03 12 | input_pixels = $04 13 | input_screens = $05 14 | sine_output_fraction = $06 15 | sine_output_pixels = $07 16 | 17 | ; 24 bit x 8 bit unsigned multiply, 24 bit result (low bytes) 18 | ; 19 | ; On Entry: 20 | ; (input_fraction, input_pixels, input_screens): 24 bit input 21 | ; multiplier: 8 bit input 22 | ; On Exit: 23 | ; (sine_output_fraction, sine_output_pixels, A): 24 bit result 24 | mult 25 | lda #0 26 | ldy #24 ; 24-bit multiplication of input by multiplier 27 | loop_over_bits_of_input 28 | lsr input_screens 29 | ror input_pixels 30 | ror input_fraction ; Get lowest bit of (fraction, pixels, screen) 31 | bcc input_bit_unset 32 | clc 33 | adc multiplier 34 | input_bit_unset 35 | ror 36 | ror sine_output_pixels 37 | ror sine_output_fraction 38 | dey 39 | bne loop_over_bits_of_input 40 | rts 41 | -------------------------------------------------------------------------------- /tests/mult24.a: -------------------------------------------------------------------------------- 1 | ; mult24.a 2 | ; 'tepples unrolled' from https://www.nesdev.org/wiki/8-bit_Multiply 3 | ; slightly tweaked 4 | ; 5 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 6 | ; Average cycles: 110.62 7 | ; 70 bytes 8 | 9 | 10 | prodlo = $02 11 | factor2 = $03 12 | 13 | * = $0200 14 | 15 | ; On Entry: 16 | ; A: multiplier 17 | ; Y: multiplicand 18 | ; On Exit: 19 | ; A: low byte of product 20 | ; Y: high byte of product 21 | mult 22 | lsr 23 | sta prodlo 24 | tya 25 | beq mul8_early_return 26 | dey 27 | sty factor2 28 | lda #0 29 | 30 | bcc + 31 | adc factor2 32 | ror 33 | + 34 | ror prodlo 35 | bcc + 36 | adc factor2 37 | + 38 | ror 39 | ror prodlo 40 | bcc + 41 | adc factor2 42 | + 43 | ror 44 | ror prodlo 45 | bcc + 46 | adc factor2 47 | + 48 | ror 49 | ror prodlo 50 | bcc + 51 | adc factor2 52 | + 53 | ror 54 | ror prodlo 55 | bcc + 56 | adc factor2 57 | + 58 | ror 59 | ror prodlo 60 | bcc + 61 | adc factor2 62 | + 63 | ror 64 | ror prodlo 65 | bcc + 66 | adc factor2 67 | + 68 | ror 69 | tay 70 | lda prodlo 71 | ror 72 | mul8_early_return 73 | rts 74 | -------------------------------------------------------------------------------- /tests/mult82.a: -------------------------------------------------------------------------------- 1 | ; mult82.a 2 | ; from Retro Software (2008): http://www.retrosoftware.co.uk/wiki/index.php?title=Fast_multiplication_routines 3 | ; 4 | ; 8 bit x 8 bit unsigned multiply 5 | ; Average cycles: 67.24 6 | ; 827 bytes 7 | 8 | 9 | num1 = $02 10 | num2 = $03 11 | result = $04 ; 2 bytes 12 | 13 | * = $0200 14 | 15 | ; Align tables to start of page for speed 16 | sqrlo 17 | !for i, 0, 255 { 18 | !byte <((i*i)/4) 19 | } 20 | sqrhi256 21 | !for i, 0, 255 { 22 | !byte >((i*i)/4) 23 | } 24 | sqrhi512 25 | !for i, 0, 255 { 26 | !byte >(((i+256)*(i+256))/4) 27 | } 28 | 29 | mult 30 | sec 31 | lda num1 32 | sbc num2 33 | bcs positive 34 | eor #255 35 | adc #1 36 | positive 37 | tay 38 | clc 39 | lda num1 40 | adc num2 41 | tax 42 | bcs morethan256 43 | lda sqrhi256,X 44 | sta result+1 45 | lda sqrlo,X 46 | sec 47 | bcs lessthan256 48 | morethan256 49 | lda sqrhi512,X 50 | sta result+1 51 | txa 52 | and #1 53 | beq skip 54 | lda #$80 55 | skip 56 | eor sqrlo,X 57 | lessthan256 58 | sbc sqrlo,Y 59 | sta result 60 | lda result+1 61 | sbc sqrhi256,Y 62 | sta result+1 63 | rts 64 | -------------------------------------------------------------------------------- /tests/mult1.a: -------------------------------------------------------------------------------- 1 | ; mult1.a 2 | ; from codebase64: https://www.codebase64.org/doku.php?id=base:16bit_multiplication_32-bit_product 3 | ; also from '6502 Software Design' by Leo J Scanlon (1980): https://archive.org/details/6502softwaredesi0000scan/page/124/mode/1up 4 | ; 5 | ; 16 bit x 16 bit unsigned multiply, 32 bit result 6 | ; Average cycles: 751 7 | ; 38 bytes 8 | 9 | 10 | multiplier = $02 ; 2 bytes 11 | multiplicand = $04 ; 2 bytes 12 | product = $06 ; 4 bytes 13 | 14 | * = $0200 15 | 16 | ; product = multiplier * multiplicand 17 | mult 18 | lda #0 19 | sta product+2 ; clear upper bits of product 20 | sta product+3 21 | ldx #16 ; set binary count to 16 22 | shift_r 23 | lsr multiplier+1 ; divide multiplier by 2 24 | ror multiplier 25 | bcc rotate_r 26 | lda product+2 ; get upper half of product and add multiplicand 27 | clc 28 | adc multiplicand 29 | sta product+2 30 | lda product+3 31 | adc multiplicand+1 32 | rotate_r 33 | ror ; rotate partial product 34 | sta product+3 35 | ror product+2 36 | ror product+1 37 | ror product 38 | dex 39 | bne shift_r 40 | rts 41 | -------------------------------------------------------------------------------- /tests/mult39.a: -------------------------------------------------------------------------------- 1 | ; mult39.a 2 | ; from https://revs.bbcelite.com/source/main/subroutine/multiply8x8.html 3 | ; From 'Revs' for the BBC Micro 4 | ; tweaked a bit for size and speed 5 | ; 6 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 7 | ; Average cycles: 107 8 | ; 69 bytes 9 | 10 | 11 | t = $02 12 | u = $03 13 | 14 | ; (A T) = A * U 15 | 16 | * = $0200 17 | 18 | ; *************************************************************************************** 19 | ; On Entry: 20 | ; A: multiplier 21 | ; u: multiplicand 22 | ; On Exit: 23 | ; t: low byte of product 24 | ; A: high byte of product 25 | Multiply8x8 26 | lsr 27 | sta t 28 | lda #0 29 | bcc + 30 | lda u 31 | lsr 32 | + 33 | ror t 34 | bcc + 35 | clc 36 | adc u 37 | + 38 | ror 39 | ror t 40 | bcc + 41 | clc 42 | adc u 43 | + 44 | ror 45 | ror t 46 | bcc + 47 | clc 48 | adc u 49 | + 50 | ror 51 | ror t 52 | bcc + 53 | clc 54 | adc u 55 | + 56 | ror 57 | ror t 58 | bcc + 59 | clc 60 | adc u 61 | + 62 | ror 63 | ror t 64 | bcc + 65 | clc 66 | adc u 67 | + 68 | ror 69 | ror t 70 | bcc + 71 | clc 72 | adc u 73 | + 74 | ror 75 | ror t 76 | rts 77 | -------------------------------------------------------------------------------- /tests/mult83.a: -------------------------------------------------------------------------------- 1 | ; mult83.a 2 | ; from Retro Software: http://www.retrosoftware.co.uk/wiki/index.php?title=Fast_multiplication_routines 3 | ; 4 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 5 | ; Average cycles: 56.00 6 | ; 1079 bytes 7 | 8 | num1 = $02 9 | num2 = $03 10 | result = $04 ; 2 bytes 11 | 12 | * = $0200 13 | 14 | ; Align tables to start of page for speed 15 | sqrlo256 16 | !for i, 0, 255 { 17 | !byte <((i*i)/4) 18 | } 19 | sqrhi256 20 | !for i, 0, 255 { 21 | !byte >((i*i)/4) 22 | } 23 | sqrlo512 24 | !for i, 0, 255 { 25 | !byte <(((i+256)*(i+256))/4) 26 | } 27 | sqrhi512 28 | !for i, 0, 255 { 29 | !byte >(((i+256)*(i+256))/4) 30 | } 31 | 32 | mult 33 | sec 34 | lda num1 35 | sbc num2 36 | bcs positive 37 | eor #255 38 | adc #1 39 | positive 40 | tay 41 | clc 42 | lda num1 43 | adc num2 44 | tax 45 | bcs morethan256 46 | sec 47 | lda sqrlo256,X 48 | sbc sqrlo256,Y 49 | sta result 50 | lda sqrhi256,X 51 | sbc sqrhi256,Y 52 | sta result+1 53 | rts 54 | 55 | morethan256 56 | lda sqrlo512,X 57 | sbc sqrlo256,Y 58 | sta result 59 | lda sqrhi512,X 60 | sbc sqrhi256,Y 61 | sta result+1 62 | rts 63 | -------------------------------------------------------------------------------- /tests/omult14.a: -------------------------------------------------------------------------------- 1 | ; omult14.a 2 | ; from FastBasic (BASIC interpreter for the Atari 8-bit computers) https://github.com/dmsc/fastbasic/blob/master/src/interp/mul.asm 3 | ; 4 | ; 16 bit x 16 bit unsigned multiply, 16 bit result (low bytes) 5 | ; Average cycles: 575.00 6 | ; 43 bytes 7 | 8 | * = $0200 9 | 10 | multiplicand = $02 ; 2 bytes 11 | tmp1 = $04 ; 2 bytes 12 | tmp2 = $06 ; 2 bytes 13 | tmp3 = $08 ; 1 byte 14 | 15 | ; On Entry: 16 | ; A: multiplier (low) 17 | ; X: multiplier (high) 18 | ; (multiplicand, multiplicand+1): 2 bytes 19 | ; On Exit: 20 | ; (tmp1, tmp1+1): 16 bit product 21 | mult 22 | ; Store A 23 | sta tmp3 24 | 25 | ; Get first bit into carry 26 | ; lda stack_h, y 27 | lda multiplicand+1 28 | lsr 29 | sta tmp1+1 30 | ; lda stack_l, y 31 | lda multiplicand 32 | ror 33 | sta tmp1 34 | 35 | lda #0 36 | sta tmp2+1 37 | ldy #16 ; Number of bits 38 | 39 | mult_loop 40 | bcc skip_add 41 | 42 | clc 43 | adc tmp3 44 | sta tmp2 45 | 46 | txa 47 | adc tmp2+1 48 | sta tmp2+1 49 | lda tmp2 50 | 51 | skip_add 52 | ror tmp2+1 53 | ror 54 | ror tmp1+1 55 | ror tmp1 56 | dey 57 | bne mult_loop 58 | rts 59 | -------------------------------------------------------------------------------- /tests/mult20.a: -------------------------------------------------------------------------------- 1 | ; mult20.a 2 | ; from Becoming Julie: https://becomingjulie.blogspot.com/2020/07/multiplying-on-6502-but-faster.html 3 | ; bug fixed. 4 | ; 5 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 6 | ; Average cycles: 244 7 | ; 27 bytes 8 | 9 | 10 | multiplicand = $02 11 | product_low = $03 12 | product_high = $04 13 | 14 | * = $0200 15 | 16 | ; On Entry: 17 | ; product_low: multiplier 18 | ; multiplicand: multiplicand 19 | ; On Exit: 20 | ; product_low: low byte of product 21 | ; product_high: high byte of product 22 | mult 23 | ldy #8 ; loop counter 24 | lda #0 ; bug fix: initialise product 25 | sta product_high ; 26 | mult_1 27 | lda product_low 28 | and #1 ; examine bit from multiplier 29 | clc ; bug fix: clc before beq 30 | beq mult_2 ; skip adding if zero 31 | lda product_high 32 | adc multiplicand ; if this sets a carry, it will just 33 | sta product_high ; get shifted into the product 34 | mult_2 ; shift whole product one bit right 35 | ror product_high ; bring in carry from addition 36 | ror product_low ; discard used bit 37 | dey ; decrease counter 38 | bne mult_1 39 | rts 40 | -------------------------------------------------------------------------------- /tests/omult25.c: -------------------------------------------------------------------------------- 1 | // omult25.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 8 * 256UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[3] = input & 255UL; 12 | memory[2] = input / 256UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.a; 20 | 21 | return high; 22 | } 23 | 24 | // ************************************************************************************** 25 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 26 | uint64_t a = input & 255UL; 27 | uint64_t b = input / 256UL; 28 | 29 | uint64_t e = (a*b) / 8; 30 | *expected = e; 31 | 32 | return actual_result == e; 33 | } 34 | 35 | // ************************************************************************************** 36 | void test_cleanup() 37 | { 38 | } 39 | -------------------------------------------------------------------------------- /tests/omult26.c: -------------------------------------------------------------------------------- 1 | // omult26.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 256UL * 256UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[3] = input & 255UL; 12 | memory[2] = input / 256UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.a; 20 | 21 | return high; 22 | } 23 | 24 | // ************************************************************************************** 25 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 26 | uint64_t a = input & 255UL; 27 | uint64_t b = input / 256UL; 28 | 29 | uint64_t e = a*b/256; 30 | *expected = e; 31 | 32 | return actual_result == e; 33 | } 34 | 35 | // ************************************************************************************** 36 | void test_cleanup() 37 | { 38 | } 39 | -------------------------------------------------------------------------------- /tests/omult2.c: -------------------------------------------------------------------------------- 1 | // omult2.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t low = threadContext->machine.state.a; 20 | 21 | return low; 22 | } 23 | 24 | // ************************************************************************************** 25 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 26 | uint64_t a = input & 255UL; 27 | uint64_t b = (input / 256UL) & 255UL; 28 | 29 | uint64_t e = (a*b) & 255; 30 | *expected = e; 31 | 32 | return actual_result == e; 33 | } 34 | 35 | // ************************************************************************************** 36 | void test_cleanup() 37 | { 38 | } 39 | -------------------------------------------------------------------------------- /tests/mult20.c: -------------------------------------------------------------------------------- 1 | // mult20.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = memory[4]; 20 | uint64_t low = memory[3]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult26.c: -------------------------------------------------------------------------------- 1 | // mult26.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = memory[5]; 20 | uint64_t low = memory[4]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult32.c: -------------------------------------------------------------------------------- 1 | // mult32.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = memory[5]; 20 | uint64_t low = memory[4]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult34.c: -------------------------------------------------------------------------------- 1 | // mult34.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = memory[6]; 20 | uint64_t low = memory[5]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult37.c: -------------------------------------------------------------------------------- 1 | // mult37.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = memory[5]; 20 | uint64_t low = memory[4]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult40.c: -------------------------------------------------------------------------------- 1 | // mult38.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[4] = input & 255UL; 12 | memory[5] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = memory[3]; 20 | uint64_t low = memory[2]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult43.c: -------------------------------------------------------------------------------- 1 | // mult43.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = memory[5]; 20 | uint64_t low = memory[4]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult47.c: -------------------------------------------------------------------------------- 1 | // mult47.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = memory[5]; 20 | uint64_t low = memory[4]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult6.c: -------------------------------------------------------------------------------- 1 | // mult6.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[0x80] = input & 255UL; 12 | memory[0x81] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t a = memory[0x85]; 20 | uint64_t b = memory[0x84]; 21 | 22 | return 256*a + b; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult77.c: -------------------------------------------------------------------------------- 1 | // mult77.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[4] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = memory[6]; 20 | uint64_t low = memory[5]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/omult16.a: -------------------------------------------------------------------------------- 1 | ; omult16.a 2 | ; from BBC BASIC 2 ROM, https://archive.org/details/BBCMicroCompendium/page/302/mode/1up?q=9236 3 | ; used for calculating multidimensional array access 4 | ; 5 | ; 16 bit x 16 bit multiply, 16 bit result (low bytes), (carry set if overflow?) 6 | ; Average cycles: 223.69 7 | ; 33 bytes 8 | 9 | multiplicand = $02 10 | multiplier = $04 11 | 12 | * = $0200 13 | 14 | 15 | mult 16 | ldx #0 17 | ldy #0 18 | loop 19 | ; Get the least significant bit of the multiplicand 20 | lsr multiplicand+1 21 | ror multiplicand 22 | bcc skip ; Do not add the multiplier to the accumulator if the bit is clear 23 | 24 | ; Add the multiplier to the accumulator 25 | clc 26 | tya 27 | adc multiplier 28 | tay 29 | txa 30 | adc multiplier+1 31 | tax 32 | 33 | ; Give a ‘Bad DIM’ error message if overflow is encountered 34 | bcs overflow 35 | skip 36 | ; Multiply the multiplier by two 37 | asl multiplier 38 | rol multiplier+1 39 | 40 | ; Continue this process until the multiplicand becomes zero 41 | lda multiplicand 42 | ora multiplicand+1 43 | bne loop 44 | clc ; TOBY: no overflow? 45 | ; Save the accumulator as the answer 46 | ; sty multiplier 47 | ; stx multiplier+1 48 | ; Exit 49 | overflow 50 | rts 51 | -------------------------------------------------------------------------------- /tests/mult79.c: -------------------------------------------------------------------------------- 1 | // mult79.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = memory[5]; 20 | uint64_t low = memory[4]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult82.c: -------------------------------------------------------------------------------- 1 | // mult82.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = memory[5]; 20 | uint64_t low = memory[4]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult83.c: -------------------------------------------------------------------------------- 1 | // mult83.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = memory[5]; 20 | uint64_t low = memory[4]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/omult3.c: -------------------------------------------------------------------------------- 1 | // omult3.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.a = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.a; 20 | 21 | return high; 22 | } 23 | 24 | // ************************************************************************************** 25 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 26 | uint64_t a = input & 255UL; 27 | uint64_t b = (input / 256UL) & 255UL; 28 | 29 | uint64_t e = (a*b) / 256; 30 | *expected = e; 31 | 32 | return actual_result == e; 33 | } 34 | 35 | // ************************************************************************************** 36 | void test_cleanup() 37 | { 38 | } 39 | -------------------------------------------------------------------------------- /tests/mult9.c: -------------------------------------------------------------------------------- 1 | // mult9.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t a = threadContext->machine.state.a; 20 | uint64_t b = memory[3]; 21 | 22 | return 256*a + b; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult10.a: -------------------------------------------------------------------------------- 1 | ; mult10.a 2 | ; from codebase64 by WhiteFlame: https://www.codebase64.org/doku.php?id=base:8bit_multiplication_16bit_product 3 | ; 4 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 5 | ; Average cycles: 215.08 6 | ; 27 bytes 7 | 8 | 9 | num1 = $02 10 | num2 = $03 11 | num1Hi = $04 12 | 13 | * = $0200 14 | 15 | ;------------------------ 16 | ; 8bit * 8bit = 16bit multiply 17 | ; By White Flame 18 | ; Multiplies "num1" by "num2" and stores result in .A (low byte, also in .X) and .Y (high byte) 19 | ; uses extra zp var "num1Hi" 20 | 21 | ; .X and .Y get clobbered. Change the tax/txa and tay/tya to stack or zp storage if this is an issue. 22 | ; idea to store 16-bit accumulator in .X and .Y instead of zp from bogax 23 | 24 | ; In this version, both inputs must be unsigned 25 | ; Remove the noted line to turn this into a 16bit(either) * 8bit(unsigned) = 16bit multiply. 26 | 27 | mult 28 | lda #0 29 | tay 30 | sty num1Hi ; remove this line for 16*8=16bit multiply 31 | beq enterLoop 32 | 33 | doAdd 34 | clc 35 | adc num1 36 | tax 37 | 38 | tya 39 | adc num1Hi 40 | tay 41 | txa 42 | 43 | loop 44 | asl num1 45 | rol num1Hi 46 | enterLoop ; accumulating multiply entry point (enter with .A=lo, .Y=hi) 47 | lsr num2 48 | bcs doAdd 49 | bne loop 50 | rts 51 | -------------------------------------------------------------------------------- /tests/mult28.a: -------------------------------------------------------------------------------- 1 | ; mult28.a 2 | ; from FAST.8X8.RBSC at http://www.txbobsc.com/aal/1986/aal8601.html#a5 3 | ; with slight change to swap output parameters 4 | ; and another change to avoid handling zero as a special case and reducing multiplicand 5 | ; since this slows the average case down and is longer. 6 | ; 7 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 8 | ; Average cycles: 130 9 | ; 27 bytes 10 | 11 | 12 | multiplicand = $02 13 | multiplier = $03 14 | 15 | * = $0200 16 | 17 | ; *************************************************************************************** 18 | ; On Entry: 19 | ; A: multiplier 20 | ; multiplicand: multiplicand 21 | ; On Exit: 22 | ; multiplier: low byte of product 23 | ; A: high byte of product 24 | mult 25 | lsr ; prepare first bit 26 | sta multiplier ; 27 | lda #0 ; 28 | ldx #4 ; 29 | - 30 | bcc + ; no add 31 | clc ; 32 | adc multiplicand ; 33 | + 34 | ror ; 35 | ror multiplier ; 36 | bcc + ; no add 37 | clc ; 38 | adc multiplicand ; 39 | + 40 | ror ; 41 | ror multiplier ; 42 | dex ; 43 | bne - ; 44 | rts ; 45 | -------------------------------------------------------------------------------- /tests/mult11.c: -------------------------------------------------------------------------------- 1 | // mult11.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.a; 20 | uint64_t low = memory[2]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult76.c: -------------------------------------------------------------------------------- 1 | // mult76.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.a; 20 | uint64_t low = memory[4]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult19.c: -------------------------------------------------------------------------------- 1 | // mult19.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.a; 20 | uint64_t low = memory[4]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult21.c: -------------------------------------------------------------------------------- 1 | // mult21.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.a; 20 | uint64_t low = memory[2]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult35.c: -------------------------------------------------------------------------------- 1 | // mult34.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.a; 20 | uint64_t low = memory[4]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult44.c: -------------------------------------------------------------------------------- 1 | // mult44.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.a; 20 | uint64_t low = memory[3]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult75.c: -------------------------------------------------------------------------------- 1 | // mult75.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t low = threadContext->machine.state.a; 20 | uint64_t high = memory[4]; 21 | 22 | return low + 256*high; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult78.c: -------------------------------------------------------------------------------- 1 | // mult77.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.a; 20 | uint64_t low = memory[4]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/omult12.c: -------------------------------------------------------------------------------- 1 | // omult12.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.a = input & 255UL; 12 | threadContext->machine.state.x = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t low = threadContext->machine.state.a; 20 | 21 | return low; 22 | } 23 | 24 | // ************************************************************************************** 25 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 26 | uint64_t a = input & 255UL; 27 | uint64_t b = (input / 256UL) & 255UL; 28 | 29 | uint64_t e = (a*b) & 255; 30 | *expected = e; 31 | 32 | return actual_result == e; 33 | } 34 | 35 | // ************************************************************************************** 36 | void test_cleanup() 37 | { 38 | } 39 | -------------------------------------------------------------------------------- /tests/mult18.a: -------------------------------------------------------------------------------- 1 | ; mult18.a 2 | ; from Elite: https://www.bbcelite.com/master/main/subroutine/mu11.html 3 | ; tweaked to handle X=0 on input, and unrolled 4 | ; 5 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 6 | ; Average cycles: 111.62 7 | ; 73 bytes 8 | 9 | 10 | ; (A P) = P * X 11 | 12 | T = $02 13 | P = $03 14 | 15 | * = 0x0200 16 | 17 | ; *************************************************************************************** 18 | ; 8 bit multiply 19 | ; 20 | ; On Entry: 21 | ; P: multiplier 22 | ; X: multiplicand 23 | ; On Exit: 24 | ; A: high byte of product 25 | ; P: low byte of product 26 | mult 27 | cpx #0 ; 28 | beq zero ; Special case: handle X=0 separately 29 | 30 | dex 31 | stx T 32 | lda #0 33 | ; tax 34 | lsr P 35 | bcc + 36 | adc T 37 | + 38 | ror 39 | ror P 40 | bcc + 41 | adc T 42 | + 43 | ror 44 | ror P 45 | bcc + 46 | adc T 47 | + 48 | ror 49 | ror P 50 | 51 | bcc + 52 | adc T 53 | + 54 | ror 55 | ror P 56 | bcc + 57 | adc T 58 | + 59 | ror 60 | ror P 61 | bcc + 62 | adc T 63 | + 64 | ror 65 | ror P 66 | bcc + 67 | adc T 68 | + 69 | ror 70 | ror P 71 | bcc + 72 | adc T 73 | + 74 | ror 75 | ror P 76 | rts 77 | 78 | zero 79 | txa 80 | sta P 81 | rts 82 | -------------------------------------------------------------------------------- /tests/mult5.c: -------------------------------------------------------------------------------- 1 | // mult5.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.a = input & 255UL; 12 | threadContext->machine.state.x = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t a = memory[5]; 20 | uint64_t b = memory[4]; 21 | 22 | return 256*a + b; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult7.a: -------------------------------------------------------------------------------- 1 | ; mult7.a 2 | ; from Apple Assembly Line, January 1986: FAST.8X8.RBSC at http://www.txbobsc.com/aal/1986/aal8601.html#a5 3 | ; with slight change to swap output parameters 4 | ; 5 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 6 | ; Average cycles: 133.52 7 | ; 36 bytes 8 | 9 | 10 | multiplicand = $02 11 | multiplier = $03 12 | 13 | * = $0200 14 | 15 | ; *************************************************************************************** 16 | ; multiply A*X 17 | ; returns product: X is the low byte, A is the high byte 18 | mult 19 | cpx #0 ; 20 | beq zero ; a*0=0 21 | dex ; decrement multiplicand to avoid the clc before 'adc multiplicand' 22 | stx multiplicand ; 23 | lsr ; prepare first bit 24 | sta multiplier ; 25 | lda #0 ; 26 | ldx #4 ; 27 | - 28 | bcc + ; no add 29 | adc multiplicand ; 30 | + 31 | ror ; 32 | ror multiplier ; 33 | bcc + ; no add 34 | adc multiplicand ; 35 | + 36 | ror ; 37 | ror multiplier ; 38 | dex ; 39 | bne - ; 40 | ldx multiplier ; 41 | rts ; 42 | 43 | zero 44 | txa ; a = 0 45 | rts ; 46 | -------------------------------------------------------------------------------- /tests/mult28.c: -------------------------------------------------------------------------------- 1 | // mult28.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.a = input & 255UL; 12 | memory[2] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t a = threadContext->machine.state.a; 20 | uint64_t b = memory[3]; 21 | 22 | return 256*a + b; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult29.c: -------------------------------------------------------------------------------- 1 | // mult28.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.a = input & 255UL; 12 | memory[2] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t a = threadContext->machine.state.a; 20 | uint64_t b = memory[3]; 21 | 22 | return 256*a + b; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult87.c: -------------------------------------------------------------------------------- 1 | // mult87.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.x = input & 255UL; 12 | threadContext->machine.state.y = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t a = memory[1]; 20 | uint64_t b = memory[0]; 21 | 22 | return 256*a + b; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult10.c: -------------------------------------------------------------------------------- 1 | // mult10.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.y; 20 | uint64_t low = threadContext->machine.state.a; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult12.c: -------------------------------------------------------------------------------- 1 | // mult12.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | threadContext->machine.state.x = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.a; 20 | uint64_t low = memory[2]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult16.c: -------------------------------------------------------------------------------- 1 | // mult16.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.a = input & 255UL; 12 | memory[2] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.a; 20 | uint64_t low = memory[3]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult17.c: -------------------------------------------------------------------------------- 1 | // mult17.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.x = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.a; 20 | uint64_t low = memory[3]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult18.c: -------------------------------------------------------------------------------- 1 | // mult18.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.x = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.a; 20 | uint64_t low = memory[3]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult25.c: -------------------------------------------------------------------------------- 1 | // mult25.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.a = input & 255UL; 12 | memory[2] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = memory[4]; 20 | uint64_t low = memory[3]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult39.c: -------------------------------------------------------------------------------- 1 | // mult38.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.a = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.a; 20 | uint64_t low = memory[2]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult80.c: -------------------------------------------------------------------------------- 1 | // mult80.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.x = input & 255UL; 12 | threadContext->machine.state.y = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = memory[3]; 20 | uint64_t low = memory[2]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult81.c: -------------------------------------------------------------------------------- 1 | // mult81.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.x = input & 255UL; 12 | threadContext->machine.state.y = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = memory[3]; 20 | uint64_t low = memory[2]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult13.c: -------------------------------------------------------------------------------- 1 | // mult13.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.a = input & 255UL; 12 | threadContext->machine.state.x = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t a = threadContext->machine.state.a; 20 | uint64_t b = memory[3]; 21 | 22 | return 256*a + b; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult74.a: -------------------------------------------------------------------------------- 1 | ; mult74.a 2 | ; from 'Mikroprozessoren 6502, 6800, 8080, Z80, 9900' by Harald Schumny (1983) 3 | ; bugfixed (clear carry on entry) 4 | ; 5 | ; 16 bit x 16 bit unsigned multiply, 32 bit result 6 | ; Average cycles: 1358.00 7 | ; 86 bytes 8 | 9 | mkdl = $00 10 | mkdh = $01 11 | mktl = $02 12 | mkth = $03 13 | zreg = $04 14 | zw1 = $05 15 | zw2 = $06 16 | zw3 = $07 17 | zw4 = $08 18 | pr1 = $09 19 | pr2 = $0a 20 | pr3 = $0b 21 | pr4 = $0c 22 | reg = $0d 23 | 24 | * = $0200 25 | 26 | bmply 27 | clc ; bugfix 28 | 29 | lda #0 30 | sta zw3 31 | sta zw4 32 | sta pr1 33 | sta pr2 34 | sta pr3 35 | sta pr4 36 | lda mkdh 37 | sta zw2 38 | lda mkdl 39 | sta zw1 40 | lda #2 41 | sta reg ; loop counter 42 | ldx #8 ; loop counter 43 | lda mktl 44 | sta zreg 45 | jmp multi 46 | 47 | high 48 | ldx #8 ; loop counter 49 | lda mkth 50 | sta zreg 51 | multi 52 | ror zreg 53 | bcc nicht 54 | clc 55 | ldy #0 ; loop counter 56 | loop 57 | lda zw1,y 58 | adc pr1,y 59 | sta pr1,y 60 | iny 61 | tya 62 | and #4 63 | beq loop 64 | nicht 65 | asl zw1 66 | rol zw2 67 | rol zw3 68 | rol zw4 69 | dex 70 | beq decrb 71 | jmp multi 72 | 73 | decrb 74 | dec reg 75 | beq ende 76 | jmp high 77 | ende 78 | rts 79 | -------------------------------------------------------------------------------- /tests/omult27.c: -------------------------------------------------------------------------------- 1 | // omult27.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL * 256UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | memory[4] = input / 65536UL; 14 | } 15 | 16 | // ************************************************************************************** 17 | uint64_t test_post(thread_context_t* threadContext) { 18 | zuint8* memory = threadContext->machine.context; 19 | 20 | uint64_t low = memory[5]; 21 | uint64_t high = memory[6]; 22 | 23 | return low + 256*high; 24 | } 25 | 26 | // ************************************************************************************** 27 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 28 | uint64_t a = input & 65535UL; 29 | uint64_t b = input / 65536UL; 30 | 31 | uint64_t e = (a*b) / 256UL; 32 | *expected = e; 33 | 34 | return actual_result == e; 35 | } 36 | 37 | // ************************************************************************************** 38 | void test_cleanup() 39 | { 40 | } 41 | -------------------------------------------------------------------------------- /tests/mult22.c: -------------------------------------------------------------------------------- 1 | // mult22.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.a = input & 255UL; 12 | threadContext->machine.state.x = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.a; 20 | uint64_t low = memory[3]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult23.c: -------------------------------------------------------------------------------- 1 | // mult23.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.a = input & 255UL; 12 | threadContext->machine.state.y = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.a; 20 | uint64_t low = memory[2]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult27.c: -------------------------------------------------------------------------------- 1 | // mult27.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.a = input & 255UL; 12 | threadContext->machine.state.x = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.a; 20 | uint64_t low = memory[2]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult38.c: -------------------------------------------------------------------------------- 1 | // mult38.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.x = input & 255UL; 12 | threadContext->machine.state.y = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.a; 20 | uint64_t low = memory[4]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult57.c: -------------------------------------------------------------------------------- 1 | // mult57.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.a = input & 255UL; 12 | threadContext->machine.state.x = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.a; 20 | uint64_t low = memory[2]; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult44.a: -------------------------------------------------------------------------------- 1 | ; mult44.a 2 | ; from 'The Sentinel' for the BBC Micro, http://level7.org.uk/miscellany/the-sentinel-disassembly.txt 3 | ; 4 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 5 | ; Average cycles: 109 6 | ; 69 bytes 7 | 8 | 9 | multiplicand = $02 10 | multiplier = $03 11 | 12 | * = $0200 13 | 14 | ; Multiply multiplier * multiplicand 15 | ; 16 | ; On Exit: 17 | ; A: high byte 18 | ; multiplier: low byte 19 | multiply_A_by_byte 20 | lda #0 21 | lsr multiplier 22 | bcc skip_bit_0 23 | clc 24 | adc multiplicand 25 | skip_bit_0 26 | ror 27 | ror multiplier 28 | bcc skip_bit_1 29 | clc 30 | adc multiplicand 31 | skip_bit_1 32 | ror 33 | ror multiplier 34 | bcc skip_bit_2 35 | clc 36 | adc multiplicand 37 | skip_bit_2 38 | ror 39 | ror multiplier 40 | bcc skip_bit_3 41 | clc 42 | adc multiplicand 43 | skip_bit_3 44 | ror 45 | ror multiplier 46 | bcc skip_bit_4 47 | clc 48 | adc multiplicand 49 | skip_bit_4 50 | ror 51 | ror multiplier 52 | bcc skip_bit_5 53 | clc 54 | adc multiplicand 55 | skip_bit_5 56 | ror 57 | ror multiplier 58 | bcc skip_bit_6 59 | clc 60 | adc multiplicand 61 | skip_bit_6 62 | ror 63 | ror multiplier 64 | bcc skip_bit_7 65 | clc 66 | adc multiplicand 67 | skip_bit_7 68 | ror 69 | ror multiplier 70 | rts 71 | -------------------------------------------------------------------------------- /tests/mult72.c: -------------------------------------------------------------------------------- 1 | // mult72.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[0x209] = input & 255UL; 12 | threadContext->machine.state.x = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t low = threadContext->machine.state.a; 20 | uint64_t high = threadContext->machine.state.y; 21 | 22 | return low + 256*high; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult14.c: -------------------------------------------------------------------------------- 1 | // mult14.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.a = input & 255UL; 12 | threadContext->machine.state.x = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t a = threadContext->machine.state.a; 20 | uint64_t b = threadContext->machine.state.y; 21 | 22 | return 256*a + b; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult7.c: -------------------------------------------------------------------------------- 1 | // mult7.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.a = input & 255UL; 12 | threadContext->machine.state.x = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t a = threadContext->machine.state.a; 20 | uint64_t b = threadContext->machine.state.x; 21 | 22 | return 256*a + b; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult8.c: -------------------------------------------------------------------------------- 1 | // mult8.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.a = input & 255UL; 12 | threadContext->machine.state.x = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t a = threadContext->machine.state.a; 20 | uint64_t b = threadContext->machine.state.x; 21 | 22 | return 256*a + b; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult24.c: -------------------------------------------------------------------------------- 1 | // mult24.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.a = input & 255UL; 12 | threadContext->machine.state.y = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.y; 20 | uint64_t low = threadContext->machine.state.a; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult26.a: -------------------------------------------------------------------------------- 1 | ; mult26.a 2 | ; 'frantik' from https://www.nesdev.org/wiki/8-bit_Multiply 3 | ; with bug fix 4 | ; 5 | ; 8 bit x 8 bit multiply, 16 bit result 6 | ; Average cycles: 278 7 | ; 47 bytes 8 | 9 | 10 | value1 = $02 11 | value2 = $03 12 | ret = $04 ; return value (2 bytes) 13 | temp = $06 ; temp storage 14 | 15 | * = $0200 16 | 17 | ; *************************************************************************************** 18 | ; On Entry: 19 | ; value1: multiplier 20 | ; value2: multiplicand 21 | ; On Exit: 22 | ; ret: low byte of product 23 | ; ret+1: high byte of product 24 | mult 25 | lda #0 ; clear temporary variables 26 | sta ret 27 | sta ret+1 28 | sta temp 29 | lda value2 30 | beq end ; BUGFIX: beq not bne 31 | jmp start 32 | 33 | loop 34 | asl value1 ; double first value 35 | rol temp ; using 16bit precision 36 | lsr value2 ; halve second vale 37 | start 38 | lda value2 ; 39 | and #1 ; is new 2nd value an odd number? 40 | beq loop ; 41 | clc ; if so, add new 1st value to running total 42 | lda ret ; 43 | adc value1 ; 44 | sta ret ; 45 | lda ret+1 ; 46 | adc temp ; 47 | sta ret+1 ; 48 | lda value2 ; 49 | cmp #1 ; is 2nd value 1? if so, we're done 50 | bne loop ; otherwise, loop 51 | end 52 | rts ; 53 | -------------------------------------------------------------------------------- /tests/mult30.c: -------------------------------------------------------------------------------- 1 | // mult30.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | threadContext->machine.state.a = input & 255UL; 12 | threadContext->machine.state.y = (input / 256UL) & 255UL; 13 | } 14 | 15 | // ************************************************************************************** 16 | uint64_t test_post(thread_context_t* threadContext) { 17 | zuint8* memory = threadContext->machine.context; 18 | 19 | uint64_t high = threadContext->machine.state.y; 20 | uint64_t low = threadContext->machine.state.a; 21 | 22 | return 256*high + low; 23 | } 24 | 25 | // ************************************************************************************** 26 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 27 | uint64_t a = input & 255UL; 28 | uint64_t b = (input / 256UL) & 255UL; 29 | 30 | uint64_t e = a*b; 31 | *expected = e; 32 | 33 | return actual_result == e; 34 | } 35 | 36 | // ************************************************************************************** 37 | void test_cleanup() 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /tests/mult48.a: -------------------------------------------------------------------------------- 1 | ; mult48.a 2 | ; from Micro 6502 Journal Issue 31 (Dec 1980) p71-74, https://archive.org/details/micro-6502-journal-31/page/n73/mode/2up 3 | ; bug fixed 4 | ; 5 | ; 16 bit x 16 bit unsigned multiply, 32 bit result 6 | ; Average cycles: 707.11 7 | ; 69 bytes 8 | 9 | 10 | * = $0200 11 | 12 | acl = $02 13 | ach = $03 14 | xtndl = $04 15 | xtndh = $05 16 | auxl = $06 17 | auxh = $07 18 | 19 | ; 16 x 16 bit unsigned multiply 20 | ; 21 | ; On Entry: 22 | ; auxl/h: 16 bit multiplier 23 | ; X (low),Y (high): 16 bit multiplicand 24 | ; On Exit: 25 | ; acl, ach, xtndl, xtndh: 32 bit product 26 | mult16x 27 | lda ach 28 | beq mul5x 29 | lda #$10 30 | multi 31 | sty auxl 32 | stx auxh 33 | tay 34 | lda #0 35 | sta xtndl 36 | sta xtndh 37 | mul3x 38 | lda acl 39 | lsr 40 | bcc mul4x ; Bug fix - original listing was missing this line! 41 | lda xtndl 42 | clc 43 | adc auxl 44 | sta xtndl 45 | lda xtndh 46 | adc auxh 47 | sta xtndh 48 | mul4x 49 | ror xtndh 50 | ror xtndl 51 | ror ach 52 | ror acl 53 | dey 54 | bne mul3x 55 | rts 56 | 57 | ;mul816 58 | ; sta acl 59 | ; lda #0 60 | ; sta ach 61 | mul5x 62 | lda #8 63 | jsr multi 64 | ldy xtndh 65 | lda #0 66 | sta xtndh 67 | lda xtndl 68 | sty xtndl 69 | ldx ach 70 | sta ach 71 | stx acl 72 | rts 73 | -------------------------------------------------------------------------------- /tests/omult29.c: -------------------------------------------------------------------------------- 1 | // omult29.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 256UL * 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | threadContext->machine.state.a = (input / 65536UL) & 255UL; 14 | } 15 | 16 | // ************************************************************************************** 17 | uint64_t test_post(thread_context_t* threadContext) { 18 | zuint8* memory = threadContext->machine.context; 19 | 20 | uint64_t low = memory[4]; 21 | uint64_t high = memory[5]; 22 | 23 | return low + 256*high; 24 | } 25 | 26 | // ************************************************************************************** 27 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 28 | uint64_t a = input & 65535UL; 29 | uint64_t b = (input / 65536UL) & 255UL; 30 | 31 | uint64_t e = (a * b) & 65535UL; 32 | *expected = e; 33 | 34 | return actual_result == e; 35 | } 36 | 37 | // ************************************************************************************** 38 | void test_cleanup() 39 | { 40 | } 41 | -------------------------------------------------------------------------------- /tests/mult67.a: -------------------------------------------------------------------------------- 1 | ; mult67.a 2 | ; from julie_m, https://stardot.org.uk/forums/viewtopic.php?p=380587#p380587 3 | ; 4 | ; 16 bit x 16 bit unsigned multiply, 32 bit result 5 | ; Average cycles: 633.00 6 | ; 37 bytes 7 | 8 | * = $0200 9 | 10 | 11 | ; ON ENTRY: 12 | ; $70, $71 => multiplier 13 | ; $72, $73 => preload (if using; gets added to product) 14 | ; $74, $75 => multiplicand 15 | ; 16 | ; ON EXIT: 17 | ; $70, $71, $72, $73 => product 18 | ; $74, $75 => unchanged 19 | ; Y = 0 20 | ; Carry flag is unaltered from entry 21 | ; Everything else is undefined 22 | 23 | mult16 24 | lda #0 ; Not using preload, so zero it out 25 | sta $73 26 | sta $72 27 | mult16_preload 28 | ldy #17 ; One more than we need, because of the DEY 29 | bne mult16_3 ; Always branches 30 | mult16_1 31 | bcc mult16_2 ; Skip addition if we shifted out 0 32 | clc ; Add multiplicand to high word of the product 33 | lda $72 34 | adc $74 35 | sta $72 36 | lda $73 37 | adc $75 38 | sta $73 39 | mult16_2 ; Shift product right 40 | ror $73 41 | ror $72 42 | mult16_3 ; Shift low bytes of product right 43 | ror $71 ; (this initially contained multiplier) 44 | ror $70 ; LSB (from shifted multiplier) is now in C 45 | dey 46 | bne mult16_1 ; Go around again if we need to 47 | rts 48 | -------------------------------------------------------------------------------- /tests/mult70.c: -------------------------------------------------------------------------------- 1 | // mult70.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | // set high bytes of addresses of table 2 12 | // normally done by calling mul_init once 13 | memory[2] = input & 255UL; 14 | memory[3] = (input / 256UL) & 255UL; 15 | } 16 | 17 | // ************************************************************************************** 18 | uint64_t test_post(thread_context_t* threadContext) { 19 | zuint8* memory = threadContext->machine.context; 20 | 21 | uint64_t low = memory[4]; 22 | uint64_t high = memory[5]; 23 | 24 | return low + 256*high; 25 | } 26 | 27 | // ************************************************************************************** 28 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 29 | uint64_t a = input & 255UL; 30 | uint64_t b = (input / 256UL) & 255UL; 31 | 32 | uint64_t e = a*b; 33 | *expected = e; 34 | 35 | return actual_result == e; 36 | } 37 | 38 | // ************************************************************************************** 39 | void test_cleanup() 40 | { 41 | } 42 | -------------------------------------------------------------------------------- /tests/mult71.c: -------------------------------------------------------------------------------- 1 | // mult70.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | // set high bytes of addresses of table 2 12 | // normally done by calling mul_init once 13 | memory[2] = input & 255UL; 14 | memory[3] = (input / 256UL) & 255UL; 15 | } 16 | 17 | // ************************************************************************************** 18 | uint64_t test_post(thread_context_t* threadContext) { 19 | zuint8* memory = threadContext->machine.context; 20 | 21 | uint64_t low = memory[4]; 22 | uint64_t high = memory[5]; 23 | 24 | return low + 256*high; 25 | } 26 | 27 | // ************************************************************************************** 28 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 29 | uint64_t a = input & 255UL; 30 | uint64_t b = (input / 256UL) & 255UL; 31 | 32 | uint64_t e = a*b; 33 | *expected = e; 34 | 35 | return actual_result == e; 36 | } 37 | 38 | // ************************************************************************************** 39 | void test_cleanup() 40 | { 41 | } 42 | -------------------------------------------------------------------------------- /tests/omult24.a: -------------------------------------------------------------------------------- 1 | ; omult24.a 2 | ; from codebase64: https://www.codebase64.org/doku.php?id=base:24bit_multiplication_24bit_product 3 | ; 4 | ; 24 bit x 24 bit unsigned multiply, 24 bit result 5 | ; Average cycles: 1356.94 6 | ; 61 bytes 7 | 8 | 9 | factor1 = $02 ; 3 bytes 10 | factor2 = $05 ; 3 bytes 11 | product = $08 ; 3 bytes 12 | 13 | * = $0200 14 | 15 | unsigned_mul24 16 | lda #0 ; set product to zero 17 | sta product 18 | sta product+1 19 | sta product+2 20 | 21 | loop 22 | lda factor2 ; while factor2 != 0 23 | beq test_zero ; OPTIMISATION: faster check for zero 24 | continue 25 | ;and #$01 26 | ;beq skip 27 | lsr ; OPTIMISATION: saves a byte over original 'and #$01; beq skip;' 28 | bcc skip ; 29 | 30 | lda factor1 ; product += factor1 31 | clc 32 | adc product 33 | sta product 34 | 35 | lda factor1+1 36 | adc product+1 37 | sta product+1 38 | 39 | lda factor1+2 40 | adc product+2 41 | sta product+2 ; end if 42 | 43 | skip 44 | asl factor1 ; << factor1 45 | rol factor1+1 46 | rol factor1+2 47 | lsr factor2+2 ; >> factor2 48 | ror factor2+1 49 | ror factor2 50 | 51 | jmp loop ; end while 52 | 53 | test_zero 54 | lda factor2+1 55 | ora factor2+2 56 | bne nz 57 | rts 58 | nz 59 | lda factor2 60 | jmp continue 61 | -------------------------------------------------------------------------------- /tests/mult30.a: -------------------------------------------------------------------------------- 1 | ; mult30.a 2 | ; 'tepples unrolled' from https://www.nesdev.org/wiki/8-bit_Multiply 3 | ; adjusted to not need to treat zero as a special case and decrement factor2, 4 | ; helping both average cycles and bytes used. 5 | ; 6 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 7 | ; Average cycles: 111.62 8 | ; 70 bytes 9 | 10 | 11 | prodlo = $02 12 | factor2 = $03 13 | 14 | * = $0200 15 | 16 | ; *************************************************************************************** 17 | ; On Entry: 18 | ; A: multiplier 19 | ; Y: multiplicand 20 | ; On Exit: 21 | ; A: low byte of product 22 | ; Y: high byte of product 23 | mult 24 | lsr 25 | sta prodlo 26 | sty factor2 27 | lda #0 28 | 29 | bcc + 30 | clc 31 | adc factor2 32 | + 33 | ror 34 | ror prodlo 35 | bcc + 36 | clc 37 | adc factor2 38 | + 39 | ror 40 | ror prodlo 41 | bcc + 42 | clc 43 | adc factor2 44 | + 45 | ror 46 | ror prodlo 47 | bcc + 48 | clc 49 | adc factor2 50 | + 51 | ror 52 | ror prodlo 53 | bcc + 54 | clc 55 | adc factor2 56 | + 57 | ror 58 | ror prodlo 59 | bcc + 60 | clc 61 | adc factor2 62 | + 63 | ror 64 | ror prodlo 65 | bcc + 66 | clc 67 | adc factor2 68 | + 69 | ror 70 | ror prodlo 71 | bcc + 72 | clc 73 | adc factor2 74 | + 75 | ror 76 | tay 77 | lda prodlo 78 | ror 79 | rts 80 | -------------------------------------------------------------------------------- /tests/mult37.a: -------------------------------------------------------------------------------- 1 | ; mult37.a 2 | ; from Andrew Blance: https://codeburst.io/lets-write-some-harder-assembly-language-code-c7860dcceba 3 | ; 4 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 5 | ; Average cycles: 278.00 6 | ; 35 bytes 7 | 8 | mpr = $02 9 | mpd = $03 10 | result = $04 11 | tmp = $06 12 | 13 | * = $200 14 | 15 | ; *************************************************************************************** 16 | ; On Entry: 17 | ; mpr: multiplier 18 | ; mpd: multiplicand 19 | ; On Exit: 20 | ; result: product (2 bytes) 21 | start 22 | lda #0 ; zero accumulator 23 | sta tmp ; clear address 24 | sta result ; clear 25 | sta result+1 ; clear 26 | ldx #8 ; x is a counter 27 | mult 28 | lsr mpr ; shift mpr right - pushing a bit into C 29 | bcc noadd ; test carry bit 30 | lda result ; load A with low part of result 31 | clc 32 | adc mpd ; add mpd to res 33 | sta result ; save result 34 | lda result+1 ; add rest off shifted mpd 35 | adc tmp 36 | sta result+1 37 | noadd 38 | asl mpd ; shift mpd left, ready for next "loop" 39 | rol tmp ; save bit from mpd into temp 40 | dex ; decrement counter 41 | bne mult ; go again if counter 0 42 | rts 43 | -------------------------------------------------------------------------------- /tests/mult68.c: -------------------------------------------------------------------------------- 1 | // mult68.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | // set high bytes of addresses of table 2 12 | // normally done by calling mul_init once 13 | memory[2] = input & 255UL; 14 | memory[3] = (input / 256UL) & 255UL; 15 | } 16 | 17 | // ************************************************************************************** 18 | uint64_t test_post(thread_context_t* threadContext) { 19 | zuint8* memory = threadContext->machine.context; 20 | 21 | uint64_t low = memory[4]; 22 | uint64_t high = threadContext->machine.state.a; 23 | 24 | return low + 256*high; 25 | } 26 | 27 | // ************************************************************************************** 28 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 29 | uint64_t a = input & 255UL; 30 | uint64_t b = (input / 256UL) & 255UL; 31 | 32 | uint64_t e = a*b; 33 | *expected = e; 34 | 35 | return actual_result == e; 36 | } 37 | 38 | // ************************************************************************************** 39 | void test_cleanup() 40 | { 41 | } 42 | -------------------------------------------------------------------------------- /tests/omult1.c: -------------------------------------------------------------------------------- 1 | // omult1.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL * 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[4] = input & 255UL; 12 | memory[5] = (input / 256UL) & 255UL; 13 | memory[2] = (input/65536UL) & 255UL; 14 | memory[3] = (input/65536UL) / 256UL; 15 | } 16 | 17 | // ************************************************************************************** 18 | uint64_t test_post(thread_context_t* threadContext) { 19 | zuint8* memory = threadContext->machine.context; 20 | 21 | uint64_t a = threadContext->machine.state.y; 22 | uint64_t b = threadContext->machine.state.x; 23 | 24 | return a + 256UL*b; 25 | } 26 | 27 | // ************************************************************************************** 28 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 29 | uint64_t x = input & 65535UL; 30 | uint64_t y = input / 65536UL; 31 | 32 | uint64_t e = (x * y) & 0xffff; 33 | *expected = e; 34 | 35 | return actual_result == e; 36 | } 37 | 38 | 39 | // ************************************************************************************** 40 | void test_cleanup() 41 | { 42 | } 43 | -------------------------------------------------------------------------------- /tests/omult17.c: -------------------------------------------------------------------------------- 1 | // omult17.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 256UL * 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | threadContext->machine.state.a = (input / 65536UL) & 255UL; 14 | } 15 | 16 | // ************************************************************************************** 17 | uint64_t test_post(thread_context_t* threadContext) { 18 | zuint8* memory = threadContext->machine.context; 19 | 20 | uint64_t low = memory[5]; 21 | uint64_t high = memory[4]; 22 | 23 | return low + 256*high; 24 | } 25 | 26 | // ************************************************************************************** 27 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 28 | uint64_t a = input & 255UL; 29 | uint64_t b = (input / 256UL) & 255UL; 30 | uint64_t c = (input / 65536UL) & 255UL; 31 | 32 | uint64_t e = ((256*a+b) * c) & 65535; 33 | *expected = e; 34 | 35 | return actual_result == e; 36 | } 37 | 38 | // ************************************************************************************** 39 | void test_cleanup() 40 | { 41 | } 42 | -------------------------------------------------------------------------------- /tests/mult12.a: -------------------------------------------------------------------------------- 1 | ; mult12.a 2 | ; from codebase64 by djmips: https://www.codebase64.org/doku.php?id=base:8bit_multiplication_16bit_product_fast_no_tables 3 | ; slightly tweaked 4 | ; 5 | ; 8 bit x 8 bit unsigned multiply, 16 bit result 6 | ; Average cycles: 108.64 7 | ; 71 bytes 8 | 9 | 10 | mul1 = $02 11 | mul2 = $03 12 | 13 | * = $0200 14 | 15 | ; mul 8x8 16 bit result for when you can't afford big tables 16 | ; by djmips 17 | ; 18 | ; inputs are mul1 and X. mul1 and mul2 should be zp locations 19 | ; output is 16 bit in A (high byte) and mul1 (low byte) 20 | ; 21 | ; inner loop credits Damon Slye CALL APPLE, JUNE 1983, P45-48. 22 | 23 | mult 24 | lda #0 ; 'A should be zero entering' 25 | cpx #0 26 | beq zro 27 | dex ; decrement mul2 because we will be adding with carry set for speed (an extra one) 28 | stx mul2 29 | lsr mul1 30 | bcc b1 31 | adc mul2 32 | ror 33 | b1 34 | ror mul1 35 | bcc b2 36 | adc mul2 37 | b2 38 | ror 39 | ror mul1 40 | bcc b3 41 | adc mul2 42 | b3 43 | ror 44 | ror mul1 45 | bcc b4 46 | adc mul2 47 | b4 48 | ror 49 | ror mul1 50 | bcc b5 51 | adc mul2 52 | b5 53 | ror 54 | ror mul1 55 | bcc b6 56 | adc mul2 57 | b6 58 | ror 59 | ror mul1 60 | bcc b7 61 | adc mul2 62 | b7 63 | ror 64 | ror mul1 65 | bcc b8 66 | adc mul2 67 | b8 68 | ror 69 | ror mul1 70 | ; inc mul2 71 | rts 72 | 73 | zro 74 | stx mul1 75 | rts 76 | -------------------------------------------------------------------------------- /tests/mult1.c: -------------------------------------------------------------------------------- 1 | // mult1.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL * 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | memory[4] = (input/65536UL) & 255UL; 14 | memory[5] = (input/65536UL) / 256UL; 15 | } 16 | 17 | // ************************************************************************************** 18 | uint64_t test_post(thread_context_t* threadContext) { 19 | zuint8* memory = threadContext->machine.context; 20 | 21 | uint64_t a = memory[6]; 22 | uint64_t b = memory[7]; 23 | uint64_t c = memory[8]; 24 | uint64_t d = memory[9]; 25 | 26 | return a + 256UL*(b + 256UL*(c + 256UL*d)); 27 | } 28 | 29 | // ************************************************************************************** 30 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 31 | uint64_t x = input & 65535UL; 32 | uint64_t y = input / 65536UL; 33 | uint64_t e = x * y; 34 | *expected = e; 35 | 36 | return actual_result == e; 37 | } 38 | 39 | 40 | // ************************************************************************************** 41 | void test_cleanup() 42 | { 43 | } 44 | -------------------------------------------------------------------------------- /tests/mult2.c: -------------------------------------------------------------------------------- 1 | // mult2.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL * 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[4] = input & 255UL; 12 | memory[5] = (input / 256UL) & 255UL; 13 | memory[2] = (input/65536UL) & 255UL; 14 | memory[3] = (input/65536UL) / 256UL; 15 | } 16 | 17 | // ************************************************************************************** 18 | uint64_t test_post(thread_context_t* threadContext) { 19 | zuint8* memory = threadContext->machine.context; 20 | 21 | uint64_t a = memory[4]; 22 | uint64_t b = memory[5]; 23 | uint64_t c = memory[6]; 24 | uint64_t d = memory[7]; 25 | 26 | return a + 256UL*(b + 256UL*(c + 256UL*d)); 27 | } 28 | 29 | // ************************************************************************************** 30 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 31 | uint64_t x = input & 65535UL; 32 | uint64_t y = input / 65536UL; 33 | uint64_t e = x * y; 34 | *expected = e; 35 | 36 | return actual_result == e; 37 | } 38 | 39 | 40 | // ************************************************************************************** 41 | void test_cleanup() 42 | { 43 | } 44 | -------------------------------------------------------------------------------- /tests/mult3.c: -------------------------------------------------------------------------------- 1 | // mult3.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL * 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[4] = input & 255UL; 12 | memory[5] = (input / 256UL) & 255UL; 13 | memory[2] = (input/65536UL) & 255UL; 14 | memory[3] = (input/65536UL) / 256UL; 15 | } 16 | 17 | // ************************************************************************************** 18 | uint64_t test_post(thread_context_t* threadContext) { 19 | zuint8* memory = threadContext->machine.context; 20 | 21 | uint64_t a = memory[6]; 22 | uint64_t b = memory[7]; 23 | uint64_t c = memory[8]; 24 | uint64_t d = memory[9]; 25 | 26 | return a + 256UL*(b + 256UL*(c + 256UL*d)); 27 | } 28 | 29 | // ************************************************************************************** 30 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 31 | uint64_t x = input & 65535UL; 32 | uint64_t y = input / 65536UL; 33 | uint64_t e = x * y; 34 | *expected = e; 35 | 36 | return actual_result == e; 37 | } 38 | 39 | 40 | // ************************************************************************************** 41 | void test_cleanup() 42 | { 43 | } 44 | -------------------------------------------------------------------------------- /tests/mult4.c: -------------------------------------------------------------------------------- 1 | // mult4.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL * 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[4] = input & 255UL; 12 | memory[5] = (input / 256UL) & 255UL; 13 | memory[2] = (input/65536UL) & 255UL; 14 | memory[3] = (input/65536UL) / 256UL; 15 | } 16 | 17 | // ************************************************************************************** 18 | uint64_t test_post(thread_context_t* threadContext) { 19 | zuint8* memory = threadContext->machine.context; 20 | 21 | uint64_t a = memory[6]; 22 | uint64_t b = memory[7]; 23 | uint64_t c = memory[8]; 24 | uint64_t d = memory[9]; 25 | 26 | return a + 256UL*(b + 256UL*(c + 256UL*d)); 27 | } 28 | 29 | // ************************************************************************************** 30 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 31 | uint64_t x = input & 65535UL; 32 | uint64_t y = input / 65536UL; 33 | uint64_t e = x * y; 34 | *expected = e; 35 | 36 | return actual_result == e; 37 | } 38 | 39 | 40 | // ************************************************************************************** 41 | void test_cleanup() 42 | { 43 | } 44 | -------------------------------------------------------------------------------- /tests/mult41.c: -------------------------------------------------------------------------------- 1 | // mult41.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL * 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[4] = input & 255UL; 12 | memory[5] = (input / 256UL) & 255UL; 13 | memory[2] = (input/65536UL) & 255UL; 14 | memory[3] = (input/65536UL) / 256UL; 15 | } 16 | 17 | // ************************************************************************************** 18 | uint64_t test_post(thread_context_t* threadContext) { 19 | zuint8* memory = threadContext->machine.context; 20 | 21 | uint64_t a = memory[6]; 22 | uint64_t b = memory[7]; 23 | uint64_t c = memory[8]; 24 | uint64_t d = memory[9]; 25 | 26 | return a + 256UL*(b + 256UL*(c + 256UL*d)); 27 | } 28 | 29 | // ************************************************************************************** 30 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 31 | uint64_t x = input & 65535UL; 32 | uint64_t y = input / 65536UL; 33 | uint64_t e = x * y; 34 | *expected = e; 35 | 36 | return actual_result == e; 37 | } 38 | 39 | 40 | // ************************************************************************************** 41 | void test_cleanup() 42 | { 43 | } 44 | -------------------------------------------------------------------------------- /tests/mult42.c: -------------------------------------------------------------------------------- 1 | // mult42.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL * 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[4] = input & 255UL; 12 | memory[5] = (input / 256UL) & 255UL; 13 | memory[2] = (input/65536UL) & 255UL; 14 | memory[3] = (input/65536UL) / 256UL; 15 | } 16 | 17 | // ************************************************************************************** 18 | uint64_t test_post(thread_context_t* threadContext) { 19 | zuint8* memory = threadContext->machine.context; 20 | 21 | uint64_t a = memory[6]; 22 | uint64_t b = memory[7]; 23 | uint64_t c = memory[8]; 24 | uint64_t d = memory[9]; 25 | 26 | return a + 256UL*(b + 256UL*(c + 256UL*d)); 27 | } 28 | 29 | // ************************************************************************************** 30 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 31 | uint64_t x = input & 65535UL; 32 | uint64_t y = input / 65536UL; 33 | uint64_t e = x * y; 34 | *expected = e; 35 | 36 | return actual_result == e; 37 | } 38 | 39 | 40 | // ************************************************************************************** 41 | void test_cleanup() 42 | { 43 | } 44 | -------------------------------------------------------------------------------- /tests/mult45.c: -------------------------------------------------------------------------------- 1 | // mult45.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL * 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | memory[6] = (input/65536UL) & 255UL; 14 | memory[7] = (input/65536UL) / 256UL; 15 | } 16 | 17 | // ************************************************************************************** 18 | uint64_t test_post(thread_context_t* threadContext) { 19 | zuint8* memory = threadContext->machine.context; 20 | 21 | uint64_t a = memory[2]; 22 | uint64_t b = memory[3]; 23 | uint64_t c = memory[4]; 24 | uint64_t d = memory[5]; 25 | 26 | return a + 256UL*(b + 256UL*(c + 256UL*d)); 27 | } 28 | 29 | // ************************************************************************************** 30 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 31 | uint64_t x = input & 65535UL; 32 | uint64_t y = input / 65536UL; 33 | uint64_t e = x * y; 34 | *expected = e; 35 | 36 | return actual_result == e; 37 | } 38 | 39 | 40 | // ************************************************************************************** 41 | void test_cleanup() 42 | { 43 | } 44 | -------------------------------------------------------------------------------- /tests/mult46.c: -------------------------------------------------------------------------------- 1 | // mult46.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL * 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[2] = input & 255UL; 12 | memory[3] = (input / 256UL) & 255UL; 13 | memory[6] = (input/65536UL) & 255UL; 14 | memory[7] = (input/65536UL) / 256UL; 15 | } 16 | 17 | // ************************************************************************************** 18 | uint64_t test_post(thread_context_t* threadContext) { 19 | zuint8* memory = threadContext->machine.context; 20 | 21 | uint64_t a = memory[2]; 22 | uint64_t b = memory[3]; 23 | uint64_t c = memory[4]; 24 | uint64_t d = memory[5]; 25 | 26 | return a + 256UL*(b + 256UL*(c + 256UL*d)); 27 | } 28 | 29 | // ************************************************************************************** 30 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 31 | uint64_t x = input & 65535UL; 32 | uint64_t y = input / 65536UL; 33 | uint64_t e = x * y; 34 | *expected = e; 35 | 36 | return actual_result == e; 37 | } 38 | 39 | 40 | // ************************************************************************************** 41 | void test_cleanup() 42 | { 43 | } 44 | -------------------------------------------------------------------------------- /tests/mult50.c: -------------------------------------------------------------------------------- 1 | // mult50.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL * 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[4] = input & 255UL; 12 | memory[5] = (input / 256UL) & 255UL; 13 | memory[2] = (input/65536UL) & 255UL; 14 | memory[3] = (input/65536UL) / 256UL; 15 | } 16 | 17 | // ************************************************************************************** 18 | uint64_t test_post(thread_context_t* threadContext) { 19 | zuint8* memory = threadContext->machine.context; 20 | 21 | uint64_t a = memory[4]; 22 | uint64_t b = memory[5]; 23 | uint64_t c = memory[6]; 24 | uint64_t d = memory[7]; 25 | 26 | return a + 256UL*(b + 256UL*(c + 256UL*d)); 27 | } 28 | 29 | // ************************************************************************************** 30 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 31 | uint64_t x = input & 65535UL; 32 | uint64_t y = input / 65536UL; 33 | uint64_t e = x * y; 34 | *expected = e; 35 | 36 | return actual_result == e; 37 | } 38 | 39 | 40 | // ************************************************************************************** 41 | void test_cleanup() 42 | { 43 | } 44 | -------------------------------------------------------------------------------- /tests/mult51.c: -------------------------------------------------------------------------------- 1 | // mult51.c 2 | 3 | // specify range of input values 4 | static const uint64_t INPUT_START = 0UL; 5 | static const uint64_t INPUT_END = 65536UL * 65536UL; 6 | 7 | // ************************************************************************************** 8 | void test_pre(thread_context_t* threadContext, uint64_t input) { 9 | zuint8* memory = threadContext->machine.context; 10 | 11 | memory[4] = input & 255UL; 12 | memory[5] = (input / 256UL) & 255UL; 13 | memory[2] = (input/65536UL) & 255UL; 14 | memory[3] = (input/65536UL) / 256UL; 15 | } 16 | 17 | // ************************************************************************************** 18 | uint64_t test_post(thread_context_t* threadContext) { 19 | zuint8* memory = threadContext->machine.context; 20 | 21 | uint64_t a = memory[4]; 22 | uint64_t b = memory[5]; 23 | uint64_t c = memory[6]; 24 | uint64_t d = memory[7]; 25 | 26 | return a + 256UL*(b + 256UL*(c + 256UL*d)); 27 | } 28 | 29 | // ************************************************************************************** 30 | int is_correct(thread_context_t* threadContext, uint64_t input, uint64_t actual_result, uint64_t* expected) { 31 | uint64_t x = input & 65535UL; 32 | uint64_t y = input / 65536UL; 33 | uint64_t e = x * y; 34 | *expected = e; 35 | 36 | return actual_result == e; 37 | } 38 | 39 | 40 | // ************************************************************************************** 41 | void test_cleanup() 42 | { 43 | } 44 | --------------------------------------------------------------------------------