PAGE 01 DAI FIRMWARE DD1A-DEB4 V1.0 Rev.1 002 ORG :DD1A 003 * 004 * 005 * 006 ******************* 007 * INPUT TEXT LINE * 008 ******************* 009 * 010 * Part of 'restart interpreter' (C853). 011 * Scans keyboard and reads in a line on the current 012 * screen line, up until car.ret. First prints 013 * car.ret and a prompt ('*'). 014 * The routine can be aborted on car.ret or Break 015 * only. 016 * 017 * Entry: A: Contains prompt. 018 * Exit: CY=1: Break pressed. 019 * CY=0: HL: Address 1st character on line. 020 * C=1: Offset 1st significant character 021 * ABDEHL preserved. 022 * 023 DD1A F5 INPL0 PUSH PSW 024 DD1B CD55DD CALL :DD55 Cursor to column 0 025 DD1E F1 POP PSW Get prompt 026 DD1F 37 INPLN STC CY=1 027 DD20 F5 PUSH PSW 028 DD21 E5 PUSH H Save cursor coord 1st char 029 DD22 CD6ADD IPL10 CALL :DD6A Print prompt 030 DD25 21B902 LXI H,:02B9 031 DD28 3600 MVI M,:00 Enable complete keyb.scan 032 DD2A CDBED6 IPL20 CALL :D6BE Get keyb. input 033 DD2D DA49DD JC :DD49 Ignore line if Break pressed 034 DD30 CA2ADD JZ :DD2A Wait for input 035 DD33 FE20 CPI :20 Printable character? 036 DD35 D222DD JNC :DD22 Print it and get next one 037 DD38 FE08 CPI :08 Backspace 038 DD3A CA22DD JZ :DD22 Print it; get next char 039 DD3D FE0D CPI :0D Car.ret? 040 DD3F C22ADD JNZ :DD2A Get next char if not 041 042 * Exit on car.ret: 043 044 DD42 35 DCR M Set KBRFL for BREAK only 045 DD43 0E01 MVI C,:01 046 DD45 E1 EXIT1 POP H Get cursor coord 1st char 047 DD46 F1 POP PSW Get prompt 048 DD47 3F CMC CY=0 049 DD48 C9 RET 050 051 * Exit on Break: 052 053 DD49 35 IPL30 DCR M Set KBRFL for BREAK only 054 DD4A 3E21 MVI A,:21 055 DD4C CD60DD CALL :DD60 Print '!' 056 DD4F CD5EDD CALL :DD5E Print car.ret 057 DD52 E1 POP H 058 DD53 F1 POP PSW Get prompt, CY=1 059 DD54 C9 RET 060 * 061 ********************** 062 * CURSOR TO COLUMN 0 * 063 ********************** PAGE 02 DAI FIRMWARE DD1A-DEB4 V1.0 Rev.1 064 * 065 * The X-coordinate of the cursor is checked. 066 * If not 0, a car.ret is printed. 067 * 068 * Entry: None. 069 * Exit: AF corrupted. BCDEHL preserved. 070 * 071 DD55 D5 COL0 PUSH D 072 DD56 E5 PUSH H 073 DD57 EF RST 5 Get cursor pos (HL) and size 074 DD58 0C DATA :0C char.screen (DE) 075 DD59 7D MOV A,L X-coord cursor in A 076 DD5A E1 POP H 077 DD5B D1 POP D 078 DD5C B7 ORA A 079 DD5D C8 RZ Abort if cursor in Col.0 080 DD5E 3E0D CRLF MVI A,:0D Else: print CR 081 * 082 * GENERAL OUTPUT ROUTINE: 083 * 084 * Outputs a character in a direction depending 085 * on OTSW (#0131). 086 * 087 * Entry: A: Character to be transmitted. 088 * Exit: AF corrupted. 089 * 090 *SCCHR 091 DD60 F5 OUTC PUSH PSW Preserve char 092 DD61 3A3101 LDA :0131 093 DD64 FE02 CPI :02 Check output direction 094 DD66 D270DD JNC :DD70 If to edit buf/DOUTC 095 096 * To screen/RS232 - OTSW=0/1: 097 098 DD69 F1 POP PSW Get char 099 DD6A EF COUTC RST 5 Character to screen 100 DD6B 03 DATA :03 101 DD6C D442D6 CNC :D642 Output to RS232 if reqd 102 DD6F C9 RET 103 104 * To DOUTC - OTSW=3: 105 106 DD70 00 OTC10 NOP 107 DD71 C24CD7 JNZ :D74C Character to DOUTC 108 109 * To editbuffer - OTSW=2: 110 111 DD74 F1 POP PSW Get char 112 DD75 F5 OTBIN PUSH PSW 113 DD76 E5 PUSH H 114 DD77 D5 PUSH D 115 DD78 2AA400 LHLD :00A4 Get edit input pointer 116 DD7B 77 MOV M,A Byte in edit buffer 117 DD7C 23 INX H 118 DD7D 22A400 SHLD :00A4 Update edit input pointer 119 DD80 EB XCHG in DE 120 DD81 2AA600 LHLD :00A6 Get end edit buffer 121 DD84 CD14DE CALL :DE14 Calculate free buffer space 122 DD87 DA8EDD JC :DD8E If edit buffer full 123 DD8A D1 POP D 124 DD8B E1 POP H 125 DD8C F1 OTC99 POP PSW PAGE 03 DAI FIRMWARE DD1A-DEB4 V1.0 Rev.1 126 DD8D C9 RET 127 128 * If edit buffer full: 129 130 DD8E CDCADE OTC20 CALL :DECA Heap back to right size 131 DD91 C310DA JMP :DA10 Run error 'OUT OF MEMORY' 132 * 133 ******************* 134 * OUTPUT TO RS232 * 135 ******************* 136 * 137 * Transmits a character to the RS232 interface via 138 * the TICC if the interface is ready for it. 139 * In case of a car.ret, also a line feed is send. 140 * 141 * Entry: A: Character to be transmitted. 142 * Exit: ABCDEHL preserved, F corrupted. 143 * 144 DD94 F5 OUTSE PUSH PSW Preserve char 145 DD95 3A00FD OTS10 LDA :FD00 146 DD98 E608 ANI :08 Check peripheral ready 147 DD9A CA95DD JZ :DD95 Wait untill ready 148 DD9D 3AF3FF OTS20 LDA :FFF3 149 DDA0 E610 ANI :10 Check TICC buffer empty 150 DDA2 CA9DDD JZ :DD9D Wait untill empty 151 DDA5 F1 POP PSW Get char 152 DDA6 32F6FF STA :FFF6 Load serial output buffer 153 DDA9 FE0D CPI :0D Carriage return? 154 DDAB C0 RNZ Ready if not 155 156 * If car.ret: 157 158 DDAC F5 PUSH PSW 159 DDAD 3E0A MVI A,:0A 160 DDAF CD94DD CALL :DD94 Send line feed too 161 DDB2 F1 POP PSW 162 DDB3 C9 RET 163 * 164 ******************** 165 * INPUT FROM RS232 * 166 ******************** 167 * 168 * Gets inputs from RS232 via TICC. Only 7-bit 169 * Ascii-code is accepted. 170 * 171 * Entry: No conditions. 172 * Exit: A: Character received (0 if nothing). 173 * BCDEHL preserved. 174 * 175 *CINC 176 DDB4 3AF3FF INSER LDA :FFF3 177 DDB7 E608 ANI :08 Check if something received 178 DDB9 C8 RZ Abort if no reception 179 DDBA 3AF0FF LDA :FFF0 Received char in A 180 DDBD E67F ANI :7F Mask bit 7 181 DDBF C9 RET 182 * 183 ********************************** 184 * RS232 FRAME ERROR - (not used) * 185 ********************************** 186 * 187 * Break test for serial input line. PAGE 04 DAI FIRMWARE DD1A-DEB4 V1.0 Rev.1 188 * 189 DDC0 3AF3FF BRSER LDA :FFF3 190 DDC3 1F RAR 191 DDC4 D0 RNC Abort if no break 192 DDC5 3AF3FF BRS10 LDA :FFF3 If break: check again 193 DDC8 1F RAR 194 DDC9 DAC5DD JC :DDC5 Wait until end of break 195 DDCC 3AF0FF LDA :FFF0 Load received character 196 DDCF 3F CMC Set CY=1 197 DDD0 C9 RET 198 * 199 * 200 * =========================== 201 *** ENCODING SERVICE ROUTINES *** 202 * =========================== 203 * 204 * 205 * The following routines are used both in 'main' 206 * and 'decode' modules. 207 * 208 ************************************************ 209 * GET CHARACTER FROM LINE, NEGLECT TAB + SPACE * 210 ************************************************ 211 * 212 * Entry: C: Position on current line. 213 * Exit: Character in A; tab and space neglected. 214 * C: Points to next character. 215 * BDEHL preserved. 216 * 217 DDD1 0C IGNBR INR C Pnts to next char 218 DDD2 CDE0DD IGNB CALL :DDE0 Get char from line 219 DDD5 FE20 CPI :20 Space? 220 DDD7 CAD1DD JZ :DDD1 Then get next char 221 DDDA FE09 CPI :09 Tab? 222 DDDC CAD1DD JZ :DDD1 Then get next char 223 DDDF C9 RET 224 * 225 *************************** 226 * GET CHARACTER TO ENCODE * 227 *************************** 228 * 229 * Returns a character from some position on the 230 * current line. The source is determined by EFSW. 231 * 232 * Entry: C: Position on current line (max. 219). 233 * Exit: EFSW=0 - Keyboard: Char on line pos in A. 234 * EFSW>=2 - Edit buf: Char on EFEPT + line 235 * pos in A. 236 * EFSW=1 - String: Idem. If COUNT=line pos 237 * then char is car.ret. 238 * F corrupted, BCDEHL preserved. 239 * 240 DDE0 3A3501 EFETCH LDA :0135 241 DDE3 FE01 CPI :01 Check input direction 242 DDE5 DAFFDD JC :DDFF If from keyb/RS232 243 DDE8 C2F4DD JNZ :DDF4 If from edit buffer 244 245 * If from string: 246 247 DDEB 3A3401 LDA :0134 If string: Get COUNT 248 DDEE B9 CMP C COUNT=pos.on curr.line? 249 DDEF 3E0D MVI A,:0D Then char is car.ret PAGE 05 DAI FIRMWARE DD1A-DEB4 V1.0 Rev.1 250 DDF1 CAFEDD JZ :DDFE And abort 251 252 * Entry if from edit buffer: 253 254 DDF4 E5 EFC10 PUSH H 255 DDF5 2A3201 LHLD :0132 Get EFEPT 256 DDF8 79 MOV A,C 257 DDF9 CD30DE CALL :DE30 Add curr.line pos to EFEPT 258 DDFC 7E MOV A,M Get character 259 DDFD E1 POP H 260 DDFE C9 EFC20 RET 261 262 * If from screen: 263 264 DDFF EF EFC30 RST 5 Get character from line 265 DE00 15 DATA :15 266 DE01 C9 RET 267 * 268 * 269 * ================================== 270 *** SINGLE AND DOUBLE BYTE UTILITIES *** 271 * ================================== 272 * 273 * 274 ********************************* 275 * CHECK IF UPPER CASE CHARACTER * 276 ********************************* 277 * 278 * Entry: A: Character to be checked. 279 * Exit: CY=0: Not upper case. 280 * CY=1: Upper case. 281 * ABCDEHL preserved, F corrupted. 282 * 283 DE02 FE41 ALPHA CPI :41 Lowest upper case char 284 DE04 3F CMC 285 DE05 D0 RNC 286 DE06 FE5B CPI :5B First lower case char 287 DE08 C9 RET 288 * 289 ********************************************** 290 * CHECK IF CHARACTER IS NUMBER OR UPPER CASE * 291 ********************************************** 292 * 293 * Entry: A: Character to be checked. 294 * Exit: CY=0: Not number, not upper case. 295 * CY=1: Number or upper case. 296 * ABCDEHL preserved. F corrupted. 297 * 298 DE09 CD02DE ALNUM CALL :DE02 Check if upper case 299 DE0C D8 RC 300 DE0D FE30 NUMER CPI :30 Lowest number 301 DE0F 3F CMC 302 DE10 D0 RNC 303 DE11 FE3A CPI :3A No number anymore 304 DE13 C9 RET 305 * 306 ********************* 307 * COMPARE HL AND DE * 308 ********************* 309 * 310 * Compares HL with DE (HL-DE). 311 * PAGE 06 DAI FIRMWARE DD1A-DEB4 V1.0 Rev.1 312 * Exit: DE=HL: Z=1, CY=0. 313 * DEHL: Z=0, CY=1. 315 * BCDEHL preserved, AF corrupted. 316 * 317 DE14 7C COMP MOV A,H 318 DE15 BA CMP D 319 DE16 C0 RNZ 320 DE17 7D MOV A,L 321 DE18 BB CMP E 322 DE19 C9 RET 323 * 324 ***************************** 325 * CALCULATE LENGTH OF BLOCK * 326 ***************************** 327 * 328 * Sets HL=HL-DE. 329 * 330 * Entry: Startaddress in DE, 1st address after 331 * block in HL. 332 * Exit: Length in HL, startaddress in DE. 333 * If DE>HL, length in 2-complement. 334 * ABCDE preserved, F as in COMP. 335 * 336 DE1A C5 SUBDE PUSH B 337 DE1B F5 PUSH PSW 338 DE1C 7D MOV A,L 339 DE1D 93 SUB E Calc. difference lowest byte 340 DE1E 6F MOV L,A 341 DE1F 7C MOV A,H 342 DE20 9A SBB D Calc. diff. highest byte 343 DE21 67 MOV H,A 344 DE22 C1 POP B 345 DE23 78 MOV A,B 346 DE24 C1 POP B 347 DE25 C9 RET 348 * 349 ****************************** 350 * DOUBLE BYTE TWO COMPLEMENT * 351 ****************************** 352 * 353 * Sets HL=-HL. 354 * 355 * Entry: Double byte to be converted in HL. 356 * Exit: Two complement in HL. ABCDEF preserved. 357 * 358 DE26 F5 CMPHL PUSH PSW 359 DE27 7C MOV A,H 360 DE28 2F CMA Complement H 361 DE29 67 MOV H,A 362 DE2A 7D MOV A,L 363 DE2B 2F CMA Complement L 364 DE2C 6F MOV L,A 365 DE2D 23 INX H Add 1 366 DE2E F1 POP PSW 367 DE2F C9 RET 368 * 369 ************************** 370 * ADD OFF-SET TO ADDRESS * 371 ************************** 372 * 373 * Adds a given offset to a base address (HL=HL+A). PAGE 07 DAI FIRMWARE DD1A-DEB4 V1.0 Rev.1 374 * 375 * Entry: Base in HL, offset in A. 376 * Exit: HL=HL+A. ABCDE preserved, F corrupted. 377 * 378 DE30 F5 DADA PUSH PSW 379 DE31 85 ADD L 380 DE32 6F MOV L,A L=L+A 381 DE33 7C MOV A,H 382 DE34 CE00 ACI :00 Add carry if overflow 383 DE36 67 MOV H,A 384 DE37 F1 POP PSW 385 DE38 C9 RET 386 * 387 ********************************** 388 * CALCULATE ADDRESS AFTER STRING * 389 ********************************** 390 * 391 * Sets HL=HL+M+1. 392 * 393 * Entry: HL points to 1st byte of string (length 394 * byte). 395 * Exit: HL points to first byte after string. 396 * AFBCDE preserved. 397 * 398 DE39 F5 DADM PUSH PSW 399 DE3A 7E MOV A,M Get length of string 400 DE3B 23 INX H HL: addr. 1st char. byte 401 DE3C CD30DE CALL :DE30 Calc addr after string 402 DE3F F1 POP PSW 403 DE40 C9 RET 404 * 405 ***************** 406 * DELAY ROUTINE * 407 ***************** 408 * 409 * Runs a fixed delay loop of 665 msec. If 410 * interrupts are enabled, the delay will be 411 * approx. 750 msec. 412 * HL is loaded with FFFF, and then decremented. 413 * 414 * Exit: ABCDEHL preserved; F corrupted. 415 * 416 DE41 E5 DELAY PUSH H 417 DE42 D5 PUSH D 418 DE43 21FFFF LXI H,:FFFF Init. delay value 419 DE46 54 MOV D,H 420 DE47 5D MOV E,L 421 DE48 19 DLY10 DAD D 422 DE49 DA48DE JC :DE48 Repeat if not ready 423 DE4C D1 POP D 424 DE4D E1 POP H 425 DE4E C9 RET 426 * 427 *********************** 428 * DATA BLOCK TRANSFER * 429 *********************** 430 * 431 * Moves a block of data starting at (DE) and 432 * ending at (HL)-1 to (BC). 433 * 434 * Entry: DE: Startaddr. source bank. 435 * BC: Startaddr. destination bank. PAGE 08 DAI FIRMWARE DD1A-DEB4 V1.0 Rev.1 436 * HL: Points after end source bank. 437 * Exit: AF preserved, BCDEHL corrupted. 438 * 439 DE4F F5 MOVE PUSH PSW 440 DE50 E5 PUSH H 441 DE51 CD1ADE CALL :DE1A Calc. length source bank 442 DE54 79 MOV A,C 443 DE55 93 SUB E 444 DE56 78 MOV A,B 445 DE57 9A SBB D 446 DE58 DA6CDE JC :DE6C If destination addr. is 447 lower than source addr. 448 449 * Destination address > source address: 450 451 DE5B 54 MOV D,H 452 DE5C 5D MOV E,L Save length in DE 453 DE5D 09 DAD B Highest dest.addr. in HL 454 DE5E C1 POP B 455 DE5F 7A MOV10 MOV A,D Check if ready 456 DE60 B3 ORA E 457 DE61 CA7ADE JZ :DE7A Then abort 458 DE64 1B DCX D 459 DE65 2B DCX H 460 DE66 0B DCX B 461 DE67 0A LDAX B Get byte to be transferred 462 DE68 77 MOV M,A Transfer it 463 DE69 C35FDE JMP :DE5F Next one 464 465 * Destination address < source address: 466 467 DE6C 7C MOV20 MOV A,H 468 DE6D B5 ORA L 469 DE6E CA79DE JZ :DE79 Abort if ready 470 DE71 2B DCX H 471 DE72 1A LDAX D Get byte to be transferred 472 DE73 02 STAX B Transfer it 473 DE74 13 INX D 474 DE75 03 INX B 475 DE76 C36CDE JMP :DE6C Next byte 476 477 * If ready: 478 479 DE79 E1 MOV30 POP H 480 DE7A F1 MOV40 POP PSW 481 DE7B C9 RET 482 * 483 ********************************* 484 * FILL BANK WITH IDENTICAL DATA * 485 ********************************* 486 * 487 * Fills an area of memory with a constant. 488 * 489 * Entry: DE: Startaddr. of bank. 490 * HL: Points after bank. 491 * A: Data to be loaded into bank. 492 * Exit: DE: Points after bank. 493 * BCHL preserved, AF corrupted. 494 * 495 DE7C C5 FILL PUSH B 496 DE7D 47 MOV B,A Save data in B 497 DE7E CD14DE FIL10 CALL :DE14 Check if bank full PAGE 09 DAI FIRMWARE DD1A-DEB4 V1.0 Rev.1 498 DE81 CA8DDE JZ :DE8D Abort if ready 499 DE84 DA8DDE JC :DE8D Abort if DE>HL 500 DE87 78 MOV A,B Get data 501 DE88 12 STAX D and store it 502 DE89 13 INX D 503 DE8A C37EDE JMP :DE7E Next addr. 504 DE8D C1 FIL20 POP B 505 DE8E C9 RET 506 * 507 ******************** 508 * MULTIPLY HL BY A * 509 ******************** 510 * 511 * Multiplies a 16-bit value by a 8-bit value. 512 * 513 * Entry: HL: 16-bit value. 514 * A: 8-bit value. 515 * Exit: CY=0: Result in HL. 516 * CY=1: Overflow. 517 * ABCDE preserved. 518 * 519 DE8F 37 HLMUL STC 520 DE90 F5 PUSH PSW 521 DE91 D5 PUSH D 522 DE92 EB XCHG 523 DE93 210000 LXI H,:0000 Init. result 524 DE96 B7 HLM10 ORA A 525 DE97 1F RAR Next bit of multiplier 526 DE98 D29FDE JNC :DE9F Jump if bit is 0 527 DE9B 19 DAD D Add 1* HL if bit is 1 528 DE9C DAADDE JC :DEAD Abort if overflow 529 DE9F B7 HLM20 ORA A 530 DEA0 CAB1DE JZ :DEB1 Abort if ready 531 DEA3 EB XCHG 532 DEA4 29 DAD H Multiply *2 533 DEA5 EB XCHG 534 DEA6 D296DE JNC :DE96 Again if no overflow 535 DEA9 00 NOP 536 DEAA 00 NOP 537 DEAB 00 NOP 538 DEAC 00 NOP 539 DEAD 00 HLM90 NOP 540 DEAE D1 POP D 541 DEAF F1 POP PSW Error exit if overflow 542 DEB0 C9 RET 543 DEB1 D1 HLM99 POP D 544 DEB2 F1 POP PSW 545 DEB3 3F CMC No error exit 546 DEB4 C9 RET 547 * 548 * 549 * 554 DEB5 END *************************** * S Y M B O L T A B L E * *************************** ALNUM DE09 ALPHA DE02 BRS10 DDC5 BRSER DDC0 CINC DDB4 CMPHL DE26 COL0 DD55 COMP DE14 COUTC DD6A CRLF DD5E DADA DE30 DADM DE39 DELAY DE41 DLY10 DE48 EFC10 DDF4 EFC20 DDFE PAGE 10 DAI FIRMWARE DD1A-DEB4 V1.0 Rev.1 EFC30 DDFF EFETCH DDE0 EXIT1 DD45 FIL10 DE7E FIL20 DE8D FILL DE7C HLM10 DE96 HLM20 DE9F HLM90 DEAD HLM99 DEB1 HLMUL DE8F IGNB DDD2 IGNBR DDD1 INPL0 DD1A INPLN DD1F INSER DDB4 IPL10 DD22 IPL20 DD2A IPL30 DD49 MOV10 DE5F MOV20 DE6C MOV30 DE79 MOV40 DE7A MOVE DE4F NUMER DE0D OTBIN DD75 OTC10 DD70 OTC20 DD8E OTC99 DD8C OTS10 DD95 OTS20 DD9D OUTC DD60 OUTSE DD94 SCCHR DD60 SUBDE DE1A