PAGE 01 DAI FIRMWARE C000-C1FA V1.0 Rev.1 002 ORG :C000 003 * 004 * 005 * 006 * ================= 007 *** MATH. UTILITIES *** 008 * ================= 009 * 010 * 011 *************** 012 * ENTRYPOINTS * 013 *************** 014 * 015 C000 C319C7 BASE JMP :C719 Reset (entry on hardware 016 reset) 017 C003 C335C0 XINIT JMP :C035 Math. package initialisation 018 C006 C3F3C0 XFINM JMP :C0F3 Incr. FPT number in memory 019 C009 C3FBC1 XFDCM JMP :C1FB Decr. FPT number in memory 020 (not used) 021 C00C C379C0 XFCOMP JMP :C079 FPT Compare 022 C00F C3BBC0 XIINM JMP :C0BB Incr. INT number in memory 023 C012 C3D5C0 XIDCM JMP :C0D5 Decr. INT number in memory 024 (not used) 025 C015 C3ACC0 XICOMP JMP :C0AC INT Compare 026 C018 C31EC2 XPUSH JMP :C21E Save MACC on stack 027 C01B C334C2 XPOP JMP :C234 Retrieve MACC from stack 028 C01E C349C2 XFCB JMP :C249 Input FPT number to MACC 029 C021 C361C3 XFBC JMP :C361 Conv. FPT number for output 030 C024 C373C5 XICB JMP :C573 Input INT number to MACC 031 C027 C3B2C5 XIBC JMP :C5B2 Conv. INT number for output 032 C02A C314C6 XHCB JMP :C614 Input Hex number to MACC 033 C02D C353C6 XHBC JMP :C653 Conv. MACC to Hex for output 034 C030 C386C4 XPRTY JMP :C486 Pretties up FPT/INT number 035 C033 E300 DECBUF DBL :00E3 Location output buffer 036 * 037 ******************************** 038 * MATH. PACKAGE INITIALISATION * 039 ******************************** 040 * 041 * Entry: HL: Address input encoding routine (DDE0). 042 * DE: Base address error routines (C7F2). 043 * Exit: AFDEHL corrupted, BC preserved. 044 * 045 C035 22D200 MINIT SHLD :00D2 Init. (00D2/3)=DDE0 046 C038 EB XCHG 047 C039 22D000 SHLD :00D0 Init. (00D0/1)=C7F2 048 C03C 3A02FB LDA :FB02 Get math.chip status 049 C03F B7 ORA A Check if math.chip present 050 C040 3E00 MVI A,:00 Flag = 0 if not 051 C042 FA47C0 JM :C047 052 C045 3E7B MVI A,:7B Flag = #7B if present 053 C047 32D400 LC18 STA :00D4 Set math.chip flag 054 C04A C9 RET 055 * 056 ************************** 057 * OVERFLOW ERROR ROUTINE * 058 ************************** 059 * 060 * (From LC20 common part for various entries). 061 * 062 * Jump to (00D0/1) = Address 'overflow error' 063 * routine (C7F2). PAGE 02 DAI FIRMWARE C000-C1FA V1.0 Rev.1 064 * 065 * Entry: If start at LC20: offset in HL. 066 * Exit: AFBCDEHL preserved. 067 * On stack original returnaddress. 068 * 069 C04B E5 FPEOV PUSH H 070 C04C 210000 LXI H,:0000 Init offset = 0 071 * 072 C04F F5 LC20 PUSH PSW 073 C050 D5 PUSH D 074 C051 EB XCHG Offset in DE 075 C052 2AD000 LHLD :00D0 Get addr pointer 076 C055 19 DAD D Add offset 077 C056 7E MOV A,M 078 C057 23 INX H 079 C058 66 MOV H,M 080 C059 6F MOV L,A Get addr routine in HL 081 C05A D1 POP D 082 C05B F1 POP PSW 083 C05C E3 XTHL New addr on stack 084 C05D C9 RET Continu with new address 085 * 086 ****************** 087 * ARGUMENT ERROR * 088 ****************** 089 * 090 * Jump to (00D0/1)+2 = Address 'number out of range' 091 * routine (C7F4). 092 * 093 * Entry/exit: See FPEOV. 094 * 095 C05E E5 FPEAE PUSH H 096 C05F 210200 LXI H,:0002 Init. offset 097 C062 C34FC0 JMP :C04F Calc. new addr, go to it 098 * 099 ******************* 100 * UNDERFLOW ERROR * 101 ******************* 102 * 103 * Jump to (00D0/1)+4 = Return (C7F6). 104 * Underflow gives 0 as result of operation. 105 * 106 * Entry/exit: See FPEOV. 107 * 108 C065 E5 FPEUN PUSH H 109 C066 215EC4 LXI H,:C45E Addr. FPT(0) 110 C069 C30CD2 JMP :D20C Copy '0' into MACC 111 * 112 ************************ 113 * DIVIDE BY ZERO ERROR * 114 ************************ 115 * 116 * Jump to (00D0/1)+6 = Address 'divide by zero' 117 * routine (C7F8). 118 * 119 * Entry/exit: See FPEOV. 120 * 121 C06C E5 FPED0 PUSH H 122 C06D 210600 LXI H,:0006 Init. offset 123 C070 C34FC0 JMP :C04F Calc. new addr, go to it 124 * 125 * PAGE 03 DAI FIRMWARE C000-C1FA V1.0 Rev.1 126 *************************** 127 * GET CHARACTER FROM LINE * 128 *************************** 129 * 130 * Entry: None. 131 * Exit : All registers preserved. 132 * Address to continue on stack. 133 * 134 C073 E5 LC22 PUSH H 135 C074 2AD200 LHLD :00D2 Get addr 'Get char' routine 136 C077 E3 XTHL on stack; restore HL 137 C078 C9 RET Goto (00D0/1)+2 138 * 139 ************************** 140 * FLOATING POINT COMPARE * 141 ************************** 142 * 143 * Compares normalised FPT numbers in MACC 144 * and in M. 145 * 146 * Exit: ABCDEHL preserved. 147 * Flags: CY=1,S=0,Z=1: both nrs. 0 148 * CY=0,S=0,Z=1: both nrs. identical 149 * CY=0,S=0,Z=0: MACC > M 150 * CY=0,S=1,Z=0: MACC < M 151 * 152 C079 C5 FCOMP PUSH B 153 C07A F5 PUSH PSW 154 C07B D5 PUSH D 155 C07C E5 PUSH H 156 C07D E7 RST 4 Copy MACC to reg A,B,C,D 157 C07E 15 DATA :15 158 C07F 5F MOV E,A Exp.byte in E 159 C080 AE XRA M XOR both exp.bytes 160 C081 FAB7C0 JM :C0B7 Jump if different signs 161 162 * If equal signs: 163 164 C084 C3E8D1 JMP :D1E8 Goto D1E8, return to C087 165 * 166 C087 17 LC23 RAL 167 C088 C2A3C0 JNZ :C0A3 168 C08B 7B LC24 MOV A,E 169 C08C 96 SUB M Comp. exp. bytes 170 C08D C2A2C0 JNZ :C0A2 Jump if not equal 171 C090 23 INX H 172 C091 78 MOV A,B 173 C092 96 SUB M Comp. 1st bytes mantissa's 174 C093 C2A2C0 JNZ :C0A2 Jump if not equal 175 C096 23 INX H 176 C097 79 MOV A,C 177 C098 96 SUB M Comp. 2nd bytes mantissa's 178 C099 C2A2C0 JNZ :C0A2 Jump if not equal 179 C09C 23 INX H 180 C09D 7A MOV A,D 181 C09E 96 SUB M Comp. 3rd bytes mantissa's 182 C09F CAA6C0 LC25 JZ :C0A6 Jump if not equal 183 C0A2 1F LC26 RAR ) Set flags for output 184 C0A3 AB LC27 XRA E ) 185 C0A4 F601 LC28 ORI :01 Clear CY-flag 186 C0A6 E1 LC29 POP H 187 C0A7 D1 POP D PAGE 04 DAI FIRMWARE C000-C1FA V1.0 Rev.1 188 C0A8 C1 POP B 189 C0A9 78 MOV A,B Restore A 190 C0AA C1 POP B 191 C0AB C9 RET 192 * 193 ******************* 194 * INTEGER COMPARE * 195 ******************* 196 * 197 * Compares INT numbers in MACC and M. 198 * REMARK: Routine is incorrect when both 199 * numbers are negative ! Then result 200 * is if MACC > M due to LC26/LC27. 201 * 202 * Exit: ABCDEHL preserved. CY=0 203 * Flags: S=0, Z=1: Both numbers equal 204 * S=0, Z=0: MACC > M 205 * S=1, Z=0: MACC < M 206 * 207 C0AC C5 ICOMP PUSH B 208 C0AD F5 PUSH PSW 209 C0AE D5 PUSH D 210 C0AF E5 PUSH H 211 C0B0 E7 RST 4 Copy MACC to reg. A,B,C,D 212 C0B1 15 DATA :15 213 C0B2 5F MOV E,A Sign byte in E 214 C0B3 AE XRA M XOR both sign bytes 215 C0B4 F28BC0 JP :C08B If both nrs have same sign: 216 compare 217 218 * If different signs: 219 220 C0B7 AE LC241 XRA M Find out which one is neg: 221 S=1: MEM pos; MACC neg 222 S=0: MEM neg; MACC pos 223 C0B8 C3A4C0 JMP :C0A4 Abort 224 * 225 ************************************** 226 * INCREMENT INTEGER NUMBER IN MEMORY * 227 ************************************** 228 * 229 * Entry: HL points to 1st byte of INT number. 230 * Exit: All registers preserved. 231 * 232 C0BB F5 IINM PUSH PSW 233 C0BC E5 PUSH H 234 C0BD 23 INX H 235 C0BE 23 INX H 236 C0BF 23 INX H HL pnts to last byte 237 C0C0 3E03 MVI A,:03 Nr of bytes for INT nr 238 C0C2 34 LC30 INR M Incr. INT nr. 239 C0C3 C2D2C0 JNZ :C0D2 Ready if no overflow 240 C0C6 2B DCX H Goto next byte 241 C0C7 3D DCR A 1st byte reached? 242 C0C8 C2C2C0 JNZ :C0C2 Incr. next byte 243 C0CB 34 INR M Incr. 1st byte 244 C0CC 7E MOV A,M Get it 245 C0CD FE80 CPI :80 msb=1? 246 C0CF CC4BC0 CZ :C04B Then overflow error 247 C0D2 E1 LC31 POP H Normal return 248 C0D3 F1 POP PSW 249 C0D4 C9 RET PAGE 05 DAI FIRMWARE C000-C1FA V1.0 Rev.1 250 * 251 *************************************************** 252 * DECREMENT INTEGER NUMBER IN MEMORY - (not used) * 253 *************************************************** 254 * 255 * Entry: HL points to 1st byte of INT number. 256 * Exit: All registers preserved. 257 * 258 C0D5 F5 IDCM PUSH PSW 259 C0D6 C5 PUSH B 260 C0D7 E5 PUSH H 261 C0D8 23 INX H 262 C0D9 23 INX H 263 C0DA 23 INX H HL pnts to last byte 264 C0DB 0603 MVI B,:03 Nr. of bytes of INT nr. 265 C0DD 35 LC32 DCR M Decr. INT nr 266 C0DE 7E MOV A,M 267 C0DF 3C INR A Check for overflow 268 C0E0 C2EFC0 JNZ :C0EF Ready if no overflow 269 C0E3 2B DCX H Goto next byte 270 C0E4 05 DCR B Decr. byte count 271 C0E5 C2DDC0 JNZ :C0DD Next byte if not ready 272 C0E8 35 DCR M Decr. hibyte 273 C0E9 7E MOV A,M 274 C0EA FE7F CPI :7F Check for overflow 275 C0EC CC4BC0 CZ :C04B Then run overflow error 276 C0EF E1 LC33 POP H Normal return 277 C0F0 C1 POP B 278 C0F1 F1 POP PSW 279 C0F2 C9 RET 280 * 281 ********************************************* 282 * INCREMENT FLOATING POINT NUMBER IN MEMORY * 283 ********************************************* 284 * 285 * If number = 0, or exponent < 0, a '1' is added 286 * to the lsb of the mantissa. Else, the position 287 * of the least significant '1' is looked up, and 288 * a '1' is added to this position. 289 * If the lsb of the mantissa is already a rounded 290 * value, no increment occurs. 291 * 292 * Entry: HL points to 1st byte of FPT number. 293 * Exit: All registers preserved. 294 * 295 C0F3 F5 FINM PUSH PSW 296 C0F4 C5 PUSH B 297 C0F5 D5 PUSH D 298 C0F6 E5 PUSH H 299 C0F7 1162C4 LXI D,:C462 Addr FPT(1) 300 C0FA 7E MOV A,M Get exp.byte 301 C0FB E67F ANI :7F Mask sign bit 302 C0FD CAACC1 JZ :C1AC If nr=0: add 1, abort 303 C100 FE40 CPI :40 Is exponent negative? 304 C102 D2ACC1 JNC :C1AC Then add 1, abort 305 C105 FE19 CPI :19 Lsb of mantissa is not lsb 306 of number ? 307 C107 D24DC1 JNC :C14D Then Popall, ret 308 C10A BE CMP M Check if nr. is negative 309 C10B 23 INX H 310 C10C C252C1 JNZ :C152 Then jump 311 PAGE 06 DAI FIRMWARE C000-C1FA V1.0 Rev.1 312 * From LC34 also used by XFDCM. 313 * Find lsb of mantissa if nr is positive: 314 315 C10F D609 LC34 SUI :09 In 1st byte ? 316 C111 DCEEC1 CC :C1EE Then SHL bit into A (A) time 317 C114 DA36C1 JC :C136 and jump 318 C117 23 INX H 319 C118 D608 SUI :08 In 2nd byte ? 320 C11A DCEEC1 CC :C1EE Then SHL bit into A (A) time 321 C11D DA2EC1 JC :C12E and jump 322 C120 23 INX H 323 C121 D608 SUI :08 In 3rd byte ? 324 C123 CDEEC1 CALL :C1EE Then SHL bit into A (A) time 325 C126 86 ADD M 326 C127 77 MOV M,A Add 1 to 3rd byte mantissa 327 C128 D24DC1 JNC :C14D Ready if no overflow 328 C12B 2B DCX H 329 C12C 3E01 MVI A,:01 Overflow: add 1 to 2nd byte 330 C12E 86 LC35 ADD M 331 C12F 77 MOV M,A Add 1 to 2nd byte mantissa 332 C130 D24DC1 JNC :C14D Ready if no overflow 333 C133 2B DCX H 334 C134 3E01 MVI A,:01 Overflow: add 1 to 1st byte 335 C136 86 LC36 ADD M 336 C137 77 MOV M,A Add 1 to 1st byte mantissa 337 C138 D24DC1 JNC :C14D Ready if no overflow 338 339 * If overflow into exponent byte: 340 341 C13B 1F RAR ) 342 C13C 77 MOV M,A ) 343 C13D 23 INX H ) 344 C13E 7E MOV A,M ) Shift all bits in 345 C13F 1F RAR ) mantissa right 346 C140 77 MOV M,A ) one position 347 C141 23 INX H ) 348 C142 7E MOV A,M ) 349 C143 1F RAR ) 350 C144 77 MOV M,A ) 351 C145 2B DCX H 352 C146 2B DCX H 353 C147 2B DCX H HL pnts to exp.byte 354 C148 3E01 MVI A,:01 355 C14A CDBAC1 LC37 CALL :C1BA Add 1 to exponent 356 * 357 C14D E1 EXIT POP H 358 C14E D1 POP D 359 C14F C1 POP B 360 C150 F1 POP PSW 361 C151 C9 RET 362 363 * Find lsb of mantissa if nr is negative: 364 365 C152 D609 LC39 SUI :09 In 1st byte ? 366 C154 DCEEC1 CC :C1EE Then SHL bit into A (A) time 367 C157 DA7DC1 JC :C17D and jump 368 C15A 23 INX H 369 C15B D608 SUI :08 In 2nd byte ? 370 C15D DCEEC1 CC :C1EE Then SHL bit into A (A) time 371 C160 DA73C1 JC :C173 and jump 372 C163 23 INX H 373 C164 D608 SUI :08 In 3rd byte ? PAGE 07 DAI FIRMWARE C000-C1FA V1.0 Rev.1 374 C166 DCEEC1 CC :C1EE Then SHL bit into A (A) time 375 C169 47 MOV B,A 376 C16A 7E MOV A,M 377 C16B 90 SUB B Subtract 1 from 3rd byte 378 C16C 77 MOV M,A 379 C16D D24DC1 JNC :C14D Ready if no borrow 380 C170 2B DCX H 381 C171 3E01 MVI A,:01 Subtract 1 from 2nd byte if 382 borrow 383 C173 47 LC40 MOV B,A 384 C174 7E MOV A,M 385 C175 90 SUB B Subtract 1 from 2nd byte 386 C176 77 MOV M,A 387 C177 D24DC1 JNC :C14D Ready if no borrow 388 C17A 2B DCX H 389 C17B 3E01 MVI A,:01 Subtract 1 from 1st byte if 390 borrow 391 C17D 47 LC41 MOV B,A 392 C17E 7E MOV A,M 393 C17F 90 SUB B Subtract 1 from 1st byte 394 C180 77 MOV M,A 395 C181 FA4DC1 JM :C14D Ready if normalised 396 397 * If not normalised: 398 399 C184 0618 MVI B,:18 Nr of mantissa bits 400 C186 23 LC42 INX H ) 401 C187 23 INX H ) 402 C188 B7 ORA A ) 403 C189 7E MOV A,M ) 404 C18A 17 RAL ) 405 C18B 77 MOV M,A ) Shift all bits 406 C18C 2B DCX H ) of mantissa 407 C18D 7E MOV A,M ) left one position 408 C18E 17 RAL ) 409 C18F 77 MOV M,A ) 410 C190 2B DCX H ) 411 C191 7E MOV A,M ) 412 C192 17 RAL ) 413 C193 77 MOV M,A ) 414 C194 B7 ORA A 415 C195 FA9FC1 JM :C19F If normalized 416 C198 05 DCR B Update exp. count 417 C199 CAA6C1 JZ :C1A6 If exp. now zero 418 C19C C386C1 JMP :C186 Cont. normalisation 419 420 * Normalisation done: 421 422 C19F 2B LC43 DCX H Pnts to exp.byte 423 C1A0 78 MOV A,B Get exp. count 424 C1A1 D619 SUI :19 Minus nr of bytes in 425 mantissa 426 C1A3 C34AC1 JMP :C14A Update exponent, quit 427 428 * If exponent is zero: 429 430 C1A6 2B LC44 DCX H 431 C1A7 3600 MVI M,:00 Exp.byte is 0 432 C1A9 C34DC1 JMP :C14D Popall, ret 433 434 * Simply add 1 (FINM) or add -1 (FDCM): 435 PAGE 08 DAI FIRMWARE C000-C1FA V1.0 Rev.1 436 C1AC E7 LC45 RST 4 Copy number into MACC 437 C1AD 0C DATA :0C 438 C1AE EB XCHG 439 C1AF E7 RST 4 Add 1 or -1 (FPT) 440 C1B0 00 DATA :00 441 C1B1 EB XCHG 442 C1B2 E7 RST 4 Copy MACC into memory 443 C1B3 0F DATA :0F 444 C1B4 C34DC1 JMP :C14D Popall, ret 445 * 446 ***************** 447 * ADD EXPONENTS * 448 ***************** 449 * 450 * LC225 for operand in MACC. 451 * LC46 for operand in M. 452 * 453 * Entry: Byte to be added to exponent in A. 454 * Exit: BCDEHL preserved. 455 * CY=0: O.K. 456 * CY=1: Overflow. 457 * 458 C1B7 21D500 LC225 LXI H,:00D5 Addr. MACC 459 * 460 C1BA E5 LC46 PUSH H 461 C1BB D5 PUSH D 462 C1BC C5 PUSH B 463 C1BD 4F MOV C,A Byte to be added in C 464 C1BE 7E MOV A,M Get exp.byte operand 465 C1BF E680 ANI :80 Sign bit mantissa only 466 C1C1 47 MOV B,A in B 467 C1C2 7E MOV A,M Get exp.byte 468 C1C3 CDE9C1 CALL :C1E9 Sign extend 469 C1C6 F5 PUSH PSW Save sign extended exp.byte 470 C1C7 A9 XRA C XOR with byte to be added 471 C1C8 2F CMA 472 C1C9 57 MOV D,A 473 C1CA F1 POP PSW Get sign extended exp.byte 474 C1CB 81 ADD C Add byte to exponent 475 C1CC 4F MOV C,A Store result 476 C1CD 1F RAR 477 C1CE A9 XRA C 478 C1CF A2 ANA D 479 C1D0 FAE2C1 JM :C1E2 If overflow into sign bit 480 C1D3 79 MOV A,C Get new exp.byte 481 C1D4 17 RAL 482 C1D5 A9 XRA C 483 C1D6 FAE2C1 JM :C1E2 If overflow into sign bit 484 C1D9 79 MOV A,C Get new exp.byte 485 C1DA E67F ANI :7F Exponent only 486 C1DC B0 ORA B Add sign bit mantissa 487 C1DD 77 MOV M,A Store it 488 C1DE C1 LC47 POP B 489 C1DF D1 POP D 490 C1E0 E1 POP H 491 C1E1 C9 RET CY=0 492 493 * If overflow into sign bit: 494 495 C1E2 79 LC48 MOV A,C Get new exp.byte 496 C1E3 17 RAL 497 C1E4 B7 ORA A PAGE 09 DAI FIRMWARE C000-C1FA V1.0 Rev.1 498 C1E5 37 STC 499 C1E6 C3DEC1 JMP :C1DE Abort with CY=1 500 * 501 *************** 502 * SIGN EXTEND * 503 *************** 504 * 505 * Exponent byte is normalized. 506 * 507 * Entry: Exp.byte in A. 508 * Exit: BCDEHL preserved. 509 * Normalized exp.byte in A: Exp.value in 510 * bits 7-2, sign mantissa in bit 1, sign 511 * exponent in bit 0. 512 * 513 C1E9 07 SEXT RLC 514 C1EA 07 RLC 515 C1EB 0F RRC 516 C1EC 1F RAR 517 C1ED C9 RET 518 * 519 ************************************ 520 * MOVE A BIT INTO A LEFT (A) TIMES * 521 ************************************ 522 * 523 * Used to place a '1' in the correct position in 524 * a byte for adding/subtracting '1' to/from the 525 * least significant '1' of a FPT mantissa. 526 * 527 * Entry: A contains a neg. number indicating 528 * how often RAL has to be performed. 529 * Exit: Result in A,B. 530 * FCDEHL preserved. 531 * 532 C1EE F5 LC50 PUSH PSW 533 C1EF 47 MOV B,A Save nr of shifts 534 C1F0 AF XRA A Clear A 535 C1F1 37 STC Set CY 536 C1F2 17 LC51 RAL SHL 537 C1F3 04 INR B Update count 538 C1F4 C2F2C1 JNZ :C1F2 Continu if not ready 539 C1F7 47 MOV B,A Save result 540 C1F8 F1 POP PSW 541 C1F9 78 MOV A,B Result in A 542 C1FA C9 RET 543 * 544 * 545 * 546 C1FB END *************************** * S Y M B O L T A B L E * *************************** BASE C000 DECBUF C033 EXIT C14D FCOMP C079 FINM C0F3 FPEAE C05E FPED0 C06C FPEOV C04B FPEUN C065 ICOMP C0AC IDCM C0D5 IINM C0BB LC18 C047 LC20 C04F LC22 C073 LC225 C1B7 LC23 C087 LC24 C08B LC241 C0B7 LC25 C09F LC26 C0A2 LC27 C0A3 LC28 C0A4 LC29 C0A6 LC30 C0C2 LC31 C0D2 LC32 C0DD LC33 C0EF LC34 C10F LC35 C12E LC36 C136 LC37 C14A PAGE 10 DAI FIRMWARE C000-C1FA V1.0 Rev.1 LC39 C152 LC40 C173 LC41 C17D LC42 C186 LC43 C19F LC44 C1A6 LC45 C1AC LC46 C1BA LC47 C1DE LC48 C1E2 LC50 C1EE LC51 C1F2 MINIT C035 SEXT C1E9 XFBC C021 XFCB C01E XFCOMP C00C XFDCM C009 XFINM C006 XHBC C02D XHCB C02A XIBC C027 XICB C024 XICOMP C015 XIDCM C012 XIINM C00F XINIT C003 XPOP C01B XPRTY C030 XPUSH C018