PAGE 01 DAI FIRMWARE D23D-D3F3 V1.0 Rev.1 002 ORG :D23D 003 * 004 * 005 * 006 * ============= 007 *** I/O HANDLER *** 008 * ============= 009 * 010 * 011 ********************* 012 * RUN basiccmd SAVE * 013 ********************* 014 * 015 * Valid as direct command and in program. 016 * Clears the Heap, zeroes all variables, evaluate 017 * an evt. program name and writes a file of type 018 * 0 (BASIC) on tape. 019 * 020 * Exit: HL: Points to end symboltable. 021 * DE: Length symboltable. 022 * BC: Updated. 023 * 024 D23D CD23CB RSAVE CALL :CB23 Empty HEAP + symtab 025 D240 2AA102 LHLD :02A1 Get start symtab 026 D243 EB XCHG in DE 027 D244 2AA302 LHLD :02A3 End symtab in HL 028 D247 CD1ADE CALL :DE1A Calculate length symtab 029 D24A E5 PUSH H Preserve length symtab 030 D24B 2A9F02 LHLD :029F Get start textbuf 031 D24E EB XCHG in DE 032 D24F CD1ADE CALL :DE1A Calculate length textbuf 033 D252 E5 PUSH H Preserve length textbuf 034 D253 D5 PUSH D Preserve start textbuf 035 D254 CD91E7 CALL :E791 (0) Evaluate program name 036 D257 00 NOP 037 D258 00 NOP 038 D259 00 NOP 039 D25A 3E30 MVI A,:30 File type byte 0 040 D25C 00 NOP 041 D25D 00 NOP 042 D25E 00 NOP 043 D25F 00 NOP 044 D260 00 NOP 045 D261 00 NOP 046 D262 00 NOP 047 D263 CDC502 CALL :02C5 Write fileleader, flagbyte, 048 file type byte, name length 049 and name. 050 D266 E1 POP H Start textbuf in HL 051 D267 D1 POP D Length textbuf in DE 052 D268 CDC802 CALL :02C8 Write length and contents 053 textbuf 054 D26B D1 POP D Length symtab in DE 055 D26C C3D8D7 JMP :D7D8 Write length and contents 056 symtab + file trailer 057 * 058 D26F FF DATA :FF 059 * 060 ********************* 061 * RUN basiccmd LOAD * 062 ********************* 063 * PAGE 02 DAI FIRMWARE D23D-D3F3 V1.0 Rev.1 064 * Valid as direct command and in program. 065 * Clears Heap and all variables. Evaluates name 066 * of program, updates BC. Required file type: 0. 067 * C is set to print type/name or not. 068 * A file (type 0: Basic) is read from tape. When 069 * a file has been found, the textbuffer and the 070 * symboltable are loaded and the pointers updated. 071 * When loading during program run: the program 072 * continues with the program just loaded. 073 * 074 * Exit: No error: BC: Updated. 075 * DE: Begin screen RAM. 076 * HL: End symbol table. 077 * 078 D270 CD23CB RLOAD CALL :CB23 Empty HEAP + symtab 079 D273 CD91E7 CALL :E791 (0) Evaluate programname 080 D276 C5 PUSH B 081 D277 00 NOP 082 D278 00 NOP 083 D279 00 NOP 084 D27A 00 NOP 085 D27B 0630 MVI B,:30 File type byte 0 086 D27D E5 PUSH H Preserve length name reqd 087 D27E 2A0001 LHLD :0100 Get CURRNT 088 D281 7C MOV A,H 089 D282 B5 ORA L Load during run program? 090 D283 0E00 MVI C,:00 091 D285 C289D2 JNZ :D289 If during run; C=00 092 D288 0D DCR C Else C=FF 093 D289 E1 RLD10 POP H 094 D28A CDCE02 CALL :02CE Switch on cassette motors; 095 read header + name 096 D28D 2AA502 LHLD :02A5 Get end free RAM 097 D290 EB XCHG Max. RAM in DE 098 D291 2A9F02 LHLD :029F Start textbuf in HL 099 D294 CDD102 CALL :02D1 Load textbuffer 100 D297 22A102 SHLD :02A1 Store end textbuffer 101 D29A DCD102 CC :02D1 Load symboltable 102 D29D CD1AD7 CALL :D71A Store end symtab; stop 103 cassette motors. 104 D2A0 C1 POP B 105 D2A1 FB EI Enable interrupts 106 D2A2 D2A8D2 JNC :D2A8 If loading error 107 D2A5 3E00 MVI A,:00 No loading error 108 D2A7 C9 RET 109 * 110 ********************* 111 * RUN LOADING ERROR * 112 ********************* 113 * 114 * The programbuffers are restored. A error message 115 * is printed. 116 * 117 D2A8 F5 RLERR PUSH PSW 118 D2A9 CDB5DE CALL :DEB5 Run 'NEW' 119 D2AC F1 POP PSW 120 D2AD 210000 LXI H,:0000 121 D2B0 220001 SHLD :0100 Set CURRNT=0 122 D2B3 C60B RLEAR ADI :0B 123 D2B5 C3F5D9 JMP :D9F5 Run 'LOADING ERROR ..' 124 * 125 * PAGE 03 DAI FIRMWARE D23D-D3F3 V1.0 Rev.1 126 ****************** 127 * OPEN TAPE FILE * 128 ****************** 129 * 130 * Entry: A: File type. 131 * HL: Points to file name. 132 * Exit: HL: Points beyond file name. 133 * DE: Length of name. 134 * BC: Preserved. 135 * A: Checksum on name. 136 * 137 D2B8 F5 CWOPEN PUSH PSW 138 D2B9 CD20D7 CALL :D720 Init. write file leader 139 D2BC F1 POP PSW 140 D2BD CD09D5 CALL :D509 Write file type byte 141 D2C0 C3F8D7 JMP :D7F8 Get name length, write it 142 on tape, incl. its c.s. 143 * 144 ********************** 145 * RUN basiccmd CHECK * 146 ********************** 147 * 148 * Valid as direct command only. 149 * Checks on file type and name. For all files 150 * with type <3, a checksum on all data is done. 151 * This routine remains in a endless loop and 152 * can be aborted with BREAK only. 153 * 154 *RCHECK 155 D2C3 210000 CHK10 LXI H,:0000 No program name given 156 D2C6 01FF00 LXI B,:00FF Any file type 157 D2C9 00 NOP 158 D2CA 00 NOP 159 D2CB CDCE02 CALL :02CE Read file header, file 160 type and name; print 161 type and name 162 D2CE 00 NOP 163 D2CF FE33 CPI :33 164 D2D1 D2EBD2 JNC :D2EB If file type >=3: no check 165 on checksum 166 167 * Test checksum: 168 169 D2D4 0C INR C BC=0 170 D2D5 CDE6D7 CALL :D7E6 Set A=0, read + check 171 a data block 172 D2D8 CCD702 CZ :02D7 Read + check next block 173 D2DB C2E6D2 JNZ :D2E6 If reading error 174 D2DE CDFFDA CALL :DAFF Print 'OK', car.ret 175 D2E1 C0DB DBL :DBC0 176 D2E3 C3C3D2 JMP :D2C3 Wait for next file 177 178 * If checksum error: 179 180 D2E6 CDFFDA CHK20 CALL :DAFF Print 'BAD' 181 D2E9 DBDB DBL :DBDB 182 D2EB CD5EDD CHK30 CALL :DD5E Print car.ret 183 D2EE C3C3D2 JMP :D2C3 Wait for next file 184 * 185 *********************** 186 * WRITE BLOCK ON TAPE * 187 *********************** PAGE 04 DAI FIRMWARE D23D-D3F3 V1.0 Rev.1 188 * 189 * Entry: HL: Startaddres block. 190 * DE: Length block. 191 * Exit: HL: 1st byte after block. 192 * A: Checksum on block contents. 193 * BCDE preserved. 194 * 195 D2F1 C5 CWBLK PUSH B 196 D2F2 D5 PUSH D 197 D2F3 00 NOP 198 D2F4 CD16D3 CALL :D316 Write block length + 199 c.s. on length 200 D2F7 0656 MVI B,:56 Initial checksum value 201 D2F9 7A LD34 MOV A,D 202 D2FA B3 ORA E 203 D2FB CA07D3 JZ :D307 If all bytes written 204 D2FE 1B DCX D 205 D2FF 7E MOV A,M Get byte of block 206 D300 23 INX H Point to next byte 207 D301 CD0FD3 CALL :D30F Write byte, update checksum 208 D304 C3F9D2 JMP :D2F9 Next byte 209 210 * If all data written: write c.s. on block: 211 212 D307 78 LD35 MOV A,B Get calculated checksum 213 D308 CD09D5 CALL :D509 Write checksum 214 D30B 00 NOP 215 D30C D1 POP D 216 D30D C1 POP B 217 D30E C9 RET 218 * 219 ******************************* 220 * WRITE BYTE, UPDATE CHECKSUM * 221 ******************************* 222 * 223 * Entry: Byte to be written in A. 224 * Checksum in B. 225 * Exit: New checksum in B; A corrupted. 226 * CDEHL preserved. 227 * 228 D30F CD09D5 LD36 CALL :D509 Write byte 229 D312 A8 XRA B 230 D313 07 RLC 231 D314 47 MOV B,A Update checksum 232 D315 C9 RET 233 * 234 *************************************** 235 * WRITE BLOCK LENGTH, UPDATE CHECKSUM * 236 *************************************** 237 * 238 * Entry: DE: length block. 239 * Exit: DEHL preserved. 240 * 241 D316 0656 LD37 MVI B,:56 Init checksum 242 D318 7A MOV A,D Get highest length byte, 243 D319 CD0FD3 CALL :D30F write it, update c.s. 244 D31C 7B MOV A,E Get lowest length byte, 245 D31D CD0FD3 CALL :D30F write it, update c.s 246 D320 78 MOV A,B Get checksum 247 D321 CD09D5 CALL :D509 Write checksum on length 248 D324 C9 RET 249 PAGE 05 DAI FIRMWARE D23D-D3F3 V1.0 Rev.1 250 ********************** 251 * START FILE READING * 252 ********************** 253 * 254 * Entry: HL: Address length byte of name requested. 255 * B: File type byte requested. 256 * C: 00 when reading during run program, 257 * else FF. 258 * Exit: A: File type byte. 259 * HL: Points to 1st byte of name requested. 260 * DE: Length name requested. 261 * BC: preserved. 262 * 263 D325 F5 CROPEN PUSH PSW 264 D326 CDFFD7 CALL :D7FF Switch cassette motors on, 265 init. registers 266 D329 00 RPN10 NOP 267 D32A 00 NOP 268 D32B 00 NOP 269 D32C 00 NOP 270 D32D 00 NOP 271 D32E F1 POP PSW 272 D32F CDF4D3 CALL :D3F4 Read file header 273 D332 F5 PUSH PSW 274 D333 CD8AD7 CALL :D78A Display file type byte 275 D336 90 SUB B 276 D337 CDA2D3 CALL :D3A2 Read and check header, 277 program name, file type byte 278 D33A B7 ORA A 0 if everything OK. 279 D33B C283D7 JNZ :D783 If failure 280 D33E F1 POP PSW 281 D33F C9 RET 282 * 283 ************** 284 * READ BLOCK * 285 ************** 286 * 287 * Read length, contents and checksum of a block 288 * 289 * Entry: HL: Addr. where to dump data read. 290 * DE: End free space. 291 * Exit: CY=1: No error: 292 * HL: Next free address. 293 * BCDE preserved; AF corrupted. 294 * CY=0: Loading error: 295 * BCDEHL preserved. 296 * A: Type of loading error. 297 * 298 D340 C5 CRBLK PUSH B 299 D341 D5 PUSH D 300 D342 E5 PUSH H 301 D343 CD90D7 CALL :D790 Calculate free RAM space 302 D346 EB XCHG Free RAM in DE 303 D347 CD8DD3 CALL :D38D Read block length + c.s. 304 length in HL 305 D34A DA7ED3 JC :D37E If loading error 3 306 D34D B7 ORA A 307 D34E 3E00 MVI A,:00 Loading error 0 308 D350 C280D3 JNZ :D380 If checksum error 0 309 D353 E5 PUSH H Save length block 310 D354 19 DAD D Calculate free RAM 311 D355 D1 POP D Get length block PAGE 06 DAI FIRMWARE D23D-D3F3 V1.0 Rev.1 312 D356 3C INR A Loading error 1 313 D357 E1 POP H 314 D358 E5 PUSH H Restore begin addr. 315 D359 DA80D3 JC :D380 If loading error 1 316 D35C 0656 MVI B,:56 Init checksum 317 D35E 7A LBK10 MOV A,D 318 D35F B3 ORA E 319 D360 CA6FD3 JZ :D36F If whole block read 320 D363 1B DCX D 321 D364 CD84D3 CALL :D384 Read next byte, update c.s 322 D367 DA7ED3 JC :D37E If loading error 3 323 D36A 77 MOV M,A Store byte in buffer 324 D36B 23 INX H 325 D36C C35ED3 JMP :D35E Next byte 326 327 * If whole block read: 328 329 D36F CDD4D4 LBK20 CALL :D4D4 Read checksum block contents 330 D372 DA7ED3 JC :D37E If loading error 3 331 D375 B8 CMP B Check checksum 332 D376 3E02 MVI A,:02 Loading error 2 333 D378 C280D3 JNZ :D380 If loading error 2 334 D37B C3B4C6 JMP :C6B4 CY=1, return: no error 335 336 * If loading error: 337 338 D37E 3E03 LBK40 MVI A,:03 Loading error 3 339 D380 B7 LOERR ORA A 340 D381 C3B6C6 JMP :C6B6 Return with CY=0: error 341 * 342 ********************************* 343 * READ BYTE, CALCULATE CHECKSUM * 344 ********************************* 345 * 346 * Entry: B: Checksum. 347 * Exit: A: Byte read. 348 * B: Updated checksum. 349 * CDEHL preserved. 350 * 351 D384 CDD4D4 INSC CALL :D4D4 Read byte 352 D387 F5 RBUEX PUSH PSW 353 D388 A8 XRA B Calculate checksum 354 D389 07 RLC 355 D38A 47 MOV B,A Store new value 356 D38B F1 POP PSW 357 D38C C9 RET 358 * 359 ******************** 360 * READ NAME LENGTH * 361 ******************** 362 * 363 * Entry: No conditions. 364 * Exit: HL: Length name read. 365 * A: Result checksum check (0 if OK). 366 * BCDE: preserved. 367 * CY=0: O.K.; CY=1: Out of data. 368 * 369 D38D C5 INLNG PUSH B 370 D38E 0656 MVI B,:56 Init. checksum 371 D390 CD84D3 CALL :D384 Read highest length byte 372 and update checksum 373 D393 67 MOV H,A PAGE 07 DAI FIRMWARE D23D-D3F3 V1.0 Rev.1 374 D394 D484D3 CNC :D384 Read lowest length byte 375 and update checksum 376 D397 6F MOV L,A 377 D398 D4D4D4 CNC :D4D4 Read checksum on length 378 D39B F5 RHLEX PUSH PSW 379 D39C 90 SUB B Check checksum 380 D39D 47 MOV B,A 381 D39E F1 POP PSW 382 D39F 78 MOV A,B 383 D3A0 C1 POP B 384 D3A1 C9 RET 385 * 386 ******************************************* 387 * READ + CHECK PROGRAM NAME AND FILE TYPE * 388 ******************************************* 389 * 390 * Routine searches for proper file name by 391 * reading file name and compare it with name 392 * requested. 393 * 394 * Entry: A: Evt. difference in file type byte 395 * read and requested. 396 * B: Requested file type. 397 * C: 00 during run program, else FF. 398 * DE: Length requested. 399 * HL: Address 1st byte name requested. 400 * Exit: BCDEHL preserved. 401 * A=0: All OK. 402 * A=1: Loading error 1. 403 * 404 D3A2 C5 CMBLK PUSH B Save file type + RUN flag 405 D3A3 E5 PUSH H Save addr reqd name 406 D3A4 47 MOV B,A Store deviation file type 407 D3A5 D5 MBK10 PUSH D Save req. name length 408 D3A6 E5 PUSH H 409 D3A7 CD8DD3 CALL :D38D Read + check program name 410 evt. c.s.failure in A 411 D3AA DAEDD3 JC :D3ED If reading error 412 D3AD B7 ORA A 413 D3AE C2EDD3 JNZ :D3ED If checksum error 414 D3B1 E5 PUSH H Save length name on tape 415 D3B2 CD1ADE CALL :DE1A Calculate difference name 416 lengths reqd and on tape 417 D3B5 7C MOV A,H 418 D3B6 B5 ORA L 419 D3B7 67 MOV H,A Difference in H 420 D3B8 68 MOV L,B Difference file type in L 421 D3B9 D1 POP D Get length name on tape 422 D3BA 0656 MVI B,:56 Initiate checksum 423 D3BC E3 MBK20 XTHL Get byte reqd name 424 D3BD 7A MOV A,D 425 D3BE B3 ORA E Length name on tape = 0 ? 426 D3BF CAD8D3 JZ :D3D8 If length = 0, or whole 427 name read. 428 D3C2 1B DCX D 429 D3C3 CD84D3 CALL :D384 Read bytes of name, update 430 checksum 431 D3C6 DAEDD3 JC :D3ED If reading error 432 D3C9 0D DCR C 433 D3CA 0C INR C Load during run? 434 D3CB F5 PUSH PSW Save length name on tape 435 D3CC C4EBD7 CNZ :D7EB Display program name PAGE 08 DAI FIRMWARE D23D-D3F3 V1.0 Rev.1 436 D3CF F1 POP PSW Get byte of name on tape 437 D3D0 AE XRA M Compare with name reqd 438 D3D1 23 INX H 439 D3D2 E3 XTHL Get 'difference flag' 440 D3D3 B4 ORA H Update it 441 D3D4 67 MOV H,A and store it in H 442 D3D5 C3BCD3 JMP :D3BC Next byte 443 444 * If whole name read: 445 446 D3D8 CDD4D4 MBK30 CALL :D4D4 Read c.s on name contents 447 D3DB DAEDD3 JC :D3ED If reading error 448 D3DE A8 MBEX XRA B Check checksum 449 D3DF E1 POP H 450 D3E0 B5 ORA L Check file type 451 D3E1 6F MOV L,A 452 D3E2 D1 POP D Get length req. name 453 D3E3 7A MOV A,D 454 D3E4 B3 ORA E No name requested ? 455 D3E5 CAE9D3 JZ :D3E9 If load without name 456 D3E8 7C MOV A,H Difference in names? 457 D3E9 B5 MBK40 ORA L Take also other checks in 458 account 459 D3EA E1 MBK45 POP H 460 D3EB C1 POP B 461 D3EC C9 RET 462 463 * If error: 464 465 D3ED E1 MBK50 POP H 466 D3EE D1 POP D 467 D3EF 3E01 MVI A,:01 Loading error 1 468 D3F1 C3E9D3 JMP :D3E9 469 * 470 * 471 * 475 D3F4 END *************************** * S Y M B O L T A B L E * *************************** CHK10 D2C3 CHK20 D2E6 CHK30 D2EB CMBLK D3A2 CRBLK D340 CROPEN D325 CWBLK D2F1 CWOPEN D2B8 INLNG D38D INSC D384 LBK10 D35E LBK20 D36F LBK40 D37E LD34 D2F9 LD35 D307 LD36 D30F LD37 D316 LOERR D380 MBEX D3DE MBK10 D3A5 MBK20 D3BC MBK30 D3D8 MBK40 D3E9 MBK45 D3EA MBK50 D3ED RBUEX D387 RCHECK D2C3 RHLEX D39B RLD10 D289 RLEAR D2B3 RLERR D2A8 RLOAD D270 RPN10 D329 RSAVE D23D