PAGE 01 DAI FIRMWARE 2E5FC-2E7FB V1.1 002 ORG :E5FC 003 * 004 * 005 * 006 ******************************* 007 * INITIALISE HEADER / TRAILER * 008 ******************************* 009 * 010 * Sets up 4 background colour lines which can act 011 * as header/trailer. Sets up colours in colour RAM. 012 * The header/trailer area consists of 4 groups of 013 * 4 bytes: 00 00 xx 3x, in which xx is the colour 014 * and 3x the mode word: 015 * x=6: Header. 016 * x=F: Trailer. 017 * x=0: Middle area (split mode). 018 * 019 * Entry: HL: 1st byte header/trailer area. 020 * DE: Address table with required colours. 021 * A : Screen mode. 022 * B : Depth -1 in scans of each blanking 023 * line: 06 (header), 0F (trailer), 024 * 00 (middle). 025 * Exit: HL: Points after header/trailer area. 026 * AFBCDE preserved. 027 * 028 E5FC F5 SSUBL PUSH PSW 029 E5FD C5 PUSH B 030 E5FE D5 PUSH D 031 E5FF 4F MOV C,A Store screen mode in C 032 E600 78 MOV A,B 033 E601 F630 ORI :30 Set 4 colour to make mode 034 word + rept.count 035 E603 F5 PUSH PSW Save mode word on stack 036 E604 0600 MVI B,:00 037 E606 7B MOV A,E Get lobyte addr colours 038 E607 D67C SUI :7C 039 E609 CA1EE6 JZ :E61E If char mode then 4 colours 040 E60C 79 MOV A,C Get screen mode 041 E60D 1F RAR 042 E60E 1F RAR 043 E60F 48 MOV C,B 044 E610 DA1FE6 JC :E61F Jump if 4-colour mode 045 046 * 16-colour modes only: 047 048 E613 F1 POP PSW Restore header/trailer info 049 E614 F680 ORI :80 Set 16-colour (msb=1) 050 E616 F5 PUSH PSW 051 E617 1A LDAX D Get colour 052 E618 87 ADD A ) 053 E619 87 ADD A ) Move lonibble into 054 E61A 87 ADD A ) hinibble 055 E61B 87 ADD A ) 056 E61C 06FF MVI B,:FF Set all foreground 057 E61E 4F SBL10 MOV C,A Colour in C 058 059 * Load header/trailer: 060 061 E61F F1 SBL20 POP PSW Get mode word 062 E620 F5 PUSH PSW 063 E621 77 MOV M,A Load 1st byte pointer PAGE 02 DAI FIRMWARE 2E5FC-2E7FB V1.1 064 E622 2B DCX H Next addr in block 065 E623 1A LDAX D Get colour info 066 E624 13 INX D 067 E625 77 MOV M,A Load 2nd byte 068 E626 2B DCX H Next addr in block 069 E627 70 MOV M,B Load 3rd byte 070 E628 2B DCX H 071 E629 71 MOV M,C Load 4th byte 072 E62A 2B DCX H 073 E62B FEB0 CPI :B0 All blocks done ? 074 E62D DA1FE6 JC :E61F Next one if not 075 E630 F1 POP PSW 076 E631 D1 POP D 077 E632 C1 POP B 078 E633 F1 POP PSW 079 E634 C9 RET 080 * 081 ***************************** 082 * SET UP A 4-LINE TEXT AREA * 083 ***************************** 084 * 085 * Locates the last few lines of text on the 086 * screen. If the screen was in split mode, the 087 * whole contents of the old screen is located. 088 * If it was mode 0, the last few lines above 089 * and the cursor line are located. 090 * The text is then moved to a required position, 091 * including the cursor, etc. 092 * 093 * Entry: HL: Points to address where the text to 094 * be put. 095 * Exit: HL: Points to new top of text. 096 * AFBCDE preserved. 097 * 098 E635 F5 SMVTXT PUSH PSW 099 E636 C5 PUSH B 100 E637 D5 PUSH D 101 E638 44 MOV B,H ) New top of text in BC 102 E639 4D MOV C,L ) 103 E63A 2A9B00 LHLD :009B Get previous start char 104 E63D E5 PUSH H on stack 105 E63E EB XCHG and in DE 106 E63F 21E8FD LXI H,:FDE8 Length split screen char 107 area 108 E642 19 DAD D Calc 1st line mode byte 109 outside screen frame 110 E643 EB XCHG in DE 111 E644 2A7200 LHLD :0072 Get cursor pos addr 112 E647 CDFBE6 CALL :E6FB Check if cursor is still 113 inside frame 114 E64A DA75E6 JC :E675 Jump if not 115 E64D EB XCHG HL is addr 1st line mode 116 outside screen frame 117 E64E D1 POP D DE is prev start char 118 E64F E5 SMV10 PUSH H Save end preserved text area 119 E650 2A7200 LHLD :0072 Get cursor pos addr 120 E653 CD6BE3 CALL :E36B Delete cursor 121 E656 E3 XTHL Previous start char in HL 122 E657 CDC2E6 CALL :E6C2 Roll screen area to new top 123 of text; cursor on last line 124 E65A E3 XTHL Cursor pos in HL 125 E65B CDF2E6 CALL :E6F2 Calc cursor pos against new PAGE 03 DAI FIRMWARE 2E5FC-2E7FB V1.1 126 frame start 127 E65E 09 DAD B Calc new cursor pos addr 128 E65F CD30E3 CALL :E330 Keep cursor on same pos on 129 line 130 E662 2A7800 LHLD :0078 Get old start line pointer 131 E665 CDF2E6 CALL :E6F2 HL=HL-DE 132 E668 09 DAD B Calc new cursor pos 133 E669 CD98E6 CALL :E698 Store addr line mode byte 134 current line and last addr 135 on that line 136 E66C E1 POP H Get end preserved text area 137 E66D CDF2E6 CALL :E6F2 HL=HL-DE 138 E670 09 DAD B 139 E671 D1 POP D 140 E672 C1 POP B 141 E673 F1 POP PSW 142 E674 C9 RET 143 144 * Scroll frame 1 line if cursor outside frame: 145 146 E675 E1 SMV20 POP H 147 E676 2A7800 LHLD :0078 Get startaddr cursor line 148 E679 117AFF LXI D,:FF7A 149 E67C 19 DAD D HL: start line after cursor 150 E67D E5 PUSH H 151 E67E 111802 LXI D,:0218 152 E681 19 DAD D Subtract 4 lines and get 153 E682 EB XCHG line mode byte in DE 154 E683 E1 POP H Get end reqd area 155 E684 C34FE6 JMP :E64F 156 * 157 ********************************* 158 * PLACE CURSOR AT BEGIN OF LINE * 159 ********************************* 160 * 161 * Sets the cursor at the beginning of a line. 162 * Several pointers are updated. 163 * 164 * SSETC: Given a pointer to the start of line, 165 * sets start and end line variables and 166 * places the cursor at the beginning of 167 * the line. 168 * SSETL: Sets only start and end line positions. 169 * 170 * Entry: HL: Address line mode byte current line. 171 * Exit: ABCDEHL preserved. 172 * 173 E687 F5 SSETC PUSH PSW 174 E688 D5 PUSH D 175 E689 E5 PUSH H 176 E68A 11F8FF LXI D,:FFF8 177 E68D 19 DAD D Get addr 1st data byte 178 on current line 179 E68E CD30E3 CALL :E330 Put cursor on screen 180 E691 AF XRA A 181 E692 327B00 STA :007B No extended lines 182 E695 E1 POP H 183 E696 D1 POP D 184 E697 F1 POP PSW 185 E698 F5 SSETL PUSH PSW 186 E699 227800 SHLD :0078 Store addr line mode byte 187 current line PAGE 04 DAI FIRMWARE 2E5FC-2E7FB V1.1 188 E69C 3E80 MVI A,:80 ) Calc lobyte last addr 189 E69E 85 ADD L ) on this line 190 E69F 327A00 STA :007A Store it in LNEND 191 E6A2 F1 POP PSW 192 E6A3 C9 RET 193 * 194 ************************ 195 * SET GRAPHICS COLOURS * 196 ************************ 197 * 198 * Sets the colours available in a 4 colour mode 199 * and the initial background in a 16 colour mode. 200 * 201 * Entry: HL: Points to colours vector. 202 * Exit: All registers preserved. 203 * 204 E6A4 F5 SCOLG PUSH PSW 205 E6A5 C5 PUSH B 206 E6A6 D5 PUSH D 207 E6A7 E5 PUSH H 208 E6A8 119E00 LXI D,:009E Addr 1st COLORG byte 209 E6AB CD54E2 CALL :E254 Set COLORG parameters 210 E6AE 3A9D00 LDA :009D Get current screen mode 211 E6B1 B7 ORA A Check mode type 212 E6B2 2A8200 LHLD :0082 Get addr after header 213 E6B5 F467E2 CP :E267 If not mode 0: Load COLORG 214 parameters in header 215 E6B8 1F RAR Check if char mode 216 E6B9 2A8E00 LHLD :008E Get addr after trailer 217 E6BC D467E2 CNC :E267 If all graphics mode: 218 Load colours in trailer 219 E6BF C338E1 SGC10 JMP :E138 Popall, ret 220 * 221 ******************** 222 * MOVE SCREEN AREA * 223 ******************** 224 * 225 * Moves a block of screen data from any position 226 * to any other. 227 * 228 * Entry: BC: Points to highaddress target area. 229 * DE: Points to highaddress source area. 230 * HL: Points to lowaddress -1 source area. 231 * Exit: All registers preserved. 232 * 233 E6C2 F5 MOVES PUSH PSW 234 E6C3 C5 PUSH B 235 E6C4 D5 PUSH D 236 E6C5 E5 PUSH H 237 E6C6 CDF2E6 CALL :E6F2 Calc length of block 238 (neg.value) 239 E6C9 7B MOV A,E 240 E6CA 91 SUB C 241 E6CB 7A MOV A,D 242 E6CC 98 SBB B 243 E6CD DAE2E6 JC :E6E2 Jump if move up 244 245 * Move down: 246 247 E6D0 54 MOV D,H ) Length in DE 248 E6D1 5D MOV E,L ) 249 E6D2 09 DAD B HL = lowest targetaddr -1 PAGE 05 DAI FIRMWARE 2E5FC-2E7FB V1.1 250 E6D3 C1 POP B BC = lowest sourceaddr -1 251 E6D4 C5 PUSH B 252 E6D5 7A MVS10 MOV A,D 253 E6D6 B3 ORA E 254 E6D7 CAEFE6 JZ :E6EF Abort if ready 255 E6DA 13 INX D 256 E6DB 23 INX H 257 E6DC 03 INX B 258 E6DD 0A LDAX B Get byte from source area 259 E6DE 77 MOV M,A and move it into target area 260 E6DF C3D5E6 JMP :E6D5 Next one 261 262 * Move up: 263 264 E6E2 7C MVS20 MOV A,H 265 E6E3 B5 ORA L 266 E6E4 CAEFE6 JZ :E6EF Quit if ready 267 E6E7 23 INX H 268 E6E8 1A LDAX D Get byte from source area 269 E6E9 02 STAX B Move it into target area 270 E6EA 0B DCX B 271 E6EB 1B DCX D 272 E6EC C3E2E6 JMP :E6E2 Next one 273 * 274 E6EF C338E1 MVS40 JMP :E138 Popall, ret 275 * 276 **************** 277 * HL = HL - DE * 278 **************** 279 * 280 * Entry: None. 281 * Exit: HL=HL-DE. 282 * Other registers preserved. 283 * 284 E6F2 F5 SUBDE PUSH PSW 285 E6F3 7D MOV A,L 286 E6F4 93 SUB E 287 E6F5 6F MOV L,A L=L-E 288 E6F6 7C MOV A,H 289 E6F7 9A SBB D 290 E6F8 67 MOV H,A H=H-D 291 E6F9 F1 POP PSW 292 E6FA C9 RET 293 * 294 ******************* 295 * COMPARE HL - DE * 296 ******************* 297 * 298 * Compares HL with DE (HL-DE). 299 * 300 * Exit: Z=0: Not identical: 301 * CY=0: DE < HL. 302 * CY=1: DE > HL. 303 * Z=1: Identical. 304 * AF corrupted, BCDEHL preserved. 305 * 306 E6FB 7C COMP MOV A,H 307 E6FC 92 SUB D 308 E6FD C0 RNZ 309 E6FE 7D MOV A,L 310 E6FF 93 SUB E 311 E700 C9 RET PAGE 06 DAI FIRMWARE 2E5FC-2E7FB V1.1 312 * 313 ************************* 314 * ADD OFFSET TO ADDRESS * 315 ************************* 316 * 317 * Sets HL = HL + A. 318 * 319 * Entry: HL: baseaddress. 320 * A : offset. 321 * Exit: HL = HL + A. 322 * BCDE preserved. 323 * 324 E701 85 DADA ADD L Add lobyte addr to offset 325 E702 6F MOV L,A and store it in L 326 E703 D0 RNC 327 E704 24 INR H Incr hibyte if overflow 328 E705 C9 RET 329 * 330 ********************************** 331 * TWO COMPLEMENT OF 16-BITS DATA * 332 ********************************** 333 * 334 * Sets HL = - HL. 335 * 336 * Entry: Data to be complemented in HL. 337 * Exit: HL contains two-complement. 338 * AFBCDE preserved. 339 * 340 E706 F5 CMPHL PUSH PSW 341 E707 7D MOV A,L 342 E708 2F CMA Compl. L 343 E709 6F MOV L,A and store it 344 E70A 7C MOV A,H 345 E70B 2F CMA Compl. H 346 E70C 67 MOV H,A and store it 347 E70D 23 INX H Add 1 348 E70E F1 POP PSW 349 E70F C9 RET 350 * 351 **************************** 352 * DRAW A DOT ON THE SCREEN * 353 **************************** 354 * 355 * Draws a single blob of a colour anywhere 356 * on the screen. 357 * 358 * Entry: C,HL: Y,X coordinate of the dot. 359 * A: Colour of the dot. 360 * Exit: CY=0: O.K. 361 * CY=1: Error code in A. 362 * ABCDEHL preserved. 363 * 364 E710 B7 SDOT ORA A 365 E711 F5 PUSH PSW 366 E712 C5 PUSH B 367 E713 D5 PUSH D 368 E714 E5 PUSH H 369 E715 41 MOV B,C Y-coord in B 370 E716 54 MOV D,H ) X-coord in DE 371 E717 5D MOV E,L ) 372 E718 C31DE8 JMP :E81D Into 'SFILL' 373 * PAGE 07 DAI FIRMWARE 2E5FC-2E7FB V1.1 374 ***************************** 375 * DRAW A LINE ON THE SCREEN * 376 ***************************** 377 * 378 * Draws a line in a given colour between two 379 * arbitrary points on the screen. 380 * 381 * The coordinates are given inclusively. The 382 * line will be drawn starting at the left end, 383 * whichever order the parameters are given in. 384 * 385 * Entry: B,DE: Y,X coordinate of one end of the 386 * line. 387 * C,HL: Idem of the other end. 388 * A: Colour of the line. 389 * Exit: CY=0: O.K. 390 * CY=1: Errorcode in A. 391 * ABCDEHL preserved. 392 * 393 E71B B7 SDRAW ORA A 394 E71C F5 PUSH PSW 395 E71D C5 PUSH B 396 E71E D5 PUSH D 397 E71F E5 PUSH H 398 E720 CD3AE8 CALL :E83A Check arguments, set colour 399 E723 F5 PUSH PSW 400 E724 CDFBE6 CALL :E6FB Check direction of line 401 E727 3E00 MVI A,:00 Set 'no X,Y swop' 402 E729 D22EE7 JNC :E72E Jump if X > Y 403 404 * Swop X,Y: 405 406 E72C EB XCHG Exchange X coordinates 407 E72D 2F CMA 408 * 409 E72E 32C000 DRL30 STA :00C0 FF if X,Y swop, else 00 410 E731 79 MOV A,C 411 E732 E607 ANI :07 412 E734 57 MOV D,A Offset in field in D 413 E735 F1 POP PSW Get Y-pos left end 414 E736 E5 PUSH H Save X length 415 E737 CDB9EB CALL :EBB9 Pntr to start of line in 416 screen RAM 417 E73A E3 XTHL 418 E73B D5 PUSH D Save offset 419 E73C E5 PUSH H Save DX 420 E73D CD06E7 CALL :E706 HL = - DX 421 E740 E3 XTHL 422 E741 E5 PUSH H Save DX 423 E742 6B MOV L,E 424 E743 2600 MVI H,:00 425 E745 29 DAD H 426 E746 22B900 SHLD :00B9 Store 2*DY (adj long 427 sectors) 428 E749 7B MOV A,E DY in A 429 E74A 32BD00 STA :00BD Set count of sectors (1-256) 430 E74D E1 POP H 431 E74E CD60EB CALL :EB60 HL = DX / DY 432 E751 22BB00 SHLD :00BB SECT is INT(DX/DY) 433 E754 C1 POP B Get -DX 434 E755 E5 PUSH H Save SECT 435 E756 7B MOV A,E PAGE 08 DAI FIRMWARE 2E5FC-2E7FB V1.1 436 E757 CD46EB CALL :EB46 HL = SECT*DY 437 E75A 09 DAD B HL = SECT*DY-DX 438 E75B 29 DAD H HL = 2*(SECT*DY-DX) 439 E75C 22B500 SHLD :00B5 Store amount to add into 440 count 441 E75F E1 POP H Get SECT 442 E760 7C MOV A,H 443 E761 1F RAR 444 E762 7D MOV A,L 445 E763 1F RAR A=INT(SECT/2) 446 E764 32BE00 STA :00BE Store amount to trim off 447 last sector 448 E767 3C INR A 449 E768 6F MOV L,A 450 E769 2600 MVI H,:00 HL = INIT 451 E76B E5 PUSH H 452 E76C 29 DAD H HL = 2*INIT 453 E76D 7B MOV A,E 454 E76E CD46EB CALL :EB46 HL = 2*INIT*DY 455 E771 09 DAD B HL = 2*INIT*DY-DX 456 E772 22B700 SHLD :00B7 Set INIT running total 457 E775 E1 POP H Get length 1st sector 458 E776 F1 POP PSW 459 E777 4F MOV C,A C is initial offset 460 E778 7B MOV A,E 461 E779 B7 ORA A 462 E77A C284E7 JNZ :E784 If more than 1 sector 463 E77D 32BE00 STA :00BE Store amount to trim off 464 last sector 465 E780 2ABB00 LHLD :00BB Get lower of 2 possible 466 sectors 467 E783 23 INX H Prig length if only 1 sector 468 E784 11BD00 DRL40 LXI D,:00BD Addr of nr of sectors 469 E787 1A LDAX D Get count of sectors 470 E788 D601 SUI :01 -1 471 E78A 12 STAX D Store it again 472 E78B D297E7 JNC :E797 Jump if not last sector 473 474 * Trim off last sector: 475 476 E78E 3ABE00 LDA :00BE Get amount to trim off 477 last sector 478 E791 2F CMA 479 E792 5F MOV E,A 480 E793 16FF MVI D,:FF 481 E795 13 INX D 482 E796 19 DAD D 483 * 484 E797 110100 DRL50 LXI D,:0001 Init Y-size is 1 485 E79A 3AC000 LDA :00C0 ) Check if swop X,Y dir. 486 E79D B7 ORA A ) (line > 45 degrees) 487 E79E CAA2E7 JZ :E7A2 Jump if not 488 E7A1 EB XCHG Swop X,Y direction 489 E7A2 43 DRL60 MOV B,E Get Y-size in B 490 E7A3 EB XCHG X-size in DE 491 E7A4 E1 POP H Get memory pointer 492 E7A5 05 DCR B 493 E7A6 3ABF00 LDA :00BF ) Check for Y-invert 494 E7A9 B7 ORA A ) 495 E7AA F5 PUSH PSW Save condition 496 E7AB C4FCE7 CNZ :E7FC Move pntr to bottom of 497 sector PAGE 09 DAI FIRMWARE 2E5FC-2E7FB V1.1 498 E7AE 1B DCX D Interfacing 499 E7AF CDF7EA CALL :EAF7 Draw next sector of line 500 E7B2 13 INX D ) Re-instate real values 501 E7B3 04 INR B ) 502 E7B4 F1 POP PSW Get earlier condition 503 E7B5 CABAE7 JZ :E7BA Jump if no Y-invert 504 E7B8 0601 MVI B,:01 Init 1 blob down only 505 E7BA CDFCE7 DRL80 CALL :E7FC Move ptr up/down 506 E7BD 79 MOV A,C Get offset 507 E7BE 83 ADD E Add X-movement 508 E7BF 4F MOV C,A ) Save result 509 E7C0 47 MOV B,A ) 510 E7C1 E607 ANI :07 511 E7C3 B9 CMP C 512 E7C4 CAD2E7 JZ :E7D2 Jump if not new field 513 514 * If new field: 515 516 E7C7 4F MOV C,A Update offset 517 E7C8 78 MOV A,B Get complement new offset 518 E7C9 A9 XRA C Clip bits 0,1,2 off 519 E7CA 1F RAR ) 520 E7CB 1F RAR ) 521 E7CC 2F CMA ) Update pointer 522 E7CD 5F MOV E,A ) to new field 523 E7CE 16FF MVI D,:FF ) 524 E7D0 13 INX D ) 525 E7D1 19 DAD D ) 526 * 527 E7D2 E5 DRL83 PUSH H Save memory pointer 528 E7D3 2AB500 LHLD :00B5 Get amount to add into count 529 E7D6 EB XCHG in DE 530 E7D7 2AB700 LHLD :00B7 Get count running total 531 E7DA 19 DAD D Add up 532 E7DB EB XCHG Result in DE 533 E7DC 2ABB00 LHLD :00BB Get lowest of 2 possible 534 sectors 535 E7DF EB XCHG in DE (distance to go) 536 E7E0 7C MOV A,H 537 E7E1 B7 ORA A 538 E7E2 F2EDE7 JP :E7ED Jump if short sector 539 540 * If long sector: 541 542 E7E5 13 INX D Go one blob further 543 E7E6 D5 PUSH D 544 E7E7 EB XCHG 545 E7E8 2AB900 LHLD :00B9 Get adjustment for long 546 sectors 547 E7EB 19 DAD D Adjust error term 548 E7EC D1 POP D 549 E7ED 22B700 DRL86 SHLD :00B7 Update running total 550 E7F0 EB XCHG 551 E7F1 3ABD00 LDA :00BD Get nr of sectors 552 E7F4 3C INR A 553 E7F5 C284E7 JNZ :E784 Next sector if not ready 554 555 * If ready: 556 557 E7F8 E1 POP H 558 E7F9 C338E1 JMP :E138 Popall, ret 559 * PAGE 10 DAI FIRMWARE 2E5FC-2E7FB V1.1 560 * 561 * 562 E7FC END *************************** * S Y M B O L T A B L E * *************************** CMPHL E706 COMP E6FB DADA E701 DRL30 E72E DRL40 E784 DRL50 E797 DRL60 E7A2 DRL80 E7BA DRL83 E7D2 DRL86 E7ED MOVES E6C2 MVS10 E6D5 MVS20 E6E2 MVS40 E6EF SBL10 E61E SBL20 E61F SCOLG E6A4 SDOT E710 SDRAW E71B SGC10 E6BF SMV10 E64F SMV20 E675 SMVTXT E635 SSETC E687 SSETL E698 SSUBL E5FC SUBDE E6F2