PAGE 01 DAI FIRMWARE 3EC45-3EDF8 V1.1 002 ORG :EC45 003 * 004 * 005 * 006 ********************** 007 * COMPARE DE WITH HL * 008 ********************** 009 * 010 * Exit: AF corrupted, BCDEHL preserved. 011 * HL > DE : A=-1, CY=1, Z=0, S=1. 012 * HL = DE : A= 0, CY=0, Z=1, S=0. 013 * HL < DE : A= 1, CY=0, Z=0, S=0. 014 * 015 EC45 7B L3E194 MOV A,E 016 EC46 95 SUB L 017 EC47 7A MOV A,D 018 EC48 9C SBB H 019 EC49 9F SBB A 020 EC4A F8 RM If HL>DE: A=1, S=1 021 EC4B 7B MOV A,E 022 EC4C AD XRA L 023 EC4D D5 PUSH D 024 EC4E 5F MOV E,A 025 EC4F 7A MOV A,D 026 EC50 AC XRA H 027 EC51 B3 ORA E 028 EC52 D1 POP D 029 EC53 37 STC 030 EC54 C8 RZ If HL=DE: A=0, Z=CY=1 031 EC55 AF XRA A 032 EC56 3C INR A 033 EC57 C9 RET If HL DE : CY=0. 044 * New HL = DE : Z=1. 045 * New HL < DE : CY=1. 046 * 047 EC58 2B L3E195 DCX H 048 EC59 7C MOV A,H 049 EC5A A5 ANA L 050 EC5B C601 ADI :01 051 EC5D D8 RC Ready if old HL was 0 052 EC5E 7D MOV A,L ) 053 EC5F 93 SUB E ) Compare HL - DE 054 EC60 7C MOV A,H ) 055 EC61 9A SBB D ) 056 EC62 C9 RET 057 * 058 ************************* 059 * RESTORE CPU REGISTERS * 060 ************************* 061 * 062 * Restores CPU registers AFBCDEHL and PC. 063 * Continues at PC address. PAGE 02 DAI FIRMWARE 3EC45-3EDF8 V1.1 064 * Stackpointer, TICC and GIC are not restored ! 065 * 066 EC63 CDE7ED L3E196 CALL :EDE7 Exchange bytes in reg. 067 save area 068 EC66 2A5300 L3E197 LHLD :0053 Get stored PSW 069 EC69 E5 PUSH H 070 EC6A F1 POP PSW Restore PSW 071 EC6B 2A5500 LHLD :0055 072 EC6E 44 MOV B,H 073 EC6F 4D MOV C,L Restore BC 074 EC70 2A5700 LHLD :0057 075 EC73 EB XCHG Restore DE 076 EC74 2A5D00 LHLD :005D 077 EC77 E5 PUSH H Addr next instr on stack 078 EC78 2A5900 LHLD :0059 Restore HL 079 EC7B C9 RET Goto addr in (005D/E) 080 * 081 ********************* 082 * CALCULATE DE - HL * 083 ********************* 084 * 085 * Exit: HL = DE - HL. 086 * BCDE preserved, AF corrupted. 087 * 088 EC7C 7B L3E198 MOV A,E 089 EC7D 95 SUB L 090 EC7E 6F MOV L,A L=E-L 091 EC7F 7A MOV A,D 092 EC80 9C SBB H 093 EC81 67 MOV H,A H=D-H-CY 094 EC82 C9 RET 095 * 096 ************ 097 * M - MOVE * 098 ************ 099 * 100 * Moves a block of data (laddr - haddr) given to 101 * a given destination address (daddr). 102 * 103 * Exit: BC: 1st unused destination address. 104 * DE: Last source address for direction of 105 * movement. 106 * HL: 1st unused source address. 107 * AF: Corrupted. 108 * 109 EC83 0E03 MOVEK MVI C,:03 Nr of addr allowed 110 EC85 CDDEEA CALL :EADE Get addr on stack 111 EC88 0D DCR C 3 addr given ? 112 EC89 F262EA JP :EA62 Error if not 113 EC8C C1 POP B daddr in BC 114 EC8D D1 POP D haddr in DE 115 EC8E E1 POP H laddr in HL 116 EC8F E5 PUSH H Save laddr on stack 117 EC90 CD7CEC CALL :EC7C Calc length of block to 118 be moved 119 EC93 DA62EA JC :EA62 Error if wrong inputs 120 EC96 E3 XTHL laddr in HL, length on stack 121 EC97 79 MOV A,C ) 122 EC98 95 SUB L ) Check if daddr < laddr 123 EC99 78 MOV A,B ) 124 EC9A 9C SBB H ) 125 EC9B DAAEEC JC :ECAE Then jump PAGE 03 DAI FIRMWARE 3EC45-3EDF8 V1.1 126 127 * If daddr > laddr: 128 129 EC9E E3 XTHL length in HL, laddr on stack 130 EC9F 09 DAD B daddr of highest byte 131 ECA0 44 MOV B,H ) Store it in BC 132 ECA1 4D MOV C,L ) 133 ECA2 E1 POP H laddr in HL 134 ECA3 EB XCHG DE: laddr, HL: haddr 135 ECA4 7E L3E200 MOV A,M Get byte to be moved 136 ECA5 02 STAX B Move it 137 ECA6 0B DCX B Decr pntr daddr 138 ECA7 CD58EC CALL :EC58 Check if ready 139 ECAA D8 RC Then quit 140 ECAB C3A4EC JMP :ECA4 Next byte 141 142 * If daddr < laddr: 143 144 ECAE E3 L3E201 XTHL Length in HL, laddr on stack 145 ECAF E1 POP H laddr in HL 146 ECB0 7E L3E202 MOV A,M Get byte 147 ECB1 02 STAX B And move it 148 ECB2 03 INX B Incr pntr daddr 149 ECB3 CD80ED CALL :ED80 INX H; check if ready 150 ECB6 D8 RC Then quit 151 ECB7 C3B0EC JMP :ECB0 Next byte 152 * 153 ************* 154 * Z - RESET * 155 ************* 156 * 157 * Z1: Reset CPU save area 0051-005E. Initialise 158 * stackpointer to F900 and save it in 005B/C. 159 * 160 * Z2: Sets: current interrupt mask (005F) = #C5, 161 * TICC control word (0060) = #FC, 162 * GIC control word (0061) = #1B. 163 * Initialises interrupt vector area #0062-#0071. 164 * Sets interrupt vector RST 0 to #EB5D. 165 * 166 * Z3: Z1 + Z2. 167 * 168 * Exit: All registers corrupted. 169 * 170 ECBA 0E01 ZEROK MVI C,:01 Nr of databytes allowed 171 ECBC CDDEEA CALL :EADE Get hexnr and store it 172 on stack 173 ECBF E1 POP H Get hexnr from stack 174 ECC0 7D MOV A,L into A 175 ECC1 F5 PUSH PSW Save it again 176 ECC2 E602 ANI :02 177 ECC4 CAE9EC JZ :ECE9 Jump if Z1 only 178 179 * If Z2 or Z3: 180 181 ECC7 3EC5 MVI A,:C5 Set interrupt mask for 182 clock, keyb, ext, timer 1 183 ECC9 325F00 STA :005F Preserve int.mask 184 ECCC 3EF4 MVI A,:F4 185 ECCE 00 NOP 186 ECCF 00 NOP 187 ECD0 00 NOP PAGE 04 DAI FIRMWARE 3EC45-3EDF8 V1.1 188 ECD1 F608 ORI :08 189 ECD3 216000 LXI H,:0060 190 ECD6 77 MOV M,A Set TICC contr.word = FC 191 ECD7 23 INX H 192 ECD8 361B MVI M,:1B Set GIC contr.word = 1B 193 ECDA CD1ED9 CALL :D91E Init int.vector addr 194 ECDD 215DEB LXI H,:EB5D 195 ECE0 226200 SHLD :0062 Set RST0 vector = EB5D 196 ECE3 00 NOP 197 ECE4 00 NOP 198 ECE5 00 NOP 199 ECE6 00 NOP 200 ECE7 00 NOP 201 ECE8 00 L3E204 NOP 202 ECE9 F1 ZERO1 POP PSW Get nr Z instr back 203 ECEA 1F RAR Check for Z2 only 204 ECEB D0 RNC Ready if Z2 only 205 206 * If Z1 or Z3: 207 208 ECEC 0E00 MVI C,:00 ) 209 ECEE 115E00 LXI D,:005E ) Init reg. save area: 210 ECF1 215100 LXI H,:0051 ) 211 ECF4 CD54ED CALL :ED54 ) Fill (0051-005E) with 00 212 ECF7 2100F9 LXI H,:F900 213 ECFA F9 SPHL Set SP=F900 214 ECFB 225B00 SHLD :005B Save SP 215 ECFE C342EA JMP :EA42 Return for new inputs 216 * 217 *************** 218 * PRINT SPACE * 219 *************** 220 * 221 * Exit: AFC corrupted, BDEHL preserved. 222 * 223 *TSP 224 ED01 0E20 LSP MVI C,:20 225 ED03 C3B4EE JMP :EEB4 Print space 226 * 227 ********************************** 228 * SCAN KEYBOARD, PRINT CHARACTER * 229 ********************************** 230 * 231 * Gets a keyboard input. Zeroes are ignored. 232 * The character is printed (if not 'ESC'). 233 * 234 * Exit: A : Character typed in. 235 * Other registers preserved. 236 * 237 ED06 CDB8EE CIE CALL :EEB8 Scan keyboard 238 ED09 E67F ANI :7F Skip bit 7 239 ED0B CA06ED JZ :ED06 Ignore zeroes (await an 240 input) 241 ED0E FE12 CPI :12 'ESC' ? 242 ED10 C5 PUSH B 243 ED11 4F MOV C,A Char in C 244 ED12 C4B4EE CNZ :EEB4 Print char if not 'ESC' 245 ED15 79 MOV A,C Char in A 246 ED16 C1 POP B 247 ED17 C9 RET 248 * 249 * PAGE 05 DAI FIRMWARE 3EC45-3EDF8 V1.1 250 ************************** 251 * PRINT ADDRESS IN ASCII * 252 ************************** 253 * 254 * LADDR: An address in HL is converted to ASCII and 255 * printed (4 nibbles). 256 * LBYTE: A 1-byte value is printed in ASCII. 257 * 258 * Entry: LADDR: Address in HL. 259 * LBYTE: Value in A. 260 * Exit: AFC corrupted, BDEHL preserved. 261 * 262 ED18 7C LADDR MOV A,H Hibyte in A. 263 ED19 CD1DED CALL :ED1D Print both nibbles in ASCII 264 ED1C 7D MOV A,L Lobyte in A 265 ED1D F5 LBYTE PUSH PSW Preserve hex value 2 char 266 ED1E 07 RLC ) 267 ED1F 07 RLC ) Move hinibble 268 ED20 07 RLC ) into lonibble 269 ED21 07 RLC ) 270 ED22 CD26ED CALL :ED26 Print lonibble 271 ED25 F1 POP PSW Restore byte 272 ED26 E60F L3E210 ANI :0F Lonibble only 273 ED28 CD40ED CALL :ED40 Convert it to ASCII 274 ED2B 4F MOV C,A And store it in C 275 ED2C C3B4EE JMP :EEB4 Print char in C 276 * 277 **************** 278 * PRINT STRING * 279 **************** 280 * 281 * Entry: HL points to string. End of string is 00. 282 * Exit: HL points to 00 at end of string. 283 * AFC corrupted, BDE preserved. 284 * 285 ED2F 7E L3E211 MOV A,M Get byte from string 286 ED30 4F MOV C,A into C 287 ED31 B7 ORA A Byte = 00 ? 288 ED32 C8 RZ Then ready 289 ED33 CDB4EE CALL :EEB4 Print char in C 290 ED36 23 INX H Pnts to next char 291 ED37 C32FED JMP :ED2F Print next char 292 * 293 ************************* 294 * PRINT CARRIAGE RETURN * 295 ************************* 296 * 297 * Exit: AFC corrupted, BDEHL preserved. 298 * 299 ED3A 0E0D LCRLF MVI C,:0D 300 ED3C CDB4EE CALL :EEB4 Print 'CR' 301 ED3F C9 RET 302 * 303 ******************************* 304 * CONVERT HEX NIBBLE TO ASCII * 305 ******************************* 306 * 307 * Entry: Hex value in A. 308 * Exit: ASCII value in A. 309 * BCDEHL preserved. F corrupted. 310 * 311 ED40 C630 L3E213 ADI :30 Convert PAGE 06 DAI FIRMWARE 3EC45-3EDF8 V1.1 312 ED42 FE3A CPI :3A Number 0-9? 313 ED44 D8 RC Then ready 314 ED45 C607 ADI :07 Convert A-F 315 ED47 C9 RET 316 * 317 ************ 318 * F - FILL * 319 ************ 320 * 321 * Fills a memory area between given boundaries 322 * with given data. 323 * 324 * Exit: CY=1. All registers corrupted. 325 * 326 ED48 0E03 FILLK MVI C,:03 Nr of addr/data allowed 327 ED4A CDDEEA CALL :EADE Get addr/data on stack 328 ED4D 0D DCR C 3 blocks given? 329 ED4E F262EA JP :EA62 Error if not 330 ED51 C1 POP B Data in C 331 ED52 D1 POP D haddr in DE 332 ED53 E1 POP H laddr in HL 333 ED54 71 FILL MOV M,C Data into memory 334 ED55 CD80ED CALL :ED80 INX H; check if ready 335 ED58 D8 RC Then quit 336 ED59 C354ED JMP :ED54 Fill next addr 337 * 338 ****************** 339 * S - SUBSTITUTE * 340 ****************** 341 * 342 ED5C 0E01 SUBSK MVI C,:01 Nr of addr allowed 343 ED5E CDDEEA CALL :EADE Get addr on stack 344 ED61 E1 POP H Addr in HL 345 ED62 7E MOV A,M Get contents of addr 346 ED63 CD1DED CALL :ED1D Print it in ASCII 347 ED66 AF XRA A 348 ED67 CD6AEE CALL :EE6A Evt. modify contents 349 ED6A D262ED JNC :ED62 Next addr 350 ED6D C9 RET 351 * 352 *************** 353 * X - EXAMINE * 354 *************** 355 * 356 ED6E 219DEE EXAMK LXI H,:EE9D Startaddr register table 357 ED71 115300 LXI D,:0053 Startaddr CPU save area 358 ED74 C339EE JMP :EE39 Go to display routine 359 * 360 ********************** 361 * V - VECTOR EXAMINE * 362 ********************** 363 * 364 ED77 21A8EE VECXK LXI H,:EEA8 Startaddr vector table 365 ED7A 115F00 LXI D,:005F Startaddr vector area 366 ED7D C339EE JMP :EE39 Go to display routine 367 * 368 ************************************ 369 * INCREMENT HL AND COMPARE WITH DE * 370 ************************************ 371 * 372 * Exit: HL was FFFF: CY=1, Z=1. 373 * Else: New HL < DE : CY=0. PAGE 07 DAI FIRMWARE 3EC45-3EDF8 V1.1 374 * New HL = DE : Z=1. 375 * New HL > DE : CY=1. 376 * BCDE preserved, HL=HL+1, AF corrupted. 377 * 378 ED80 23 INXCK INX H 379 ED81 37 STC CY=1 380 ED82 7C MOV A,H 381 ED83 B5 ORA L 382 ED84 C8 RZ Abort if new HL is 0000 383 ED85 7B MOV A,E 384 ED86 95 SUB L 385 ED87 7A MOV A,D 386 ED88 9C SBB H 387 ED89 C9 RET 388 * 389 ********** 390 * G - GO * 391 ********** 392 * 393 * Reads one field if given. 394 * If no field given: Restores CPU registers, goes 395 * to PC address. Returnaddress is #EA42 (into 396 * command loop). 397 * If field given: Saves it as PC, initialises TICC 398 * and GIC. Returnaddress is #EA04. Goes to the 399 * given address. 400 * REMARK: The stackpointer is never restored ! 401 * 402 ED8A 0E01 GOK MVI C,:01 403 ED8C CD07EB CALL :EB07 Scan keyb; addr on stack 404 ED8F 0D DCR C No addr given? 405 ED90 F5 PUSH PSW 406 ED91 CC56EB CZ :EB56 Then check if 'CR' 407 ED94 F1 POP PSW 408 ED95 CA63EC JZ :EC63 No addr: restore CPU reg 409 (but not SP/TICC/GIC !) and 410 go to addr in 005D/E 411 ED98 E1 POP H 'GO' addr in HL 412 ED99 225D00 SHLD :005D Save it 413 ED9C 2A6000 L3E221 LHLD :0060 Get GIC/TICC init values 414 ED9F 7C MOV A,H GIC init value in A 415 EDA0 CDD5ED CALL :EDD5 Init GIC 416 EDA3 7D MOV A,L TICC init value in A 417 EDA4 CDB7ED CALL :EDB7 Init TICC 418 EDA7 3A5F00 LDA :005F Get current int mask 419 EDAA 32F8FF STA :FFF8 Set int mask 420 EDAD CDE7ED CALL :EDE7 exch. bytes in 0051-5E 421 EDB0 2104EA LXI H,:EA04 Returnaddr for 'GO' 422 EDB3 E5 PUSH H Save EA04 on stack 423 EDB4 C366EC JMP :EC66 Restore CPU reg and 'GO' 424 * 425 * INITIALISE TICC: 426 * 427 * Entry: A: Initial value TICC command word (#FC). 428 * Exit: AFBC corrupted, DEHL preserved. 429 * 430 EDB7 47 L3E222 MOV B,A Init.value in B 431 EDB8 07 RLC A=F9 432 EDB9 F5 PUSH PSW On stack: A=F9, CY=1 433 EDBA 07 RLC A=F3 434 EDBB 07 RLC A=E7 435 EDBC 07 RLC A=CF PAGE 08 DAI FIRMWARE 3EC45-3EDF8 V1.1 436 EDBD E607 ANI :07 A=07 437 EDBF 4F MOV C,A C=07 438 EDC0 AF XRA A A=0 439 EDC1 37 STC CY=1 440 EDC2 17 L3E223 RAL ) On exit: A=80, 441 EDC3 0D DCR C ) C=FF, CY=0 442 EDC4 F2C2ED JP :EDC2 ) 443 EDC7 4F MOV C,A C=80 444 EDC8 F1 POP PSW A=F9, CY=1 445 EDC9 79 MOV A,C A=80 446 EDCA 1F RAR A=C0 447 EDCB 32F5FF STA :FFF5 Set comm.rate reg for 9600 448 baud, 1 stop bit 449 EDCE 78 MOV A,B A=FC 450 EDCF E60F ANI :0F A=0C 451 EDD1 32F4FF STA :FFF4 Set cmd reg for IN7, INTA 452 enable 453 EDD4 C9 RET 454 * 455 * INITIALISE GIC: 456 * 457 * This initialisation cancels the initial setting 458 * done during 'power-on' by 3EF90. Only used during 459 * 'GO'. 460 * There seems to be some bug in the routine. All 461 * ports are set to input, and then data is written 462 * into one of this ports (PB - FE01). The function 463 * of L3E225 is nonsense (?!). 464 * 465 * Entry: A: Initial value GIC command word (#1B). 466 * Exit: AFBC corrupted, DEHL preserved. 467 * 468 EDD5 F5 L3E224 PUSH PSW Init value on stack, CY=0 469 EDD6 0103FE LXI B,:FE03 Addr command word 470 EDD9 F680 ORI :80 A=9B 471 EDDB 02 STAX B Set all ports to input 472 EDDC 0D DCR C BC=FE02 473 EDDD F1 POP PSW A=1B, CY=0 474 EDDE 07 RLC A=36, CY=0 475 EDDF 9F SBB A A=0 476 EDE0 0B L3E225 DCX B BC=FE01 477 EDE1 02 STAX B (FE01)=00 (?!) 478 EDE2 0D DCR C BC=FE00 479 EDE3 F2E0ED JP :EDE0 Writes 00 in non-existing 480 address FDFE (?!) 481 EDE6 C9 RET 482 * 483 **************************************** 484 * EXCHANGE BYTES IN REGISTER SAVE AREA * 485 **************************************** 486 * 487 * The hibytes and the lobytes of the addresses 488 * 0053/0054 thru 0059/5A are exchanged which 489 * each other. 490 * 491 * Exit: AFBCHL corrupted. DE preserved. 492 * 493 EDE7 215300 L3E238 LXI H,:0053 Startaddr 494 EDEA 3E04 MVI A,:04 Nr of addr to be exchanged 495 EDEC 46 L3E226 MOV B,M 1st byte in B 496 EDED 23 INX H Pnts to next location 497 EDEE 4E MOV C,M 2nd byte in C PAGE 09 DAI FIRMWARE 3EC45-3EDF8 V1.1 498 EDEF 70 MOV M,B 1st byte in 2nd location 499 EDF0 2B DCX H 500 EDF1 71 MOV M,C 2nd byte in 1st location 501 EDF2 23 INX H 502 EDF3 23 INX H Points to next addr 503 EDF4 3D DCR A Update counter 504 EDF5 C2ECED JNZ :EDEC Next addr if not ready 505 EDF8 C9 RET 506 * 507 * 508 * 512 EDF9 END *************************** * S Y M B O L T A B L E * *************************** CIE ED06 EXAMK ED6E FILL ED54 FILLK ED48 GOK ED8A INXCK ED80 L3E194 EC45 L3E195 EC58 L3E196 EC63 L3E197 EC66 L3E198 EC7C L3E200 ECA4 L3E201 ECAE L3E202 ECB0 L3E204 ECE8 L3E210 ED26 L3E211 ED2F L3E213 ED40 L3E221 ED9C L3E222 EDB7 L3E223 EDC2 L3E224 EDD5 L3E225 EDE0 L3E226 EDEC L3E238 EDE7 LADDR ED18 LBYTE ED1D LCRLF ED3A LSP ED01 MOVEK EC83 SUBSK ED5C TSP ED01 VECXK ED77 ZERO1 ECE9 ZEROK ECBA