├── BASIC disassembly-source.rom ├── README.md ├── BASIC disassembly-source.txt └── BASIC disassembly-source.lst /BASIC disassembly-source.rom: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/option8/Altair-BASIC/HEAD/BASIC disassembly-source.rom -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Altair-BASIC 2 | 3 | Micro-Soft Altair BASIC 3.2 (4K) - Annotated Disassembly 4 | 5 | Copyright 1975, Bill Gates, Paul Allen, Monte Davidoff 6 | 7 | Source: http://altairbasic.org/ compiled by Reuben Harris 8 | 9 | Additional cleanup, relocation by Charles Mangin, March, 2019 10 | -------------------------------------------------------------------------------- /BASIC disassembly-source.txt: -------------------------------------------------------------------------------- 1 | ; ---------------------------------------------------------------------------- 2 | ;Micro-Soft Altair BASIC 3.2 (4K) - Annotated Disassembly 3 | ; 4 | ;Copyright 1975, Bill Gates, Paul Allen, Monte Davidoff 5 | ;Source: http://altairbasic.org/ compiled by Reuben Harris 6 | ;Additional cleanup, relocation by Charles Mangin, March, 2019 7 | ; ---------------------------------------------------------------------------- 8 | 9 | 10 | ORG 00 11 | 12 | Start DI 13 | JMP Init 14 | 15 | DW 0490h 16 | DW 07F9h 17 | 18 | SyntaxCheck MOV A,M ;A=Byte of BASIC program. 19 | XTHL ;HL=return address. 20 | CMP M ;Compare to byte expected. 21 | INX H ;Return address++; 22 | XTHL ; 23 | JNZ SyntaxError ;Error if not what was expected. 24 | NextChar INX H 25 | MOV A,M 26 | CPI 0x3A 27 | RNC 28 | JMP NextChar_tail 29 | OutChar PUSH PSW 30 | LDA TERMINAL_X 31 | JMP OutChar_tail 32 | NOP 33 | CompareHLDE MOV A,H 34 | SUB D 35 | RNZ 36 | MOV A,L 37 | SUB E 38 | RET 39 | TERMINAL_Y DB 01 40 | TERMINAL_X DB 00 41 | FTestSign LDA FACCUM+3 42 | ORA A 43 | JNZ FTestSign_tail 44 | RET 45 | PushNextWord XTHL 46 | SHLD L003A+1 47 | POP H 48 | MOV C,M 49 | INX H 50 | MOV B,M 51 | INX H 52 | PUSH B 53 | L003A JMP L003A 54 | KW_INLINE_FNS DW Sgn 55 | DW Int 56 | DW Abs 57 | DW FunctionCallError 58 | DW Sqr 59 | DW Rnd 60 | DW Sin 61 | KW_ARITH_OP_FNS DB 79h 62 | DW FAdd ;+ 63 | DB 79h 64 | DW FSub ;- 65 | DB 7Ch 66 | DW FMul ;* 67 | DB 7Ch 68 | DW FDiv ;/ 69 | KEYWORDS DB 454EC4h ;"END" 80 70 | DB 464FD2h ; "FOR" 71 | DB 4E4558D4h ; "NEXT" 82 72 | DB 444154C1h ; "DATA" 83 73 | DB 494E5055D4h ; "INPUT" 84 74 | DB 4449CDh ; "DIM" 85 75 | DB 524541C4h ; "READ" 86 76 | DB 4C45D4h ; "LET" 87 77 | DB 474F54CFh ; "GOTO" 88 78 | DB 5255CEh ; "RUN" 89 79 | DB 49C6h ; "IF" 8A 80 | DB 524553544F52C5h ; "RESTORE" 8B 81 | DB 474F5355C2h ; "GOSUB" 8C 82 | DB 5245545552CEh ; "RETURN" 8D 83 | DB 5245CDh ; "REM" 8E 84 | DB 53544FD0h ; "STOP" 8F 85 | DB 5052494ED4h ; "PRINT" 90 86 | DB 4C4953D4h ; "LIST" 91 87 | DB 434C4541D2h ; "CLEAR" 92 88 | DB 4E45D7h ; "NEW" 93 89 | ; 90 | DB 544142A8h ; "TAB(" 94 91 | DB 54CFh ; "TO" 95 92 | DB 544845CEh ; "THEN" 96 93 | DB 535445D0h ; "STEP" 97 94 | ; 95 | DB 0xAB ; "+" 98 96 | DB 0xAD ; "-" 99 97 | DB 0xAA ; "*" 9A 98 | DB 0xAF ; "/" 9B 99 | DB 0xBE ; ">" 9C 100 | DB 0xBD ; "=" 9D 101 | DB 0xBC ; "<" 9E 102 | ; 103 | DB 5347CEh ; "SGN" 9F 104 | DB 494ED4h ; "INT" A0 105 | DB 4142D3h ; "ABS" A1 106 | DB 5553D2h ; "USR" A2 107 | DB 5351D2h ; "SQR" A3 108 | DB 524EC4h ; "RND" A4 109 | DB 5349CEh ; "SIN" A5 110 | ; 111 | DB 0x00 ; 112 | ; 113 | KW_GENERAL_FNS DW Stop ;END 114 | DW For ;FOR 115 | DW Next ;NEXT 116 | DW FindNextStatement ;DATA 117 | DW Input ;INPUT 118 | DW Dim ;DIM 119 | DW Read ;READ 120 | DW Let ;LET 121 | DW Goto ;GOTO 122 | DW Run ;RUN 123 | DW If ;IF 124 | DW Restore ;RESTORE 125 | DW Gosub ;GOSUB 126 | DW Return ;RETURN 127 | DW Rem ;REM 128 | DW Stop ;STOP 129 | DW Print ;PRINT 130 | DW List ;LIST 131 | DW Clear ;CLEAR 132 | DW New ;NEW 133 | 134 | ERROR_CODES DB 4EC6h ;"NF" NEXT without FOR. 135 | DB 53CEh ;"SN" Syntax Error 136 | DB 52C7h ;"RG" RETURN without GOSUB. 137 | DB 4FC4h ;"OD" Out of Data 138 | DB 46C3h ;"FC" Illegal Function Call 139 | DB 4FD6h ;"OV" Overflow. 140 | DB 4FCDh ;"OM" Out of memory. 141 | DB 55D3h ;"US" Undefined Subroutine 142 | DB 42D3h ;"BS" Bad Subscript 143 | DB 44C4h ;"DD" Duplicate Definition 144 | DB 2FB0h ;"\0" Division by zero. 145 | DB 49C4h ;"ID" Invalid in Direct mode. 146 | 147 | DB ',' ; 148 | LINE_BUFFER DW 0000,0000,0000,0000h ;72 chars 149 | DW 0000,0000,0000,0000h ; 150 | DW 0000,0000,0000,0000h ; 151 | DW 0000,0000,0000,0000h ; 152 | DW 0000,0000,0000,0000h ; 153 | DW 0000,0000,0000,0000h ; 154 | DW 0000,0000,0000,0000h ; 155 | DW 0000,0000,0000,0000h ; 156 | DW 0000,0000,0000,0000h ; 157 | 158 | DIM_OR_EVAL DB 00h ; 159 | INPUT_OR_READ DB 00h ; 160 | PROG_PTR_TEMP DW 0000h ; 161 | L015F DW 0000h ; 162 | CURRENT_LINE DW 0000h ; 163 | STACK_TOP DW 0F1Ah ; RELOCATE*** 164 | PROGRAM_BASE DW 0000h ; 165 | VAR_BASE DW 0000h ; 166 | VAR_ARRAY_BASE DW 0000h ; 167 | VAR_TOP DW 0000h ; 168 | DATA_PROG_PTR DW 0000h ; 169 | FACCUM DB 00000000h ; 170 | FTEMP DB 00h ; 171 | FBUFFER DW 0000,0000,0000 172 | DW 0000,0000,0000 173 | DB 00 ; 174 | szError DB 0x20,0x45,0x52,0x52,0x4F,0xD2,0x00 ;" ERROR\0" 175 | szIn DB 0x20,0x49,0x4E,0xA0,0x00 ;" IN \0" 176 | szOK DB 0x0D,0x4F,0xCB,0x0D,0x00 ;"\rOK\r\0" 177 | GetFlowPtr LXI H,0004h ;HL=SP+4 (ie get word 178 | DAD SP ;just past return addr) 179 | MOV A,M ; 180 | INX H ; 181 | CPI 0x81 ;'FOR'? 182 | RNZ ;Return if not 'FOR' 183 | RST 6 ; RST PushNextWord ;PUSH (HL) 184 | XTHL ;POP HL (ie HL=(HL)) 185 | RST 4 ; RST CompareHLDE ;HL==DE? 186 | LXI B,000Dh ; 187 | POP H ;Restore HL 188 | RZ ;Return if var ptrs match. 189 | DAD B ;HL+=000D 190 | JMP GetFlowPtr+4 ;Loop 191 | CopyMemoryUp CALL CheckEnoughMem; 192 | PUSH B ;Exchange BC with HL. 193 | XTHL ; 194 | POP B ; 195 | CopyMemLoop RST 4 ;HL==DE? 196 | MOV A,M ; 197 | STAX B ; 198 | RZ ;Exit if DE reached. 199 | DCX B ; 200 | DCX H ; 201 | JMP CopyMemLoop ; 202 | CheckEnoughVarSpace PUSH H ; 203 | LHLD VAR_TOP ; 204 | MVI B,00h ;BC=C*4 205 | DAD B ; 206 | DAD B ; 207 | CALL CheckEnoughMem; 208 | POP H ; 209 | RET ; 210 | CheckEnoughMem PUSH D ; 211 | XCHG ; 212 | LXI H,0xFFDE ;HL=-34 (extra 2 bytes for return address) 213 | DAD SP ; 214 | RST 4 ; 215 | XCHG ; 216 | POP D ; 217 | RNC ; 218 | OutOfMemory MVI E,0Ch ; 219 | DB 01 ;LXI B,.... ; 220 | SyntaxError MVI E,02h ; 221 | DB 01 ;LXI B,.... ; 222 | DivideByZero MVI E,14h ; 223 | Error CALL ResetStack ; 224 | CALL NewLine ; 225 | LXI H,ERROR_CODES ; 226 | MOV D,A ; 227 | MVI A,'?' ;Print '?' 228 | RST 03 ;RST OutChar ; 229 | DAD D ;HL points to error code. 230 | MOV A,M ; 231 | RST 03 ;RST OutChar 11 011 111 ;Print first char of code. 232 | RST 02 ;RST NextChar 11 010 111 ; 233 | RST 03 ;RST OutChar ;Print second char of code. 234 | LXI H,szError ;Print " ERROR". 235 | CALL PrintString ; 236 | LHLD CURRENT_LINE ; 237 | MOV A,H ; 238 | ANA L ; 239 | INR A ; 240 | CNZ PrintIN ; 241 | DB 01 ;LXI B,.... ;LXI over Stop and fall into Main 242 | Stop RNZ ;Syntax Error if args. 243 | POP B ;Lose return address. 244 | Main LXI H,szOK ; 245 | CALL Init ; 246 | GetNonBlankLine LXI H,0xFFFF ; 247 | SHLD CURRENT_LINE ; 248 | CALL InputLine ; 249 | RST 02 ;RST NextChar ; 250 | INR A ; 251 | DCR A ; 252 | JZ GetNonBlankLine ; 253 | PUSH PSW 254 | CALL LineNumberFromStr 255 | PUSH D 256 | CALL Tokenize 257 | MOV B,A 258 | POP D 259 | POP PSW 260 | JNC Exec 261 | StoreProgramLine PUSH D ;Push line number 262 | PUSH B ;Push line length 263 | RST 02 ;RST NextChar ;Get first char of line 264 | ORA A ;Zero set if line is empty (ie removing a line) 265 | PUSH PSW ;Preserve line-empty flag 266 | CALL FindProgramLine ;Get nearest program line address in BC. 267 | PUSH B ;Push line address. 268 | JNC InsertProgramLine ;If line doesn't exist, jump ahead to insert it. 269 | RemoveProgramLine XCHG ;DE=Next line address. 270 | LHLD VAR_BASE ; 271 | RemoveLine LDAX D ;Move byte of program remainder down 272 | STAX B ;in memory. 273 | INX B ; 274 | INX D ; 275 | RST 4 ;Loop until DE==VAR_BASE, ie whole 276 | JNZ RemoveLine ;program remainder done. 277 | MOV H,B ; 278 | MOV L,C ;Update VAR_BASE from BC. 279 | SHLD VAR_BASE ; 280 | InsertProgramLine POP D ;DE=Line address (from 224) 281 | POP PSW ;Restore line-empty flag (see above) 282 | JZ UpdateLinkedList;If line is empty, then we don't need to insert it so can jump ahead. 283 | LHLD VAR_BASE ; 284 | XTHL ;HL = Line length (see 21D) 285 | POP B ;BC = VAR_BASE 286 | DAD B ;HL = VAR_BASE + line length. 287 | PUSH H ; 288 | CALL CopyMemoryUp ;Move remainder of program so there's enough space for the new line. 289 | POP H ; 290 | SHLD VAR_BASE ;Update VAR_BASE 291 | XCHG ;HL=Line address, DE=VAR_BASE 292 | MOV M,H ;??? 293 | INX H ;Skip over next line ptr (updated below) 294 | INX H ; 295 | POP D ;DE = line number (see 21C) 296 | MOV M,E ;Write line number to program line memory. 297 | INX H ; 298 | MOV M,D ; 299 | INX H ; 300 | CopyFromBuffer LXI D,LINE_BUFFER ;Copy the line into the program. 301 | LDAX D ; 302 | MOV M,A ; 303 | INX H ; 304 | INX D ; 305 | ORA A ; 306 | JNZ CopyFromBuffer+3; 307 | UpdateLinkedList CALL ResetAll ; 308 | INX H ; 309 | XCHG ; 310 | L0265 MOV H,D ; 311 | MOV L,E ; 312 | MOV A,M ;If the pointer to the next line is a null 313 | INX H ;word then we've reached the end of the 314 | ORA M ;program, job is done, and we can jump back 315 | JZ GetNonBlankLine ;to let the user type in the next line. 316 | INX H ;Skip over line number. 317 | INX H ; 318 | INX H ; 319 | XRA A ; 320 | L0271 CMP M ; 321 | INX H ; 322 | JNZ L0271 ; 323 | XCHG ; 324 | MOV M,E ; 325 | INX H ; 326 | MOV M,D ; 327 | JMP L0265 ; 328 | FindProgramLine LHLD PROGRAM_BASE ; 329 | MOV B,H ;BC=this line 330 | MOV C,L ; 331 | MOV A,M ;If we've found two consecutive 332 | INX H ;null bytes, then we've reached the end 333 | ORA M ;of the program and so return. 334 | DCX H ; 335 | RZ ; 336 | PUSH B ;Push this line address 337 | RST 6 ;Push (next line address) 338 | RST 6 ;Push (this line number) 339 | POP H ;HL = this line number 340 | RST 4 ;Compare line numbers 341 | POP H ;HL = next line address 342 | POP B ;BC = this line address 343 | CMC ; 344 | RZ ;Return carry set if line numbers match. 345 | CMC ; 346 | RNC ;Return if we've reached a line number greater than the one required. 347 | JMP FindProgramLine+3 348 | New RNZ 349 | LHLD PROGRAM_BASE 350 | XRA A 351 | MOV M,A 352 | INX H 353 | MOV M,A 354 | INX H 355 | SHLD VAR_BASE 356 | Run RNZ 357 | ResetAll LHLD PROGRAM_BASE 358 | DCX H 359 | Clear SHLD PROG_PTR_TEMP 360 | CALL Restore 361 | LHLD VAR_BASE 362 | SHLD VAR_ARRAY_BASE 363 | SHLD VAR_TOP 364 | ResetStack POP B 365 | LHLD STACK_TOP 366 | SPHL 367 | XRA A 368 | MOV L,A 369 | PUSH H 370 | PUSH B 371 | LHLD PROG_PTR_TEMP 372 | RET 373 | InputLineWith MVI A,'?' ;Print '?' 374 | RST 03 ;RST OutChar ; 375 | MVI A,' ' ;Print ' ' 376 | RST 03 ;RST OutChar ; 377 | CALL InputLine ; 378 | INX H ; 379 | Tokenize MVI C,05 ;Initialise line length to 5. 380 | LXI D,LINE_BUFFER ;ie, output ptr is same as input ptr at start. 381 | MOV A,M ; 382 | CPI ' ' ; 383 | JZ WriteChar ; 384 | MOV B,A ; 385 | CPI '"' ; 386 | JZ FreeCopy ; 387 | ORA A ; 388 | JZ Exit ; 389 | PUSH D ;Preserve output ptr. 390 | MVI B,00 ;Initialise Keyword ID to 0. 391 | LXI D,KEYWORDS-1 ; 392 | PUSH H ;Preserve input ptr. 393 | DB 3Eh ;LXI over get-next-char 394 | KwCompare RST 02 ; RST 01 ; SyntaxCheck0 ;Get next input char 395 | INX D ; 396 | LDAX D ;Get keyword char to compare with. 397 | ANI 7Fh ;Ignore bit 7 of keyword char. 398 | JZ NotAKeyword ;If keyword char==0, then end of keywords reached. 399 | CMP M ;Keyword char matches input char? 400 | JNZ NextKeyword ;If not, jump to get next keyword. 401 | LDAX D ; 402 | ORA A ; 403 | JP KwCompare ; 404 | POP PSW ;Remove input ptr from stack. We don't need it. 405 | MOV A,B ;A=Keyword ID 406 | ORI 0x80 ;Set bit 7 (indicates a keyword) 407 | DB 0xF2 ;JP .... ;LXI trick again. 408 | NotAKeyword POP H ;Restore input ptr 409 | MOV A,M ;and get input char 410 | POP D ;Restore output ptr 411 | WriteChar INX H ;Advance input ptr 412 | STAX D ;Store output char 413 | INX D ;Advance output ptr 414 | INR C ;C++ (arf!). 415 | SUI 8Eh ;If it's not the 416 | JNZ Tokenize+5 ; 417 | MOV B,A ;B=0 418 | FreeCopyLoop MOV A,M ;A=Input char 419 | ORA A ;If char is null then exit 420 | JZ Exit ; 421 | CMP B ;If input char is term char then 422 | JZ WriteChar ;we're done free copying. 423 | FreeCopy INX H ; 424 | STAX D ; 425 | INR C ; 426 | INX D ; 427 | JMP FreeCopyLoop ; 428 | NextKeyword POP H ;Restore input ptr 429 | PUSH H ; 430 | INR B ;Keyword ID ++; 431 | XCHG ;HL=keyword table ptr 432 | NextKwLoop ORA M ;Loop until 433 | INX H ;bit 7 of previous 434 | JP NextKwLoop ;keyword char is set. 435 | XCHG ;DE=keyword ptr, HL=input ptr 436 | JMP KwCompare+2 ; 437 | Exit LXI H,LINE_BUFFER-1 ; 438 | STAX D ; 439 | INX D ; 440 | STAX D ; 441 | INX D ; 442 | STAX D ; 443 | RET ; 444 | Backspace DCR B ;Char count--; 445 | DCX H ;Input ptr--; 446 | RST 03 ;RST OutChar ;Print backspace char. 447 | JNZ InputNext ; 448 | ResetInput RST 03 ;RST OutChar ; 449 | CALL NewLine ; 450 | InputLine LXI H,LINE_BUFFER ; 451 | MVI B,01 ; 452 | InputNext CALL InputChar ; 453 | CPI 0x0D ; 454 | JZ TerminateInput ; 455 | CPI ' ' ;If < ' ' 456 | JC InputNext ;or 457 | CPI 0x7D ;> '}' 458 | JNC InputNext ;then loop back. 459 | CPI '@' ; 460 | JZ ResetInput ; 461 | CPI '_' ; 462 | JZ Backspace ; 463 | MOV C,A ; 464 | MOV A,B ; 465 | CPI 0x48 ; 466 | MVI A,07 ; 467 | JNC L036A ; 468 | MOV A,C ;Write char to LINE_BUFFER. 469 | MOV M,C ; 470 | INX H ; 471 | INR B ; 472 | L036A RST 03 ;RST OutChar ; 473 | JMP InputNext ; 474 | OutChar_tail CPI 0x48 ; 475 | CZ NewLine ; 476 | INR A ; 477 | STA TERMINAL_X ; 478 | WaitTermReady IN 00 ; 479 | ANI 80h ; 480 | JNZ WaitTermReady ; 481 | POP PSW ; 482 | OUT 01 ; 483 | RET ; 484 | InputChar IN 00 ; 485 | ANI 01 ; 486 | JNZ InputChar ; 487 | IN 01 ; 488 | ANI 7Fh ; 489 | RET ; 490 | List CALL LineNumberFromStr 491 | RNZ 492 | POP B ;?why get return address? 493 | CALL FindProgramLine 494 | PUSH B 495 | ListNextLine POP H 496 | RST 6 497 | POP B 498 | MOV A,B 499 | ORA C 500 | JZ Main 501 | CALL TestBreakKey 502 | PUSH B 503 | CALL NewLine 504 | RST 6 505 | XTHL 506 | CALL PrintInt 507 | MVI A,' ' 508 | POP H 509 | ListChar RST 03 ;RST OutChar 510 | MOV A,M 511 | ORA A 512 | INX H 513 | JZ ListNextLine 514 | JP ListChar 515 | SUI 7Fh ;A is now keyword index + 1. 516 | MOV C,A 517 | PUSH H 518 | LXI D,KEYWORDS 519 | PUSH D 520 | ToNextKeyword LDAX D 521 | INX D 522 | ORA A 523 | JP ToNextKeyword 524 | DCR C 525 | POP H 526 | JNZ ToNextKeyword-1 527 | PrintKeyword MOV A,M 528 | ORA A 529 | JM ListChar-1 530 | RST 03 ;RST OutChar 531 | INX H 532 | JMP PrintKeyword 533 | For CALL Let 534 | XTHL 535 | CALL GetFlowPtr 536 | POP D 537 | JNZ L03E2 538 | DAD B 539 | SPHL 540 | L03E2 XCHG 541 | MVI C,08 542 | CALL CheckEnoughVarSpace 543 | PUSH H 544 | CALL FindNextStatement 545 | XTHL 546 | PUSH H 547 | LHLD CURRENT_LINE 548 | XTHL 549 | RST 01 ; SyntaxCheck; SyntaxCheck 550 | DB 95h ;KWID_TO 551 | CALL EvalExpression 552 | PUSH H 553 | CALL FCopyToBCDE 554 | POP H 555 | PUSH B 556 | PUSH D 557 | LXI B,8100h 558 | MOV D,C 559 | MOV E,D 560 | MOV A,M 561 | CPI 0x97 ;KWID_STEP 562 | MVI A,01h 563 | JNZ PushStepValue 564 | CALL EvalExpression+1 565 | PUSH H 566 | CALL FCopyToBCDE 567 | RST 05 ; FTestSign 568 | POP H 569 | PushStepValue PUSH B 570 | PUSH D 571 | PUSH PSW 572 | INX SP 573 | PUSH H 574 | LHLD PROG_PTR_TEMP 575 | XTHL 576 | EndOfForHandler MVI B,0x81 577 | PUSH B 578 | INX SP 579 | ExecNext CALL TestBreakKey 580 | MOV A,M 581 | CPI ':' 582 | JZ Exec 583 | ORA A 584 | JNZ SyntaxError 585 | INX H 586 | MOV A,M 587 | INX H 588 | ORA M 589 | INX H 590 | JZ Main 591 | MOV E,M 592 | INX H 593 | MOV D,M 594 | XCHG 595 | SHLD CURRENT_LINE 596 | XCHG 597 | Exec RST 02 ;RST NextChar 598 | LXI D,ExecNext 599 | PUSH D 600 | RZ 601 | SUI 80h 602 | JC Let 603 | CPI 0x14 604 | JNC SyntaxError 605 | RLC ;BC = A*2 606 | MOV C,A 607 | MVI B,00h 608 | XCHG 609 | LXI H,KW_GENERAL_FNS 610 | DAD B 611 | MOV C,M 612 | INX H 613 | MOV B,M 614 | PUSH B 615 | XCHG 616 | RST 02 ;RST NextChar 617 | RET 618 | NextChar_tail CPI ' ' 619 | JZ NextChar 620 | CPI '0' 621 | CMC 622 | INR A 623 | DCR A 624 | RET 625 | Restore XCHG 626 | LHLD PROGRAM_BASE 627 | DCX H 628 | L046E SHLD DATA_PROG_PTR 629 | XCHG 630 | RET 631 | TestBreakKey IN 00 ;Exit if no key pressed. 632 | ANI 01 ; 633 | RNZ ; 634 | CALL InputChar ; 635 | CPI 0x03 ;Break key? 636 | JMP Stop 637 | CharIsAlpha MOV A,M 638 | CPI 'A' 639 | RC 640 | CPI 'Z'+1 641 | CMC 642 | RET 643 | GetSubscript RST 02 ;RST NextChar 644 | CALL EvalExpression 645 | RST 05 ; FTestSign 646 | JM FunctionCallError 647 | LDA FACCUM+3 648 | CPI 0x90 649 | JC FAsInteger 650 | FunctionCallError MVI E,08h 651 | JMP Error 652 | LineNumberFromStr DCX H 653 | LXI D,0000 654 | NextLineNumChar RST 02 ;RST NextChar 655 | RNC 656 | PUSH H 657 | PUSH PSW ;Preserve flags 658 | LXI H,1998h ;Decimal 6552 659 | RST 4 660 | JC SyntaxError 661 | MOV H,D 662 | MOV L,E 663 | DAD D 664 | DAD H 665 | DAD D 666 | DAD H 667 | POP PSW 668 | SUI '0' 669 | MOV E,A 670 | MVI D,00h 671 | DAD D 672 | XCHG 673 | POP H 674 | JMP NextLineNumChar 675 | Gosub MVI C,03h 676 | CALL CheckEnoughVarSpace 677 | POP B 678 | PUSH H 679 | PUSH H 680 | LHLD CURRENT_LINE 681 | XTHL 682 | MVI D,0x8C 683 | PUSH D 684 | INX SP 685 | PUSH B 686 | Goto CALL LineNumberFromStr 687 | RNZ 688 | CALL FindProgramLine 689 | MOV H,B 690 | MOV L,C 691 | DCX H 692 | RC 693 | MVI E,0Eh 694 | JMP Error 695 | Return RNZ 696 | MVI D,0xFF 697 | CALL GetFlowPtr 698 | SPHL 699 | CPI 0x8C 700 | MVI E,04h 701 | JNZ Error 702 | POP H 703 | SHLD CURRENT_LINE 704 | LXI H,ExecNext 705 | XTHL 706 | FindNextStatement DB 013Ah ;LXI B,..3A 707 | Rem DB 10h 708 | NOP 709 | FindNextStatementLoop MOV A,M 710 | ORA A 711 | RZ 712 | CMP C 713 | RZ 714 | INX H 715 | JMP FindNextStatementLoop 716 | Let CALL GetVar 717 | RST 01 ; SyntaxCheck 718 | DB 9Dh 719 | AssignVar PUSH D 720 | CALL EvalExpression 721 | XTHL 722 | SHLD PROG_PTR_TEMP 723 | PUSH H 724 | CALL FCopyToMem 725 | POP D 726 | POP H 727 | RET 728 | If CALL EvalExpression 729 | MOV A,M 730 | CALL FPush 731 | MVI D,00 732 | GetCompareOpLoop SUI 9Ch ; KWID_> 733 | JC GotCompareOp 734 | CPI 0x03 735 | JNC GotCompareOp 736 | CPI 0x01 737 | RAL 738 | ORA D 739 | MOV D,A 740 | RST 02 ;RST NextChar 741 | JMP GetCompareOpLoop 742 | GotCompareOp MOV A,D 743 | ORA A 744 | JZ SyntaxError 745 | PUSH PSW 746 | CALL EvalExpression 747 | RST 01 ; SyntaxCheck 748 | DB 96h ;KWID_THEN 749 | DCX H 750 | POP PSW 751 | POP B 752 | POP D 753 | PUSH H 754 | PUSH PSW 755 | CALL FCompare 756 | INR A 757 | RAL 758 | POP B 759 | ANA B 760 | POP H 761 | JZ Rem 762 | RST 02 ;RST NextChar 763 | JC Goto 764 | JMP Exec+5 765 | DCX H 766 | RST 02 ;RST NextChar 767 | Print JZ NewLine 768 | RZ 769 | CPI '"' 770 | CZ PrintString-1 771 | JZ Print-2 772 | CPI 0x94 ;KWID_TAB 773 | JZ Tab 774 | PUSH H 775 | CPI ',' 776 | JZ ToNextTabBreak 777 | CPI ';' 778 | JZ ExitTab 779 | POP B 780 | CALL EvalExpression 781 | PUSH H 782 | CALL FOut 783 | CALL PrintString 784 | MVI A,' ' 785 | RST 03 ;RST OutChar 786 | POP H 787 | JMP Print-2 788 | TerminateInput MVI M,00h 789 | LXI H,LINE_BUFFER-1 790 | NewLine MVI A,0Dh 791 | STA TERMINAL_X 792 | RST 03 ;RST OutChar 793 | MVI A,0Ah 794 | RST 03 ;RST OutChar 795 | LDA TERMINAL_Y 796 | PrintNullLoop DCR A 797 | STA TERMINAL_X 798 | RZ 799 | PUSH PSW 800 | XRA A 801 | RST 03 ;RST OutChar 802 | POP PSW 803 | JMP PrintNullLoop 804 | INX H 805 | PrintString MOV A,M 806 | ORA A 807 | RZ 808 | INX H 809 | CPI '"' 810 | RZ 811 | RST 03 ;RST OutChar 812 | CPI 0x0D 813 | CZ NewLine 814 | JMP PrintString 815 | ToNextTabBreak LDA TERMINAL_X 816 | CPI 0x38 817 | CNC NewLine 818 | JNC ExitTab 819 | CalcSpaceCount SUI 0Eh 820 | JNC CalcSpaceCount 821 | CMA 822 | JMP PrintSpaces 823 | Tab CALL GetSubscript 824 | RST 01 ; SyntaxCheck 825 | DB 29h ;')' 826 | DCX H 827 | PUSH H 828 | LDA TERMINAL_X 829 | CMA 830 | ADD E 831 | JNC ExitTab 832 | PrintSpaces INR A 833 | MOV B,A 834 | MVI A,' ' 835 | PrintSpaceLoop RST 03 ;RST OutChar 836 | DCR B 837 | JNZ PrintSpaceLoop 838 | ExitTab POP H 839 | RST 02 ;RST NextChar 840 | JMP Print+3 841 | Input PUSH H 842 | LHLD CURRENT_LINE 843 | MVI E,16h 844 | INX H 845 | MOV A,L 846 | ORA H 847 | JZ Error 848 | CALL InputLineWith 849 | JMP L05FA+1 850 | Read PUSH H 851 | LHLD DATA_PROG_PTR 852 | L05FA ORI 0xAF 853 | ;XRA A 854 | STA INPUT_OR_READ 855 | XTHL 856 | DB 01 ;LXI B,.... 857 | ReadNext RST 01 ; SyntaxCheck 858 | DB 2Ch ;',' 859 | CALL GetVar 860 | XTHL 861 | PUSH D 862 | MOV A,M 863 | CPI ',' 864 | JZ GotDataItem 865 | ORA A 866 | JNZ SyntaxError 867 | LDA INPUT_OR_READ 868 | ORA A 869 | INX H 870 | JNZ NextDataLine+1 871 | MVI A,'?' 872 | RST 03 ;RST OutChar 873 | CALL InputLineWith 874 | GotDataItem POP D 875 | INX H 876 | CALL AssignVar 877 | XTHL 878 | DCX H 879 | RST 02 ;RST NextChar 880 | JNZ ReadNext 881 | POP D 882 | LDA INPUT_OR_READ 883 | ORA A 884 | RZ 885 | XCHG 886 | JNZ L046E 887 | NextDataLine POP H 888 | RST 6 889 | MOV A,C 890 | ORA B 891 | MVI E,06h 892 | JZ Error 893 | INX H 894 | RST 02 ;RST NextChar 895 | CPI 0x83 ;KWID_DATA 896 | JNZ NextDataLine 897 | POP B 898 | JMP GotDataItem 899 | Next CALL GetVar 900 | SHLD PROG_PTR_TEMP 901 | CALL GetFlowPtr 902 | SPHL 903 | PUSH D 904 | MOV A,M 905 | INX H 906 | PUSH PSW 907 | PUSH D 908 | MVI E,00h 909 | JNZ Error 910 | CALL FLoadFromMem 911 | XTHL 912 | PUSH H 913 | CALL FAddMem 914 | POP H 915 | CALL FCopyToMem 916 | POP H 917 | CALL FLoadBCDEfromMem 918 | PUSH H 919 | CALL FCompare 920 | POP H 921 | POP B 922 | SUB B 923 | CALL FLoadBCDEfromMem 924 | JZ ForLoopIsComplete 925 | XCHG 926 | SHLD CURRENT_LINE 927 | MOV L,C 928 | MOV H,B 929 | JMP EndOfForHandler 930 | ForLoopIsComplete SPHL 931 | LHLD PROG_PTR_TEMP 932 | JMP ExecNext 933 | EvalExpression DCX H 934 | MVI D,00h 935 | PUSH D 936 | MVI C,01h 937 | CALL CheckEnoughVarSpace 938 | CALL EvalTerm 939 | SHLD L015F 940 | ArithParse LHLD L015F 941 | POP B 942 | MOV A,M 943 | MVI D,00h 944 | SUI 0x98 ;KWID_PLUS 945 | RC 946 | CPI 0x04 947 | RNC 948 | MOV E,A 949 | RLC 950 | ADD E 951 | MOV E,A 952 | LXI H,KW_ARITH_OP_FNS 953 | DAD D 954 | MOV A,B 955 | MOV D,M 956 | CMP D 957 | RNC 958 | INX H 959 | PUSH B 960 | LXI B,ArithParse 961 | PUSH B 962 | MOV C,D ;??? 963 | CALL FPush 964 | MOV D,C 965 | RST 6 966 | LHLD L015F 967 | JMP EvalExpression+3 968 | EvalTerm RST 02 ;RST NextChar 969 | JC FIn 970 | CALL CharIsAlpha 971 | JNC EvalVarTerm 972 | CPI 0x98 ;KWID_PLUS 973 | JZ EvalTerm 974 | CPI '.' 975 | JZ FIn 976 | CPI 0x99 ;KWID_MINUS 977 | JZ EvalMinusTerm 978 | SUI 9Fh 979 | JNC EvalInlineFn 980 | EvalBracketed RST 01 ; SyntaxCheck 981 | DB 28h ;'(' 982 | CALL EvalExpression 983 | RST 01 ; SyntaxCheck 984 | DB 29h ;')' 985 | RET 986 | EvalMinusTerm CALL EvalTerm 987 | PUSH H 988 | CALL FNegate 989 | POP H 990 | RET 991 | EvalVarTerm CALL GetVar 992 | PUSH H 993 | XCHG 994 | CALL FLoadFromMem 995 | POP H 996 | RET 997 | EvalInlineFn MVI B,00h 998 | RLC 999 | MOV C,A 1000 | PUSH B 1001 | RST 02 ;RST NextChar 1002 | CALL EvalBracketed 1003 | XTHL 1004 | LXI D,06F1h 1005 | PUSH D 1006 | LXI B,KW_INLINE_FNS 1007 | DAD B 1008 | RST 6 1009 | RET 1010 | DimContd DCX H 1011 | RST 02 ;RST NextChar 1012 | RZ 1013 | RST 01 ; SyntaxCheck 1014 | DB 2Ch ;',' 1015 | Dim LXI B,DimContd 1016 | PUSH B 1017 | DB 0xF6 1018 | GetVar XRA A 1019 | STA DIM_OR_EVAL 1020 | MOV B,M 1021 | CALL CharIsAlpha 1022 | JC SyntaxError 1023 | XRA A 1024 | MOV C,A 1025 | RST 02 ;RST NextChar 1026 | JNC 072Eh 1027 | MOV C,A 1028 | RST 02 ;RST NextChar 1029 | SUI '(' 1030 | JZ GetArrayVar 1031 | PUSH H 1032 | LHLD VAR_ARRAY_BASE 1033 | XCHG 1034 | LHLD VAR_BASE 1035 | FindVarLoop RST 4 1036 | JZ AllocNewVar 1037 | MOV A,C 1038 | SUB M 1039 | INX H 1040 | JNZ L0747 1041 | MOV A,B 1042 | SUB M 1043 | L0747 INX H 1044 | JZ L0782 1045 | INX H 1046 | INX H 1047 | INX H 1048 | INX H 1049 | JMP FindVarLoop 1050 | AllocNewVar POP H ;HL=prog ptr 1051 | XTHL ;(SP)=prog ptr, HL=ret.addr. 1052 | PUSH D ; 1053 | LXI D,06F6h ;an address inside EvalTerm 1054 | RST 4 ; 1055 | POP D ; 1056 | JZ AlreadyAllocd ; 1057 | XTHL ;(SP)=ret.addr, HL=prog ptr. 1058 | PUSH H ;Prog ptr back on stack 1059 | PUSH B ;Preserve var name on stack 1060 | LXI B,0006h 1061 | LHLD VAR_TOP 1062 | PUSH H 1063 | DAD B 1064 | POP B 1065 | PUSH H 1066 | CALL CopyMemoryUp 1067 | POP H 1068 | SHLD VAR_TOP 1069 | MOV H,B 1070 | MOV L,C 1071 | SHLD VAR_ARRAY_BASE 1072 | InitVarLoop DCX H 1073 | MVI M,00h 1074 | RST 4 1075 | JNZ InitVarLoop 1076 | POP D 1077 | MOV M,E 1078 | INX H 1079 | MOV M,D 1080 | INX H 1081 | L0782 XCHG 1082 | POP H 1083 | RET 1084 | AlreadyAllocd STA FACCUM+3 ;A was set to zero at 075A. 1085 | POP H 1086 | RET 1087 | GetArrayVar PUSH B 1088 | LDA DIM_OR_EVAL 1089 | PUSH PSW 1090 | CALL GetSubscript 1091 | RST 01 ; SyntaxCheck 1092 | DB 29h ;')' 1093 | POP PSW 1094 | STA DIM_OR_EVAL 1095 | XTHL 1096 | XCHG 1097 | DAD H 1098 | DAD H 1099 | PUSH H 1100 | LHLD VAR_ARRAY_BASE 1101 | DB 0x01 ;LXI B,.... 1102 | FindArray POP B 1103 | DAD B 1104 | XCHG 1105 | PUSH H 1106 | LHLD VAR_TOP 1107 | RST 4 1108 | XCHG 1109 | POP D 1110 | JZ AllocArray 1111 | RST 6 1112 | XTHL 1113 | RST 4 1114 | POP H 1115 | RST 6 1116 | JNZ FindArray 1117 | LDA DIM_OR_EVAL 1118 | ORA A 1119 | MVI E,12h 1120 | JNZ Error 1121 | L07BF POP D 1122 | DCX D 1123 | XTHL 1124 | RST 4 1125 | MVI E,10h 1126 | JNC Error 1127 | POP D 1128 | DAD D 1129 | POP D 1130 | XCHG 1131 | RET 1132 | AllocArray MOV M,E 1133 | INX H 1134 | MOV M,D 1135 | INX H 1136 | LXI D,002Ch 1137 | LDA DIM_OR_EVAL 1138 | ORA A 1139 | JZ L07E1 1140 | POP D 1141 | PUSH D 1142 | INX D 1143 | INX D 1144 | INX D 1145 | INX D 1146 | L07E1 PUSH D 1147 | MOV M,E 1148 | INX H 1149 | MOV M,D 1150 | INX H 1151 | PUSH H 1152 | DAD D 1153 | CALL CheckEnoughMem 1154 | SHLD VAR_TOP 1155 | POP D 1156 | InitElements DCX H 1157 | MVI M,00h 1158 | RST 4 1159 | JNZ InitElements 1160 | JMP L07BF 1161 | FWordToFloat MOV D,B 1162 | MVI E,00h 1163 | MVI B,90h ;exponent=2^16 1164 | JMP FCharToFloat+5 ; 1165 | FAddOneHalf LXI H,ONE_HALF ;Load BCDE with (float) 0.5. 1166 | FAddMem CALL FLoadBCDEfromMem 1167 | JMP FAdd+2 1168 | FSub POP B ;Get lhs in BCDE. 1169 | POP D ; 1170 | CALL FNegate ;Negate rhs and slimily 1171 | DB 0x21 ;LXI H,.... ;LXI into FAdd + 2. 1172 | FAdd POP B ;Get lhs in BCDE. 1173 | POP D ; 1174 | MOV A,B ;If lhs==0 then we don't need 1175 | ORA A ;to do anything and can just 1176 | RZ ;exit. 1177 | LDA FACCUM+3 ;If rhs==0 then exit via a copy 1178 | ORA A ;of lhs to FACCUM. 1179 | JZ FLoadFromBCDE ; 1180 | SUB B ;A=rhs.exponent-lhs.exponent. 1181 | JNC L082C ;If rhs' exponent >= lhs'exponent, jump ahead. 1182 | CMA ;Two's complement the exponent 1183 | INR A ;difference, so it's correct. 1184 | XCHG ; 1185 | CALL FPush ;Push old rhs 1186 | XCHG ; 1187 | CALL FLoadFromBCDE ;rhs = old lhs 1188 | POP B ;lhs = old rhs. 1189 | POP D ; 1190 | L082C PUSH PSW ;Preserve exponent diff 1191 | CALL FUnpackMantissas 1192 | MOV H,A ;H=sign relationship 1193 | POP PSW ;A=exponent diff. 1194 | CALL FMantissaRtMult ;Shift lhs mantissa right by (exponent diff) places. 1195 | ORA H ;A=0 after last call, so this tests 1196 | LXI H,FACCUM ;the sign relationship. 1197 | JP FSubMantissas ;Jump ahead if we need to subtract. 1198 | CALL FAddMantissas ; 1199 | JNC FRoundUp ;Jump ahead if that didn't overflow. 1200 | INX H ;Flip the sign in FTEMP_SIGN. 1201 | INR M ; 1202 | JZ Overflow ;Error out if exponent overflowed. 1203 | CALL FMantissaRtOnce;Shift mantissa one place right 1204 | JMP FRoundUp ;Jump ahead. 1205 | FSubMantissas XRA A ;B=0-B 1206 | SUB B ; 1207 | MOV B,A ; 1208 | MOV A,M ;E=(FACCUM)-E 1209 | SBB E ; 1210 | MOV E,A ; 1211 | INX H ; 1212 | MOV A,M ;D=(FACCUM+1)-D 1213 | SBB D 1214 | MOV D,A 1215 | INX H 1216 | MOV A,M ;C=(FACCUM+2)-C 1217 | SBB C ; 1218 | MOV C,A ; 1219 | FNormalise CC FNegateInt ; 1220 | MVI H,00h ; 1221 | MOV A,C ;Test most-significant bit of mantissa 1222 | ORA A ;and jump ahead if it's 1. 1223 | JM FRoundUp ; 1224 | NormLoop CPI 0xE0 ;If we've shifted 32 times, 1225 | JZ FZero ;then the number is 0. 1226 | DCR H ; 1227 | MOV A,B ;Left-shift extra mantissa byte 1228 | ADD A ; 1229 | MOV B,A ; 1230 | CALL FMantissaLeft ;Left-shift mantissa. 1231 | MOV A,H ; 1232 | JP NormLoop ;Loop 1233 | LXI H,FACCUM+3 ; 1234 | ADD M ; 1235 | MOV M,A ;Since A was a -ve number, that certainly should 1236 | JNC FZero ;have carried, hence the extra check for zero. 1237 | RZ ;?why? 1238 | FRoundUp MOV A,B ;A=extra mantissa byte 1239 | LXI H,FACCUM+3 ; 1240 | ORA A ;If bit 7 of the extra mantissa byte 1241 | CM FMantissaInc ;is set, then round up the mantissa. 1242 | MOV B,M ;B=exponent 1243 | INX H ; 1244 | MOV A,M ;A=FTEMP_SIGN 1245 | ANI 0x80 ; 1246 | XRA C ;Bit 7 of C is always 1. Thi 1247 | MOV C,A ; 1248 | JMP FLoadFromBCDE ;Exit via copying BCDE to FACCUM. 1249 | FMantissaLeft MOV A,E 1250 | RAL 1251 | MOV E,A 1252 | MOV A,D 1253 | RAL 1254 | MOV D,A 1255 | MOV A,C 1256 | ADC A 1257 | MOV C,A 1258 | RET 1259 | FMantissaInc INR E 1260 | RNZ 1261 | INR D 1262 | RNZ 1263 | INR C 1264 | RNZ 1265 | MVI C,80h ;Mantissa overflowed to zero, so set it 1266 | INR M ;to 1 and increment the exponent. 1267 | RNZ ;And if the exponent overflows... 1268 | Overflow MVI E,0Ah 1269 | JMP Error 1270 | FAddMantissas MOV A,M 1271 | ADD E 1272 | MOV E,A 1273 | INX H 1274 | MOV A,M 1275 | ADC D 1276 | MOV D,A 1277 | INX H 1278 | MOV A,M 1279 | ADC C 1280 | MOV C,A 1281 | RET 1282 | FNegateInt LXI H,FTEMP 1283 | MOV A,M 1284 | CMA 1285 | MOV M,A 1286 | XRA A 1287 | MOV L,A 1288 | SUB B 1289 | MOV B,A 1290 | MOV A,L 1291 | SBB E 1292 | MOV E,A 1293 | MOV A,L 1294 | SBB D 1295 | MOV D,A 1296 | MOV A,L 1297 | SBB C 1298 | MOV C,A 1299 | RET 1300 | FMantissaRtMult MVI B,00h ;Initialise extra mantissa byte 1301 | INR A 1302 | MOV L,A 1303 | RtMultLoop XRA A 1304 | DCR L 1305 | RZ 1306 | CALL FMantissaRtOnce 1307 | JMP RtMultLoop 1308 | FMantissaRtOnce MOV A,C 1309 | RAR 1310 | MOV C,A 1311 | MOV A,D 1312 | RAR 1313 | MOV D,A 1314 | MOV A,E 1315 | RAR 1316 | MOV E,A 1317 | MOV A,B ;NB: B is the extra 1318 | RAR ;mantissa byte. 1319 | MOV B,A ; 1320 | RET ; 1321 | FMul POP B ;Get lhs in BCDE 1322 | POP D ; 1323 | RST 05 ; FTestSign ;If rhs==0 then exit 1324 | RZ ; 1325 | MVI L,00h ;L=0 to signify exponent add 1326 | CALL FExponentAdd 1327 | MOV A,C 1328 | STA FMulInnerLoop+13 1329 | XCHG 1330 | SHLD FMulInnerLoop+8 1331 | LXI B,0000h 1332 | MOV D,B 1333 | MOV E,B 1334 | LXI H,FNormalise+3 1335 | PUSH H 1336 | LXI H,FMulOuterLoop 1337 | PUSH H 1338 | PUSH H 1339 | LXI H,FACCUM 1340 | FMulOuterLoop MOV A,M ;A=FACCUM mantissa byte 1341 | INX H ; 1342 | PUSH H ;Preserve FACCUM ptr 1343 | MVI L,08h ;8 bits to do 1344 | FMulInnerLoop RAR ;Test lowest bit of mantissa byte 1345 | MOV H,A ;Preserve mantissa byte 1346 | MOV A,C ;A=result mantissa's high byte 1347 | JNC L0919 ;If that bit of multiplicand was 0, then skip over adding mantissas. 1348 | PUSH H ; 1349 | LXI H,0000h ; 1350 | DAD D ; 1351 | POP D ; 1352 | ACI 00 ;A=result mantissa high byte. This gets back to C 1353 | XCHG ;in the call to FMantissaRtOnce+1. 1354 | L0919 CALL FMantissaRtOnce+1 1355 | DCR L 1356 | MOV A,H ;Restore mantissa byte and 1357 | JNZ FMulInnerLoop ;jump back if L is not yet 0. 1358 | PopHLandReturn POP H ;Restore FACCUM ptr 1359 | RET ;Return to FMulOuterLoop, or if finished that then exit to FNormalise 1360 | FDivByTen CALL FPush ; 1361 | LXI B,8420h ;BCDE=(float)10; 1362 | LXI D,0000h 1363 | CALL FLoadFromBCDE 1364 | FDiv POP B 1365 | POP D 1366 | RST 05 ; FTestSign 1367 | JZ DivideByZero 1368 | MVI L,0xFF 1369 | CALL FExponentAdd 1370 | INR M 1371 | INR M 1372 | DCX H 1373 | MOV A,M 1374 | STA L095F+1 1375 | DCX H 1376 | MOV A,M 1377 | STA L095F-3 1378 | DCX H 1379 | MOV A,M 1380 | STA L095F-7 1381 | MOV B,C 1382 | XCHG 1383 | XRA A 1384 | MOV C,A 1385 | MOV D,A 1386 | MOV E,A 1387 | STA L095F+4 1388 | FDivLoop PUSH H 1389 | PUSH B 1390 | MOV A,L 1391 | SUI 00h 1392 | MOV L,A 1393 | MOV A,H 1394 | SBI 00 1395 | MOV H,A 1396 | MOV A,B 1397 | L095F SBI 00 1398 | MOV B,A 1399 | MVI A,00h 1400 | SBI 00 1401 | CMC 1402 | JNC L0971 1403 | STA L095F+4h 1404 | POP PSW 1405 | POP PSW 1406 | STC 1407 | DB 0xD2 ;JNC .... 1408 | L0971 POP B 1409 | POP H 1410 | MOV A,C 1411 | INR A 1412 | DCR A 1413 | RAR 1414 | JM FRoundUp+1 1415 | RAL 1416 | CALL FMantissaLeft 1417 | DAD H 1418 | MOV A,B 1419 | RAL 1420 | MOV B,A 1421 | LDA L095F+4h 1422 | RAL 1423 | STA L095F+4h 1424 | MOV A,C 1425 | ORA D 1426 | ORA E 1427 | JNZ FDivLoop 1428 | PUSH H 1429 | LXI H,FACCUM+3 1430 | DCR M 1431 | POP H 1432 | JNZ FDivLoop 1433 | JMP Overflow 1434 | FExponentAdd MOV A,B 1435 | ORA A 1436 | JZ FExponentAdd+31 1437 | MOV A,L ;A=0 for add, FF for subtract. 1438 | LXI H,FACCUM+3 ; 1439 | XRA M ;XOR with FAccum's exponent. 1440 | ADD B ;Add exponents 1441 | MOV B,A ; 1442 | RAR ;Carry (after the add) into bit 7. 1443 | XRA B ;XOR with old bit 7. 1444 | MOV A,B ; 1445 | JP FExponentAdd+30 ;If 1446 | ADI 0x80 1447 | MOV M,A 1448 | JZ PopHLandReturn 1449 | CALL FUnpackMantissas 1450 | MOV M,A 1451 | DCX H 1452 | RET 1453 | ORA A 1454 | POP H ;Ignore return address so we'll end 1455 | JM Overflow 1456 | FZero XRA A 1457 | STA FACCUM+3 1458 | RET 1459 | FMulByTen CALL FCopyToBCDE 1460 | MOV A,B 1461 | ORA A 1462 | RZ 1463 | ADI 02 1464 | JC Overflow 1465 | MOV B,A 1466 | CALL FAdd+2 1467 | LXI H,FACCUM+3 1468 | INR M 1469 | RNZ 1470 | JMP Overflow 1471 | FTestSign_tail LDA FACCUM+2 1472 | DB 0xFE 1473 | InvSignToInt CMA 1474 | SignToInt RAL 1475 | SBB A 1476 | RNZ 1477 | INR A 1478 | RET 1479 | Sgn RST 05 ; FTestSign 1480 | FCharToFloat MVI B,88h ;ie 2^8 1481 | LXI D,0000h 1482 | LXI H,FACCUM+3 1483 | MOV C,A 1484 | MOV M,B 1485 | MVI B,00h 1486 | INX H 1487 | MVI M,80h 1488 | RAL 1489 | JMP FNormalise 1490 | Abs RST 05 ; FTestSign 1491 | RP 1492 | FNegate LXI H,FACCUM+2 1493 | MOV A,M 1494 | XRI 0x80 1495 | MOV M,A 1496 | RET 1497 | FPush XCHG 1498 | LHLD FACCUM 1499 | XTHL 1500 | PUSH H 1501 | LHLD FACCUM+2 1502 | XTHL 1503 | PUSH H 1504 | XCHG 1505 | RET 1506 | FLoadFromMem CALL FLoadBCDEfromMem 1507 | FLoadFromBCDE XCHG 1508 | SHLD FACCUM 1509 | MOV H,B 1510 | MOV L,C 1511 | SHLD FACCUM+2 1512 | XCHG 1513 | RET 1514 | FCopyToBCDE LXI H,FACCUM 1515 | FLoadBCDEfromMem MOV E,M 1516 | INX H 1517 | MOV D,M 1518 | INX H 1519 | MOV C,M 1520 | INX H 1521 | MOV B,M 1522 | IncHLReturn INX H 1523 | RET 1524 | FCopyToMem LXI D,FACCUM 1525 | MVI B,04h 1526 | FCopyLoop LDAX D 1527 | MOV M,A 1528 | INX D 1529 | INX H 1530 | DCR B 1531 | JNZ FCopyLoop 1532 | RET 1533 | FUnpackMantissas LXI H,FACCUM+2 1534 | MOV A,M ; 1535 | RLC ;Move FACCUM's sign to bit 0. 1536 | STC ;Set MSB of FACCUM mantissa, 1537 | RAR ;FACCUM's sign is now in carry. 1538 | MOV M,A ; 1539 | CMC ;Negate FACCUM's sign. 1540 | RAR ;Bit 7 of A is now FACCUM's sign. 1541 | INX H ;Store negated FACCUM sign at FTEMP_SIGN. 1542 | INX H ; 1543 | MOV M,A ; 1544 | MOV A,C ; 1545 | RLC ;Set MSB of BCDE mantissa, 1546 | STC ;BCDE's sign is now in carry. 1547 | RAR ; 1548 | MOV C,A ; 1549 | RAR ;Bit 7 of A is now BCDE's sign 1550 | XRA M ;XORed with FTEMP_SIGN. 1551 | RET ; 1552 | FCompare MOV A,B 1553 | ORA A 1554 | JZ FTestSign 1555 | LXI H,InvSignToInt 1556 | PUSH H 1557 | RST 05 ; FTestSign 1558 | MOV A,C 1559 | RZ 1560 | LXI H,FACCUM+2 1561 | XRA M 1562 | MOV A,C 1563 | RM 1564 | CALL FIsEqual 1565 | RAR 1566 | XRA C 1567 | RET 1568 | FIsEqual INX H 1569 | MOV A,B 1570 | CMP M 1571 | RNZ 1572 | DCX H 1573 | MOV A,C 1574 | CMP M 1575 | RNZ 1576 | DCX H 1577 | MOV A,D 1578 | CMP M 1579 | RNZ 1580 | DCX H 1581 | MOV A,E 1582 | SUB M 1583 | RNZ ; 1584 | POP H ;Lose 0A5E 1585 | POP H ;Lose 09DE 1586 | RET ;Return to caller 1587 | FAsInteger MOV B,A ; 1588 | MOV C,A 1589 | MOV D,A 1590 | MOV E,A 1591 | ORA A 1592 | RZ 1593 | PUSH H 1594 | CALL FCopyToBCDE 1595 | CALL FUnpackMantissas 1596 | XRA M ;Get sign back 1597 | MOV H,A 1598 | CM FMantissaDec 1599 | MVI A,98h 1600 | SUB B ;by (24-exponent) places? 1601 | CALL FMantissaRtMult ;WHY? 1602 | MOV A,H 1603 | RAL 1604 | CC FMantissaInc 1605 | MVI B,00h ;Needed for FNegateInt. 1606 | CC FNegateInt 1607 | POP H 1608 | RET 1609 | FMantissaDec DCX D ;DE-- 1610 | MOV A,D ;If DE!=0xFFFF... 1611 | ANA E ; 1612 | INR A ; 1613 | RNZ ;... then return 1614 | DCR C ;C-- 1615 | RET ; 1616 | Int LXI H,FACCUM+3 ; 1617 | MOV A,M ; 1618 | CPI 0x98 ; 1619 | RNC ; 1620 | CALL FAsInteger ; 1621 | MVI M,98h ; 1622 | MOV A,C ; 1623 | RAL ; 1624 | JMP FNormalise ; 1625 | FIn DCX H ; 1626 | CALL FZero ; 1627 | MOV B,A ;B=count of fractional digits 1628 | MOV D,A ;D=exponent sign 1629 | MOV E,A ;E=exponent 1630 | CMA ;C=decimal_point_done (0xFF for no, 0x00 for yes) 1631 | MOV C,A ; 1632 | FInLoop RST 02 ;RST NextChar 1633 | JC ProcessDigit 1634 | CPI '.' 1635 | JZ L0AE4 1636 | CPI 'E' 1637 | JNZ ScaleResult 1638 | GetExponent RST 02 ;RST NextChar 1639 | DCR D 1640 | CPI 0x99 ;KWID_MINUS 1641 | JZ NextExponentDigit 1642 | INR D 1643 | CPI 0x98 ;KWID_PLUS 1644 | JZ NextExponentDigit 1645 | DCX H 1646 | NextExponentDigit RST 02 ;RST NextChar 1647 | JC DoExponentDigit 1648 | INR D 1649 | JNZ ScaleResult 1650 | XRA A 1651 | SUB E 1652 | MOV E,A 1653 | INR C ;C was 0xFF, so here it 1654 | L0AE4 INR C ;becomes 0x01. 1655 | JZ FInLoop ;If C is now zero 1656 | ScaleResult PUSH H 1657 | MOV A,E 1658 | SUB B 1659 | DecimalLoop CP DecimalShiftUp 1660 | JP DecimalLoopEnd 1661 | PUSH PSW 1662 | CALL FDivByTen 1663 | POP PSW 1664 | INR A 1665 | DecimalLoopEnd JNZ DecimalLoop 1666 | POP H 1667 | RET 1668 | DecimalShiftUp RZ 1669 | PUSH PSW 1670 | CALL FMulByTen 1671 | POP PSW 1672 | DCR A 1673 | RET 1674 | ProcessDigit PUSH D 1675 | MOV D,A 1676 | MOV A,B 1677 | ADC C 1678 | MOV B,A 1679 | PUSH B 1680 | PUSH H 1681 | PUSH D 1682 | CALL FMulByTen 1683 | POP PSW 1684 | SUI '0' 1685 | CALL FPush 1686 | CALL FCharToFloat 1687 | POP B 1688 | POP D 1689 | CALL FAdd+2 1690 | POP H 1691 | POP B 1692 | POP D 1693 | JMP FInLoop 1694 | DoExponentDigit MOV A,E 1695 | RLC 1696 | RLC 1697 | ADD E 1698 | RLC 1699 | ADD M 1700 | SUI '0' 1701 | MOV E,A 1702 | JMP NextExponentDigit 1703 | PrintIN PUSH H 1704 | LXI H,szIn 1705 | CALL PrintString 1706 | POP H 1707 | PrintInt XCHG ;DE=integer 1708 | XRA A ;A=0 (ends up in C) 1709 | MVI B,98h ;B (ie exponent) = 24 1710 | CALL FCharToFloat+5 1711 | LXI H,PrintString-1 1712 | PUSH H 1713 | FOut LXI H,FBUFFER 1714 | PUSH H 1715 | RST 05 ; FTestSign 1716 | MVI M,' ' 1717 | JP DoZero 1718 | MVI M,'-' 1719 | DoZero INX H 1720 | MVI M,'0' 1721 | JZ NullTerm-3 1722 | PUSH H 1723 | CM FNegate 1724 | XRA A 1725 | PUSH PSW 1726 | CALL ToUnder1000000 1727 | ToOver100000 LXI B,9143h ;BCDE=(float)100,000. 1728 | LXI D,4FF8h ; 1729 | CALL FCompare ;If FACCUM >= 100,000 1730 | JPO PrepareToPrint ;then jump to PrepareToPrint. 1731 | POP PSW ;A=DecExpAdj 1732 | CALL DecimalShiftUp+1 ;FACCUM*=10; DecExpAdj--; 1733 | PUSH PSW ; 1734 | JMP ToOver100000 1735 | L0B71 CALL FDivByTen 1736 | POP PSW 1737 | INR A ;DecExpAdj++; 1738 | PUSH PSW 1739 | CALL ToUnder1000000 1740 | PrepareToPrint CALL FAddOneHalf 1741 | INR A 1742 | CALL FAsInteger 1743 | CALL FLoadFromBCDE 1744 | LXI B,0206h 1745 | POP PSW ;A=DecExpAdj+6. 1746 | ADD C ; 1747 | JM L0B95 ;If A<1 or A>6 Then goto fixme. 1748 | CPI 0x07 ; 1749 | JNC L0B95 ; 1750 | INR A ; 1751 | MOV B,A ; 1752 | MVI A,01h ;A=1, indicating scientific notation. 1753 | L0B95 DCR A ; 1754 | POP H ;HL=output buffer 1755 | PUSH PSW ;Preserve decimal exponent adjustment (and preserve zero flag used to indicate scientific notation wanted). 1756 | LXI D,DECIMAL_POWERS 1757 | NextDigit DCR B 1758 | MVI M,'.' 1759 | CZ IncHLReturn ;0A27 just happens to inc HL and RET. 1760 | PUSH B ; 1761 | PUSH H ; 1762 | PUSH D ;DE=>decimal power 1763 | CALL FCopyToBCDE ;Store BCDE to FACCUM. 1764 | POP H ;HL=>decimal power. 1765 | MVI B,'0'-1 ; 1766 | DigitLoop INR B ; 1767 | MOV A,E ; 1768 | SUB M ; 1769 | MOV E,A ; 1770 | INX H ; 1771 | MOV A,D ; 1772 | SBB M ; 1773 | MOV D,A ; 1774 | INX H ; 1775 | MOV A,C ; 1776 | SBB M ; 1777 | MOV C,A ; 1778 | DCX H ; 1779 | DCX H ; 1780 | JNC DigitLoop ; 1781 | CALL FAddMantissas ; 1782 | INX H ;??? 1783 | CALL FLoadFromBCDE ; 1784 | XCHG ; 1785 | POP H ;HL=output buffer 1786 | MOV M,B ; 1787 | INX H ; 1788 | POP B ;B=decimal point place 1789 | DCR C ;C=digits remaining, minus one. 1790 | JNZ NextDigit ; 1791 | DCR B ; 1792 | JZ L0BDB ; 1793 | L0BCF DCX H ; 1794 | MOV A,M ; 1795 | CPI '0' ; 1796 | JZ L0BCF ; 1797 | CPI '.' ; 1798 | CNZ IncHLReturn ; 1799 | L0BDB POP PSW ; 1800 | JZ NullTerm ; 1801 | MVI M,'E' ;Write 'E' 1802 | INX H ; 1803 | MVI M,'+' ;Write '+' or '-' 1804 | JP L0BEB ; 1805 | MVI M,'-' ;Write '-' if it's negative, also 1806 | CMA ;two's complement the decimal exponent 1807 | INR A ;so printing it will work. 1808 | L0BEB MVI B,'0'-1 ; 1809 | ExpDigitLoop INR B ; 1810 | SUI 0Ah ; 1811 | JNC ExpDigitLoop ; 1812 | ADI 3Ah ;Adding '0'+10 gives us the 2nd digit 1813 | INX H ;of the exponent. 1814 | MOV M,B ;Write first digit. 1815 | INX H ; 1816 | MOV M,A ;Write second digit of exponent. 1817 | INX H ; 1818 | NullTerm MOV M,C ;Null byte terminator. 1819 | POP H ; 1820 | RET ; 1821 | ToUnder1000000 LXI B,9474h ; 1822 | LXI D,23F7h ; 1823 | CALL FCompare ; 1824 | POP H ; 1825 | JPO L0B71 ; 1826 | PCHL ; 1827 | ONE_HALF DB 0x00,0x00,0x00,0x80 ; DD 0.5 1828 | DECIMAL_POWERS DB 0xA0,0x86,0x01 ; DT 100000 1829 | DB 0x10,0x27,0x00 ; DT 10000 1830 | DB 0xE8,0x03,0x00 ; DT 1000 1831 | DB 0x64,0x00,0x00 ; DT 100 1832 | DB 0x0A,0x00,0x00 ; DT 10 1833 | DB 0x01,0x00,0x00 ; DT 1 1834 | Sqr RST 05 ; FTestSign ; 1835 | JM FunctionCallError; 1836 | RZ ; 1837 | LXI H,FACCUM+3 ; 1838 | MOV A,M ; 1839 | RAR ; 1840 | PUSH PSW ; 1841 | PUSH H ; 1842 | MVI A,40h ; 1843 | RAL ; 1844 | MOV M,A ; 1845 | LXI H,FBUFFER ; 1846 | CALL FCopyToMem ; 1847 | MVI A,04h ; 1848 | SqrLoop PUSH PSW ; 1849 | CALL FPush ; 1850 | LXI H,FBUFFER ; 1851 | CALL FLoadBCDEfromMem 1852 | CALL FDiv+2 1853 | POP B 1854 | POP D 1855 | CALL FAdd+2 1856 | LXI B,8000h 1857 | MOV D,C 1858 | MOV E,C 1859 | CALL FMul+2 1860 | POP PSW 1861 | DCR A 1862 | JNZ SqrLoop 1863 | POP H 1864 | POP PSW 1865 | ADI 0xC0 1866 | ADD M 1867 | MOV M,A 1868 | RET 1869 | Rnd RST 05 ; FTestSign 1870 | JM L0C7C 1871 | LXI H,RND_SEED 1872 | CALL FLoadFromMem 1873 | RZ 1874 | LXI B,9835h 1875 | LXI D,447Ah 1876 | CALL FMul+2 1877 | LXI B,0x6828 1878 | LXI D,0xB146 1879 | CALL FAdd+2 1880 | L0C7C CALL FCopyToBCDE 1881 | MOV A,E 1882 | MOV E,C 1883 | MOV C,A 1884 | MVI M,80h 1885 | DCX H 1886 | MOV B,M 1887 | MVI M,80h 1888 | CALL FNormalise+3 1889 | LXI H,RND_SEED 1890 | JMP FCopyToMem 1891 | RND_SEED DB 52C74F80h 1892 | Sin CALL FPush ;ush x 1893 | LXI B,8349h ;CDE=2p 1894 | LXI D,0FDBh ; 1895 | CALL FLoadFromBCDE ;hs = 2p 1896 | POP B ;hs = x 1897 | POP D ; 1898 | CALL FDiv+2 ;=x/2p 1899 | CALL FPush ; 1900 | CALL Int ;hs = INT(u) 1901 | POP B ;hs = u 1902 | POP D ; 1903 | CALL FSub+2 ;=u-INT(u) 1904 | LXI B,7F00h ;CDE=0.25 1905 | MOV D,C ; 1906 | MOV E,C ; 1907 | CALL FSub+2 ; 1908 | RST 05 ; FTestSign ; 1909 | STC ;set carry (ie no later negate) 1910 | JP NegateIfPositive ; 1911 | CALL FAddOneHalf ; 1912 | RST 05 ; 1913 | ORA A ;resets carry (ie later negate) 1914 | NegateIfPositive PUSH PSW ; 1915 | CP FNegate ; 1916 | LXI B,7F00h ;CDE=0.25 1917 | MOV D,C ; 1918 | MOV E,C ; 1919 | CALL FAdd+2 ; 1920 | POP PSW ; 1921 | CNC FNegate ; 1922 | CALL FPush ; 1923 | CALL FCopyToBCDE ; 1924 | CALL FMul+2 ; = x*x 1925 | CALL FPush ;ush x*x 1926 | LXI H,TAYLOR_SERIES ; 1927 | CALL FLoadFromMem ; 1928 | POP B ; 1929 | POP D ; 1930 | MVI A,04h ; 1931 | TaylorLoop PUSH PSW ;ush #terms remaining 1932 | PUSH D ;ush BCDE 1933 | PUSH B ; 1934 | PUSH H ; 1935 | CALL FMul+2 ; 1936 | POP H ; 1937 | CALL FLoadBCDEfromMem ; 1938 | PUSH H ; 1939 | CALL FAdd+2 ; 1940 | POP H ; 1941 | POP B ; 1942 | POP D ; 1943 | POP PSW ;op #terms remaining into A. 1944 | DCR A ;ecrement #terms and loop back if not 1945 | JNZ TaylorLoop ;one all 4 of them. 1946 | JMP FMul ; 1947 | TAYLOR_SERIES DB 0xBA,0xD7,0x1E,0x86 ;DD 39.710670 1948 | DB 0x64,0x26,0x99,0x87 ;DD -76.574982 1949 | DB 0x58,0x34,0x23,0x87 ;DD 81.602234 1950 | DB 0xE0,0x5D,0xA5,0x86 ;DD -41.341675 1951 | DB 0xDA,0x0F,0x49,0x83 ;DD 6.283185 1952 | L0D17 DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ; DD 6.283185 1953 | Init LXI H,0x0F1A ; *** STACK_TOP RELOCATE 1954 | SPHL ; 1955 | SHLD STACK_TOP ; 1956 | IN 01 ; 1957 | MVI C,0xFF ; 1958 | LXI D,ConfigIOcode ; 1959 | PUSH D ; 1960 | LDA 0FFFh ; *** RELOCATE 1961 | MOV B,A ; 1962 | IN 0xFF ; 1963 | RAR ; 1964 | JC L0D42-1 ; 1965 | ANI 0Ch ; 1966 | JZ L0D42 ; 1967 | MVI B,10h ; 1968 | MOV A,B ; 1969 | L0D42 STA L0D8D-1 ; 1970 | IN 0xFF ; 1971 | RAL ; 1972 | RAL ; 1973 | MVI B,20h ; 1974 | L0D4B LXI D,0xCA02 ; 1975 | RC ; 1976 | RAL ; 1977 | MOV B,E ; 1978 | DCR E ; 1979 | RC ; 1980 | RAL ; 1981 | JC L0D6F ; 1982 | MOV B,E ; 1983 | LXI D,0xC280 ; 1984 | RAL ; 1985 | RNC ; 1986 | RAL ; 1987 | MVI A,03h ; 1988 | CALL L0D8B ; 1989 | DCR A ; 1990 | ADC A ; 1991 | ADD A ; 1992 | ADD A ; 1993 | INR A ; 1994 | CALL L0D8B ; 1995 | STC ; 1996 | JMP L0D4B ; 1997 | L0D6F XRA A ; 1998 | CALL L0D8B ; 1999 | CALL L0D87 ; 2000 | CALL L0D87 ; 2001 | MOV C,E ; 2002 | CMA ; 2003 | CALL L0D87 ; 2004 | MVI A,04h ; 2005 | DCR M ; 2006 | CALL L0D8B ; 2007 | DCR M ; 2008 | DCR M ; 2009 | DCR M ; 2010 | L0D87 LXI H,L0D8D-1 ; 2011 | INR M ; 2012 | L0D8B OUT 00 ; 2013 | L0D8D RET ; 2014 | ConfigIOcode MOV H,D ; 2015 | MOV L,B ; 2016 | SHLD InputChar+3 ; 2017 | MOV A,H ; 2018 | ANI 0xC8 ; 2019 | MOV H,A ; 2020 | SHLD TestBreakKey+3 ; 2021 | XCHG ; 2022 | SHLD WaitTermReady+3 ; 2023 | LDA L0D8D-1 ; 2024 | STA InputChar+1 ; 2025 | STA TestBreakKey+1 ; 2026 | INR A ; 2027 | STA InputChar+8 ; 2028 | ADD C ; 2029 | STA WaitTermReady+1 ; 2030 | INR A ; 2031 | STA InputChar-2 ; 2032 | LXI H,0xFFFF ; 2033 | SHLD CURRENT_LINE ; 2034 | CALL NewLine ; 2035 | LXI H,szMemorySize ; 2036 | CALL PrintString 2037 | CALL InputLineWith 2038 | RST 02 ;RST NextChar 2039 | ORA A 2040 | JNZ L0DDE 2041 | LXI H,UnusedMemory 2042 | FindMemTopLoop INX H 2043 | MVI A,37h 2044 | MOV M,A 2045 | CMP M 2046 | JNZ DoneMemSize 2047 | DCR A 2048 | MOV M,A 2049 | CMP M 2050 | JZ FindMemTopLoop 2051 | JMP DoneMemSize 2052 | L0DDE LXI H,LINE_BUFFER 2053 | CALL LineNumberFromStr 2054 | ORA A 2055 | JNZ SyntaxError 2056 | XCHG 2057 | DCX H 2058 | DoneMemSize DCX H 2059 | PUSH H 2060 | GetTerminalWidth LXI H,szTerminalWidth 2061 | CALL PrintString 2062 | CALL InputLineWith 2063 | RST 02 ;RST NextChar 2064 | ORA A 2065 | JZ DoOptionalFns 2066 | LXI H,LINE_BUFFER 2067 | CALL LineNumberFromStr 2068 | MOV A,D 2069 | ORA A 2070 | JNZ GetTerminalWidth 2071 | MOV A,E 2072 | CPI 0x10 2073 | JC GetTerminalWidth 2074 | STA OutChar_tail+1 2075 | CalcTabBrkSize SUI 0Eh 2076 | JNC CalcTabBrkSize 2077 | ADI 1Ch 2078 | CMA 2079 | INR A 2080 | ADD E 2081 | STA ToNextTabBreak+4 2082 | DoOptionalFns LXI H,OPT_FN_DESCS 2083 | OptionalFnsLoop RST 6 2084 | LXI D,szWantSin 2085 | RST 4 2086 | JZ L0E32 2087 | RST 6 2088 | XTHL 2089 | CALL PrintString 2090 | CALL InputLineWith 2091 | RST 02 ;RST NextChar 2092 | POP H 2093 | CPI 'Y' 2094 | L0E32 POP D 2095 | JZ InitProgramBase 2096 | CPI 'N' 2097 | JNZ DoOptionalFns 2098 | RST 6 2099 | XTHL 2100 | LXI D,FunctionCallError 2101 | MOV M,E 2102 | INX H 2103 | MOV M,D 2104 | POP H 2105 | JMP OptionalFnsLoop 2106 | InitProgramBase XCHG 2107 | MVI M,00h 2108 | INX H 2109 | SHLD PROGRAM_BASE 2110 | XTHL 2111 | LXI D,0F1Ah ; *** RELOCATE STACK_TOP 2112 | RST 4 2113 | JC OutOfMemory 2114 | POP D 2115 | SPHL 2116 | SHLD STACK_TOP 2117 | XCHG 2118 | CALL CheckEnoughMem 2119 | MOV A,E 2120 | SUB L 2121 | MOV L,A 2122 | MOV A,D 2123 | SBB H 2124 | MOV H,A 2125 | LXI B,0xFFF0 2126 | DAD B 2127 | CALL NewLine 2128 | CALL PrintInt 2129 | LXI H,szVersionInfo 2130 | CALL PrintString 2131 | LXI H,PrintString 2132 | SHLD Main+4 2133 | CALL New+1 2134 | LXI H,Main 2135 | SHLD Start+2 2136 | PCHL 2137 | 2138 | OPT_FN_DESCS DW L0D17 2139 | DW szWantSin 2140 | DW KW_INLINE_FNS+12 2141 | DW Sin 2142 | DW szWantRnd 2143 | DW KW_INLINE_FNS+10 2144 | DW Rnd 2145 | DW szWantSqr 2146 | DW KW_INLINE_FNS+8 2147 | 2148 | DW Sqr 2149 | 2150 | szWantSin DB 57414E54205349CE00h ; DS "WANT SIN\0" 2151 | szWantRnd DB 57414E5420524EC400h ; DS "WANT RND\0" 2152 | szWantSqr DB 57414E54205351D200h ; DS "WANT SQR\0" 2153 | 2154 | 2155 | szTerminalWidth DB 5445524D494E414C2057494454C800h ; DS "TERMINAL WIDTH\0" 2156 | 2157 | szVersionInfo DB 0x20,0x42,0x59,0x54,0x45,0x53,0x20,0x46,0x52,0x45,0xC5,0x0D,0x0D ; DS " BYTES FREE\r\r" 2158 | DB 0x42,0x41,0x53,0x49,0x43,0x20,0x56,0x45,0x52,0x53,0x49,0x4F,0x4E,0x20,0x33,0x2E ; "BASIC VERSION 3." 2159 | DB 0xB2,0x0D,0x5B,0x34,0x4B,0x20,0x56,0x45,0x52,0x53,0x49,0x4F,0x4E,0xDD,0x0D,0x00 ; "2\r[4K VERSION]\r\0" 2160 | szMemorySize DB 0x4D,0x45,0x4D,0x4F,0x52,0x59,0x20,0x53,0x49,0x5A,0xC5,0x00 ; DS "MEMORY SIZE\0" 2161 | 2162 | 2163 | 2164 | UnusedMemory DB 00 -------------------------------------------------------------------------------- /BASIC disassembly-source.lst: -------------------------------------------------------------------------------- 1 | ; -------------------------------------- 2 | ; zasm: assemble "BASIC disassembly-source.txt" 3 | ; opts: --asm8080 4 | ; date: 2019-03-10 19:52:16 5 | ; -------------------------------------- 6 | 7 | 8 | ; ---------------------------------------------------------------------------- 9 | ;Micro-Soft Altair BASIC 3.2 (4K) - Annotated Disassembly 10 | ; 11 | ;Copyright 1975, Bill Gates, Paul Allen, Monte Davidoff 12 | ;Source: http://altairbasic.org/ compiled by Reuben Harris 13 | ;Additional cleanup, relocation by Charles Mangin, March, 2019 14 | ; ---------------------------------------------------------------------------- 15 | 16 | 17 | 0000: ORG 00 18 | 19 | 0000: F3 Start DI 20 | 0001: C3210D JMP Init 21 | 22 | 0004: 9004 DW 0490h 23 | 0006: F907 DW 07F9h 24 | 25 | 0008: 7E SyntaxCheck MOV A,M ;A=Byte of BASIC program. 26 | 0009: E3 XTHL ;HL=return address. 27 | 000A: BE CMP M ;Compare to byte expected. 28 | 000B: 23 INX H ;Return address++; 29 | 000C: E3 XTHL ; 30 | 000D: C2D001 JNZ SyntaxError ;Error if not what was expected. 31 | 0010: 23 NextChar INX H 32 | 0011: 7E MOV A,M 33 | 0012: FE3A CPI 0x3A 34 | 0014: D0 RNC 35 | 0015: C35E04 JMP NextChar_tail 36 | 0018: F5 OutChar PUSH PSW 37 | 0019: 3A2700 LDA TERMINAL_X 38 | 001C: C36E03 JMP OutChar_tail 39 | 001F: 00 NOP 40 | 0020: 7C CompareHLDE MOV A,H 41 | 0021: 92 SUB D 42 | 0022: C0 RNZ 43 | 0023: 7D MOV A,L 44 | 0024: 93 SUB E 45 | 0025: C9 RET 46 | 0026: 01 TERMINAL_Y DB 01 47 | 0027: 00 TERMINAL_X DB 00 48 | 0028: 3A7201 FTestSign LDA FACCUM+3 49 | 002B: B7 ORA A 50 | 002C: C2DA09 JNZ FTestSign_tail 51 | 002F: C9 RET 52 | 0030: E3 PushNextWord XTHL 53 | 0031: 223B00 SHLD L003A+1 54 | 0034: E1 POP H 55 | 0035: 4E MOV C,M 56 | 0036: 23 INX H 57 | 0037: 46 MOV B,M 58 | 0038: 23 INX H 59 | 0039: C5 PUSH B 60 | 003A: C33A00 L003A JMP L003A 61 | 003D: E409 KW_INLINE_FNS DW Sgn 62 | 003F: A20A DW Int 63 | 0041: F809 DW Abs 64 | 0043: 9804 DW FunctionCallError 65 | 0045: 210C DW Sqr 66 | 0047: 5F0C DW Rnd 67 | 0049: 950C DW Sin 68 | 004B: 79 KW_ARITH_OP_FNS DB 79h 69 | 004C: 1008 DW FAdd ;+ 70 | 004E: 79 DB 79h 71 | 004F: 0A08 DW FSub ;- 72 | 0051: 7C DB 7Ch 73 | 0052: E308 DW FMul ;* 74 | 0054: 7C DB 7Ch 75 | 0055: 2F09 DW FDiv ;/ 76 | 0057: 454EC4 KEYWORDS DB 454EC4h ;"END" 80 77 | 005A: 464FD2 DB 464FD2h ; "FOR" 78 | 005D: 4E4558D4 DB 4E4558D4h ; "NEXT" 82 79 | 0061: 444154C1 DB 444154C1h ; "DATA" 83 80 | 0065: 494E5055 DB 494E5055D4h ; "INPUT" 84 81 | 0069: D4 82 | 006A: 4449CD DB 4449CDh ; "DIM" 85 83 | 006D: 524541C4 DB 524541C4h ; "READ" 86 84 | 0071: 4C45D4 DB 4C45D4h ; "LET" 87 85 | 0074: 474F54CF DB 474F54CFh ; "GOTO" 88 86 | 0078: 5255CE DB 5255CEh ; "RUN" 89 87 | 007B: 49C6 DB 49C6h ; "IF" 8A 88 | 007D: 52455354 DB 524553544F52C5h ; "RESTORE" 8B 89 | 0081: 4F52C5 90 | 0084: 474F5355 DB 474F5355C2h ; "GOSUB" 8C 91 | 0088: C2 92 | 0089: 52455455 DB 5245545552CEh ; "RETURN" 8D 93 | 008D: 52CE 94 | 008F: 5245CD DB 5245CDh ; "REM" 8E 95 | 0092: 53544FD0 DB 53544FD0h ; "STOP" 8F 96 | 0096: 5052494E DB 5052494ED4h ; "PRINT" 90 97 | 009A: D4 98 | 009B: 4C4953D4 DB 4C4953D4h ; "LIST" 91 99 | 009F: 434C4541 DB 434C4541D2h ; "CLEAR" 92 100 | 00A3: D2 101 | 00A4: 4E45D7 DB 4E45D7h ; "NEW" 93 102 | ; 103 | 00A7: 544142A8 DB 544142A8h ; "TAB(" 94 104 | 00AB: 54CF DB 54CFh ; "TO" 95 105 | 00AD: 544845CE DB 544845CEh ; "THEN" 96 106 | 00B1: 535445D0 DB 535445D0h ; "STEP" 97 107 | ; 108 | 00B5: AB DB 0xAB ; "+" 98 109 | 00B6: AD DB 0xAD ; "-" 99 110 | 00B7: AA DB 0xAA ; "*" 9A 111 | 00B8: AF DB 0xAF ; "/" 9B 112 | 00B9: BE DB 0xBE ; ">" 9C 113 | 00BA: BD DB 0xBD ; "=" 9D 114 | 00BB: BC DB 0xBC ; "<" 9E 115 | ; 116 | 00BC: 5347CE DB 5347CEh ; "SGN" 9F 117 | 00BF: 494ED4 DB 494ED4h ; "INT" A0 118 | 00C2: 4142D3 DB 4142D3h ; "ABS" A1 119 | 00C5: 5553D2 DB 5553D2h ; "USR" A2 120 | 00C8: 5351D2 DB 5351D2h ; "SQR" A3 121 | 00CB: 524EC4 DB 524EC4h ; "RND" A4 122 | 00CE: 5349CE DB 5349CEh ; "SIN" A5 123 | ; 124 | 00D1: 00 DB 0x00 ; 125 | ; 126 | 00D2: F701 KW_GENERAL_FNS DW Stop ;END 127 | 00D4: D503 DW For ;FOR 128 | 00D6: 4906 DW Next ;NEXT 129 | 00D8: F504 DW FindNextStatement ;DATA 130 | 00DA: E405 DW Input ;INPUT 131 | 00DC: 1607 DW Dim ;DIM 132 | 00DE: F605 DW Read ;READ 133 | 00E0: 0205 DW Let ;LET 134 | 00E2: CF04 DW Goto ;GOTO 135 | 00E4: A102 DW Run ;RUN 136 | 00E6: 1605 DW If ;IF 137 | 00E8: 6904 DW Restore ;RESTORE 138 | 00EA: BE04 DW Gosub ;GOSUB 139 | 00EC: DF04 DW Return ;RETURN 140 | 00EE: F704 DW Rem ;REM 141 | 00F0: F701 DW Stop ;STOP 142 | 00F2: 5705 DW Print ;PRINT 143 | 00F4: 8E03 DW List ;LIST 144 | 00F6: A602 DW Clear ;CLEAR 145 | 00F8: 9502 DW New ;NEW 146 | 147 | 00FA: 4EC6 ERROR_CODES DB 4EC6h ;"NF" NEXT without FOR. 148 | 00FC: 53CE DB 53CEh ;"SN" Syntax Error 149 | 00FE: 52C7 DB 52C7h ;"RG" RETURN without GOSUB. 150 | 0100: 4FC4 DB 4FC4h ;"OD" Out of Data 151 | 0102: 46C3 DB 46C3h ;"FC" Illegal Function Call 152 | 0104: 4FD6 DB 4FD6h ;"OV" Overflow. 153 | 0106: 4FCD DB 4FCDh ;"OM" Out of memory. 154 | 0108: 55D3 DB 55D3h ;"US" Undefined Subroutine 155 | 010A: 42D3 DB 42D3h ;"BS" Bad Subscript 156 | 010C: 44C4 DB 44C4h ;"DD" Duplicate Definition 157 | 010E: 2FB0 DB 2FB0h ;"\0" Division by zero. 158 | 0110: 49C4 DB 49C4h ;"ID" Invalid in Direct mode. 159 | 160 | 0112: 2C DB ',' ; 161 | 0113: 00000000 LINE_BUFFER DW 0000,0000,0000,0000h ;72 chars 162 | 0117: 00000000 163 | 011B: 00000000 DW 0000,0000,0000,0000h ; 164 | 011F: 00000000 165 | 0123: 00000000 DW 0000,0000,0000,0000h ; 166 | 0127: 00000000 167 | 012B: 00000000 DW 0000,0000,0000,0000h ; 168 | 012F: 00000000 169 | 0133: 00000000 DW 0000,0000,0000,0000h ; 170 | 0137: 00000000 171 | 013B: 00000000 DW 0000,0000,0000,0000h ; 172 | 013F: 00000000 173 | 0143: 00000000 DW 0000,0000,0000,0000h ; 174 | 0147: 00000000 175 | 014B: 00000000 DW 0000,0000,0000,0000h ; 176 | 014F: 00000000 177 | 0153: 00000000 DW 0000,0000,0000,0000h ; 178 | 0157: 00000000 179 | 180 | 015B: 00 DIM_OR_EVAL DB 00h ; 181 | 015C: 00 INPUT_OR_READ DB 00h ; 182 | 015D: 0000 PROG_PTR_TEMP DW 0000h ; 183 | 015F: 0000 L015F DW 0000h ; 184 | 0161: 0000 CURRENT_LINE DW 0000h ; 185 | 0163: 1A0F STACK_TOP DW 0F1Ah ; RELOCATE*** 186 | 0165: 0000 PROGRAM_BASE DW 0000h ; 187 | 0167: 0000 VAR_BASE DW 0000h ; 188 | 0169: 0000 VAR_ARRAY_BASE DW 0000h ; 189 | 016B: 0000 VAR_TOP DW 0000h ; 190 | 016D: 0000 DATA_PROG_PTR DW 0000h ; 191 | 016F: 00000000 FACCUM DB 00000000h ; 192 | 0173: 00 FTEMP DB 00h ; 193 | 0174: 00000000 FBUFFER DW 0000,0000,0000 194 | 0178: 0000 195 | 017A: 00000000 DW 0000,0000,0000 196 | 017E: 0000 197 | 0180: 00 DB 00 ; 198 | 0181: 20455252 szError DB 0x20,0x45,0x52,0x52,0x4F,0xD2,0x00 ;" ERROR\0" 199 | 0185: 4FD200 200 | 0188: 20494EA0 szIn DB 0x20,0x49,0x4E,0xA0,0x00 ;" IN \0" 201 | 018C: 00 202 | 018D: 0D4FCB0D szOK DB 0x0D,0x4F,0xCB,0x0D,0x00 ;"\rOK\r\0" 203 | 0191: 00 204 | 0192: 210400 GetFlowPtr LXI H,0004h ;HL=SP+4 (ie get word 205 | 0195: 39 DAD SP ;just past return addr) 206 | 0196: 7E MOV A,M ; 207 | 0197: 23 INX H ; 208 | 0198: FE81 CPI 0x81 ;'FOR'? 209 | 019A: C0 RNZ ;Return if not 'FOR' 210 | 019B: F7 RST 6 ; RST PushNextWord ;PUSH (HL) 211 | 019C: E3 XTHL ;POP HL (ie HL=(HL)) 212 | 019D: E7 RST 4 ; RST CompareHLDE ;HL==DE? 213 | 019E: 010D00 LXI B,000Dh ; 214 | 01A1: E1 POP H ;Restore HL 215 | 01A2: C8 RZ ;Return if var ptrs match. 216 | 01A3: 09 DAD B ;HL+=000D 217 | 01A4: C39601 JMP GetFlowPtr+4 ;Loop 218 | 01A7: CDC301 CopyMemoryUp CALL CheckEnoughMem; 219 | 01AA: C5 PUSH B ;Exchange BC with HL. 220 | 01AB: E3 XTHL ; 221 | 01AC: C1 POP B ; 222 | 01AD: E7 CopyMemLoop RST 4 ;HL==DE? 223 | 01AE: 7E MOV A,M ; 224 | 01AF: 02 STAX B ; 225 | 01B0: C8 RZ ;Exit if DE reached. 226 | 01B1: 0B DCX B ; 227 | 01B2: 2B DCX H ; 228 | 01B3: C3AD01 JMP CopyMemLoop ; 229 | 01B6: E5 CheckEnoughVarSpace PUSH H ; 230 | 01B7: 2A6B01 LHLD VAR_TOP ; 231 | 01BA: 0600 MVI B,00h ;BC=C*4 232 | 01BC: 09 DAD B ; 233 | 01BD: 09 DAD B ; 234 | 01BE: CDC301 CALL CheckEnoughMem; 235 | 01C1: E1 POP H ; 236 | 01C2: C9 RET ; 237 | 01C3: D5 CheckEnoughMem PUSH D ; 238 | 01C4: EB XCHG ; 239 | 01C5: 21DEFF LXI H,0xFFDE ;HL=-34 (extra 2 bytes for return address) 240 | 01C8: 39 DAD SP ; 241 | 01C9: E7 RST 4 ; 242 | 01CA: EB XCHG ; 243 | 01CB: D1 POP D ; 244 | 01CC: D0 RNC ; 245 | 01CD: 1E0C OutOfMemory MVI E,0Ch ; 246 | 01CF: 01 DB 01 ;LXI B,.... ; 247 | 01D0: 1E02 SyntaxError MVI E,02h ; 248 | 01D2: 01 DB 01 ;LXI B,.... ; 249 | 01D3: 1E14 DivideByZero MVI E,14h ; 250 | 01D5: CDB502 Error CALL ResetStack ; 251 | 01D8: CD8A05 CALL NewLine ; 252 | 01DB: 21FA00 LXI H,ERROR_CODES ; 253 | 01DE: 57 MOV D,A ; 254 | 01DF: 3E3F MVI A,'?' ;Print '?' 255 | 01E1: DF RST 03 ;RST OutChar ; 256 | 01E2: 19 DAD D ;HL points to error code. 257 | 01E3: 7E MOV A,M ; 258 | 01E4: DF RST 03 ;RST OutChar 11 011 111 ;Print first char of code. 259 | 01E5: D7 RST 02 ;RST NextChar 11 010 111 ; 260 | 01E6: DF RST 03 ;RST OutChar ;Print second char of code. 261 | 01E7: 218101 LXI H,szError ;Print " ERROR". 262 | 01EA: CDA305 CALL PrintString ; 263 | 01ED: 2A6101 LHLD CURRENT_LINE ; 264 | 01F0: 7C MOV A,H ; 265 | 01F1: A5 ANA L ; 266 | 01F2: 3C INR A ; 267 | 01F3: C42F0B CNZ PrintIN ; 268 | 01F6: 01 DB 01 ;LXI B,.... ;LXI over Stop and fall into Main 269 | 01F7: C0 Stop RNZ ;Syntax Error if args. 270 | 01F8: C1 POP B ;Lose return address. 271 | 01F9: 218D01 Main LXI H,szOK ; 272 | 01FC: CD210D CALL Init ; 273 | 01FF: 21FFFF GetNonBlankLine LXI H,0xFFFF ; 274 | 0202: 226101 SHLD CURRENT_LINE ; 275 | 0205: CD3C03 CALL InputLine ; 276 | 0208: D7 RST 02 ;RST NextChar ; 277 | 0209: 3C INR A ; 278 | 020A: 3D DCR A ; 279 | 020B: CAFF01 JZ GetNonBlankLine ; 280 | 020E: F5 PUSH PSW 281 | 020F: CD9D04 CALL LineNumberFromStr 282 | 0212: D5 PUSH D 283 | 0213: CDCC02 CALL Tokenize 284 | 0216: 47 MOV B,A 285 | 0217: D1 POP D 286 | 0218: F1 POP PSW 287 | 0219: D23E04 JNC Exec 288 | 021C: D5 StoreProgramLine PUSH D ;Push line number 289 | 021D: C5 PUSH B ;Push line length 290 | 021E: D7 RST 02 ;RST NextChar ;Get first char of line 291 | 021F: B7 ORA A ;Zero set if line is empty (ie removing a line) 292 | 0220: F5 PUSH PSW ;Preserve line-empty flag 293 | 0221: CD7D02 CALL FindProgramLine ;Get nearest program line address in BC. 294 | 0224: C5 PUSH B ;Push line address. 295 | 0225: D23902 JNC InsertProgramLine ;If line doesn't exist, jump ahead to insert it. 296 | 0228: EB RemoveProgramLine XCHG ;DE=Next line address. 297 | 0229: 2A6701 LHLD VAR_BASE ; 298 | 022C: 1A RemoveLine LDAX D ;Move byte of program remainder down 299 | 022D: 02 STAX B ;in memory. 300 | 022E: 03 INX B ; 301 | 022F: 13 INX D ; 302 | 0230: E7 RST 4 ;Loop until DE==VAR_BASE, ie whole 303 | 0231: C22C02 JNZ RemoveLine ;program remainder done. 304 | 0234: 60 MOV H,B ; 305 | 0235: 69 MOV L,C ;Update VAR_BASE from BC. 306 | 0236: 226701 SHLD VAR_BASE ; 307 | 0239: D1 InsertProgramLine POP D ;DE=Line address (from 224) 308 | 023A: F1 POP PSW ;Restore line-empty flag (see above) 309 | 023B: CA6002 JZ UpdateLinkedList;If line is empty, then we don't need to insert it so can jump ahead. 310 | 023E: 2A6701 LHLD VAR_BASE ; 311 | 0241: E3 XTHL ;HL = Line length (see 21D) 312 | 0242: C1 POP B ;BC = VAR_BASE 313 | 0243: 09 DAD B ;HL = VAR_BASE + line length. 314 | 0244: E5 PUSH H ; 315 | 0245: CDA701 CALL CopyMemoryUp ;Move remainder of program so there's enough space for the new line. 316 | 0248: E1 POP H ; 317 | 0249: 226701 SHLD VAR_BASE ;Update VAR_BASE 318 | 024C: EB XCHG ;HL=Line address, DE=VAR_BASE 319 | 024D: 74 MOV M,H ;??? 320 | 024E: 23 INX H ;Skip over next line ptr (updated below) 321 | 024F: 23 INX H ; 322 | 0250: D1 POP D ;DE = line number (see 21C) 323 | 0251: 73 MOV M,E ;Write line number to program line memory. 324 | 0252: 23 INX H ; 325 | 0253: 72 MOV M,D ; 326 | 0254: 23 INX H ; 327 | 0255: 111301 CopyFromBuffer LXI D,LINE_BUFFER ;Copy the line into the program. 328 | 0258: 1A LDAX D ; 329 | 0259: 77 MOV M,A ; 330 | 025A: 23 INX H ; 331 | 025B: 13 INX D ; 332 | 025C: B7 ORA A ; 333 | 025D: C25802 JNZ CopyFromBuffer+3; 334 | 0260: CDA202 UpdateLinkedList CALL ResetAll ; 335 | 0263: 23 INX H ; 336 | 0264: EB XCHG ; 337 | 0265: 62 L0265 MOV H,D ; 338 | 0266: 6B MOV L,E ; 339 | 0267: 7E MOV A,M ;If the pointer to the next line is a null 340 | 0268: 23 INX H ;word then we've reached the end of the 341 | 0269: B6 ORA M ;program, job is done, and we can jump back 342 | 026A: CAFF01 JZ GetNonBlankLine ;to let the user type in the next line. 343 | 026D: 23 INX H ;Skip over line number. 344 | 026E: 23 INX H ; 345 | 026F: 23 INX H ; 346 | 0270: AF XRA A ; 347 | 0271: BE L0271 CMP M ; 348 | 0272: 23 INX H ; 349 | 0273: C27102 JNZ L0271 ; 350 | 0276: EB XCHG ; 351 | 0277: 73 MOV M,E ; 352 | 0278: 23 INX H ; 353 | 0279: 72 MOV M,D ; 354 | 027A: C36502 JMP L0265 ; 355 | 027D: 2A6501 FindProgramLine LHLD PROGRAM_BASE ; 356 | 0280: 44 MOV B,H ;BC=this line 357 | 0281: 4D MOV C,L ; 358 | 0282: 7E MOV A,M ;If we've found two consecutive 359 | 0283: 23 INX H ;null bytes, then we've reached the end 360 | 0284: B6 ORA M ;of the program and so return. 361 | 0285: 2B DCX H ; 362 | 0286: C8 RZ ; 363 | 0287: C5 PUSH B ;Push this line address 364 | 0288: F7 RST 6 ;Push (next line address) 365 | 0289: F7 RST 6 ;Push (this line number) 366 | 028A: E1 POP H ;HL = this line number 367 | 028B: E7 RST 4 ;Compare line numbers 368 | 028C: E1 POP H ;HL = next line address 369 | 028D: C1 POP B ;BC = this line address 370 | 028E: 3F CMC ; 371 | 028F: C8 RZ ;Return carry set if line numbers match. 372 | 0290: 3F CMC ; 373 | 0291: D0 RNC ;Return if we've reached a line number greater than the one required. 374 | 0292: C38002 JMP FindProgramLine+3 375 | 0295: C0 New RNZ 376 | 0296: 2A6501 LHLD PROGRAM_BASE 377 | 0299: AF XRA A 378 | 029A: 77 MOV M,A 379 | 029B: 23 INX H 380 | 029C: 77 MOV M,A 381 | 029D: 23 INX H 382 | 029E: 226701 SHLD VAR_BASE 383 | 02A1: C0 Run RNZ 384 | 02A2: 2A6501 ResetAll LHLD PROGRAM_BASE 385 | 02A5: 2B DCX H 386 | 02A6: 225D01 Clear SHLD PROG_PTR_TEMP 387 | 02A9: CD6904 CALL Restore 388 | 02AC: 2A6701 LHLD VAR_BASE 389 | 02AF: 226901 SHLD VAR_ARRAY_BASE 390 | 02B2: 226B01 SHLD VAR_TOP 391 | 02B5: C1 ResetStack POP B 392 | 02B6: 2A6301 LHLD STACK_TOP 393 | 02B9: F9 SPHL 394 | 02BA: AF XRA A 395 | 02BB: 6F MOV L,A 396 | 02BC: E5 PUSH H 397 | 02BD: C5 PUSH B 398 | 02BE: 2A5D01 LHLD PROG_PTR_TEMP 399 | 02C1: C9 RET 400 | 02C2: 3E3F InputLineWith MVI A,'?' ;Print '?' 401 | 02C4: DF RST 03 ;RST OutChar ; 402 | 02C5: 3E20 MVI A,' ' ;Print ' ' 403 | 02C7: DF RST 03 ;RST OutChar ; 404 | 02C8: CD3C03 CALL InputLine ; 405 | 02CB: 23 INX H ; 406 | 02CC: 0E05 Tokenize MVI C,05 ;Initialise line length to 5. 407 | 02CE: 111301 LXI D,LINE_BUFFER ;ie, output ptr is same as input ptr at start. 408 | 02D1: 7E MOV A,M ; 409 | 02D2: FE20 CPI ' ' ; 410 | 02D4: CA0203 JZ WriteChar ; 411 | 02D7: 47 MOV B,A ; 412 | 02D8: FE22 CPI '"' ; 413 | 02DA: CA1503 JZ FreeCopy ; 414 | 02DD: B7 ORA A ; 415 | 02DE: CA2903 JZ Exit ; 416 | 02E1: D5 PUSH D ;Preserve output ptr. 417 | 02E2: 0600 MVI B,00 ;Initialise Keyword ID to 0. 418 | 02E4: 115600 LXI D,KEYWORDS-1 ; 419 | 02E7: E5 PUSH H ;Preserve input ptr. 420 | 02E8: 3E DB 3Eh ;LXI over get-next-char 421 | 02E9: D7 KwCompare RST 02 ; RST 01 ; SyntaxCheck0 ;Get next input char 422 | 02EA: 13 INX D ; 423 | 02EB: 1A LDAX D ;Get keyword char to compare with. 424 | 02EC: E67F ANI 7Fh ;Ignore bit 7 of keyword char. 425 | 02EE: CAFF02 JZ NotAKeyword ;If keyword char==0, then end of keywords reached. 426 | 02F1: BE CMP M ;Keyword char matches input char? 427 | 02F2: C21C03 JNZ NextKeyword ;If not, jump to get next keyword. 428 | 02F5: 1A LDAX D ; 429 | 02F6: B7 ORA A ; 430 | 02F7: F2E902 JP KwCompare ; 431 | 02FA: F1 POP PSW ;Remove input ptr from stack. We don't need it. 432 | 02FB: 78 MOV A,B ;A=Keyword ID 433 | 02FC: F680 ORI 0x80 ;Set bit 7 (indicates a keyword) 434 | 02FE: F2 DB 0xF2 ;JP .... ;LXI trick again. 435 | 02FF: E1 NotAKeyword POP H ;Restore input ptr 436 | 0300: 7E MOV A,M ;and get input char 437 | 0301: D1 POP D ;Restore output ptr 438 | 0302: 23 WriteChar INX H ;Advance input ptr 439 | 0303: 12 STAX D ;Store output char 440 | 0304: 13 INX D ;Advance output ptr 441 | 0305: 0C INR C ;C++ (arf!). 442 | 0306: D68E SUI 8Eh ;If it's not the 443 | 0308: C2D102 JNZ Tokenize+5 ; 444 | 030B: 47 MOV B,A ;B=0 445 | 030C: 7E FreeCopyLoop MOV A,M ;A=Input char 446 | 030D: B7 ORA A ;If char is null then exit 447 | 030E: CA2903 JZ Exit ; 448 | 0311: B8 CMP B ;If input char is term char then 449 | 0312: CA0203 JZ WriteChar ;we're done free copying. 450 | 0315: 23 FreeCopy INX H ; 451 | 0316: 12 STAX D ; 452 | 0317: 0C INR C ; 453 | 0318: 13 INX D ; 454 | 0319: C30C03 JMP FreeCopyLoop ; 455 | 031C: E1 NextKeyword POP H ;Restore input ptr 456 | 031D: E5 PUSH H ; 457 | 031E: 04 INR B ;Keyword ID ++; 458 | 031F: EB XCHG ;HL=keyword table ptr 459 | 0320: B6 NextKwLoop ORA M ;Loop until 460 | 0321: 23 INX H ;bit 7 of previous 461 | 0322: F22003 JP NextKwLoop ;keyword char is set. 462 | 0325: EB XCHG ;DE=keyword ptr, HL=input ptr 463 | 0326: C3EB02 JMP KwCompare+2 ; 464 | 0329: 211201 Exit LXI H,LINE_BUFFER-1 ; 465 | 032C: 12 STAX D ; 466 | 032D: 13 INX D ; 467 | 032E: 12 STAX D ; 468 | 032F: 13 INX D ; 469 | 0330: 12 STAX D ; 470 | 0331: C9 RET ; 471 | 0332: 05 Backspace DCR B ;Char count--; 472 | 0333: 2B DCX H ;Input ptr--; 473 | 0334: DF RST 03 ;RST OutChar ;Print backspace char. 474 | 0335: C24103 JNZ InputNext ; 475 | 0338: DF ResetInput RST 03 ;RST OutChar ; 476 | 0339: CD8A05 CALL NewLine ; 477 | 033C: 211301 InputLine LXI H,LINE_BUFFER ; 478 | 033F: 0601 MVI B,01 ; 479 | 0341: CD8203 InputNext CALL InputChar ; 480 | 0344: FE0D CPI 0x0D ; 481 | 0346: CA8505 JZ TerminateInput ; 482 | 0349: FE20 CPI ' ' ;If < ' ' 483 | 034B: DA4103 JC InputNext ;or 484 | 034E: FE7D CPI 0x7D ;> '}' 485 | 0350: D24103 JNC InputNext ;then loop back. 486 | 0353: FE40 CPI '@' ; 487 | 0355: CA3803 JZ ResetInput ; 488 | 0358: FE5F CPI '_' ; 489 | 035A: CA3203 JZ Backspace ; 490 | 035D: 4F MOV C,A ; 491 | 035E: 78 MOV A,B ; 492 | 035F: FE48 CPI 0x48 ; 493 | 0361: 3E07 MVI A,07 ; 494 | 0363: D26A03 JNC L036A ; 495 | 0366: 79 MOV A,C ;Write char to LINE_BUFFER. 496 | 0367: 71 MOV M,C ; 497 | 0368: 23 INX H ; 498 | 0369: 04 INR B ; 499 | 036A: DF L036A RST 03 ;RST OutChar ; 500 | 036B: C34103 JMP InputNext ; 501 | 036E: FE48 OutChar_tail CPI 0x48 ; 502 | 0370: CC8A05 CZ NewLine ; 503 | 0373: 3C INR A ; 504 | 0374: 322700 STA TERMINAL_X ; 505 | 0377: DB00 WaitTermReady IN 00 ; 506 | 0379: E680 ANI 80h ; 507 | 037B: C27703 JNZ WaitTermReady ; 508 | 037E: F1 POP PSW ; 509 | 037F: D301 OUT 01 ; 510 | 0381: C9 RET ; 511 | 0382: DB00 InputChar IN 00 ; 512 | 0384: E601 ANI 01 ; 513 | 0386: C28203 JNZ InputChar ; 514 | 0389: DB01 IN 01 ; 515 | 038B: E67F ANI 7Fh ; 516 | 038D: C9 RET ; 517 | 038E: CD9D04 List CALL LineNumberFromStr 518 | 0391: C0 RNZ 519 | 0392: C1 POP B ;?why get return address? 520 | 0393: CD7D02 CALL FindProgramLine 521 | 0396: C5 PUSH B 522 | 0397: E1 ListNextLine POP H 523 | 0398: F7 RST 6 524 | 0399: C1 POP B 525 | 039A: 78 MOV A,B 526 | 039B: B1 ORA C 527 | 039C: CAF901 JZ Main 528 | 039F: CD7304 CALL TestBreakKey 529 | 03A2: C5 PUSH B 530 | 03A3: CD8A05 CALL NewLine 531 | 03A6: F7 RST 6 532 | 03A7: E3 XTHL 533 | 03A8: CD370B CALL PrintInt 534 | 03AB: 3E20 MVI A,' ' 535 | 03AD: E1 POP H 536 | 03AE: DF ListChar RST 03 ;RST OutChar 537 | 03AF: 7E MOV A,M 538 | 03B0: B7 ORA A 539 | 03B1: 23 INX H 540 | 03B2: CA9703 JZ ListNextLine 541 | 03B5: F2AE03 JP ListChar 542 | 03B8: D67F SUI 7Fh ;A is now keyword index + 1. 543 | 03BA: 4F MOV C,A 544 | 03BB: E5 PUSH H 545 | 03BC: 115700 LXI D,KEYWORDS 546 | 03BF: D5 PUSH D 547 | 03C0: 1A ToNextKeyword LDAX D 548 | 03C1: 13 INX D 549 | 03C2: B7 ORA A 550 | 03C3: F2C003 JP ToNextKeyword 551 | 03C6: 0D DCR C 552 | 03C7: E1 POP H 553 | 03C8: C2BF03 JNZ ToNextKeyword-1 554 | 03CB: 7E PrintKeyword MOV A,M 555 | 03CC: B7 ORA A 556 | 03CD: FAAD03 JM ListChar-1 557 | 03D0: DF RST 03 ;RST OutChar 558 | 03D1: 23 INX H 559 | 03D2: C3CB03 JMP PrintKeyword 560 | 03D5: CD0205 For CALL Let 561 | 03D8: E3 XTHL 562 | 03D9: CD9201 CALL GetFlowPtr 563 | 03DC: D1 POP D 564 | 03DD: C2E203 JNZ L03E2 565 | 03E0: 09 DAD B 566 | 03E1: F9 SPHL 567 | 03E2: EB L03E2 XCHG 568 | 03E3: 0E08 MVI C,08 569 | 03E5: CDB601 CALL CheckEnoughVarSpace 570 | 03E8: E5 PUSH H 571 | 03E9: CDF504 CALL FindNextStatement 572 | 03EC: E3 XTHL 573 | 03ED: E5 PUSH H 574 | 03EE: 2A6101 LHLD CURRENT_LINE 575 | 03F1: E3 XTHL 576 | 03F2: CF RST 01 ; SyntaxCheck; SyntaxCheck 577 | 03F3: 95 DB 95h ;KWID_TO 578 | 03F4: CD8A06 CALL EvalExpression 579 | 03F7: E5 PUSH H 580 | 03F8: CD1D0A CALL FCopyToBCDE 581 | 03FB: E1 POP H 582 | 03FC: C5 PUSH B 583 | 03FD: D5 PUSH D 584 | 03FE: 010081 LXI B,8100h 585 | 0401: 51 MOV D,C 586 | 0402: 5A MOV E,D 587 | 0403: 7E MOV A,M 588 | 0404: FE97 CPI 0x97 ;KWID_STEP 589 | 0406: 3E01 MVI A,01h 590 | 0408: C21404 JNZ PushStepValue 591 | 040B: CD8B06 CALL EvalExpression+1 592 | 040E: E5 PUSH H 593 | 040F: CD1D0A CALL FCopyToBCDE 594 | 0412: EF RST 05 ; FTestSign 595 | 0413: E1 POP H 596 | 0414: C5 PushStepValue PUSH B 597 | 0415: D5 PUSH D 598 | 0416: F5 PUSH PSW 599 | 0417: 33 INX SP 600 | 0418: E5 PUSH H 601 | 0419: 2A5D01 LHLD PROG_PTR_TEMP 602 | 041C: E3 XTHL 603 | 041D: 0681 EndOfForHandler MVI B,0x81 604 | 041F: C5 PUSH B 605 | 0420: 33 INX SP 606 | 0421: CD7304 ExecNext CALL TestBreakKey 607 | 0424: 7E MOV A,M 608 | 0425: FE3A CPI ':' 609 | 0427: CA3E04 JZ Exec 610 | 042A: B7 ORA A 611 | 042B: C2D001 JNZ SyntaxError 612 | 042E: 23 INX H 613 | 042F: 7E MOV A,M 614 | 0430: 23 INX H 615 | 0431: B6 ORA M 616 | 0432: 23 INX H 617 | 0433: CAF901 JZ Main 618 | 0436: 5E MOV E,M 619 | 0437: 23 INX H 620 | 0438: 56 MOV D,M 621 | 0439: EB XCHG 622 | 043A: 226101 SHLD CURRENT_LINE 623 | 043D: EB XCHG 624 | 043E: D7 Exec RST 02 ;RST NextChar 625 | 043F: 112104 LXI D,ExecNext 626 | 0442: D5 PUSH D 627 | 0443: C8 RZ 628 | 0444: D680 SUI 80h 629 | 0446: DA0205 JC Let 630 | 0449: FE14 CPI 0x14 631 | 044B: D2D001 JNC SyntaxError 632 | 044E: 07 RLC ;BC = A*2 633 | 044F: 4F MOV C,A 634 | 0450: 0600 MVI B,00h 635 | 0452: EB XCHG 636 | 0453: 21D200 LXI H,KW_GENERAL_FNS 637 | 0456: 09 DAD B 638 | 0457: 4E MOV C,M 639 | 0458: 23 INX H 640 | 0459: 46 MOV B,M 641 | 045A: C5 PUSH B 642 | 045B: EB XCHG 643 | 045C: D7 RST 02 ;RST NextChar 644 | 045D: C9 RET 645 | 045E: FE20 NextChar_tail CPI ' ' 646 | 0460: CA1000 JZ NextChar 647 | 0463: FE30 CPI '0' 648 | 0465: 3F CMC 649 | 0466: 3C INR A 650 | 0467: 3D DCR A 651 | 0468: C9 RET 652 | 0469: EB Restore XCHG 653 | 046A: 2A6501 LHLD PROGRAM_BASE 654 | 046D: 2B DCX H 655 | 046E: 226D01 L046E SHLD DATA_PROG_PTR 656 | 0471: EB XCHG 657 | 0472: C9 RET 658 | 0473: DB00 TestBreakKey IN 00 ;Exit if no key pressed. 659 | 0475: E601 ANI 01 ; 660 | 0477: C0 RNZ ; 661 | 0478: CD8203 CALL InputChar ; 662 | 047B: FE03 CPI 0x03 ;Break key? 663 | 047D: C3F701 JMP Stop 664 | 0480: 7E CharIsAlpha MOV A,M 665 | 0481: FE41 CPI 'A' 666 | 0483: D8 RC 667 | 0484: FE5B CPI 'Z'+1 668 | 0486: 3F CMC 669 | 0487: C9 RET 670 | 0488: D7 GetSubscript RST 02 ;RST NextChar 671 | 0489: CD8A06 CALL EvalExpression 672 | 048C: EF RST 05 ; FTestSign 673 | 048D: FA9804 JM FunctionCallError 674 | 0490: 3A7201 LDA FACCUM+3 675 | 0493: FE90 CPI 0x90 676 | 0495: DA770A JC FAsInteger 677 | 0498: 1E08 FunctionCallError MVI E,08h 678 | 049A: C3D501 JMP Error 679 | 049D: 2B LineNumberFromStr DCX H 680 | 049E: 110000 LXI D,0000 681 | 04A1: D7 NextLineNumChar RST 02 ;RST NextChar 682 | 04A2: D0 RNC 683 | 04A3: E5 PUSH H 684 | 04A4: F5 PUSH PSW ;Preserve flags 685 | 04A5: 219819 LXI H,1998h ;Decimal 6552 686 | 04A8: E7 RST 4 687 | 04A9: DAD001 JC SyntaxError 688 | 04AC: 62 MOV H,D 689 | 04AD: 6B MOV L,E 690 | 04AE: 19 DAD D 691 | 04AF: 29 DAD H 692 | 04B0: 19 DAD D 693 | 04B1: 29 DAD H 694 | 04B2: F1 POP PSW 695 | 04B3: D630 SUI '0' 696 | 04B5: 5F MOV E,A 697 | 04B6: 1600 MVI D,00h 698 | 04B8: 19 DAD D 699 | 04B9: EB XCHG 700 | 04BA: E1 POP H 701 | 04BB: C3A104 JMP NextLineNumChar 702 | 04BE: 0E03 Gosub MVI C,03h 703 | 04C0: CDB601 CALL CheckEnoughVarSpace 704 | 04C3: C1 POP B 705 | 04C4: E5 PUSH H 706 | 04C5: E5 PUSH H 707 | 04C6: 2A6101 LHLD CURRENT_LINE 708 | 04C9: E3 XTHL 709 | 04CA: 168C MVI D,0x8C 710 | 04CC: D5 PUSH D 711 | 04CD: 33 INX SP 712 | 04CE: C5 PUSH B 713 | 04CF: CD9D04 Goto CALL LineNumberFromStr 714 | 04D2: C0 RNZ 715 | 04D3: CD7D02 CALL FindProgramLine 716 | 04D6: 60 MOV H,B 717 | 04D7: 69 MOV L,C 718 | 04D8: 2B DCX H 719 | 04D9: D8 RC 720 | 04DA: 1E0E MVI E,0Eh 721 | 04DC: C3D501 JMP Error 722 | 04DF: C0 Return RNZ 723 | 04E0: 16FF MVI D,0xFF 724 | 04E2: CD9201 CALL GetFlowPtr 725 | 04E5: F9 SPHL 726 | 04E6: FE8C CPI 0x8C 727 | 04E8: 1E04 MVI E,04h 728 | 04EA: C2D501 JNZ Error 729 | 04ED: E1 POP H 730 | 04EE: 226101 SHLD CURRENT_LINE 731 | 04F1: 212104 LXI H,ExecNext 732 | 04F4: E3 XTHL 733 | 04F5: 013A FindNextStatement DB 013Ah ;LXI B,..3A 734 | 04F7: 10 Rem DB 10h 735 | 04F8: 00 NOP 736 | 04F9: 7E FindNextStatementLoop MOV A,M 737 | 04FA: B7 ORA A 738 | 04FB: C8 RZ 739 | 04FC: B9 CMP C 740 | 04FD: C8 RZ 741 | 04FE: 23 INX H 742 | 04FF: C3F904 JMP FindNextStatementLoop 743 | 0502: CD1B07 Let CALL GetVar 744 | 0505: CF RST 01 ; SyntaxCheck 745 | 0506: 9D DB 9Dh 746 | 0507: D5 AssignVar PUSH D 747 | 0508: CD8A06 CALL EvalExpression 748 | 050B: E3 XTHL 749 | 050C: 225D01 SHLD PROG_PTR_TEMP 750 | 050F: E5 PUSH H 751 | 0510: CD290A CALL FCopyToMem 752 | 0513: D1 POP D 753 | 0514: E1 POP H 754 | 0515: C9 RET 755 | 0516: CD8A06 If CALL EvalExpression 756 | 0519: 7E MOV A,M 757 | 051A: CD020A CALL FPush 758 | 051D: 1600 MVI D,00 759 | 051F: D69C GetCompareOpLoop SUI 9Ch ; KWID_> 760 | 0521: DA3205 JC GotCompareOp 761 | 0524: FE03 CPI 0x03 762 | 0526: D23205 JNC GotCompareOp 763 | 0529: FE01 CPI 0x01 764 | 052B: 17 RAL 765 | 052C: B2 ORA D 766 | 052D: 57 MOV D,A 767 | 052E: D7 RST 02 ;RST NextChar 768 | 052F: C31F05 JMP GetCompareOpLoop 769 | 0532: 7A GotCompareOp MOV A,D 770 | 0533: B7 ORA A 771 | 0534: CAD001 JZ SyntaxError 772 | 0537: F5 PUSH PSW 773 | 0538: CD8A06 CALL EvalExpression 774 | 053B: CF RST 01 ; SyntaxCheck 775 | 053C: 96 DB 96h ;KWID_THEN 776 | 053D: 2B DCX H 777 | 053E: F1 POP PSW 778 | 053F: C1 POP B 779 | 0540: D1 POP D 780 | 0541: E5 PUSH H 781 | 0542: F5 PUSH PSW 782 | 0543: CD4C0A CALL FCompare 783 | 0546: 3C INR A 784 | 0547: 17 RAL 785 | 0548: C1 POP B 786 | 0549: A0 ANA B 787 | 054A: E1 POP H 788 | 054B: CAF704 JZ Rem 789 | 054E: D7 RST 02 ;RST NextChar 790 | 054F: DACF04 JC Goto 791 | 0552: C34304 JMP Exec+5 792 | 0555: 2B DCX H 793 | 0556: D7 RST 02 ;RST NextChar 794 | 0557: CA8A05 Print JZ NewLine 795 | 055A: C8 RZ 796 | 055B: FE22 CPI '"' 797 | 055D: CCA205 CZ PrintString-1 798 | 0560: CA5505 JZ Print-2 799 | 0563: FE94 CPI 0x94 ;KWID_TAB 800 | 0565: CAC705 JZ Tab 801 | 0568: E5 PUSH H 802 | 0569: FE2C CPI ',' 803 | 056B: CAB305 JZ ToNextTabBreak 804 | 056E: FE3B CPI ';' 805 | 0570: CADF05 JZ ExitTab 806 | 0573: C1 POP B 807 | 0574: CD8A06 CALL EvalExpression 808 | 0577: E5 PUSH H 809 | 0578: CD420B CALL FOut 810 | 057B: CDA305 CALL PrintString 811 | 057E: 3E20 MVI A,' ' 812 | 0580: DF RST 03 ;RST OutChar 813 | 0581: E1 POP H 814 | 0582: C35505 JMP Print-2 815 | 0585: 3600 TerminateInput MVI M,00h 816 | 0587: 211201 LXI H,LINE_BUFFER-1 817 | 058A: 3E0D NewLine MVI A,0Dh 818 | 058C: 322700 STA TERMINAL_X 819 | 058F: DF RST 03 ;RST OutChar 820 | 0590: 3E0A MVI A,0Ah 821 | 0592: DF RST 03 ;RST OutChar 822 | 0593: 3A2600 LDA TERMINAL_Y 823 | 0596: 3D PrintNullLoop DCR A 824 | 0597: 322700 STA TERMINAL_X 825 | 059A: C8 RZ 826 | 059B: F5 PUSH PSW 827 | 059C: AF XRA A 828 | 059D: DF RST 03 ;RST OutChar 829 | 059E: F1 POP PSW 830 | 059F: C39605 JMP PrintNullLoop 831 | 05A2: 23 INX H 832 | 05A3: 7E PrintString MOV A,M 833 | 05A4: B7 ORA A 834 | 05A5: C8 RZ 835 | 05A6: 23 INX H 836 | 05A7: FE22 CPI '"' 837 | 05A9: C8 RZ 838 | 05AA: DF RST 03 ;RST OutChar 839 | 05AB: FE0D CPI 0x0D 840 | 05AD: CC8A05 CZ NewLine 841 | 05B0: C3A305 JMP PrintString 842 | 05B3: 3A2700 ToNextTabBreak LDA TERMINAL_X 843 | 05B6: FE38 CPI 0x38 844 | 05B8: D48A05 CNC NewLine 845 | 05BB: D2DF05 JNC ExitTab 846 | 05BE: D60E CalcSpaceCount SUI 0Eh 847 | 05C0: D2BE05 JNC CalcSpaceCount 848 | 05C3: 2F CMA 849 | 05C4: C3D605 JMP PrintSpaces 850 | 05C7: CD8804 Tab CALL GetSubscript 851 | 05CA: CF RST 01 ; SyntaxCheck 852 | 05CB: 29 DB 29h ;')' 853 | 05CC: 2B DCX H 854 | 05CD: E5 PUSH H 855 | 05CE: 3A2700 LDA TERMINAL_X 856 | 05D1: 2F CMA 857 | 05D2: 83 ADD E 858 | 05D3: D2DF05 JNC ExitTab 859 | 05D6: 3C PrintSpaces INR A 860 | 05D7: 47 MOV B,A 861 | 05D8: 3E20 MVI A,' ' 862 | 05DA: DF PrintSpaceLoop RST 03 ;RST OutChar 863 | 05DB: 05 DCR B 864 | 05DC: C2DA05 JNZ PrintSpaceLoop 865 | 05DF: E1 ExitTab POP H 866 | 05E0: D7 RST 02 ;RST NextChar 867 | 05E1: C35A05 JMP Print+3 868 | 05E4: E5 Input PUSH H 869 | 05E5: 2A6101 LHLD CURRENT_LINE 870 | 05E8: 1E16 MVI E,16h 871 | 05EA: 23 INX H 872 | 05EB: 7D MOV A,L 873 | 05EC: B4 ORA H 874 | 05ED: CAD501 JZ Error 875 | 05F0: CDC202 CALL InputLineWith 876 | 05F3: C3FB05 JMP L05FA+1 877 | 05F6: E5 Read PUSH H 878 | 05F7: 2A6D01 LHLD DATA_PROG_PTR 879 | 05FA: F6AF L05FA ORI 0xAF 880 | ;XRA A 881 | 05FC: 325C01 STA INPUT_OR_READ 882 | 05FF: E3 XTHL 883 | 0600: 01 DB 01 ;LXI B,.... 884 | 0601: CF ReadNext RST 01 ; SyntaxCheck 885 | 0602: 2C DB 2Ch ;',' 886 | 0603: CD1B07 CALL GetVar 887 | 0606: E3 XTHL 888 | 0607: D5 PUSH D 889 | 0608: 7E MOV A,M 890 | 0609: FE2C CPI ',' 891 | 060B: CA2006 JZ GotDataItem 892 | 060E: B7 ORA A 893 | 060F: C2D001 JNZ SyntaxError 894 | 0612: 3A5C01 LDA INPUT_OR_READ 895 | 0615: B7 ORA A 896 | 0616: 23 INX H 897 | 0617: C23606 JNZ NextDataLine+1 898 | 061A: 3E3F MVI A,'?' 899 | 061C: DF RST 03 ;RST OutChar 900 | 061D: CDC202 CALL InputLineWith 901 | 0620: D1 GotDataItem POP D 902 | 0621: 23 INX H 903 | 0622: CD0705 CALL AssignVar 904 | 0625: E3 XTHL 905 | 0626: 2B DCX H 906 | 0627: D7 RST 02 ;RST NextChar 907 | 0628: C20106 JNZ ReadNext 908 | 062B: D1 POP D 909 | 062C: 3A5C01 LDA INPUT_OR_READ 910 | 062F: B7 ORA A 911 | 0630: C8 RZ 912 | 0631: EB XCHG 913 | 0632: C26E04 JNZ L046E 914 | 0635: E1 NextDataLine POP H 915 | 0636: F7 RST 6 916 | 0637: 79 MOV A,C 917 | 0638: B0 ORA B 918 | 0639: 1E06 MVI E,06h 919 | 063B: CAD501 JZ Error 920 | 063E: 23 INX H 921 | 063F: D7 RST 02 ;RST NextChar 922 | 0640: FE83 CPI 0x83 ;KWID_DATA 923 | 0642: C23506 JNZ NextDataLine 924 | 0645: C1 POP B 925 | 0646: C32006 JMP GotDataItem 926 | 0649: CD1B07 Next CALL GetVar 927 | 064C: 225D01 SHLD PROG_PTR_TEMP 928 | 064F: CD9201 CALL GetFlowPtr 929 | 0652: F9 SPHL 930 | 0653: D5 PUSH D 931 | 0654: 7E MOV A,M 932 | 0655: 23 INX H 933 | 0656: F5 PUSH PSW 934 | 0657: D5 PUSH D 935 | 0658: 1E00 MVI E,00h 936 | 065A: C2D501 JNZ Error 937 | 065D: CD0F0A CALL FLoadFromMem 938 | 0660: E3 XTHL 939 | 0661: E5 PUSH H 940 | 0662: CD0408 CALL FAddMem 941 | 0665: E1 POP H 942 | 0666: CD290A CALL FCopyToMem 943 | 0669: E1 POP H 944 | 066A: CD200A CALL FLoadBCDEfromMem 945 | 066D: E5 PUSH H 946 | 066E: CD4C0A CALL FCompare 947 | 0671: E1 POP H 948 | 0672: C1 POP B 949 | 0673: 90 SUB B 950 | 0674: CD200A CALL FLoadBCDEfromMem 951 | 0677: CA8306 JZ ForLoopIsComplete 952 | 067A: EB XCHG 953 | 067B: 226101 SHLD CURRENT_LINE 954 | 067E: 69 MOV L,C 955 | 067F: 60 MOV H,B 956 | 0680: C31D04 JMP EndOfForHandler 957 | 0683: F9 ForLoopIsComplete SPHL 958 | 0684: 2A5D01 LHLD PROG_PTR_TEMP 959 | 0687: C32104 JMP ExecNext 960 | 068A: 2B EvalExpression DCX H 961 | 068B: 1600 MVI D,00h 962 | 068D: D5 PUSH D 963 | 068E: 0E01 MVI C,01h 964 | 0690: CDB601 CALL CheckEnoughVarSpace 965 | 0693: CDC406 CALL EvalTerm 966 | 0696: 225F01 SHLD L015F 967 | 0699: 2A5F01 ArithParse LHLD L015F 968 | 069C: C1 POP B 969 | 069D: 7E MOV A,M 970 | 069E: 1600 MVI D,00h 971 | 06A0: D698 SUI 0x98 ;KWID_PLUS 972 | 06A2: D8 RC 973 | 06A3: FE04 CPI 0x04 974 | 06A5: D0 RNC 975 | 06A6: 5F MOV E,A 976 | 06A7: 07 RLC 977 | 06A8: 83 ADD E 978 | 06A9: 5F MOV E,A 979 | 06AA: 214B00 LXI H,KW_ARITH_OP_FNS 980 | 06AD: 19 DAD D 981 | 06AE: 78 MOV A,B 982 | 06AF: 56 MOV D,M 983 | 06B0: BA CMP D 984 | 06B1: D0 RNC 985 | 06B2: 23 INX H 986 | 06B3: C5 PUSH B 987 | 06B4: 019906 LXI B,ArithParse 988 | 06B7: C5 PUSH B 989 | 06B8: 4A MOV C,D ;??? 990 | 06B9: CD020A CALL FPush 991 | 06BC: 51 MOV D,C 992 | 06BD: F7 RST 6 993 | 06BE: 2A5F01 LHLD L015F 994 | 06C1: C38D06 JMP EvalExpression+3 995 | 06C4: D7 EvalTerm RST 02 ;RST NextChar 996 | 06C5: DAB30A JC FIn 997 | 06C8: CD8004 CALL CharIsAlpha 998 | 06CB: D2F306 JNC EvalVarTerm 999 | 06CE: FE98 CPI 0x98 ;KWID_PLUS 1000 | 06D0: CAC406 JZ EvalTerm 1001 | 06D3: FE2E CPI '.' 1002 | 06D5: CAB30A JZ FIn 1003 | 06D8: FE99 CPI 0x99 ;KWID_MINUS 1004 | 06DA: CAEA06 JZ EvalMinusTerm 1005 | 06DD: D69F SUI 9Fh 1006 | 06DF: D2FD06 JNC EvalInlineFn 1007 | 06E2: CF EvalBracketed RST 01 ; SyntaxCheck 1008 | 06E3: 28 DB 28h ;'(' 1009 | 06E4: CD8A06 CALL EvalExpression 1010 | 06E7: CF RST 01 ; SyntaxCheck 1011 | 06E8: 29 DB 29h ;')' 1012 | 06E9: C9 RET 1013 | 06EA: CDC406 EvalMinusTerm CALL EvalTerm 1014 | 06ED: E5 PUSH H 1015 | 06EE: CDFA09 CALL FNegate 1016 | 06F1: E1 POP H 1017 | 06F2: C9 RET 1018 | 06F3: CD1B07 EvalVarTerm CALL GetVar 1019 | 06F6: E5 PUSH H 1020 | 06F7: EB XCHG 1021 | 06F8: CD0F0A CALL FLoadFromMem 1022 | 06FB: E1 POP H 1023 | 06FC: C9 RET 1024 | 06FD: 0600 EvalInlineFn MVI B,00h 1025 | 06FF: 07 RLC 1026 | 0700: 4F MOV C,A 1027 | 0701: C5 PUSH B 1028 | 0702: D7 RST 02 ;RST NextChar 1029 | 0703: CDE206 CALL EvalBracketed 1030 | 0706: E3 XTHL 1031 | 0707: 11F106 LXI D,06F1h 1032 | 070A: D5 PUSH D 1033 | 070B: 013D00 LXI B,KW_INLINE_FNS 1034 | 070E: 09 DAD B 1035 | 070F: F7 RST 6 1036 | 0710: C9 RET 1037 | 0711: 2B DimContd DCX H 1038 | 0712: D7 RST 02 ;RST NextChar 1039 | 0713: C8 RZ 1040 | 0714: CF RST 01 ; SyntaxCheck 1041 | 0715: 2C DB 2Ch ;',' 1042 | 0716: 011107 Dim LXI B,DimContd 1043 | 0719: C5 PUSH B 1044 | 071A: F6 DB 0xF6 1045 | 071B: AF GetVar XRA A 1046 | 071C: 325B01 STA DIM_OR_EVAL 1047 | 071F: 46 MOV B,M 1048 | 0720: CD8004 CALL CharIsAlpha 1049 | 0723: DAD001 JC SyntaxError 1050 | 0726: AF XRA A 1051 | 0727: 4F MOV C,A 1052 | 0728: D7 RST 02 ;RST NextChar 1053 | 0729: D22E07 JNC 072Eh 1054 | 072C: 4F MOV C,A 1055 | 072D: D7 RST 02 ;RST NextChar 1056 | 072E: D628 SUI '(' 1057 | 0730: CA8A07 JZ GetArrayVar 1058 | 0733: E5 PUSH H 1059 | 0734: 2A6901 LHLD VAR_ARRAY_BASE 1060 | 0737: EB XCHG 1061 | 0738: 2A6701 LHLD VAR_BASE 1062 | 073B: E7 FindVarLoop RST 4 1063 | 073C: CA5207 JZ AllocNewVar 1064 | 073F: 79 MOV A,C 1065 | 0740: 96 SUB M 1066 | 0741: 23 INX H 1067 | 0742: C24707 JNZ L0747 1068 | 0745: 78 MOV A,B 1069 | 0746: 96 SUB M 1070 | 0747: 23 L0747 INX H 1071 | 0748: CA8207 JZ L0782 1072 | 074B: 23 INX H 1073 | 074C: 23 INX H 1074 | 074D: 23 INX H 1075 | 074E: 23 INX H 1076 | 074F: C33B07 JMP FindVarLoop 1077 | 0752: E1 AllocNewVar POP H ;HL=prog ptr 1078 | 0753: E3 XTHL ;(SP)=prog ptr, HL=ret.addr. 1079 | 0754: D5 PUSH D ; 1080 | 0755: 11F606 LXI D,06F6h ;an address inside EvalTerm 1081 | 0758: E7 RST 4 ; 1082 | 0759: D1 POP D ; 1083 | 075A: CA8507 JZ AlreadyAllocd ; 1084 | 075D: E3 XTHL ;(SP)=ret.addr, HL=prog ptr. 1085 | 075E: E5 PUSH H ;Prog ptr back on stack 1086 | 075F: C5 PUSH B ;Preserve var name on stack 1087 | 0760: 010600 LXI B,0006h 1088 | 0763: 2A6B01 LHLD VAR_TOP 1089 | 0766: E5 PUSH H 1090 | 0767: 09 DAD B 1091 | 0768: C1 POP B 1092 | 0769: E5 PUSH H 1093 | 076A: CDA701 CALL CopyMemoryUp 1094 | 076D: E1 POP H 1095 | 076E: 226B01 SHLD VAR_TOP 1096 | 0771: 60 MOV H,B 1097 | 0772: 69 MOV L,C 1098 | 0773: 226901 SHLD VAR_ARRAY_BASE 1099 | 0776: 2B InitVarLoop DCX H 1100 | 0777: 3600 MVI M,00h 1101 | 0779: E7 RST 4 1102 | 077A: C27607 JNZ InitVarLoop 1103 | 077D: D1 POP D 1104 | 077E: 73 MOV M,E 1105 | 077F: 23 INX H 1106 | 0780: 72 MOV M,D 1107 | 0781: 23 INX H 1108 | 0782: EB L0782 XCHG 1109 | 0783: E1 POP H 1110 | 0784: C9 RET 1111 | 0785: 327201 AlreadyAllocd STA FACCUM+3 ;A was set to zero at 075A. 1112 | 0788: E1 POP H 1113 | 0789: C9 RET 1114 | 078A: C5 GetArrayVar PUSH B 1115 | 078B: 3A5B01 LDA DIM_OR_EVAL 1116 | 078E: F5 PUSH PSW 1117 | 078F: CD8804 CALL GetSubscript 1118 | 0792: CF RST 01 ; SyntaxCheck 1119 | 0793: 29 DB 29h ;')' 1120 | 0794: F1 POP PSW 1121 | 0795: 325B01 STA DIM_OR_EVAL 1122 | 0798: E3 XTHL 1123 | 0799: EB XCHG 1124 | 079A: 29 DAD H 1125 | 079B: 29 DAD H 1126 | 079C: E5 PUSH H 1127 | 079D: 2A6901 LHLD VAR_ARRAY_BASE 1128 | 07A0: 01 DB 0x01 ;LXI B,.... 1129 | 07A1: C1 FindArray POP B 1130 | 07A2: 09 DAD B 1131 | 07A3: EB XCHG 1132 | 07A4: E5 PUSH H 1133 | 07A5: 2A6B01 LHLD VAR_TOP 1134 | 07A8: E7 RST 4 1135 | 07A9: EB XCHG 1136 | 07AA: D1 POP D 1137 | 07AB: CACD07 JZ AllocArray 1138 | 07AE: F7 RST 6 1139 | 07AF: E3 XTHL 1140 | 07B0: E7 RST 4 1141 | 07B1: E1 POP H 1142 | 07B2: F7 RST 6 1143 | 07B3: C2A107 JNZ FindArray 1144 | 07B6: 3A5B01 LDA DIM_OR_EVAL 1145 | 07B9: B7 ORA A 1146 | 07BA: 1E12 MVI E,12h 1147 | 07BC: C2D501 JNZ Error 1148 | 07BF: D1 L07BF POP D 1149 | 07C0: 1B DCX D 1150 | 07C1: E3 XTHL 1151 | 07C2: E7 RST 4 1152 | 07C3: 1E10 MVI E,10h 1153 | 07C5: D2D501 JNC Error 1154 | 07C8: D1 POP D 1155 | 07C9: 19 DAD D 1156 | 07CA: D1 POP D 1157 | 07CB: EB XCHG 1158 | 07CC: C9 RET 1159 | 07CD: 73 AllocArray MOV M,E 1160 | 07CE: 23 INX H 1161 | 07CF: 72 MOV M,D 1162 | 07D0: 23 INX H 1163 | 07D1: 112C00 LXI D,002Ch 1164 | 07D4: 3A5B01 LDA DIM_OR_EVAL 1165 | 07D7: B7 ORA A 1166 | 07D8: CAE107 JZ L07E1 1167 | 07DB: D1 POP D 1168 | 07DC: D5 PUSH D 1169 | 07DD: 13 INX D 1170 | 07DE: 13 INX D 1171 | 07DF: 13 INX D 1172 | 07E0: 13 INX D 1173 | 07E1: D5 L07E1 PUSH D 1174 | 07E2: 73 MOV M,E 1175 | 07E3: 23 INX H 1176 | 07E4: 72 MOV M,D 1177 | 07E5: 23 INX H 1178 | 07E6: E5 PUSH H 1179 | 07E7: 19 DAD D 1180 | 07E8: CDC301 CALL CheckEnoughMem 1181 | 07EB: 226B01 SHLD VAR_TOP 1182 | 07EE: D1 POP D 1183 | 07EF: 2B InitElements DCX H 1184 | 07F0: 3600 MVI M,00h 1185 | 07F2: E7 RST 4 1186 | 07F3: C2EF07 JNZ InitElements 1187 | 07F6: C3BF07 JMP L07BF 1188 | 07F9: 50 FWordToFloat MOV D,B 1189 | 07FA: 1E00 MVI E,00h 1190 | 07FC: 0690 MVI B,90h ;exponent=2^16 1191 | 07FE: C3EA09 JMP FCharToFloat+5 ; 1192 | 0801: 210B0C FAddOneHalf LXI H,ONE_HALF ;Load BCDE with (float) 0.5. 1193 | 0804: CD200A FAddMem CALL FLoadBCDEfromMem 1194 | 0807: C31208 JMP FAdd+2 1195 | 080A: C1 FSub POP B ;Get lhs in BCDE. 1196 | 080B: D1 POP D ; 1197 | 080C: CDFA09 CALL FNegate ;Negate rhs and slimily 1198 | 080F: 21 DB 0x21 ;LXI H,.... ;LXI into FAdd + 2. 1199 | 0810: C1 FAdd POP B ;Get lhs in BCDE. 1200 | 0811: D1 POP D ; 1201 | 0812: 78 MOV A,B ;If lhs==0 then we don't need 1202 | 0813: B7 ORA A ;to do anything and can just 1203 | 0814: C8 RZ ;exit. 1204 | 0815: 3A7201 LDA FACCUM+3 ;If rhs==0 then exit via a copy 1205 | 0818: B7 ORA A ;of lhs to FACCUM. 1206 | 0819: CA120A JZ FLoadFromBCDE ; 1207 | 081C: 90 SUB B ;A=rhs.exponent-lhs.exponent. 1208 | 081D: D22C08 JNC L082C ;If rhs' exponent >= lhs'exponent, jump ahead. 1209 | 0820: 2F CMA ;Two's complement the exponent 1210 | 0821: 3C INR A ;difference, so it's correct. 1211 | 0822: EB XCHG ; 1212 | 0823: CD020A CALL FPush ;Push old rhs 1213 | 0826: EB XCHG ; 1214 | 0827: CD120A CALL FLoadFromBCDE ;rhs = old lhs 1215 | 082A: C1 POP B ;lhs = old rhs. 1216 | 082B: D1 POP D ; 1217 | 082C: F5 L082C PUSH PSW ;Preserve exponent diff 1218 | 082D: CD370A CALL FUnpackMantissas 1219 | 0830: 67 MOV H,A ;H=sign relationship 1220 | 0831: F1 POP PSW ;A=exponent diff. 1221 | 0832: CDC908 CALL FMantissaRtMult ;Shift lhs mantissa right by (exponent diff) places. 1222 | 0835: B4 ORA H ;A=0 after last call, so this tests 1223 | 0836: 216F01 LXI H,FACCUM ;the sign relationship. 1224 | 0839: F24D08 JP FSubMantissas ;Jump ahead if we need to subtract. 1225 | 083C: CDA908 CALL FAddMantissas ; 1226 | 083F: D27E08 JNC FRoundUp ;Jump ahead if that didn't overflow. 1227 | 0842: 23 INX H ;Flip the sign in FTEMP_SIGN. 1228 | 0843: 34 INR M ; 1229 | 0844: CAA408 JZ Overflow ;Error out if exponent overflowed. 1230 | 0847: CDD608 CALL FMantissaRtOnce;Shift mantissa one place right 1231 | 084A: C37E08 JMP FRoundUp ;Jump ahead. 1232 | 084D: AF FSubMantissas XRA A ;B=0-B 1233 | 084E: 90 SUB B ; 1234 | 084F: 47 MOV B,A ; 1235 | 0850: 7E MOV A,M ;E=(FACCUM)-E 1236 | 0851: 9B SBB E ; 1237 | 0852: 5F MOV E,A ; 1238 | 0853: 23 INX H ; 1239 | 0854: 7E MOV A,M ;D=(FACCUM+1)-D 1240 | 0855: 9A SBB D 1241 | 0856: 57 MOV D,A 1242 | 0857: 23 INX H 1243 | 0858: 7E MOV A,M ;C=(FACCUM+2)-C 1244 | 0859: 99 SBB C ; 1245 | 085A: 4F MOV C,A ; 1246 | 085B: DCB508 FNormalise CC FNegateInt ; 1247 | 085E: 2600 MVI H,00h ; 1248 | 0860: 79 MOV A,C ;Test most-significant bit of mantissa 1249 | 0861: B7 ORA A ;and jump ahead if it's 1. 1250 | 0862: FA7E08 JM FRoundUp ; 1251 | 0865: FEE0 NormLoop CPI 0xE0 ;If we've shifted 32 times, 1252 | 0867: CABE09 JZ FZero ;then the number is 0. 1253 | 086A: 25 DCR H ; 1254 | 086B: 78 MOV A,B ;Left-shift extra mantissa byte 1255 | 086C: 87 ADD A ; 1256 | 086D: 47 MOV B,A ; 1257 | 086E: CD9008 CALL FMantissaLeft ;Left-shift mantissa. 1258 | 0871: 7C MOV A,H ; 1259 | 0872: F26508 JP NormLoop ;Loop 1260 | 0875: 217201 LXI H,FACCUM+3 ; 1261 | 0878: 86 ADD M ; 1262 | 0879: 77 MOV M,A ;Since A was a -ve number, that certainly should 1263 | 087A: D2BE09 JNC FZero ;have carried, hence the extra check for zero. 1264 | 087D: C8 RZ ;?why? 1265 | 087E: 78 FRoundUp MOV A,B ;A=extra mantissa byte 1266 | 087F: 217201 LXI H,FACCUM+3 ; 1267 | 0882: B7 ORA A ;If bit 7 of the extra mantissa byte 1268 | 0883: FC9A08 CM FMantissaInc ;is set, then round up the mantissa. 1269 | 0886: 46 MOV B,M ;B=exponent 1270 | 0887: 23 INX H ; 1271 | 0888: 7E MOV A,M ;A=FTEMP_SIGN 1272 | 0889: E680 ANI 0x80 ; 1273 | 088B: A9 XRA C ;Bit 7 of C is always 1. Thi 1274 | 088C: 4F MOV C,A ; 1275 | 088D: C3120A JMP FLoadFromBCDE ;Exit via copying BCDE to FACCUM. 1276 | 0890: 7B FMantissaLeft MOV A,E 1277 | 0891: 17 RAL 1278 | 0892: 5F MOV E,A 1279 | 0893: 7A MOV A,D 1280 | 0894: 17 RAL 1281 | 0895: 57 MOV D,A 1282 | 0896: 79 MOV A,C 1283 | 0897: 8F ADC A 1284 | 0898: 4F MOV C,A 1285 | 0899: C9 RET 1286 | 089A: 1C FMantissaInc INR E 1287 | 089B: C0 RNZ 1288 | 089C: 14 INR D 1289 | 089D: C0 RNZ 1290 | 089E: 0C INR C 1291 | 089F: C0 RNZ 1292 | 08A0: 0E80 MVI C,80h ;Mantissa overflowed to zero, so set it 1293 | 08A2: 34 INR M ;to 1 and increment the exponent. 1294 | 08A3: C0 RNZ ;And if the exponent overflows... 1295 | 08A4: 1E0A Overflow MVI E,0Ah 1296 | 08A6: C3D501 JMP Error 1297 | 08A9: 7E FAddMantissas MOV A,M 1298 | 08AA: 83 ADD E 1299 | 08AB: 5F MOV E,A 1300 | 08AC: 23 INX H 1301 | 08AD: 7E MOV A,M 1302 | 08AE: 8A ADC D 1303 | 08AF: 57 MOV D,A 1304 | 08B0: 23 INX H 1305 | 08B1: 7E MOV A,M 1306 | 08B2: 89 ADC C 1307 | 08B3: 4F MOV C,A 1308 | 08B4: C9 RET 1309 | 08B5: 217301 FNegateInt LXI H,FTEMP 1310 | 08B8: 7E MOV A,M 1311 | 08B9: 2F CMA 1312 | 08BA: 77 MOV M,A 1313 | 08BB: AF XRA A 1314 | 08BC: 6F MOV L,A 1315 | 08BD: 90 SUB B 1316 | 08BE: 47 MOV B,A 1317 | 08BF: 7D MOV A,L 1318 | 08C0: 9B SBB E 1319 | 08C1: 5F MOV E,A 1320 | 08C2: 7D MOV A,L 1321 | 08C3: 9A SBB D 1322 | 08C4: 57 MOV D,A 1323 | 08C5: 7D MOV A,L 1324 | 08C6: 99 SBB C 1325 | 08C7: 4F MOV C,A 1326 | 08C8: C9 RET 1327 | 08C9: 0600 FMantissaRtMult MVI B,00h ;Initialise extra mantissa byte 1328 | 08CB: 3C INR A 1329 | 08CC: 6F MOV L,A 1330 | 08CD: AF RtMultLoop XRA A 1331 | 08CE: 2D DCR L 1332 | 08CF: C8 RZ 1333 | 08D0: CDD608 CALL FMantissaRtOnce 1334 | 08D3: C3CD08 JMP RtMultLoop 1335 | 08D6: 79 FMantissaRtOnce MOV A,C 1336 | 08D7: 1F RAR 1337 | 08D8: 4F MOV C,A 1338 | 08D9: 7A MOV A,D 1339 | 08DA: 1F RAR 1340 | 08DB: 57 MOV D,A 1341 | 08DC: 7B MOV A,E 1342 | 08DD: 1F RAR 1343 | 08DE: 5F MOV E,A 1344 | 08DF: 78 MOV A,B ;NB: B is the extra 1345 | 08E0: 1F RAR ;mantissa byte. 1346 | 08E1: 47 MOV B,A ; 1347 | 08E2: C9 RET ; 1348 | 08E3: C1 FMul POP B ;Get lhs in BCDE 1349 | 08E4: D1 POP D ; 1350 | 08E5: EF RST 05 ; FTestSign ;If rhs==0 then exit 1351 | 08E6: C8 RZ ; 1352 | 08E7: 2E00 MVI L,00h ;L=0 to signify exponent add 1353 | 08E9: CD9B09 CALL FExponentAdd 1354 | 08EC: 79 MOV A,C 1355 | 08ED: 321709 STA FMulInnerLoop+13 1356 | 08F0: EB XCHG 1357 | 08F1: 221209 SHLD FMulInnerLoop+8 1358 | 08F4: 010000 LXI B,0000h 1359 | 08F7: 50 MOV D,B 1360 | 08F8: 58 MOV E,B 1361 | 08F9: 215E08 LXI H,FNormalise+3 1362 | 08FC: E5 PUSH H 1363 | 08FD: 210509 LXI H,FMulOuterLoop 1364 | 0900: E5 PUSH H 1365 | 0901: E5 PUSH H 1366 | 0902: 216F01 LXI H,FACCUM 1367 | 0905: 7E FMulOuterLoop MOV A,M ;A=FACCUM mantissa byte 1368 | 0906: 23 INX H ; 1369 | 0907: E5 PUSH H ;Preserve FACCUM ptr 1370 | 0908: 2E08 MVI L,08h ;8 bits to do 1371 | 090A: 1F FMulInnerLoop RAR ;Test lowest bit of mantissa byte 1372 | 090B: 67 MOV H,A ;Preserve mantissa byte 1373 | 090C: 79 MOV A,C ;A=result mantissa's high byte 1374 | 090D: D21909 JNC L0919 ;If that bit of multiplicand was 0, then skip over adding mantissas. 1375 | 0910: E5 PUSH H ; 1376 | 0911: 210000 LXI H,0000h ; 1377 | 0914: 19 DAD D ; 1378 | 0915: D1 POP D ; 1379 | 0916: CE00 ACI 00 ;A=result mantissa high byte. This gets back to C 1380 | 0918: EB XCHG ;in the call to FMantissaRtOnce+1. 1381 | 0919: CDD708 L0919 CALL FMantissaRtOnce+1 1382 | 091C: 2D DCR L 1383 | 091D: 7C MOV A,H ;Restore mantissa byte and 1384 | 091E: C20A09 JNZ FMulInnerLoop ;jump back if L is not yet 0. 1385 | 0921: E1 PopHLandReturn POP H ;Restore FACCUM ptr 1386 | 0922: C9 RET ;Return to FMulOuterLoop, or if finished that then exit to FNormalise 1387 | 0923: CD020A FDivByTen CALL FPush ; 1388 | 0926: 012084 LXI B,8420h ;BCDE=(float)10; 1389 | 0929: 110000 LXI D,0000h 1390 | 092C: CD120A CALL FLoadFromBCDE 1391 | 092F: C1 FDiv POP B 1392 | 0930: D1 POP D 1393 | 0931: EF RST 05 ; FTestSign 1394 | 0932: CAD301 JZ DivideByZero 1395 | 0935: 2EFF MVI L,0xFF 1396 | 0937: CD9B09 CALL FExponentAdd 1397 | 093A: 34 INR M 1398 | 093B: 34 INR M 1399 | 093C: 2B DCX H 1400 | 093D: 7E MOV A,M 1401 | 093E: 326009 STA L095F+1 1402 | 0941: 2B DCX H 1403 | 0942: 7E MOV A,M 1404 | 0943: 325C09 STA L095F-3 1405 | 0946: 2B DCX H 1406 | 0947: 7E MOV A,M 1407 | 0948: 325809 STA L095F-7 1408 | 094B: 41 MOV B,C 1409 | 094C: EB XCHG 1410 | 094D: AF XRA A 1411 | 094E: 4F MOV C,A 1412 | 094F: 57 MOV D,A 1413 | 0950: 5F MOV E,A 1414 | 0951: 326309 STA L095F+4 1415 | 0954: E5 FDivLoop PUSH H 1416 | 0955: C5 PUSH B 1417 | 0956: 7D MOV A,L 1418 | 0957: D600 SUI 00h 1419 | 0959: 6F MOV L,A 1420 | 095A: 7C MOV A,H 1421 | 095B: DE00 SBI 00 1422 | 095D: 67 MOV H,A 1423 | 095E: 78 MOV A,B 1424 | 095F: DE00 L095F SBI 00 1425 | 0961: 47 MOV B,A 1426 | 0962: 3E00 MVI A,00h 1427 | 0964: DE00 SBI 00 1428 | 0966: 3F CMC 1429 | 0967: D27109 JNC L0971 1430 | 096A: 326309 STA L095F+4h 1431 | 096D: F1 POP PSW 1432 | 096E: F1 POP PSW 1433 | 096F: 37 STC 1434 | 0970: D2 DB 0xD2 ;JNC .... 1435 | 0971: C1 L0971 POP B 1436 | 0972: E1 POP H 1437 | 0973: 79 MOV A,C 1438 | 0974: 3C INR A 1439 | 0975: 3D DCR A 1440 | 0976: 1F RAR 1441 | 0977: FA7F08 JM FRoundUp+1 1442 | 097A: 17 RAL 1443 | 097B: CD9008 CALL FMantissaLeft 1444 | 097E: 29 DAD H 1445 | 097F: 78 MOV A,B 1446 | 0980: 17 RAL 1447 | 0981: 47 MOV B,A 1448 | 0982: 3A6309 LDA L095F+4h 1449 | 0985: 17 RAL 1450 | 0986: 326309 STA L095F+4h 1451 | 0989: 79 MOV A,C 1452 | 098A: B2 ORA D 1453 | 098B: B3 ORA E 1454 | 098C: C25409 JNZ FDivLoop 1455 | 098F: E5 PUSH H 1456 | 0990: 217201 LXI H,FACCUM+3 1457 | 0993: 35 DCR M 1458 | 0994: E1 POP H 1459 | 0995: C25409 JNZ FDivLoop 1460 | 0998: C3A408 JMP Overflow 1461 | 099B: 78 FExponentAdd MOV A,B 1462 | 099C: B7 ORA A 1463 | 099D: CABA09 JZ FExponentAdd+31 1464 | 09A0: 7D MOV A,L ;A=0 for add, FF for subtract. 1465 | 09A1: 217201 LXI H,FACCUM+3 ; 1466 | 09A4: AE XRA M ;XOR with FAccum's exponent. 1467 | 09A5: 80 ADD B ;Add exponents 1468 | 09A6: 47 MOV B,A ; 1469 | 09A7: 1F RAR ;Carry (after the add) into bit 7. 1470 | 09A8: A8 XRA B ;XOR with old bit 7. 1471 | 09A9: 78 MOV A,B ; 1472 | 09AA: F2B909 JP FExponentAdd+30 ;If 1473 | 09AD: C680 ADI 0x80 1474 | 09AF: 77 MOV M,A 1475 | 09B0: CA2109 JZ PopHLandReturn 1476 | 09B3: CD370A CALL FUnpackMantissas 1477 | 09B6: 77 MOV M,A 1478 | 09B7: 2B DCX H 1479 | 09B8: C9 RET 1480 | 09B9: B7 ORA A 1481 | 09BA: E1 POP H ;Ignore return address so we'll end 1482 | 09BB: FAA408 JM Overflow 1483 | 09BE: AF FZero XRA A 1484 | 09BF: 327201 STA FACCUM+3 1485 | 09C2: C9 RET 1486 | 09C3: CD1D0A FMulByTen CALL FCopyToBCDE 1487 | 09C6: 78 MOV A,B 1488 | 09C7: B7 ORA A 1489 | 09C8: C8 RZ 1490 | 09C9: C602 ADI 02 1491 | 09CB: DAA408 JC Overflow 1492 | 09CE: 47 MOV B,A 1493 | 09CF: CD1208 CALL FAdd+2 1494 | 09D2: 217201 LXI H,FACCUM+3 1495 | 09D5: 34 INR M 1496 | 09D6: C0 RNZ 1497 | 09D7: C3A408 JMP Overflow 1498 | 09DA: 3A7101 FTestSign_tail LDA FACCUM+2 1499 | 09DD: FE DB 0xFE 1500 | 09DE: 2F InvSignToInt CMA 1501 | 09DF: 17 SignToInt RAL 1502 | 09E0: 9F SBB A 1503 | 09E1: C0 RNZ 1504 | 09E2: 3C INR A 1505 | 09E3: C9 RET 1506 | 09E4: EF Sgn RST 05 ; FTestSign 1507 | 09E5: 0688 FCharToFloat MVI B,88h ;ie 2^8 1508 | 09E7: 110000 LXI D,0000h 1509 | 09EA: 217201 LXI H,FACCUM+3 1510 | 09ED: 4F MOV C,A 1511 | 09EE: 70 MOV M,B 1512 | 09EF: 0600 MVI B,00h 1513 | 09F1: 23 INX H 1514 | 09F2: 3680 MVI M,80h 1515 | 09F4: 17 RAL 1516 | 09F5: C35B08 JMP FNormalise 1517 | 09F8: EF Abs RST 05 ; FTestSign 1518 | 09F9: F0 RP 1519 | 09FA: 217101 FNegate LXI H,FACCUM+2 1520 | 09FD: 7E MOV A,M 1521 | 09FE: EE80 XRI 0x80 1522 | 0A00: 77 MOV M,A 1523 | 0A01: C9 RET 1524 | 0A02: EB FPush XCHG 1525 | 0A03: 2A6F01 LHLD FACCUM 1526 | 0A06: E3 XTHL 1527 | 0A07: E5 PUSH H 1528 | 0A08: 2A7101 LHLD FACCUM+2 1529 | 0A0B: E3 XTHL 1530 | 0A0C: E5 PUSH H 1531 | 0A0D: EB XCHG 1532 | 0A0E: C9 RET 1533 | 0A0F: CD200A FLoadFromMem CALL FLoadBCDEfromMem 1534 | 0A12: EB FLoadFromBCDE XCHG 1535 | 0A13: 226F01 SHLD FACCUM 1536 | 0A16: 60 MOV H,B 1537 | 0A17: 69 MOV L,C 1538 | 0A18: 227101 SHLD FACCUM+2 1539 | 0A1B: EB XCHG 1540 | 0A1C: C9 RET 1541 | 0A1D: 216F01 FCopyToBCDE LXI H,FACCUM 1542 | 0A20: 5E FLoadBCDEfromMem MOV E,M 1543 | 0A21: 23 INX H 1544 | 0A22: 56 MOV D,M 1545 | 0A23: 23 INX H 1546 | 0A24: 4E MOV C,M 1547 | 0A25: 23 INX H 1548 | 0A26: 46 MOV B,M 1549 | 0A27: 23 IncHLReturn INX H 1550 | 0A28: C9 RET 1551 | 0A29: 116F01 FCopyToMem LXI D,FACCUM 1552 | 0A2C: 0604 MVI B,04h 1553 | 0A2E: 1A FCopyLoop LDAX D 1554 | 0A2F: 77 MOV M,A 1555 | 0A30: 13 INX D 1556 | 0A31: 23 INX H 1557 | 0A32: 05 DCR B 1558 | 0A33: C22E0A JNZ FCopyLoop 1559 | 0A36: C9 RET 1560 | 0A37: 217101 FUnpackMantissas LXI H,FACCUM+2 1561 | 0A3A: 7E MOV A,M ; 1562 | 0A3B: 07 RLC ;Move FACCUM's sign to bit 0. 1563 | 0A3C: 37 STC ;Set MSB of FACCUM mantissa, 1564 | 0A3D: 1F RAR ;FACCUM's sign is now in carry. 1565 | 0A3E: 77 MOV M,A ; 1566 | 0A3F: 3F CMC ;Negate FACCUM's sign. 1567 | 0A40: 1F RAR ;Bit 7 of A is now FACCUM's sign. 1568 | 0A41: 23 INX H ;Store negated FACCUM sign at FTEMP_SIGN. 1569 | 0A42: 23 INX H ; 1570 | 0A43: 77 MOV M,A ; 1571 | 0A44: 79 MOV A,C ; 1572 | 0A45: 07 RLC ;Set MSB of BCDE mantissa, 1573 | 0A46: 37 STC ;BCDE's sign is now in carry. 1574 | 0A47: 1F RAR ; 1575 | 0A48: 4F MOV C,A ; 1576 | 0A49: 1F RAR ;Bit 7 of A is now BCDE's sign 1577 | 0A4A: AE XRA M ;XORed with FTEMP_SIGN. 1578 | 0A4B: C9 RET ; 1579 | 0A4C: 78 FCompare MOV A,B 1580 | 0A4D: B7 ORA A 1581 | 0A4E: CA2800 JZ FTestSign 1582 | 0A51: 21DE09 LXI H,InvSignToInt 1583 | 0A54: E5 PUSH H 1584 | 0A55: EF RST 05 ; FTestSign 1585 | 0A56: 79 MOV A,C 1586 | 0A57: C8 RZ 1587 | 0A58: 217101 LXI H,FACCUM+2 1588 | 0A5B: AE XRA M 1589 | 0A5C: 79 MOV A,C 1590 | 0A5D: F8 RM 1591 | 0A5E: CD640A CALL FIsEqual 1592 | 0A61: 1F RAR 1593 | 0A62: A9 XRA C 1594 | 0A63: C9 RET 1595 | 0A64: 23 FIsEqual INX H 1596 | 0A65: 78 MOV A,B 1597 | 0A66: BE CMP M 1598 | 0A67: C0 RNZ 1599 | 0A68: 2B DCX H 1600 | 0A69: 79 MOV A,C 1601 | 0A6A: BE CMP M 1602 | 0A6B: C0 RNZ 1603 | 0A6C: 2B DCX H 1604 | 0A6D: 7A MOV A,D 1605 | 0A6E: BE CMP M 1606 | 0A6F: C0 RNZ 1607 | 0A70: 2B DCX H 1608 | 0A71: 7B MOV A,E 1609 | 0A72: 96 SUB M 1610 | 0A73: C0 RNZ ; 1611 | 0A74: E1 POP H ;Lose 0A5E 1612 | 0A75: E1 POP H ;Lose 09DE 1613 | 0A76: C9 RET ;Return to caller 1614 | 0A77: 47 FAsInteger MOV B,A ; 1615 | 0A78: 4F MOV C,A 1616 | 0A79: 57 MOV D,A 1617 | 0A7A: 5F MOV E,A 1618 | 0A7B: B7 ORA A 1619 | 0A7C: C8 RZ 1620 | 0A7D: E5 PUSH H 1621 | 0A7E: CD1D0A CALL FCopyToBCDE 1622 | 0A81: CD370A CALL FUnpackMantissas 1623 | 0A84: AE XRA M ;Get sign back 1624 | 0A85: 67 MOV H,A 1625 | 0A86: FC9B0A CM FMantissaDec 1626 | 0A89: 3E98 MVI A,98h 1627 | 0A8B: 90 SUB B ;by (24-exponent) places? 1628 | 0A8C: CDC908 CALL FMantissaRtMult ;WHY? 1629 | 0A8F: 7C MOV A,H 1630 | 0A90: 17 RAL 1631 | 0A91: DC9A08 CC FMantissaInc 1632 | 0A94: 0600 MVI B,00h ;Needed for FNegateInt. 1633 | 0A96: DCB508 CC FNegateInt 1634 | 0A99: E1 POP H 1635 | 0A9A: C9 RET 1636 | 0A9B: 1B FMantissaDec DCX D ;DE-- 1637 | 0A9C: 7A MOV A,D ;If DE!=0xFFFF... 1638 | 0A9D: A3 ANA E ; 1639 | 0A9E: 3C INR A ; 1640 | 0A9F: C0 RNZ ;... then return 1641 | 0AA0: 0D DCR C ;C-- 1642 | 0AA1: C9 RET ; 1643 | 0AA2: 217201 Int LXI H,FACCUM+3 ; 1644 | 0AA5: 7E MOV A,M ; 1645 | 0AA6: FE98 CPI 0x98 ; 1646 | 0AA8: D0 RNC ; 1647 | 0AA9: CD770A CALL FAsInteger ; 1648 | 0AAC: 3698 MVI M,98h ; 1649 | 0AAE: 79 MOV A,C ; 1650 | 0AAF: 17 RAL ; 1651 | 0AB0: C35B08 JMP FNormalise ; 1652 | 0AB3: 2B FIn DCX H ; 1653 | 0AB4: CDBE09 CALL FZero ; 1654 | 0AB7: 47 MOV B,A ;B=count of fractional digits 1655 | 0AB8: 57 MOV D,A ;D=exponent sign 1656 | 0AB9: 5F MOV E,A ;E=exponent 1657 | 0ABA: 2F CMA ;C=decimal_point_done (0xFF for no, 0x00 for yes) 1658 | 0ABB: 4F MOV C,A ; 1659 | 0ABC: D7 FInLoop RST 02 ;RST NextChar 1660 | 0ABD: DA040B JC ProcessDigit 1661 | 0AC0: FE2E CPI '.' 1662 | 0AC2: CAE40A JZ L0AE4 1663 | 0AC5: FE45 CPI 'E' 1664 | 0AC7: C2E80A JNZ ScaleResult 1665 | 0ACA: D7 GetExponent RST 02 ;RST NextChar 1666 | 0ACB: 15 DCR D 1667 | 0ACC: FE99 CPI 0x99 ;KWID_MINUS 1668 | 0ACE: CAD80A JZ NextExponentDigit 1669 | 0AD1: 14 INR D 1670 | 0AD2: FE98 CPI 0x98 ;KWID_PLUS 1671 | 0AD4: CAD80A JZ NextExponentDigit 1672 | 0AD7: 2B DCX H 1673 | 0AD8: D7 NextExponentDigit RST 02 ;RST NextChar 1674 | 0AD9: DA230B JC DoExponentDigit 1675 | 0ADC: 14 INR D 1676 | 0ADD: C2E80A JNZ ScaleResult 1677 | 0AE0: AF XRA A 1678 | 0AE1: 93 SUB E 1679 | 0AE2: 5F MOV E,A 1680 | 0AE3: 0C INR C ;C was 0xFF, so here it 1681 | 0AE4: 0C L0AE4 INR C ;becomes 0x01. 1682 | 0AE5: CABC0A JZ FInLoop ;If C is now zero 1683 | 0AE8: E5 ScaleResult PUSH H 1684 | 0AE9: 7B MOV A,E 1685 | 0AEA: 90 SUB B 1686 | 0AEB: F4FC0A DecimalLoop CP DecimalShiftUp 1687 | 0AEE: F2F70A JP DecimalLoopEnd 1688 | 0AF1: F5 PUSH PSW 1689 | 0AF2: CD2309 CALL FDivByTen 1690 | 0AF5: F1 POP PSW 1691 | 0AF6: 3C INR A 1692 | 0AF7: C2EB0A DecimalLoopEnd JNZ DecimalLoop 1693 | 0AFA: E1 POP H 1694 | 0AFB: C9 RET 1695 | 0AFC: C8 DecimalShiftUp RZ 1696 | 0AFD: F5 PUSH PSW 1697 | 0AFE: CDC309 CALL FMulByTen 1698 | 0B01: F1 POP PSW 1699 | 0B02: 3D DCR A 1700 | 0B03: C9 RET 1701 | 0B04: D5 ProcessDigit PUSH D 1702 | 0B05: 57 MOV D,A 1703 | 0B06: 78 MOV A,B 1704 | 0B07: 89 ADC C 1705 | 0B08: 47 MOV B,A 1706 | 0B09: C5 PUSH B 1707 | 0B0A: E5 PUSH H 1708 | 0B0B: D5 PUSH D 1709 | 0B0C: CDC309 CALL FMulByTen 1710 | 0B0F: F1 POP PSW 1711 | 0B10: D630 SUI '0' 1712 | 0B12: CD020A CALL FPush 1713 | 0B15: CDE509 CALL FCharToFloat 1714 | 0B18: C1 POP B 1715 | 0B19: D1 POP D 1716 | 0B1A: CD1208 CALL FAdd+2 1717 | 0B1D: E1 POP H 1718 | 0B1E: C1 POP B 1719 | 0B1F: D1 POP D 1720 | 0B20: C3BC0A JMP FInLoop 1721 | 0B23: 7B DoExponentDigit MOV A,E 1722 | 0B24: 07 RLC 1723 | 0B25: 07 RLC 1724 | 0B26: 83 ADD E 1725 | 0B27: 07 RLC 1726 | 0B28: 86 ADD M 1727 | 0B29: D630 SUI '0' 1728 | 0B2B: 5F MOV E,A 1729 | 0B2C: C3D80A JMP NextExponentDigit 1730 | 0B2F: E5 PrintIN PUSH H 1731 | 0B30: 218801 LXI H,szIn 1732 | 0B33: CDA305 CALL PrintString 1733 | 0B36: E1 POP H 1734 | 0B37: EB PrintInt XCHG ;DE=integer 1735 | 0B38: AF XRA A ;A=0 (ends up in C) 1736 | 0B39: 0698 MVI B,98h ;B (ie exponent) = 24 1737 | 0B3B: CDEA09 CALL FCharToFloat+5 1738 | 0B3E: 21A205 LXI H,PrintString-1 1739 | 0B41: E5 PUSH H 1740 | 0B42: 217401 FOut LXI H,FBUFFER 1741 | 0B45: E5 PUSH H 1742 | 0B46: EF RST 05 ; FTestSign 1743 | 0B47: 3620 MVI M,' ' 1744 | 0B49: F24E0B JP DoZero 1745 | 0B4C: 362D MVI M,'-' 1746 | 0B4E: 23 DoZero INX H 1747 | 0B4F: 3630 MVI M,'0' 1748 | 0B51: CAF70B JZ NullTerm-3 1749 | 0B54: E5 PUSH H 1750 | 0B55: FCFA09 CM FNegate 1751 | 0B58: AF XRA A 1752 | 0B59: F5 PUSH PSW 1753 | 0B5A: CDFD0B CALL ToUnder1000000 1754 | 0B5D: 014391 ToOver100000 LXI B,9143h ;BCDE=(float)100,000. 1755 | 0B60: 11F84F LXI D,4FF8h ; 1756 | 0B63: CD4C0A CALL FCompare ;If FACCUM >= 100,000 1757 | 0B66: E27A0B JPO PrepareToPrint ;then jump to PrepareToPrint. 1758 | 0B69: F1 POP PSW ;A=DecExpAdj 1759 | 0B6A: CDFD0A CALL DecimalShiftUp+1 ;FACCUM*=10; DecExpAdj--; 1760 | 0B6D: F5 PUSH PSW ; 1761 | 0B6E: C35D0B JMP ToOver100000 1762 | 0B71: CD2309 L0B71 CALL FDivByTen 1763 | 0B74: F1 POP PSW 1764 | 0B75: 3C INR A ;DecExpAdj++; 1765 | 0B76: F5 PUSH PSW 1766 | 0B77: CDFD0B CALL ToUnder1000000 1767 | 0B7A: CD0108 PrepareToPrint CALL FAddOneHalf 1768 | 0B7D: 3C INR A 1769 | 0B7E: CD770A CALL FAsInteger 1770 | 0B81: CD120A CALL FLoadFromBCDE 1771 | 0B84: 010602 LXI B,0206h 1772 | 0B87: F1 POP PSW ;A=DecExpAdj+6. 1773 | 0B88: 81 ADD C ; 1774 | 0B89: FA950B JM L0B95 ;If A<1 or A>6 Then goto fixme. 1775 | 0B8C: FE07 CPI 0x07 ; 1776 | 0B8E: D2950B JNC L0B95 ; 1777 | 0B91: 3C INR A ; 1778 | 0B92: 47 MOV B,A ; 1779 | 0B93: 3E01 MVI A,01h ;A=1, indicating scientific notation. 1780 | 0B95: 3D L0B95 DCR A ; 1781 | 0B96: E1 POP H ;HL=output buffer 1782 | 0B97: F5 PUSH PSW ;Preserve decimal exponent adjustment (and preserve zero flag used to indicate scientific notation wanted). 1783 | 0B98: 110F0C LXI D,DECIMAL_POWERS 1784 | 0B9B: 05 NextDigit DCR B 1785 | 0B9C: 362E MVI M,'.' 1786 | 0B9E: CC270A CZ IncHLReturn ;0A27 just happens to inc HL and RET. 1787 | 0BA1: C5 PUSH B ; 1788 | 0BA2: E5 PUSH H ; 1789 | 0BA3: D5 PUSH D ;DE=>decimal power 1790 | 0BA4: CD1D0A CALL FCopyToBCDE ;Store BCDE to FACCUM. 1791 | 0BA7: E1 POP H ;HL=>decimal power. 1792 | 0BA8: 062F MVI B,'0'-1 ; 1793 | 0BAA: 04 DigitLoop INR B ; 1794 | 0BAB: 7B MOV A,E ; 1795 | 0BAC: 96 SUB M ; 1796 | 0BAD: 5F MOV E,A ; 1797 | 0BAE: 23 INX H ; 1798 | 0BAF: 7A MOV A,D ; 1799 | 0BB0: 9E SBB M ; 1800 | 0BB1: 57 MOV D,A ; 1801 | 0BB2: 23 INX H ; 1802 | 0BB3: 79 MOV A,C ; 1803 | 0BB4: 9E SBB M ; 1804 | 0BB5: 4F MOV C,A ; 1805 | 0BB6: 2B DCX H ; 1806 | 0BB7: 2B DCX H ; 1807 | 0BB8: D2AA0B JNC DigitLoop ; 1808 | 0BBB: CDA908 CALL FAddMantissas ; 1809 | 0BBE: 23 INX H ;??? 1810 | 0BBF: CD120A CALL FLoadFromBCDE ; 1811 | 0BC2: EB XCHG ; 1812 | 0BC3: E1 POP H ;HL=output buffer 1813 | 0BC4: 70 MOV M,B ; 1814 | 0BC5: 23 INX H ; 1815 | 0BC6: C1 POP B ;B=decimal point place 1816 | 0BC7: 0D DCR C ;C=digits remaining, minus one. 1817 | 0BC8: C29B0B JNZ NextDigit ; 1818 | 0BCB: 05 DCR B ; 1819 | 0BCC: CADB0B JZ L0BDB ; 1820 | 0BCF: 2B L0BCF DCX H ; 1821 | 0BD0: 7E MOV A,M ; 1822 | 0BD1: FE30 CPI '0' ; 1823 | 0BD3: CACF0B JZ L0BCF ; 1824 | 0BD6: FE2E CPI '.' ; 1825 | 0BD8: C4270A CNZ IncHLReturn ; 1826 | 0BDB: F1 L0BDB POP PSW ; 1827 | 0BDC: CAFA0B JZ NullTerm ; 1828 | 0BDF: 3645 MVI M,'E' ;Write 'E' 1829 | 0BE1: 23 INX H ; 1830 | 0BE2: 362B MVI M,'+' ;Write '+' or '-' 1831 | 0BE4: F2EB0B JP L0BEB ; 1832 | 0BE7: 362D MVI M,'-' ;Write '-' if it's negative, also 1833 | 0BE9: 2F CMA ;two's complement the decimal exponent 1834 | 0BEA: 3C INR A ;so printing it will work. 1835 | 0BEB: 062F L0BEB MVI B,'0'-1 ; 1836 | 0BED: 04 ExpDigitLoop INR B ; 1837 | 0BEE: D60A SUI 0Ah ; 1838 | 0BF0: D2ED0B JNC ExpDigitLoop ; 1839 | 0BF3: C63A ADI 3Ah ;Adding '0'+10 gives us the 2nd digit 1840 | 0BF5: 23 INX H ;of the exponent. 1841 | 0BF6: 70 MOV M,B ;Write first digit. 1842 | 0BF7: 23 INX H ; 1843 | 0BF8: 77 MOV M,A ;Write second digit of exponent. 1844 | 0BF9: 23 INX H ; 1845 | 0BFA: 71 NullTerm MOV M,C ;Null byte terminator. 1846 | 0BFB: E1 POP H ; 1847 | 0BFC: C9 RET ; 1848 | 0BFD: 017494 ToUnder1000000 LXI B,9474h ; 1849 | 0C00: 11F723 LXI D,23F7h ; 1850 | 0C03: CD4C0A CALL FCompare ; 1851 | 0C06: E1 POP H ; 1852 | 0C07: E2710B JPO L0B71 ; 1853 | 0C0A: E9 PCHL ; 1854 | 0C0B: 00000080 ONE_HALF DB 0x00,0x00,0x00,0x80 ; DD 0.5 1855 | 0C0F: A08601 DECIMAL_POWERS DB 0xA0,0x86,0x01 ; DT 100000 1856 | 0C12: 102700 DB 0x10,0x27,0x00 ; DT 10000 1857 | 0C15: E80300 DB 0xE8,0x03,0x00 ; DT 1000 1858 | 0C18: 640000 DB 0x64,0x00,0x00 ; DT 100 1859 | 0C1B: 0A0000 DB 0x0A,0x00,0x00 ; DT 10 1860 | 0C1E: 010000 DB 0x01,0x00,0x00 ; DT 1 1861 | 0C21: EF Sqr RST 05 ; FTestSign ; 1862 | 0C22: FA9804 JM FunctionCallError; 1863 | 0C25: C8 RZ ; 1864 | 0C26: 217201 LXI H,FACCUM+3 ; 1865 | 0C29: 7E MOV A,M ; 1866 | 0C2A: 1F RAR ; 1867 | 0C2B: F5 PUSH PSW ; 1868 | 0C2C: E5 PUSH H ; 1869 | 0C2D: 3E40 MVI A,40h ; 1870 | 0C2F: 17 RAL ; 1871 | 0C30: 77 MOV M,A ; 1872 | 0C31: 217401 LXI H,FBUFFER ; 1873 | 0C34: CD290A CALL FCopyToMem ; 1874 | 0C37: 3E04 MVI A,04h ; 1875 | 0C39: F5 SqrLoop PUSH PSW ; 1876 | 0C3A: CD020A CALL FPush ; 1877 | 0C3D: 217401 LXI H,FBUFFER ; 1878 | 0C40: CD200A CALL FLoadBCDEfromMem 1879 | 0C43: CD3109 CALL FDiv+2 1880 | 0C46: C1 POP B 1881 | 0C47: D1 POP D 1882 | 0C48: CD1208 CALL FAdd+2 1883 | 0C4B: 010080 LXI B,8000h 1884 | 0C4E: 51 MOV D,C 1885 | 0C4F: 59 MOV E,C 1886 | 0C50: CDE508 CALL FMul+2 1887 | 0C53: F1 POP PSW 1888 | 0C54: 3D DCR A 1889 | 0C55: C2390C JNZ SqrLoop 1890 | 0C58: E1 POP H 1891 | 0C59: F1 POP PSW 1892 | 0C5A: C6C0 ADI 0xC0 1893 | 0C5C: 86 ADD M 1894 | 0C5D: 77 MOV M,A 1895 | 0C5E: C9 RET 1896 | 0C5F: EF Rnd RST 05 ; FTestSign 1897 | 0C60: FA7C0C JM L0C7C 1898 | 0C63: 21910C LXI H,RND_SEED 1899 | 0C66: CD0F0A CALL FLoadFromMem 1900 | 0C69: C8 RZ 1901 | 0C6A: 013598 LXI B,9835h 1902 | 0C6D: 117A44 LXI D,447Ah 1903 | 0C70: CDE508 CALL FMul+2 1904 | 0C73: 012868 LXI B,0x6828 1905 | 0C76: 1146B1 LXI D,0xB146 1906 | 0C79: CD1208 CALL FAdd+2 1907 | 0C7C: CD1D0A L0C7C CALL FCopyToBCDE 1908 | 0C7F: 7B MOV A,E 1909 | 0C80: 59 MOV E,C 1910 | 0C81: 4F MOV C,A 1911 | 0C82: 3680 MVI M,80h 1912 | 0C84: 2B DCX H 1913 | 0C85: 46 MOV B,M 1914 | 0C86: 3680 MVI M,80h 1915 | 0C88: CD5E08 CALL FNormalise+3 1916 | 0C8B: 21910C LXI H,RND_SEED 1917 | 0C8E: C3290A JMP FCopyToMem 1918 | 0C91: 52C74F80 RND_SEED DB 52C74F80h 1919 | 0C95: CD020A Sin CALL FPush ;ush x 1920 | 0C98: 014983 LXI B,8349h ;CDE=2p 1921 | 0C9B: 11DB0F LXI D,0FDBh ; 1922 | 0C9E: CD120A CALL FLoadFromBCDE ;hs = 2p 1923 | 0CA1: C1 POP B ;hs = x 1924 | 0CA2: D1 POP D ; 1925 | 0CA3: CD3109 CALL FDiv+2 ;=x/2p 1926 | 0CA6: CD020A CALL FPush ; 1927 | 0CA9: CDA20A CALL Int ;hs = INT(u) 1928 | 0CAC: C1 POP B ;hs = u 1929 | 0CAD: D1 POP D ; 1930 | 0CAE: CD0C08 CALL FSub+2 ;=u-INT(u) 1931 | 0CB1: 01007F LXI B,7F00h ;CDE=0.25 1932 | 0CB4: 51 MOV D,C ; 1933 | 0CB5: 59 MOV E,C ; 1934 | 0CB6: CD0C08 CALL FSub+2 ; 1935 | 0CB9: EF RST 05 ; FTestSign ; 1936 | 0CBA: 37 STC ;set carry (ie no later negate) 1937 | 0CBB: F2C30C JP NegateIfPositive ; 1938 | 0CBE: CD0108 CALL FAddOneHalf ; 1939 | 0CC1: EF RST 05 ; 1940 | 0CC2: B7 ORA A ;resets carry (ie later negate) 1941 | 0CC3: F5 NegateIfPositive PUSH PSW ; 1942 | 0CC4: F4FA09 CP FNegate ; 1943 | 0CC7: 01007F LXI B,7F00h ;CDE=0.25 1944 | 0CCA: 51 MOV D,C ; 1945 | 0CCB: 59 MOV E,C ; 1946 | 0CCC: CD1208 CALL FAdd+2 ; 1947 | 0CCF: F1 POP PSW ; 1948 | 0CD0: D4FA09 CNC FNegate ; 1949 | 0CD3: CD020A CALL FPush ; 1950 | 0CD6: CD1D0A CALL FCopyToBCDE ; 1951 | 0CD9: CDE508 CALL FMul+2 ; = x*x 1952 | 0CDC: CD020A CALL FPush ;ush x*x 1953 | 0CDF: 21030D LXI H,TAYLOR_SERIES ; 1954 | 0CE2: CD0F0A CALL FLoadFromMem ; 1955 | 0CE5: C1 POP B ; 1956 | 0CE6: D1 POP D ; 1957 | 0CE7: 3E04 MVI A,04h ; 1958 | 0CE9: F5 TaylorLoop PUSH PSW ;ush #terms remaining 1959 | 0CEA: D5 PUSH D ;ush BCDE 1960 | 0CEB: C5 PUSH B ; 1961 | 0CEC: E5 PUSH H ; 1962 | 0CED: CDE508 CALL FMul+2 ; 1963 | 0CF0: E1 POP H ; 1964 | 0CF1: CD200A CALL FLoadBCDEfromMem ; 1965 | 0CF4: E5 PUSH H ; 1966 | 0CF5: CD1208 CALL FAdd+2 ; 1967 | 0CF8: E1 POP H ; 1968 | 0CF9: C1 POP B ; 1969 | 0CFA: D1 POP D ; 1970 | 0CFB: F1 POP PSW ;op #terms remaining into A. 1971 | 0CFC: 3D DCR A ;ecrement #terms and loop back if not 1972 | 0CFD: C2E90C JNZ TaylorLoop ;one all 4 of them. 1973 | 0D00: C3E308 JMP FMul ; 1974 | 0D03: BAD71E86 TAYLOR_SERIES DB 0xBA,0xD7,0x1E,0x86 ;DD 39.710670 1975 | 0D07: 64269987 DB 0x64,0x26,0x99,0x87 ;DD -76.574982 1976 | 0D0B: 58342387 DB 0x58,0x34,0x23,0x87 ;DD 81.602234 1977 | 0D0F: E05DA586 DB 0xE0,0x5D,0xA5,0x86 ;DD -41.341675 1978 | 0D13: DA0F4983 DB 0xDA,0x0F,0x49,0x83 ;DD 6.283185 1979 | 0D17: 00000000 L0D17 DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ; DD 6.283185 1980 | 0D1B: 00... 1981 | 0D21: 211A0F Init LXI H,0x0F1A ; *** STACK_TOP RELOCATE 1982 | 0D24: F9 SPHL ; 1983 | 0D25: 226301 SHLD STACK_TOP ; 1984 | 0D28: DB01 IN 01 ; 1985 | 0D2A: 0EFF MVI C,0xFF ; 1986 | 0D2C: 118E0D LXI D,ConfigIOcode ; 1987 | 0D2F: D5 PUSH D ; 1988 | 0D30: 3AFF0F LDA 0FFFh ; *** RELOCATE 1989 | 0D33: 47 MOV B,A ; 1990 | 0D34: DBFF IN 0xFF ; 1991 | 0D36: 1F RAR ; 1992 | 0D37: DA410D JC L0D42-1 ; 1993 | 0D3A: E60C ANI 0Ch ; 1994 | 0D3C: CA420D JZ L0D42 ; 1995 | 0D3F: 0610 MVI B,10h ; 1996 | 0D41: 78 MOV A,B ; 1997 | 0D42: 328C0D L0D42 STA L0D8D-1 ; 1998 | 0D45: DBFF IN 0xFF ; 1999 | 0D47: 17 RAL ; 2000 | 0D48: 17 RAL ; 2001 | 0D49: 0620 MVI B,20h ; 2002 | 0D4B: 1102CA L0D4B LXI D,0xCA02 ; 2003 | 0D4E: D8 RC ; 2004 | 0D4F: 17 RAL ; 2005 | 0D50: 43 MOV B,E ; 2006 | 0D51: 1D DCR E ; 2007 | 0D52: D8 RC ; 2008 | 0D53: 17 RAL ; 2009 | 0D54: DA6F0D JC L0D6F ; 2010 | 0D57: 43 MOV B,E ; 2011 | 0D58: 1180C2 LXI D,0xC280 ; 2012 | 0D5B: 17 RAL ; 2013 | 0D5C: D0 RNC ; 2014 | 0D5D: 17 RAL ; 2015 | 0D5E: 3E03 MVI A,03h ; 2016 | 0D60: CD8B0D CALL L0D8B ; 2017 | 0D63: 3D DCR A ; 2018 | 0D64: 8F ADC A ; 2019 | 0D65: 87 ADD A ; 2020 | 0D66: 87 ADD A ; 2021 | 0D67: 3C INR A ; 2022 | 0D68: CD8B0D CALL L0D8B ; 2023 | 0D6B: 37 STC ; 2024 | 0D6C: C34B0D JMP L0D4B ; 2025 | 0D6F: AF L0D6F XRA A ; 2026 | 0D70: CD8B0D CALL L0D8B ; 2027 | 0D73: CD870D CALL L0D87 ; 2028 | 0D76: CD870D CALL L0D87 ; 2029 | 0D79: 4B MOV C,E ; 2030 | 0D7A: 2F CMA ; 2031 | 0D7B: CD870D CALL L0D87 ; 2032 | 0D7E: 3E04 MVI A,04h ; 2033 | 0D80: 35 DCR M ; 2034 | 0D81: CD8B0D CALL L0D8B ; 2035 | 0D84: 35 DCR M ; 2036 | 0D85: 35 DCR M ; 2037 | 0D86: 35 DCR M ; 2038 | 0D87: 218C0D L0D87 LXI H,L0D8D-1 ; 2039 | 0D8A: 34 INR M ; 2040 | 0D8B: D300 L0D8B OUT 00 ; 2041 | 0D8D: C9 L0D8D RET ; 2042 | 0D8E: 62 ConfigIOcode MOV H,D ; 2043 | 0D8F: 68 MOV L,B ; 2044 | 0D90: 228503 SHLD InputChar+3 ; 2045 | 0D93: 7C MOV A,H ; 2046 | 0D94: E6C8 ANI 0xC8 ; 2047 | 0D96: 67 MOV H,A ; 2048 | 0D97: 227604 SHLD TestBreakKey+3 ; 2049 | 0D9A: EB XCHG ; 2050 | 0D9B: 227A03 SHLD WaitTermReady+3 ; 2051 | 0D9E: 3A8C0D LDA L0D8D-1 ; 2052 | 0DA1: 328303 STA InputChar+1 ; 2053 | 0DA4: 327404 STA TestBreakKey+1 ; 2054 | 0DA7: 3C INR A ; 2055 | 0DA8: 328A03 STA InputChar+8 ; 2056 | 0DAB: 81 ADD C ; 2057 | 0DAC: 327803 STA WaitTermReady+1 ; 2058 | 0DAF: 3C INR A ; 2059 | 0DB0: 328003 STA InputChar-2 ; 2060 | 0DB3: 21FFFF LXI H,0xFFFF ; 2061 | 0DB6: 226101 SHLD CURRENT_LINE ; 2062 | 0DB9: CD8A05 CALL NewLine ; 2063 | 0DBC: 21F00E LXI H,szMemorySize ; 2064 | 0DBF: CDA305 CALL PrintString 2065 | 0DC2: CDC202 CALL InputLineWith 2066 | 0DC5: D7 RST 02 ;RST NextChar 2067 | 0DC6: B7 ORA A 2068 | 0DC7: C2DE0D JNZ L0DDE 2069 | 0DCA: 21FC0E LXI H,UnusedMemory 2070 | 0DCD: 23 FindMemTopLoop INX H 2071 | 0DCE: 3E37 MVI A,37h 2072 | 0DD0: 77 MOV M,A 2073 | 0DD1: BE CMP M 2074 | 0DD2: C2EA0D JNZ DoneMemSize 2075 | 0DD5: 3D DCR A 2076 | 0DD6: 77 MOV M,A 2077 | 0DD7: BE CMP M 2078 | 0DD8: CACD0D JZ FindMemTopLoop 2079 | 0DDB: C3EA0D JMP DoneMemSize 2080 | 0DDE: 211301 L0DDE LXI H,LINE_BUFFER 2081 | 0DE1: CD9D04 CALL LineNumberFromStr 2082 | 0DE4: B7 ORA A 2083 | 0DE5: C2D001 JNZ SyntaxError 2084 | 0DE8: EB XCHG 2085 | 0DE9: 2B DCX H 2086 | 0DEA: 2B DoneMemSize DCX H 2087 | 0DEB: E5 PUSH H 2088 | 0DEC: 21B40E GetTerminalWidth LXI H,szTerminalWidth 2089 | 0DEF: CDA305 CALL PrintString 2090 | 0DF2: CDC202 CALL InputLineWith 2091 | 0DF5: D7 RST 02 ;RST NextChar 2092 | 0DF6: B7 ORA A 2093 | 0DF7: CA1B0E JZ DoOptionalFns 2094 | 0DFA: 211301 LXI H,LINE_BUFFER 2095 | 0DFD: CD9D04 CALL LineNumberFromStr 2096 | 0E00: 7A MOV A,D 2097 | 0E01: B7 ORA A 2098 | 0E02: C2EC0D JNZ GetTerminalWidth 2099 | 0E05: 7B MOV A,E 2100 | 0E06: FE10 CPI 0x10 2101 | 0E08: DAEC0D JC GetTerminalWidth 2102 | 0E0B: 326F03 STA OutChar_tail+1 2103 | 0E0E: D60E CalcTabBrkSize SUI 0Eh 2104 | 0E10: D20E0E JNC CalcTabBrkSize 2105 | 0E13: C61C ADI 1Ch 2106 | 0E15: 2F CMA 2107 | 0E16: 3C INR A 2108 | 0E17: 83 ADD E 2109 | 0E18: 32B705 STA ToNextTabBreak+4 2110 | 0E1B: 21850E DoOptionalFns LXI H,OPT_FN_DESCS 2111 | 0E1E: F7 OptionalFnsLoop RST 6 2112 | 0E1F: 11990E LXI D,szWantSin 2113 | 0E22: E7 RST 4 2114 | 0E23: CA320E JZ L0E32 2115 | 0E26: F7 RST 6 2116 | 0E27: E3 XTHL 2117 | 0E28: CDA305 CALL PrintString 2118 | 0E2B: CDC202 CALL InputLineWith 2119 | 0E2E: D7 RST 02 ;RST NextChar 2120 | 0E2F: E1 POP H 2121 | 0E30: FE59 CPI 'Y' 2122 | 0E32: D1 L0E32 POP D 2123 | 0E33: CA470E JZ InitProgramBase 2124 | 0E36: FE4E CPI 'N' 2125 | 0E38: C21B0E JNZ DoOptionalFns 2126 | 0E3B: F7 RST 6 2127 | 0E3C: E3 XTHL 2128 | 0E3D: 119804 LXI D,FunctionCallError 2129 | 0E40: 73 MOV M,E 2130 | 0E41: 23 INX H 2131 | 0E42: 72 MOV M,D 2132 | 0E43: E1 POP H 2133 | 0E44: C31E0E JMP OptionalFnsLoop 2134 | 0E47: EB InitProgramBase XCHG 2135 | 0E48: 3600 MVI M,00h 2136 | 0E4A: 23 INX H 2137 | 0E4B: 226501 SHLD PROGRAM_BASE 2138 | 0E4E: E3 XTHL 2139 | 0E4F: 111A0F LXI D,0F1Ah ; *** RELOCATE STACK_TOP 2140 | 0E52: E7 RST 4 2141 | 0E53: DACD01 JC OutOfMemory 2142 | 0E56: D1 POP D 2143 | 0E57: F9 SPHL 2144 | 0E58: 226301 SHLD STACK_TOP 2145 | 0E5B: EB XCHG 2146 | 0E5C: CDC301 CALL CheckEnoughMem 2147 | 0E5F: 7B MOV A,E 2148 | 0E60: 95 SUB L 2149 | 0E61: 6F MOV L,A 2150 | 0E62: 7A MOV A,D 2151 | 0E63: 9C SBB H 2152 | 0E64: 67 MOV H,A 2153 | 0E65: 01F0FF LXI B,0xFFF0 2154 | 0E68: 09 DAD B 2155 | 0E69: CD8A05 CALL NewLine 2156 | 0E6C: CD370B CALL PrintInt 2157 | 0E6F: 21C30E LXI H,szVersionInfo 2158 | 0E72: CDA305 CALL PrintString 2159 | 0E75: 21A305 LXI H,PrintString 2160 | 0E78: 22FD01 SHLD Main+4 2161 | 0E7B: CD9602 CALL New+1 2162 | 0E7E: 21F901 LXI H,Main 2163 | 0E81: 220200 SHLD Start+2 2164 | 0E84: E9 PCHL 2165 | 2166 | 0E85: 170D OPT_FN_DESCS DW L0D17 2167 | 0E87: 990E DW szWantSin 2168 | 0E89: 4900 DW KW_INLINE_FNS+12 2169 | 0E8B: 950C DW Sin 2170 | 0E8D: A20E DW szWantRnd 2171 | 0E8F: 4700 DW KW_INLINE_FNS+10 2172 | 0E91: 5F0C DW Rnd 2173 | 0E93: AB0E DW szWantSqr 2174 | 0E95: 4500 DW KW_INLINE_FNS+8 2175 | 2176 | 0E97: 210C DW Sqr 2177 | 2178 | 0E99: 57414E54 szWantSin DB 57414E54205349CE00h ; DS "WANT SIN\0" 2179 | 0E9D: 205349CE 2180 | 0EA1: 00 2181 | 0EA2: 57414E54 szWantRnd DB 57414E5420524EC400h ; DS "WANT RND\0" 2182 | 0EA6: 20524EC4 2183 | 0EAA: 00 2184 | 0EAB: 57414E54 szWantSqr DB 57414E54205351D200h ; DS "WANT SQR\0" 2185 | 0EAF: 205351D2 2186 | 0EB3: 00 2187 | 2188 | 2189 | 0EB4: 5445524D szTerminalWidth DB 5445524D494E414C2057494454C800h ; DS "TERMINAL WIDTH\0" 2190 | 0EB8: 494E414C 2191 | 0EBC: 20574944 2192 | 0EC0: 54C800 2193 | 2194 | 0EC3: 20425954 szVersionInfo DB 0x20,0x42,0x59,0x54,0x45,0x53,0x20,0x46,0x52,0x45,0xC5,0x0D,0x0D ; DS " BYTES FREE\r\r" 2195 | 0EC7: 45532046 2196 | 0ECB: 5245C50D 2197 | 0ECF: 0D 2198 | 0ED0: 42415349 DB 0x42,0x41,0x53,0x49,0x43,0x20,0x56,0x45,0x52,0x53,0x49,0x4F,0x4E,0x20,0x33,0x2E ; "BASIC VERSION 3." 2199 | 0ED4: 43205645 2200 | 0ED8: 5253494F 2201 | 0EDC: 4E20332E 2202 | 0EE0: B20D5B34 DB 0xB2,0x0D,0x5B,0x34,0x4B,0x20,0x56,0x45,0x52,0x53,0x49,0x4F,0x4E,0xDD,0x0D,0x00 ; "2\r[4K VERSION]\r\0" 2203 | 0EE4: 4B205645 2204 | 0EE8: 5253494F 2205 | 0EEC: 4EDD0D00 2206 | 0EF0: 4D454D4F szMemorySize DB 0x4D,0x45,0x4D,0x4F,0x52,0x59,0x20,0x53,0x49,0x5A,0xC5,0x00 ; DS "MEMORY SIZE\0" 2207 | 0EF4: 52592053 2208 | 0EF8: 495AC500 2209 | 2210 | 2211 | 2212 | 0EFC: 00 UnusedMemory DB 00 2213 | 2214 | 2215 | total time: 0.0312 sec. 2216 | no errors 2217 | --------------------------------------------------------------------------------