PAGE 01 DAI FIRMWARE 1E22B-1E413 V1.1 002 ORG :E22B 003 * 004 * 005 * 006 ******************** 007 * INTEGER DIVISION * 008 ******************** 009 * 010 * Signed 32-bit fixed point division: 011 * MACC = MACC / MEM. 012 * 013 * Entry: HL: Points to divisor. 014 * Exit: All registers preserved. 015 * 016 E22B F5 XIDIV PUSH PSW 017 E22C C5 PUSH B 018 E22D D5 PUSH D 019 E22E E5 PUSH H 020 E22F CD42E2 CALL :E242 Signed division 021 E232 CDCFE3 CALL :E3CF Quotient into MACC 022 E235 C34DC1 JMP :C14D Popall, ret 023 * 024 ************************ 025 * INT DIVIDE REMAINDER * 026 ************************ 027 * 028 * For INT values: MACC = Remainder of (MACC / MEM). 029 * 030 * Entry: HL: Points to divisor. 031 * Exit: All registers preserved. 032 * 033 E238 F5 XIREM PUSH PSW 034 E239 C5 PUSH B 035 E23A D5 PUSH D 036 E23B E5 PUSH H 037 E23C CD42E2 CALL :E242 Signed division; 038 Remainder in MACC 039 E23F C34DC1 JMP :C14D Popall, ret 040 * 041 *************************** 042 * SIGNED INTEGER DIVISION * 043 *************************** 044 * 045 * Divides MACC / MEM; quotient is left in registers 046 * B,C,D,E and the remainder in MACC. 047 * 048 * Entry: HL: Points to divisor. 049 * MACC: Dividend. 050 * Exit: BCDE: Quotient; remainder in MACC. 051 * S-flag: Set for result. 052 * AHL: Corrupted, CY=0. 053 * 054 E242 CD8FED L1E24 CALL :ED8F Get signbyte dividend in A, 055 compare it with sign divisor 056 E245 78 MOV A,B Get signbyte dividend 057 E246 F5 PUSH PSW Save result compare 058 E247 CD0EEA CALL :EA0E Copy divisor into BCDE 059 E24A 78 MOV A,B ) 060 E24B B1 ORA C ) Check if divisor = 0 061 E24C B2 ORA D ) 062 E24D B3 ORA E ) 063 E24E CAE4E2 JZ :E2E4 Then error 'divide by zero' PAGE 02 DAI FIRMWARE 1E22B-1E413 V1.1 064 E251 78 MOV A,B Get signbyte divisor 065 E252 B7 ORA A Is it negative ? 066 E253 FCC9E3 CM :E3C9 Then negate divisor 067 E256 DAE4E2 JC :E2E4 Error exit if overflow 068 E259 C5 PUSH B ) Save divisor on stack 069 E25A D5 PUSH D ) 070 E25B CDECE2 CALL :E2EC Normalize divisor 071 E25E 2F CMA ) H = pos. value of nr of 072 E25F 3C INR A ) times shifted for norma- 073 E260 67 MOV H,A ) lisation 074 E261 3AD500 LDA :00D5 Get signbyte dividend 075 E264 B7 ORA A Is dividend negative ? 076 E265 FC15E3 CM :E315 Then change sign dividend 077 E268 CDD6E3 CALL :E3D6 Copy dividend in reg BCDE 078 E26B B1 ORA C ) 079 E26C B2 ORA D ) Check if dividend zero 080 E26D B3 ORA E ) 081 E26E CAE0E2 JZ :E2E0 Then abort, leaving 0000 in 082 MACC and reg BCDE 083 E271 CDECE2 CALL :E2EC Normalize dividend; nrs of 084 shifts in A 085 E274 D1 POP D ) Restore divisor in BCDE 086 E275 C1 POP B ) 087 E276 84 ADD H Add nr of shifts for divisor 088 H is total nrs of shifts 089 E277 FAC9E2 JM :E2C9 If resulting nrs of shifts 090 < 0 then result = 0000 091 E27A CD39EB CALL :EB39 Shift divisor left (A) times 092 E27D D5 PUSH D ) Save shifted divisor on 093 E27E C5 PUSH B ) stack 094 E27F 010080 LXI B,:8000 Init BCDE for max neg number 095 E282 110000 LXI D,:0000 096 E285 CD55EB CALL :EB55 Shift BCDE right (A) times 097 E288 60 MOV H,B ) Shifted BC in HL 098 E289 69 MOV L,C ) 099 E28A C1 POP B Get hibytes shifted divisor 100 E28B E3 XTHL HL: lobytes shifted divisor; 101 shifted BC on stack 102 E28C EB XCHG DE: lobytes shifted divisor; 103 HL: shifted DE 104 E28D E5 PUSH H Shifted DE on stack 105 E28E 2AD700 L1E25 LHLD :00D7 Get lobytes dividend 106 E291 7C MOV A,H ) 107 E292 93 SUB E ) 108 E293 67 MOV H,A ) (00D7/8)=(00D7/8)-lobytes 109 E294 7D MOV A,L ) shifted divisor 110 E295 9A SBB D ) 111 E296 6F MOV L,A ) 112 E297 22D700 SHLD :00D7 ) 113 E29A 2AD500 LHLD :00D5 Get hibytes dividend 114 E29D 7C MOV A,H ) 115 E29E 99 SBB C ) 116 E29F 67 MOV H,A ) (00D5/6)=(00D5/6)-hibytes 117 E2A0 7D MOV A,L ) shifted divisor 118 E2A1 98 SBB B ) 119 E2A2 6F MOV L,A ) 120 E2A3 22D500 SHLD :00D5 ) 121 E2A6 E1 L1E26 POP H Get shifted DE 122 E2A7 17 RAL 123 E2A8 3F CMC 124 E2A9 7D MOV A,L 125 E2AA 17 RAL PAGE 03 DAI FIRMWARE 1E22B-1E413 V1.1 126 E2AB 6F MOV L,A 127 E2AC 7C MOV A,H 128 E2AD 17 RAL 129 E2AE 67 MOV H,A 130 E2AF E3 XTHL Get shifted 'BC' in HL 131 E2B0 7D MOV A,L 132 E2B1 17 RAL 133 E2B2 6F MOV L,A 134 E2B3 7C MOV A,H 135 E2B4 17 RAL 136 E2B5 67 MOV H,A 137 E2B6 E3 XTHL New 'BC' back on stack 138 E2B7 DAD0E2 JC :E2D0 139 E2BA CD70EB CALL :EB70 Rotate BCDE right 1 bit 140 E2BD 7D MOV A,L 141 E2BE 1F RAR 142 E2BF E5 PUSH H New 'DE' back on stack 143 E2C0 DA8EE2 JC :E28E CY=1: again 144 E2C3 CDF2E2 CALL :E2F2 MACC = MACC + BCDE 145 E2C6 C3A6E2 JMP :E2A6 Again 146 147 * If resulting nr of shifts is negative: 148 149 E2C9 110000 L1E27 LXI D,:0000 150 E2CC D5 PUSH D 151 E2CD C3D7E2 JMP :E2D7 BCDE = 0000; abort 152 153 * If ready: 154 155 E2D0 7D L1E28 MOV A,L 156 E2D1 1F RAR 157 E2D2 E5 PUSH H 158 E2D3 D4F2E2 CNC :E2F2 CY=0: MACC = MACC + BCDE 159 E2D6 D1 POP D 160 E2D7 C1 L1E29 POP B 161 E2D8 F1 POP PSW Get result sign compare 162 E2D9 CD88ED CALL :ED88 Evt negate BCDE 163 E2DC FC15E3 CM :E315 Evt change sign MACC 164 E2DF C9 RET 165 166 * If dividend is zero: 167 168 E2E0 E1 L1E30 POP H ) Save BCDE = 0000 169 E2E1 E1 POP H ) 170 E2E2 F1 POP PSW 171 E2E3 C9 RET 172 173 * If errors: 174 175 E2E4 DC4BC0 L1E31 CC :C04B CY=1: Run overflow error 176 E2E7 CC6CC0 CZ :C06C Z=1: Run divide by 0 error 177 E2EA F1 POP PSW 178 E2EB C9 RET 179 * 180 ********************************************* 181 * INT: NORMALIZE CONTENTS REGISTERS B,C,D,E * 182 ********************************************* 183 * 184 * Exit: HL preserved. 185 * 186 E2EC E5 L1E32 PUSH H 187 E2ED CDA0EB CALL :EBA0 Normalize BCDE (INT) PAGE 04 DAI FIRMWARE 1E22B-1E413 V1.1 188 E2F0 E1 POP H 189 E2F1 C9 RET 190 * 191 ****************************************** 192 * ADD CONTENTS REGISTERS B,C,D,E TO MACC * 193 ****************************************** 194 * 195 * Exit: BCDE preserved, AHL corrupted. 196 * F set on hibyte of result. 197 * 198 E2F2 2AD700 L1E33 LHLD :00D7 ) 199 E2F5 7C MOV A,H ) 200 E2F6 83 ADD E ) Add DE to 00D7/8 201 E2F7 67 MOV H,A ) 202 E2F8 7D MOV A,L ) 203 E2F9 8A ADC D ) 204 E2FA 6F MOV L,A 205 E2FB 22D700 SHLD :00D7 206 E2FE 2AD500 LHLD :00D5 207 E301 7C MOV A,H ) 208 E302 89 ADC C ) 209 E303 67 MOV H,A ) Add BC to 00D5/6 210 E304 7D MOV A,L ) 211 E305 88 ADC B ) 212 E306 6F MOV L,A ) 213 E307 22D500 SHLD :00D5 214 E30A C9 RET 215 * 216 *********** 217 * INT ABS * 218 *********** 219 * 220 * For INT values: MACC = absolute value of MACC. 221 * 222 * Exit: All registers preserved. 223 * 224 E30B F5 XIABS PUSH PSW 225 E30C 3AD500 LDA :00D5 Get sign byte 226 E30F B7 ORA A 227 E310 FC15E3 CM :E315 If <0: change sign 228 E313 F1 POP PSW 229 E314 C9 RET 230 * 231 ********************************** 232 * INT: CHANGE SIGN MACC CONTENTS * 233 ********************************** 234 * 235 * For INT values: MACC = - MACC. 236 * 237 * Exit: All registers preserved. 238 * 239 E315 F5 XICHS PUSH PSW 240 E316 C5 PUSH B 241 E317 D5 PUSH D 242 E318 E5 PUSH H 243 E319 CDD6E3 CALL :E3D6 Copy MACC into reg BCDE 244 E31C CDC9E3 CALL :E3C9 Negate BCDE 245 E31F D228E3 JNC :E328 Jump if no error 246 247 * If overflow error: 248 249 E322 CD4BC0 L1E36 CALL :C04B Run overflow error PAGE 05 DAI FIRMWARE 1E22B-1E413 V1.1 250 E325 C34DC1 JMP :C14D Popall, ret 251 252 * If O.K.: 253 254 E328 CDCFE3 L1E37 CALL :E3CF Copy reg BCDE into MACC 255 E32B C34DC1 JMP :C14D Popall, ret 256 * 257 ******** 258 * IAND * 259 ******** 260 * 261 * Logical 'AND': MACC = MACC IAND MEM. 262 * 263 * Entry: HL points to operand in memory. 264 * Exit: All registers preserved. 265 * 266 E32E F5 XIAND PUSH PSW 267 E32F C5 PUSH B 268 E330 D5 PUSH D 269 E331 E5 PUSH H 270 E332 C3E1EC JMP :ECE1 Prepare IAND and perform 271 * 272 **************** 273 * PERFORM IAND * 274 **************** 275 * 276 * Performs: MEM IAND EBCA, result in ABCD. 277 * 278 * Entry: HL points to last byte of MEM. 279 * Fixed point number in EBCA. 280 * Exit: HL points to 1st byte of MEM. 281 * E preserved. 282 * 283 E335 A6 SIAND ANA M 284 E336 57 MOV D,A 285 E337 2B DCX H 286 E338 79 MOV A,C 287 E339 A6 ANA M 288 E33A 4F MOV C,A 289 E33B 2B DCX H 290 E33C 78 MOV A,B 291 E33D A6 ANA M 292 E33E 47 MOV B,A 293 E33F 2B DCX H 294 E340 7B MOV A,E 295 E341 A6 ANA M 296 E342 C9 RET 297 * 298 E343 85E3 L1E40 DBL :E385 (not used) 299 * 300 ******* 301 * IOR * 302 ******* 303 * 304 * Logical 'OR': MACC = MACC IOR MEM. 305 * 306 * Entry: HL points to operand in memory. 307 * Exit: All registers preserved. 308 * 309 E345 F5 XIOR PUSH PSW 310 E346 C5 PUSH B 311 E347 D5 PUSH D PAGE 06 DAI FIRMWARE 1E22B-1E413 V1.1 312 E348 E5 PUSH H 313 E349 C3EAEC JMP :ECEA Prepare IOR and perform 314 * 315 *************** 316 * PERFORM IOR * 317 *************** 318 * 319 * Performs MEM IOR EBCA. Result in ABCD. 320 * 321 * Entry: HL points to last byte of MEM. 322 * Fixed point nr in EBCA. 323 * Exit: HL points to 1st byte of MEM. 324 * E preserved. 325 * 326 E34C B6 SIOR ORA M 327 E34D 57 MOV D,A 328 E34E 2B DCX H 329 E34F 79 MOV A,C 330 E350 B6 ORA M 331 E351 4F MOV C,A 332 E352 2B DCX H 333 E353 78 MOV A,B 334 E354 B6 ORA M 335 E355 47 MOV B,A 336 E356 2B DCX H 337 E357 7B MOV A,E 338 E358 B6 ORA M 339 E359 C9 RET 340 * 341 E35A 85E3 L1E43 DBL :E385 (not used) 342 * 343 ******** 344 * IXOR * 345 ******** 346 * 347 * Logical 'XOR': MACC = MACC IXOR MEM. 348 * 349 * Entry: HL points to operand in memory. 350 * Exit: All registers preserved. 351 * 352 E35C F5 XIXOR PUSH PSW 353 E35D C5 PUSH B 354 E35E D5 PUSH D 355 E35F E5 PUSH H 356 E360 C3F3EC JMP :ECF3 Prepare IXOR and perform 357 * 358 **************** 359 * PERFORM IXOR * 360 **************** 361 * 362 * Performs MEM IXOR EBCA, result in ABCD. 363 * 364 * Entry: HL points last byte of MEM. 365 * Fixed point number in EBCA. 366 * Exit: HL points to 1st byte of MEM. 367 * E preserved. 368 * 369 E363 AE SIXOR XRA M 370 E364 57 MOV D,A 371 E365 2B DCX H 372 E366 79 MOV A,C 373 E367 AE XRA M PAGE 07 DAI FIRMWARE 1E22B-1E413 V1.1 374 E368 4F MOV C,A 375 E369 2B DCX H 376 E36A 78 MOV A,B 377 E36B AE XRA M 378 E36C 47 MOV B,A 379 E36D 2B DCX H 380 E36E 7B MOV A,E 381 E36F AE XRA M 382 E370 C9 RET 383 * 384 E371 85E3 L1E46 DBL :E385 (not used) 385 * 386 ******** 387 * INOT * 388 ******** 389 * 390 * Logical 'INOT': MACC = INOT (MACC). 391 * 392 * Exit: All registers preserved. 393 * 394 E373 F5 XINOT PUSH PSW 395 E374 C5 PUSH B 396 E375 D5 PUSH D 397 E376 E5 PUSH H 398 E377 CDFCEC CALL :ECFC Copy MACC into ABCD; CMA 399 E37A 5F MOV E,A Save hibyte 400 E37B 7A MOV A,D 401 E37C 2F CMA INOT D 402 E37D 57 MOV D,A 403 E37E 79 MOV A,C 404 E37F 2F CMA INOT C 405 E380 4F MOV C,A 406 E381 78 MOV A,B 407 E382 2F CMA INOT B 408 E383 47 MOV B,A 409 E384 7B L1E48 MOV A,E Get back hibyte 410 E385 CD26E1 L1E49 CALL :E126 Copy ABCD into MACC 411 E388 C34DC1 JMP :C14D Popall, ret 412 * 413 E38B C9 L1E50 RET (not used) 414 * 415 *********************************** 416 * COPY MACC INTO REG. E,B,C,A * 417 * D = compl. 00D5 EXOR hibyte MEM * 418 *********************************** 419 * 420 * Entry: HL points to 1st byte MEM. 421 * Exit: HL points to last byte MEM. 422 * D = complement EXOR hibytes MACC and MEM. 423 * Msb D = 1: sign bits identical. 424 * Msb D = 0: sign bits different. 425 * 426 E38C C301ED L1E51 JMP :ED01 Copy MACC into ABCD, A in E; 427 jump to E38F 428 * 429 E38F AE L1E52 XRA M EXOR sign bytes 430 E390 2F CMA Complement result 431 E391 23 INX H 432 E392 23 INX H 433 E393 23 INX H 434 E394 D5 PUSH D 435 E395 57 MOV D,A A = compl EXOR signbytes PAGE 08 DAI FIRMWARE 1E22B-1E413 V1.1 436 E396 F1 POP PSW Get D in A 437 E397 C9 RET 438 * 439 ******* 440 * SHR * 441 ******* 442 * 443 * MACC = MACC SHR MEM. 444 * Shifts contents MACC right (MEM) places. 445 * 446 * Entry: HL points to operand in memory. 447 * Exit: All registers preserved. 448 * Result is 0 if MEM < 0 or > 31. 449 * 450 E398 F5 XSHR PUSH PSW 451 E399 C5 PUSH B 452 E39A D5 PUSH D 453 E39B E5 PUSH H 454 E39C CD08ED CALL :ED08 Check MEM. If <=31: 455 MACC into BCDE, shift in A 456 Else: clear ABCDE 457 E39F CD55EB CALL :EB55 Shift BCDE right A places 458 E3A2 C328E3 JMP :E328 BCDE into MACC; quit 459 * 460 ******* 461 * SHL * 462 ******* 463 * 464 * MACC = MACC SHL MEM. 465 * Shifts contents MACC left (MEM) places. 466 * 467 * Entry/exit: See XSHR. 468 * 469 E3A5 F5 XSHL PUSH PSW 470 E3A6 C5 PUSH B 471 E3A7 D5 PUSH D 472 E3A8 E5 PUSH H 473 E3A9 CD08ED CALL :ED08 Check MEM. If <= 31: MACC 474 into BCDE, shift in A 475 Else: clear ABCDE 476 E3AC CD39EB CALL :EB39 Shift BCDE left A places 477 E3AF C328E3 JMP :E328 BCDE into MACC; quit 478 * 479 ******************************* 480 * TEST VALUE OF AN INT NUMBER * 481 ******************************* 482 * 483 * Tests if an INT has a value between 0 and 31. 484 * If true: Number into A, else: Clear ABCDE. 485 * 486 * Entry: HL points to a 4-byte number. 487 * Exit: Nr <= #1F: Number in A. 488 * Nr > #1F: ABCDE cleared. 489 * HL points to 4th byte in memory. 490 * 491 E3B2 7E XSTST MOV A,M Get 1st byte 492 E3B3 23 INX H 493 E3B4 B6 ORA M OR with 2nd 494 E3B5 23 INX H 495 E3B6 B6 ORA M OR with 3rd 496 E3B7 23 INX H 497 E3B8 C2C2E3 JNZ :E3C2 Jump if highest bytes <>0 PAGE 09 DAI FIRMWARE 1E22B-1E413 V1.1 498 E3BB 7E MOV A,M Get 4th byte 499 E3BC E6E0 ANI :E0 Test 3 highest bits 500 E3BE 00 NOP 501 E3BF 00 NOP 502 E3C0 7E MOV A,M Get 4th byte in A 503 E3C1 C8 RZ Abort if 4th byte <= #1F 504 505 * If nr > #1F: 506 507 E3C2 3E00 L1E56 MVI A,:00 ) 508 E3C4 47 MOV B,A ) 509 E3C5 4F MOV C,A ) Clear ABCDE 510 E3C6 57 MOV D,A ) 511 E3C7 5F MOV E,A ) 512 E3C8 C9 RET 513 * 514 ****************************************** 515 * INT: NEGATE CONTENTS REGISTERS B,C,D,E * 516 ****************************************** 517 * 518 * Exit: HL preserved. 519 * CY=1: Overflow into msb. 520 * 521 E3C9 E5 L1E57 PUSH H 522 E3CA CD82EB CALL :EB82 Negate BCDE (INT) 523 E3CD E1 POP H 524 E3CE C9 RET 525 * 526 ************************************ 527 * COPY REGISTERS B,C,D,E INTO MACC * 528 ************************************ 529 * 530 * Entry: none. 531 * Exit: ABCD corrupted, FHL preserved. 532 * 533 E3CF 78 L1E58 MOV A,B 534 E3D0 41 MOV B,C 535 E3D1 4A MOV C,D 536 E3D2 53 MOV D,E 537 E3D3 C326E1 JMP :E126 Copy ABCD into MACC 538 * 539 ************************************ 540 * COPY MACC INTO REGISTERS B,C,D,E * 541 ************************************ 542 * 543 * Entry: None. 544 * Exit: AFHL preserved. 545 * 546 E3D6 F5 L1E59 PUSH PSW 547 E3D7 CD33E1 CALL :E133 Copy MACC into ABCD 548 E3DA C313ED JMP :ED13 Copy ABCD into BCDE 549 * 550 E3DD C9 L1E60 RET 551 * 552 ******************************* 553 * CHANGE CONTENTS MACC TO FPT * 554 ******************************* 555 * 556 * Result is incorrect if MACC = 80 00 00 00. 557 * Then exponent is 1 too high (E3FC should be 558 * a NOP instruction). 559 * PAGE 10 DAI FIRMWARE 1E22B-1E413 V1.1 560 * Entry: None. 561 * Exit: All registers preserved. 562 * 563 E3DE F5 XFLT PUSH PSW 564 E3DF C5 PUSH B 565 E3E0 D5 PUSH D 566 E3E1 E5 PUSH H 567 E3E2 CDD6E3 CALL :E3D6 Copy MACC into BCDE 568 E3E5 CD83ED CALL :ED83 Check if BCDE is 0. 569 E3E8 CA0EE4 JZ :E40E Then clear MACC + BCDE 570 E3EB 2620 MVI H,:20 Init exp.byte for pos.nr 571 E3ED 78 MOV A,B ) 572 E3EE B7 ORA A ) Check sign bit 573 E3EF F2FDE3 JP :E3FD Jump if nr is positive 574 575 * If INT nr is negative: 576 577 E3F2 26A0 MVI H,:A0 Init exp.byte for neg.nr 578 E3F4 CDC9E3 CALL :E3C9 Negate BCDE 579 E3F7 D2FDE3 JNC :E3FD Jump if no overflow 580 E3FA 0680 MVI B,:80 581 E3FC 24 INR H 582 583 * Convert to FPT: 584 585 E3FD 7C L1E62 MOV A,H Get init.exp.byte 586 E3FE 21D500 LXI H,:00D5 Addr MACC 587 E401 77 MOV M,A Init.exp.byte in MACC 588 E402 E5 PUSH H 589 E403 CD96EB CALL :EB96 Normalize BCDE 590 E406 E1 POP H 591 E407 7E MOV A,M Get init.exp.byte 592 E408 CDDBE9 CALL :E9DB Copy ABCD into MACC 593 E40B C34DC1 JMP :C14D Popall, ret 594 595 * If INT number is 0: 596 597 E40E CD16EA L1E63 CALL :EA16 Clear MACC + reg ABCD 598 E411 C34DC1 JMP :C14D Popall; ret 599 * 600 * 601 * 602 E414 END *************************** * S Y M B O L T A B L E * *************************** L1E24 E242 L1E25 E28E L1E26 E2A6 L1E27 E2C9 L1E28 E2D0 L1E29 E2D7 L1E30 E2E0 L1E31 E2E4 L1E32 E2EC L1E33 E2F2 L1E36 E322 L1E37 E328 L1E40 E343 L1E43 E35A L1E46 E371 L1E48 E384 L1E49 E385 L1E50 E38B L1E51 E38C L1E52 E38F L1E56 E3C2 L1E57 E3C9 L1E58 E3CF L1E59 E3D6 L1E60 E3DD L1E62 E3FD L1E63 E40E SIAND E335 SIOR E34C SIXOR E363 XFLT E3DE XIABS E30B XIAND E32E XICHS E315 XIDIV E22B XINOT E373 XIOR E345 XIREM E238 XIXOR E35C XSHL E3A5 XSHR E398 XSTST E3B2