PAGE 01 DAI FIRMWARE D620-D78F V1.1 002 ORG :D620 003 * 004 * 005 * 006 ************************** 007 * COMPLETE KEYBOARD SCAN * 008 ************************** 009 * 010 * Initialises a complete keyboard scan, 011 * independent of the KNSCAN flag, and performs it. 012 * 013 * Exit: All registers preserved. 014 * 015 D620 F5 KFSCAN PUSH PSW 016 D621 C5 PUSH B 017 D622 D5 PUSH D 018 D623 E5 PUSH H 019 D624 21B902 LXI H,:02B9 Addr KNSCAN pointer 020 D627 3600 MVI M,:00 Enable complete scan 021 D629 E5 PUSH H 022 D62A CD9AD5 CALL :D59A Scan keyboard and store 023 result in circ.buffer 024 D62D E1 POP H 025 D62E 35 DCR M Scan for BREAK only 026 D62F C356CB JMP :CB56 Popall; return 027 * 028 ********************************** 029 * GET ASCII VALUE OF KEY PRESSED * 030 ********************************** 031 * 032 * Calculates address in ASCII table in ROM and gets 033 * ASCII value of the key pressed. The result is 034 * stored in the 4-bye circular buffer KLIND. 035 * 036 * Entry: A: Keycode of scanned row (7 bits only). 037 * B: FF when REPT pressed; else 00. 038 * C: Number of row. 039 * DE: Address in MAP2. 040 * HL: Address in MAP1. 041 * Exit: BCDEHL preserved; AF corrupted. 042 * 043 D632 C5 TKEY PUSH B 044 D633 0607 MVI B,:07 Check which key in row is 045 D635 1F TKY10 RAR pressed; calculate offset 046 D636 DC3FD6 CC :D63F Get ASCII value; store it 047 in KLIND 048 D639 05 DCR B 049 D63A C235D6 JNZ :D635 Next column 050 D63D C1 POP B 051 D63E C9 RET 052 * 053 * GET KEY-ASCII VALUE AND STORE IT: 054 * 055 D63F CF SINKEY RST 1 Get ASCII-value from ROM- 056 D640 12 DATA :12 table and store it in KLIND 057 D641 C9 RET 058 * 059 ******************************* 060 * OUTPUT TO RS232 IF REQUIRED * 061 ******************************* 062 * 063 * Checks if output is to RS232. If positive, PAGE 02 DAI FIRMWARE D620-D78F V1.1 064 * output is performed. 065 * 066 * Entry: Byte to be transmitted in A. 067 * 068 D642 F5 TOUTSE PUSH PSW 069 D643 3A3101 LDA :0131 Get output direction 070 D646 B7 ORA A Check if RS232 output 071 D647 C28CDD JNZ :DD8C Abort if not 072 D64A F1 POP PSW 073 D64B C394DD JMP :DD94 Output to RS232 074 * 075 ****************************************** 076 * GET ASCII-VALUE OF CHARACTER IN BUFFER * 077 ****************************************** 078 * 079 * Routine is not used. 080 * 081 * The Ascii-value of a character is stored in 082 * KLIND. Afterwards, Bank select is restored. 083 * 084 D64E CD3FE9 LD67 CALL :E93F (3) Ascii-value in KLIND 085 D651 F1 POP PSW A contains POROM 086 D652 CD08D8 CALL :D808 Update PORO and POROM 087 D655 F1 POP PSW 088 D656 E1 POP H 089 D657 C9 RET 090 * 091 ************************************ 092 * parts of RUN 'RANDOMISE' (0E40C) * 093 ************************************ 094 * 095 *RMI15 096 D658 3D MPT39 DCR A 097 D659 C258D6 JNZ :D658 Again till A=0 098 D65C 7E MOV A,M Get contents FD00 099 D65D AB XRA E 100 D65E C9 RET 101 * 102 * Entry: L = 0. 103 * 104 D65F 3AC101 MPT38 LDA :01C1 Get keyb.scan time count 105 (0, 1 or 2) 106 D662 0F RRC 107 D663 0F RRC A= 0, #40 or #80 108 D664 5F MOV E,A in E 109 D665 45 MOV B,L ) 110 D666 4D MOV C,L ) BC=0 111 D667 C9 RET 112 * 113 ************************************ 114 * WRITE 2 BLOCKS + TRAILER ON TAPE * 115 ************************************ 116 * 117 * Entry: HL: Startaddress 1st block. 118 * Stack: Length 2nd block. 119 * Startaddress 2nd block. 120 * 121 D668 110100 MPT13 LXI D,:0001 Length 1st block = 1 122 D66B CDC802 CALL :02C8 Write 1st block 123 D66E D1 POP D Get length 2nd block 124 D66F E1 POP H Get startaddr. 2nd block 125 D670 CDC802 CALL :02C8 Write 2nd block PAGE 03 DAI FIRMWARE D620-D78F V1.1 126 D673 CDCB02 CALL :02CB Write trailer 127 D676 B7 ORA A 128 D677 C9 RET 129 * 130 ******************************** 131 * LOADA: EVALUATE PROGRAM NAME * 132 ******************************** 133 * 134 * The program name is evaluated. Selection of 135 * ROM bank 1 is prepared. 136 * 137 D678 CD87D6 MPT14 CALL :D687 Evaluate program name 138 D67B 3A4000 LDA :0040 Get POROM 139 D67E F640 ORI :40 Prepare selection ROMbank 1 140 D680 C9 RET 141 * 142 ****************** 143 * OPEN READ FILE * 144 ****************** 145 * 146 D681 D5 MPT18 PUSH D 147 D682 CDCE02 CALL :02CE Open READ file 148 D685 D1 POP D 149 D686 C9 RET 150 * 151 ********************************* 152 * EVALUATE A STRING EXPRESSSION * 153 ********************************* 154 * 155 * A string expression is evaluated. Eventually, 156 * the Heap entry is cleared if the string was 157 * temporarily on Heap. 158 * 159 * Exit: DE preserved, BC updated. 160 * HL points after string 161 * 162 D687 D5 MPT15 PUSH D 163 D688 CD91E7 CALL :E791 (0) Eval. string expr. 164 evt. clear Heap entry 165 D68B D1 POP D 166 D68C C9 RET 167 * 168 ******************* 169 * CURSOR HANDLING * 170 ******************* 171 * 172 * Load the cursor pointers with the address, the 173 * colour and the contents of a new cursor address. 174 * 175 * Entry: HL: New cursor address. 176 * D: The colour byte of this location. 177 * E: The contents of this location. 178 * Exit: HL and DE exchanged; ABCF preserved. 179 * 180 D68D 227200 SPT00 SHLD :0072 Store cursor address 181 D690 EB XCHG 182 D691 227600 SHLD :0076 Store cursor addr.contents 183 D694 C9 RET 184 * 185 ************************ 186 * OUTPUT ONE CHARACTER * 187 ************************ PAGE 04 DAI FIRMWARE D620-D78F V1.1 188 * 189 * Output direction depending on OTSW. 190 * This routine is useable for all data output 191 * functions in machine language programs. 192 * 193 * Entry: Character for output in A. 194 * Exit: All registers preserved. 195 * 196 D695 F5 MPT31 PUSH PSW 197 D696 CD60DD CALL :DD60 Output character in A. 198 D699 F1 POP PSW 199 D69A C9 RET 200 * 201 D69B FF DATA :FF 202 * 203 ************************************************ 204 * KEYB. SCANNING: UPDATE POINTER OUTPUT BUFFER * 205 ************************************************ 206 * 207 * Updates the pointer to the circular output 208 * buffer #02BA-#02BD. 209 * 210 * Entry: HL: KLIOU. 211 * Exit: HL: Updated KLIOU. 212 * AF corrupted. BCDE preserved. 213 * 214 D69C 23 KPTRU INX H Incr. KLIOU 215 D69D 7D MOV A,L Lobyte into A 216 D69E FEBE CPI :BE Buffer full? 217 D6A0 C0 RNZ Quit if not 218 D6A1 21BA02 LXI H,:02BA Else: wrap around 219 D6A4 C9 RET 220 * 221 ****************************************** 222 * KEYBOARD SCANNING: CHECK IF NEW INPUTS * 223 ****************************************** 224 * 225 * Returns a flag if BREAK has been pressed or if 226 * there is a character available. 227 * 228 * Entry: No conditions. 229 * Exit: BCDEHL preserved. 230 * A: Difference KLIIN and KLIOU. 231 * CY=1: Break pressed. 232 * CY=0, Z=1: No inputs. 233 * CY=0, Z=0: New input available. 234 * 235 *ASKKEY 236 D6A5 E5 BREAK PUSH H 237 238 * If suspended: 239 240 D6A6 21C402 LXI H,:02C4 Addr break pntr 241 D6A9 7E MOV A,M 242 D6AA 3D DCR A 243 D6AB FEFE CPI :FE Test if not 0 or FF 244 D6AD DAB9D6 JC :D6B9 Abort if break: CY=1 245 * 246 D6B0 2AC002 LHLD :02C0 Get KLIOU 247 D6B3 3ABE02 LDA :02BE Get KLIIN 248 D6B6 95 SUB L New keys pressed? 249 D6B7 37 STC PAGE 05 DAI FIRMWARE D620-D78F V1.1 250 D6B8 3F CMC CY=0 251 D6B9 E1 OTK10 POP H 252 D6BA C9 RET 253 * 254 ****************** 255 * INPUT SCANNING * 256 ****************** 257 * 258 * Gets input from keyboard or DINC, depending on 259 * INSW (0296). 260 * 261 * FGETC: Gets a character, even if keyboard 262 * scanning is turned off. 263 * GETC: Returns a flag if break, and sets break 264 * accepted. Returns also a flag if a 265 * character is available. 266 * 267 * Exit: CY=1: Break pressed. 268 * Z=1: No inputs. Then A=0. 269 * Else: Character in A. 270 * 271 D6BB CD20D6 FGETC CALL :D620 Complete keyboard scan 272 D6BE C3DBD1 GETC JMP :D1DB Check input keyb/DINC; 273 scan for new keys pressed 274 D6C1 DAD4D6 MPR29 JC :D6D4 Jump if Break pressed. 275 D6C4 C8 RZ No new input or buffer full 276 277 * If inputs: 278 279 D6C5 E5 PUSH H 280 D6C6 2AC002 LHLD :02C0 Get addr pntr output buffer 281 D6C9 7E MOV A,M Get ASCII char in A 282 D6CA F5 PUSH PSW 283 D6CB CD9CD6 CALL :D69C Update pntr 284 D6CE F1 POP PSW 285 D6CF 22C002 SHLD :02C0 Re-instate KLIOU 286 D6D2 E1 POP H 287 D6D3 C9 RET CY=0 288 289 * If Break pressed: 290 291 D6D4 3EFF GTC10 MVI A,:FF Flag 'break accepted' 292 D6D6 32C402 STA :02C4 Scan for break only 293 D6D9 C9 RET CY=1 294 * 295 ********************* 296 * WAIT FOR SPACEBAR * 297 ********************* 298 * 299 * Wait until spacebar (or break) is pressed. 300 * 301 * Entry: None. 302 * Exit: CY=1: Break pressed. 303 * CY=0: Space in A. 304 * BCDEHL preserved. 305 * 306 D6DA CDBBD6 WSPACE CALL :D6BB Input scanning 307 D6DD D8 RC Abort if BREAK pressed 308 D6DE FE20 CPI :20 Check if spacebar 309 D6E0 C2DAD6 JNZ :D6DA Wait for space bar 310 D6E3 B7 ORA A 311 D6E4 C9 RET PAGE 06 DAI FIRMWARE D620-D78F V1.1 312 * 313 ************************* 314 * part of LOADA (1EE0F) * 315 ************************* 316 * 317 D6E5 E3 MPT20 XTHL Orig. DE in HL, free RAM 318 pntr on stack 319 D6E6 CD14DE CALL :DE14 Compare DE-HL 320 D6E9 D2EDD6 JNC :D6ED If DE<=HL 321 D6EC EB XCHG 322 D6ED 42 RLA15 MOV B,D ) Lowest value in BC 323 D6EE 4B MOV C,E ) 324 D6EF D1 POP D 325 D6F0 E1 POP H 326 D6F1 E3 XTHL 327 D6F2 C34CEE JMP :EE4C (1) Continu 328 * 329 ***************************************** 330 * CHECK SUFFICIENT SCREEN RAM AVAILABLE * 331 * PREPARE SELECTION SPLIT MODE * 332 ***************************************** 333 * 334 D6F5 37 SPT01 STC CY=1 335 D6F6 2A9000 LHLD :0090 Get end area splitting mode 336 D6F9 CDA6E5 CALL :E5A6 (2) Ask for temporary area 337 D6FC 21A0E5 LXI H,:E5A0 (2) Startaddr table screen 338 parameters split modes 339 D6FF C9 RET 340 * 341 ****************************************** 342 * CHANGE FROM SPLIT TO FULL GRAPHIC MODE * 343 ****************************************** 344 * 345 D700 CDF5D6 SSM20 CALL :D6F5 Check suff. screen RAM 346 D703 C385E4 JMP :E485 (2) Change split to full 347 * 348 ***************************************** 349 * CHECK SUFFICIENT SCREEN RAM AVAILABLE * 350 * PREPARE FULL GRAPHICS MODE * 351 ***************************************** 352 * 353 D706 CDF5D6 SPTA2 CALL :D6F5 Check suff. screen RAM 354 D709 219AE5 LXI H,:E59A (2) Startaddr table screen 355 parameters full graph.modes 356 D70C C9 RET 357 * 358 ****************************** 359 * SET UP CURRENT SCREEN MODE * 360 ****************************** 361 * 362 D70D D1 SMA20 POP D 363 D70E F1 POP PSW 364 D70F 3A9D00 SMA30 LDA :009D Get current screen mode 365 D712 B7 ORA A 366 D713 1F RAR Split or all-graph mode ? 367 D714 CD39E5 CALL :E539 (2) Set up screen mode 368 D717 C33CE4 JMP :E43C (2) Pop PSW, ret 369 * 370 ************************* 371 * STOP LOADING PROGRAMS * 372 ************************* 373 * PAGE 07 DAI FIRMWARE D620-D78F V1.1 374 * Entry: HL: New end symbol table. 375 * Exit: All registers preserved. 376 * 377 D71A 22A302 MPT11 SHLD :02A3 Store end symtab 378 D71D C3D402 JMP :02D4 Stop loading 379 * 380 ***************************** 381 * INIT. WRITING FILE LEADER * 382 ***************************** 383 * 384 * Procedure depends on saving in program or not. 385 * 386 D720 E5 MPT21 PUSH H 387 D721 2A0001 LHLD :0100 Get start current line 388 D724 7C MOV A,H 389 D725 B5 ORA L 0 if not during run 390 D726 E1 POP H 391 D727 C214D4 JNZ :D414 If SAVE during run 392 D72A C30CD4 JMP :D40C Write file leader 393 * 394 ****************************************** 395 * INIT. SOUNDGENERATOR, GIC, START HEAP, * 396 * MOVE CASSETTE VECTORS, GET DCE INPUTS * 397 ****************************************** 398 * 399 D72D CDA6D8 MPT00 CALL :D8A6 Init. sound generator 400 D730 CD95D7 CALL :D795 Transfer cassette vectors 401 D733 21EC02 LXI H,:02EC 402 D736 CF RST 1 Init. GIC: get evt. inputs 403 D737 0C DATA :0C from DCE-bus (bootstrap) 404 D738 229B02 SHLD :029B Set HEAP start 405 D73B C9 RET 406 * 407 D73C 02 DATA :02 (not used) 408 * 409 ******************************************** 410 * part of RUN A VARIABLE REFERENCE (0E95A) * 411 ******************************************** 412 * 413 D73D CD6DE9 MPT49 CALL :E96D (0) Run VARPTR 414 D740 D1 POP D 415 D741 C9 RET 416 * 417 D742 DD DATA :DD (not used) 418 * 419 ************************************************* 420 * SET INPUT DIRECTION, LOAD SOUND + KEYB TIMERS * 421 ************************************************* 422 * 423 * Part of 'stack interrupt' (D9E2). 424 * 425 D743 323501 MPT30 STA :0135 Set input direction 426 D746 CD9DD9 CALL :D99D Reload keyboard timer 427 D749 C3A3D9 JMP :D9A3 Reload sound timer, ret 428 * 429 ******************************* 430 * DATA OUTPUT ROUTINE 'DOUTC' * 431 ******************************* 432 * 433 * Part of DD70. 434 * On #02DD, an jump to an user determined output 435 * routine can be written. As default, a RET is PAGE 08 DAI FIRMWARE D620-D78F V1.1 436 * on this address. 437 * 438 D74C F1 OTC30 POP PSW Output char in A 439 D74D C3DD02 JMP :02DD Goto user DOUTC 440 * 441 ******************** 442 * CHECK BREAK FLAG * 443 ******************** 444 * 445 * Part of 'scan keyboard' (D59A). 446 * 447 * Entry: Address 'break' flag in BC. 448 * Exit: BCDEHL preserved, AF corrupted. 449 * 450 D750 0A MPT28 LDAX B Get KBRFL 451 D751 3C INR A 452 D752 C0 RNZ Quit if it was <> FF 453 D753 02 STAX B KBRFL=0: No recent break 454 D754 C9 RET 455 * 456 *************************** 457 * SOUND INTERRUPT (RST 3) * 458 *************************** 459 * 460 * Called periodically every few milliseconds. 461 * Adjust the volume for the sound channels and 462 * approaches the correct frequency if necessary. 463 * 464 * Saves all registers + interrupt mask. 465 * Enables only clock and sound interrupts. 466 * Sound interrupt timer is re-loaded and sound 467 * control blocks are executed. 468 * 469 * Entry: HL must already be saved on stack. 470 * Exit: All registers preserved. 471 * Bank select is restored. 472 * 473 D755 F5 SNTMP PUSH PSW 474 D756 C5 PUSH B 475 D757 D5 PUSH D 476 D758 3A5F00 LDA :005F Get current int. mask 477 D75B F5 PUSH PSW and save it 478 D75C 3E84 MVI A,:84 ) 479 D75E 325F00 STA :005F ) Enable clock and sound 480 D761 32F8FF STA :FFF8 ) interrupts only 481 D764 FB EI 482 D765 CDA3D9 CALL :D9A3 Reload sound timer 483 D768 3A4000 LDA :0040 Get POROM 484 D76B F5 PUSH PSW and save it 485 D76C E63F ANI :3F 486 D76E F640 ORI :40 Select ROM bank 1 487 D770 324000 STA :0040 Set POROM 488 D773 3206FD STA :FD06 and PORO 489 D776 CD6EEE CALL :EE6E (1) Execute SCB('s) 490 D779 F1 POP PSW 491 D77A 324000 STA :0040 Re-instate old ROM bank 492 D77D 3206FD STA :FD06 and save it 493 D780 C3CDD9 JMP :D9CD Restore int. mask; ret 494 * 495 ************************ 496 * FAILURE DURING ROPEN * 497 ************************ PAGE 09 DAI FIRMWARE D620-D78F V1.1 498 * 499 D783 05 MPT54 DCR B 500 D784 04 INR B 501 D785 C2DED7 JNZ :D7DE If file type byte <>0: 502 Run error 503 D788 F1 POP PSW 504 D789 C9 RET 505 * 506 ************************************ 507 * CHECK IF LOAD DURING RUN PROGRAM * 508 ************************************ 509 * 510 * Entry: C: 00 if load during run, else it is FF. 511 * A: File type byte. 512 * Exit: ABCDEHL preserved. 513 * 514 D78A 0D MPT24 DCR C 515 D78B 0C INR C Check C 516 D78C C8 RZ Abort if during run 517 D78D C3ECD7 JMP :D7EC Display file type byte! 518 * 519 * 520 * 525 D790 END *************************** * S Y M B O L T A B L E * *************************** ASKKEY D6A5 BREAK D6A5 FGETC D6BB GETC D6BE GTC10 D6D4 KFSCAN D620 KPTRU D69C LD67 D64E MPR29 D6C1 MPT00 D72D MPT11 D71A MPT13 D668 MPT14 D678 MPT15 D687 MPT18 D681 MPT20 D6E5 MPT21 D720 MPT24 D78A MPT28 D750 MPT30 D743 MPT31 D695 MPT38 D65F MPT39 D658 MPT49 D73D MPT54 D783 OTC30 D74C OTK10 D6B9 RLA15 D6ED RMI15 D658 SINKEY D63F SMA20 D70D SMA30 D70F SNTMP D755 SPT00 D68D SPT01 D6F5 SPTA2 D706 SSM20 D700 TKEY D632 TKY10 D635 TOUTSE D642 WSPACE D6DA