PAGE 01 DAI FIRMWARE 1EE0B-1EFFF V1.1 002 ORG :EE0B 003 * 004 * 005 * 006 ************** 007 * (not used) * 008 ************** 009 * 010 EE0B E5 L1E245 PUSH H 011 EE0C CD91D8 CALL :D891 012 * 013 *********************************************** 014 * LOADA: READ ARRAY DATA FROM TAPE INTO ARRAY * 015 *********************************************** 016 * 017 * Reads block(s) from tape into the free RAM space 018 * and move it afterwards into the array. 019 * 020 * Entry: HL: Length of name requested. 021 * A: Variable type. 022 * On stack: Address where to dump data. 023 * 024 EE0F C5 L1E273 PUSH B 025 EE10 F5 PUSH PSW Save var.type 026 EE11 010032 LXI B,:3200 File type in B, C for load 027 during program 028 EE14 CD81D6 CALL :D681 Open read file 029 EE17 E1 POP H Get var.type in H 030 EE18 CDB5EF CALL :EFB5 Read var.type from tape 031 EE1B BC CMP H Correct type ? 032 EE1C C21ADA JNZ :DA1A Run error 'TYPE MISMATCH' 033 if not 034 EE1F FE20 CPI :20 035 EE21 CA38EE JZ :EE38 Jump if string arrays 036 037 * If INT/FPT arrays: 038 039 EE24 E1 POP H 040 EE25 E3 XTHL Get dumpaddr in HL 041 EE26 EB XCHG Get length in HL 042 EE27 19 DAD D HL is end dump area 043 EE28 EB XCHG in DE; HL is start dump 044 EE29 CDD102 CALL :02D1 Read block from tape 045 EE2C D2B3D2 JNC :D2B3 Evt run 'LOADING ERROR ..' 046 EE2F CDD402 L1E246 CALL :02D4 Stop reading 047 EE32 3A4000 LDA :0040 Get POROM 048 EE35 C3A6EF JMP :EFA6 Select ROM bank 0, abort 049 050 * If string arrays: 051 052 EE38 D5 L1E247 PUSH D 053 EE39 2AA502 LHLD :02A5 Get bottom screen RAM 054 EE3C EB XCHG in DE 055 EE3D 2AA302 LHLD :02A3 Get begin free RAM space 056 EE40 E5 PUSH H 057 EE41 CD97D8 CALL :D897 Read block from tape into 058 free RAM area; evt.run error 059 EE44 E1 POP H Get begin free RAM 060 EE45 56 MOV D,M ) 061 EE46 23 INX H ) Length of array in DE 062 EE47 5E MOV E,M ) 063 EE48 23 INX H PAGE 02 DAI FIRMWARE 1EE0B-1EFFF V1.1 064 EE49 C3E5D6 JMP :D6E5 Via D6E5 to 1EE4C 065 * 066 EE4C C5 L1E248 PUSH B Save length array 067 EE4D D5 PUSH D 068 EE4E CDA8CB CALL :CBA8 Erase stringreference 069 in heap and symtab 070 EE51 2B DCX H 071 EE52 2B DCX H 072 EE53 D1 POP D 073 EE54 E5 PUSH H 074 EE55 1A LDAX D 075 EE56 CD8BD1 CALL :D18B Get place in heap for string 076 EE59 E5 PUSH H 077 EE5A CD72D1 CALL :D172 Transfer string into heap 078 EE5D C1 POP B 079 EE5E E1 POP H ) 080 EE5F 71 MOV M,C ) Length into heap at 081 EE60 23 INX H ) begin of string 082 EE61 70 MOV M,B ) 083 EE62 23 INX H 084 EE63 C1 POP B Get length array 085 EE64 0B DCX B ) Update it 086 EE65 0B DCX B ) 087 EE66 78 MOV A,B 088 EE67 B1 ORA C 089 EE68 C24CEE JNZ :EE4C Next string if not ready 090 * 091 ********* 092 * LOADA * 093 ********* 094 * 095 * Switching off the cassette motors is now part of 096 * D897. So the cassette motors are switched off 097 * directy after the reading from tape is done. 098 * 099 EE6B C332EE JMP :EE32 ] Adapted to new situation 100 * 101 * 102 * ============ 103 *** SOUND MODULE *** 104 * ============ 105 * 106 * 107 EE6E 0E00 TEMPO MVI C,:00 Count SCB 108 EE70 21C201 LXI H,:01C2 Addr sound control block 0 109 EE73 E5 L1E250 PUSH H Preserve addr SCB 110 EE74 7E MOV A,M Get value of volume counter 111 EE75 FEFE CPI :FE 112 EE77 CA7EEE JZ :EE7E If FE: No increment (sound 113 forever) 114 EE7A D29DEF JNC :EF9D If FF: Goto next block 115 (sound off) 116 EE7D 34 INR M ) Incr duration count volume 117 EE7E 3C L1E251 INR A ) 118 EE7F E5 PUSH H Preserve addr SCB 119 EE80 47 MOV B,A Save incr duration count 120 EE81 23 INX H 121 EE82 5E MOV E,M ) Get pntr envelope count 122 EE83 23 INX H ) in DE 123 EE84 56 MOV D,M ) 124 EE85 1A LDAX D Get envelope duration count 125 EE86 B8 CMP B Comp with volume count PAGE 03 DAI FIRMWARE 1EE0B-1EFFF V1.1 126 EE87 D2B8EE JNC :EEB8 Jump if env. not counted out 127 128 * Envelope counted out: 129 130 EE8A EB XCHG 131 EE8B E3 XTHL Addr env.duration on stack; 132 addr SCB in HL 133 EE8C 3600 MVI M,:00 Present duration count is 0 134 EE8E E1 POP H Get pntr to env.table 135 EE8F 23 INX H +1 136 EE90 7E MOV A,M Get next env. duration 137 EE91 B7 ORA A Is it FF ? 138 EE92 FC93EF CM :EF93 Then restart envelope 139 EE95 47 MOV B,A Env duration in B 140 EE96 23 INX H Pnts to next pos env table 141 EE97 7E MOV A,M Value in A 142 EE98 EB XCHG 143 EE99 72 MOV M,D ) Set env pointer in SCB 144 EE9A 2B DCX H ) to new time field 145 EE9B 73 MOV M,E ) 146 EE9C 23 INX H 147 EE9D 23 INX H 148 EE9E 23 INX H 149 EE9F 23 INX H HL pnts to vol.multiplier 150 EEA0 E5 PUSH H 151 EEA1 6E MOV L,M Sound volume *8 in L 152 EEA2 2600 MVI H,:00 153 EEA4 29 DAD H *16 in HL 154 EEA5 EB XCHG Multiplier in DE 155 EEA6 218000 LXI H,:0080 Init.value 156 EEA9 05 L1E252 DCR B Decr. envelope duration 157 EEAA FAB1EE JM :EEB1 Jump if ready 158 EEAD 19 DAD D Add multiplier 159 EEAE C3A9EE JMP :EEA9 Again 160 EEB1 44 L1E253 MOV B,H New eff. volume in B 161 EEB2 E1 POP H 162 EEB3 23 INX H 163 EEB4 70 MOV M,B Set new basic volume 164 EEB5 C3BDEE JMP :EEBD 165 166 * If envelope not counted out: 167 168 EEB8 D1 L1E254 POP D 169 EEB9 23 INX H 170 EEBA 23 INX H 171 EEBB 23 INX H 172 EEBC 23 INX H 173 174 * Handle tremolo: 175 176 EEBD 46 L1E255 MOV B,M Get basic volume in B 177 EEBE 23 INX H 178 EEBF 7E MOV A,M Get tremolo count 179 EEC0 B7 ORA A 180 EEC1 CAEBEE JZ :EEEB Jump if no tremolo adj. 181 EEC4 C601 ADI :01 ) 182 EEC6 CE00 ACI :00 ) Incr tremolo count 183 EEC8 77 MOV M,A ) 184 EEC9 1F RAR 185 EECA 1F RAR 186 EECB 1F RAR 187 EECC D2DCEE JNC :EEDC No adj. if bit 2 of PAGE 04 DAI FIRMWARE 1EE0B-1EFFF V1.1 188 is 0 189 EECF 04 INR B ) 190 EED0 04 INR B ) Else add 4 units to 191 EED1 04 INR B ) basic volume 192 EED2 04 INR B ) 193 EED3 1F RAR 194 EED4 00 NOP 195 EED5 DADCEE JC :EEDC No adjust if bit 2 of 196 = 0 197 EED8 78 MOV A,B 198 EED9 D608 SUI :08 Else: basic vol. -2 units 199 EEDB 47 MOV B,A 200 * 201 EEDC 00 L1E256 NOP 202 EEDD 78 MOV A,B Get updated basic volume 203 EEDE 0600 MVI B,:00 204 EEE0 B7 ORA A 205 EEE1 FAEBEE JM :EEEB Jump if B1-FF 206 EEE4 060F MVI B,:0F 207 EEE6 B8 CMP B 208 EEE7 D2EBEE JNC :EEEB Jump if >=0F (max.value) 209 EEEA 47 MOV B,A 210 * 211 EEEB 23 L1E257 INX H Pnts to actual volume 212 EEEC 78 MOV A,B Get new basic volume 213 EEED 96 SUB M Minus actual volume 214 EEEE 07 RLC ) 215 EEEF 1F RAR ) 216 EEF0 3F CMC ) New actual volume is 217 EEF1 CE00 ACI :00 ) old one + 0.5 218 EEF3 07 RLC ) (difference +/- 1) 219 EEF4 1F RAR ) 220 EEF5 1F RAR ) 221 EEF6 86 ADD M ) 222 EEF7 77 MOV M,A Store in SCB 223 EEF8 47 MOV B,A and in B 224 EEF9 E5 PUSH H 225 EEFA C5 PUSH B 226 EEFB 119402 LXI D,:0294 Addr POROM 227 EEFE 2104FD LXI H,:FD04 Addr PORO 228 EF01 79 MOV A,C Get SCB count 229 EF02 0EF0 MVI C,:F0 Mask for vol. SCB0,SCB2 230 EF04 0F RRC 231 EF05 D212EF JNC :EF12 Jump if SCB0,SCB2 232 EF08 0E0F MVI C,:0F Mask for vol. SCB1,NCB 233 EF0A F5 PUSH PSW 234 EF0B 78 MOV A,B ) 235 EF0C 87 ADD A ) Actual volume into 236 EF0D 87 ADD A ) hinibble for SCB1 237 EF0E 87 ADD A ) and NCB 238 EF0F 87 ADD A ) 239 EF10 47 MOV B,A ) 240 EF11 F1 POP PSW 241 EF12 1F L1E258 RAR 242 EF13 D218EF JNC :EF18 Jump if SCB0,SCB1 243 EF16 13 INX D ) POR0M+1,POR0+1 244 EF17 23 INX H ) for SCB2,NCB 245 EF18 1A L1E259 LDAX D Get POR0M,POR1M 246 EF19 A1 ANA C Only reqd volume 247 EF1A B0 ORA B Update it 248 EF1B 12 STAX D Back in POR0M,POR1M 249 EF1C 77 MOV M,A and in POR0,POR1 PAGE 05 DAI FIRMWARE 1EE0B-1EFFF V1.1 250 EF1D C1 POP B 251 EF1E E1 POP H 252 EF1F 0C INR C SCB count +1 253 EF20 79 MOV A,C 254 EF21 FE04 CPI :04 255 EF23 CAA4EF JZ :EFA4 Ready if block was NCB 256 257 258 259 EF26 23 INX H 260 EF27 7E MOV A,M Get glissando flag 261 EF28 3D DCR A 262 EF29 FA8BEF JM :EF8B Ready if end period 263 reached 264 EF2C 23 INX H 265 EF2D 5E MOV E,M ) Get current period of 266 EF2E 23 INX H ) output in DE 267 EF2F 56 MOV D,M ) 268 EF30 E5 PUSH H 269 EF31 23 INX H 270 EF32 7E MOV A,M ) Get reqd final period 271 EF33 23 INX H ) in HL 272 EF34 66 MOV H,M ) 273 EF35 6F MOV L,A 274 EF36 C23BEF JNZ :EF3B Jump if end period not 275 reached 276 EF39 54 MOV D,H ) HL=DE if 'set freq' 277 EF3A 5D MOV E,L ) 278 EF3B CD14DE L1E260 CALL :DE14 Compare HL-DE 279 EF3E F5 PUSH PSW 280 EF3F D5 PUSH D 281 EF40 D244EF JNC :EF44 Jump if final period >= 282 current period 283 EF43 EB XCHG Else exchange values 284 EF44 CD1ADE L1E261 CALL :DE1A Calc difference in HL 285 EF47 D1 POP D 286 EF48 D5 PUSH D 287 EF49 E5 PUSH H 288 EF4A EB XCHG 289 EF4B 1E40 MVI E,:40 ) 290 EF4D 7D L1E262 MOV A,L ) 291 EF4E 17 RAL ) 292 EF4F 6F MOV L,A ) 293 EF50 7C MOV A,H ) 294 EF51 17 RAL ) HL = HL SHL 6 295 EF52 67 MOV H,A ) 296 EF53 7B MOV A,E ) 297 EF54 17 RAL ) 298 EF55 5F MOV E,A ) 299 EF56 D24DEF JNC :EF4D 300 EF59 6C MOV L,H ) HL = 1/64 orig. value 301 EF5A 63 MOV H,E ) 302 EF5B 7C MOV A,H 303 EF5C B5 ORA L 304 EF5D C261EF JNZ :EF61 305 EF60 23 INX H 306 EF61 D1 L1E263 POP D 307 EF62 CD14DE CALL :DE14 Compare HL-DE 308 EF65 0602 MVI B,:02 309 EF67 DA6DEF JC :EF6D Jump if DE > HL 310 EF6A 0600 MVI B,:00 311 EF6C EB XCHG PAGE 06 DAI FIRMWARE 1EE0B-1EFFF V1.1 312 EF6D D1 L1E264 POP D 313 EF6E F1 POP PSW 314 EF6F D275EF JNC :EF75 315 EF72 CD26DE CALL :DE26 HL is its 2-compl. 316 EF75 19 L1E265 DAD D 317 EF76 EB XCHG 318 EF77 E1 POP H 319 EF78 72 MOV M,D ) Set new current period 320 EF79 2B DCX H ) 321 EF7A 73 MOV M,E ) 322 EF7B 2B DCX H 323 EF7C 70 MOV M,B Set glissando flag 324 EF7D C5 PUSH B 325 EF7E 79 MOV A,C ) 326 EF7F 3D DCR A ) Calc offset for oscill. 327 EF80 87 ADD A ) address 328 EF81 4F MOV C,A ) 329 EF82 0600 MVI B,:00 330 EF84 2100FC LXI H,:FC00 Addr osc. channel 0 331 EF87 09 DAD B HL = addr current osc 332 EF88 73 MOV M,E ) Load oscillator 333 EF89 72 MOV M,D ) 334 EF8A C1 POP B 335 336 * Block done: 337 338 EF8B 110E00 L1E266 LXI D,:000E 339 EF8E E1 POP H Get startadr prev. block 340 EF8F 19 DAD D HL pnts to next block 341 EF90 C373EE JMP :EE73 Run next block 342 * 343 * RESTART ENVELOPE: 344 * 345 * Gets 1st volume of envelope. 346 * 347 * Entry: DE: Points to 2nd byte of envelope pointer 348 * of a SCB. 349 * Exit: A: Volume. 350 * HL: Address volume field in envelope. 351 * BCDEF preserved. 352 * 353 EF93 D5 L1E267 PUSH D Save pntr 354 EF94 13 INX D 355 EF95 1A LDAX D Get lobyte env pntr 356 EF96 6F MOV L,A in L 357 EF97 13 INX D 358 EF98 1A LDAX D Get hibyte env pntr 359 EF99 67 MOV H,A in H 360 EF9A D1 POP D Restore pntr 361 EF9B 7E MOV A,M Get volume in A 362 EF9C C9 RET 363 * 364 * IF SOUND OF BLOCK IS 'OFF': GOTO NEXT BLOCK: 365 * 366 EF9D 0C L1E268 INR C Update SCB count 367 EF9E 79 MOV A,C 368 EF9F FE04 CPI :04 All blocks done ? 369 EFA1 C28BEF JNZ :EF8B Next block if not 370 EFA4 E1 L1E269 POP H 371 EFA5 C9 RET 372 * 373 *************** PAGE 07 DAI FIRMWARE 1EE0B-1EFFF V1.1 374 * BANK RETURN * 375 *************** 376 * 377 * Goto ROM bank 0. 378 * 379 * Entry: A: Current POROM. 380 * 381 EFA6 C1 BRET POP B 382 EFA7 E63F ANI :3F Select ROM bank 0 383 EFA9 C308D8 JMP :D808 Load PORO/POROM 384 * 385 EFAC FF DATA :FF 386 EFAD FF DATA :FF 387 EFAE FF DATA :FF 388 EFAF FF DATA :FF 389 EFB0 FF DATA :FF 390 EFB1 FF DATA :FF 391 EFB2 FF DATA :FF 392 EFB3 FF DATA :FF 393 EFB4 FF DATA :FF 394 * 395 *************************************** 396 * LOADA: READ VARIABLE TYPE FROM TAPE * 397 *************************************** 398 * 399 * Reads 1 byte from tape. 400 * 401 * Exit: A: Variable type. 402 * DEHL preserved. 403 * 404 EFB5 E5 R1BB PUSH H 405 EFB6 D5 PUSH D 406 EFB7 213E01 LXI H,:013E Startaddr EBUF 407 EFBA 113F01 LXI D,:013F Next addr 408 EFBD CDD102 CALL :02D1 Read type from tape 409 EFC0 D2B3D2 JNC :D2B3 Evt run 'LOADING ERROR ..' 410 EFC3 3A3E01 LDA :013E Get var.type in A 411 EFC6 D1 POP D 412 EFC7 E1 POP H 413 EFC8 C9 RET 414 * 415 EFC9 7A MOV A,D ] Get lobyte MACC 416 EFCA E6C0 ANI :C0 ] Check for max. value 417 EFCC C28BE6 JNZ :E68B ] Jump if nr too big 418 EFCF C394E6 JMP :E694 ] If O.K. 419 EFD2 FF DATA :FF 420 EFD3 FF DATA :FF 421 EFD4 FF DATA :FF 422 EFD5 FF DATA :FF 423 EFD6 FF DATA :FF 424 EFD7 FF DATA :FF 425 EFD8 FF DATA :FF 426 EFD9 FF DATA :FF 427 EFDA FF DATA :FF 428 EFDB FF DATA :FF 429 EFDC FF DATA :FF 430 EFDD FF DATA :FF 431 EFDE FF DATA :FF 432 EFDF FF DATA :FF 433 EFE0 FF DATA :FF 434 EFE1 FF DATA :FF 435 EFE2 FF DATA :FF PAGE 08 DAI FIRMWARE 1EE0B-1EFFF V1.1 436 EFE3 FF DATA :FF 437 EFE4 FF DATA :FF 438 EFE5 FF DATA :FF 439 EFE6 FF DATA :FF 440 EFE7 FF DATA :FF 441 EFE8 FF DATA :FF 442 EFE9 FF DATA :FF 443 EFEA FF DATA :FF 444 EFEB FF DATA :FF 445 EFEC FF DATA :FF 446 EFED FF DATA :FF 447 EFEE FF DATA :FF 448 EFEF FF DATA :FF 449 EFF0 FF DATA :FF 450 EFF1 FF DATA :FF 451 EFF2 FF DATA :FF 452 EFF3 FF DATA :FF 453 EFF4 FF DATA :FF 454 EFF5 FF DATA :FF 455 EFF6 FF DATA :FF 456 EFF7 FF DATA :FF 457 EFF8 FF DATA :FF 458 * 459 ************************* 460 * part of 'EXP' (1E667) * 461 ************************* 462 * 463 EFF9 B4 L1E272 ORA H 464 EFFA F2B8E6 JP :E6B8 465 EFFD C3ADE6 JMP :E6AD 466 * 467 * 468 * 469 F000 END *************************** * S Y M B O L T A B L E * *************************** BRET EFA6 L1E245 EE0B L1E246 EE2F L1E247 EE38 L1E248 EE4C L1E250 EE73 L1E251 EE7E L1E252 EEA9 L1E253 EEB1 L1E254 EEB8 L1E255 EEBD L1E256 EEDC L1E257 EEEB L1E258 EF12 L1E259 EF18 L1E260 EF3B L1E261 EF44 L1E262 EF4D L1E263 EF61 L1E264 EF6D L1E265 EF75 L1E266 EF8B L1E267 EF93 L1E268 EF9D L1E269 EFA4 L1E272 EFF9 L1E273 EE0F R1BB EFB5 TEMPO EE6E