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