PAGE 01 DAI FIRMWARE 1EE0B-1EFFF V1.0 Rev.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.0 Rev.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 EE6B C32FEE JMP :EE2F Stop reading, select ROM 091 bank 0; abort 092 * 093 * 094 * ============ 095 *** SOUND MODULE *** 096 * ============ 097 * 098 * 099 EE6E 0E00 TEMPO MVI C,:00 Count SCB 100 EE70 21C201 LXI H,:01C2 Addr sound control block 0 101 EE73 E5 L1E250 PUSH H Preserve addr SCB 102 EE74 7E MOV A,M Get value of volume counter 103 EE75 FEFE CPI :FE 104 EE77 CA7EEE JZ :EE7E If FE: No increment (sound 105 forever) 106 EE7A D29DEF JNC :EF9D If FF: Goto next block 107 (sound off) 108 EE7D 34 INR M ) Incr duration count volume 109 EE7E 3C L1E251 INR A ) 110 EE7F E5 PUSH H Preserve addr SCB 111 EE80 47 MOV B,A Save incr duration count 112 EE81 23 INX H 113 EE82 5E MOV E,M ) Get pntr envelope count 114 EE83 23 INX H ) in DE 115 EE84 56 MOV D,M ) 116 EE85 1A LDAX D Get envelope duration count 117 EE86 B8 CMP B Comp with volume count 118 EE87 D2B8EE JNC :EEB8 Jump if env. not counted out 119 120 * Envelope counted out: 121 122 EE8A EB XCHG 123 EE8B E3 XTHL Addr env.duration on stack; 124 addr SCB in HL 125 EE8C 3600 MVI M,:00 Present duration count is 0 PAGE 03 DAI FIRMWARE 1EE0B-1EFFF V1.0 Rev.1 126 EE8E E1 POP H Get pntr to env.table 127 EE8F 23 INX H +1 128 EE90 7E MOV A,M Get next env. duration 129 EE91 B7 ORA A Is it FF ? 130 EE92 FC93EF CM :EF93 Then restart envelope 131 EE95 47 MOV B,A Env duration in B 132 EE96 23 INX H Pnts to next pos env table 133 EE97 7E MOV A,M Value in A 134 EE98 EB XCHG 135 EE99 72 MOV M,D ) Set env pointer in SCB 136 EE9A 2B DCX H ) to new time field 137 EE9B 73 MOV M,E ) 138 EE9C 23 INX H 139 EE9D 23 INX H 140 EE9E 23 INX H 141 EE9F 23 INX H HL pnts to vol.multiplier 142 EEA0 E5 PUSH H 143 EEA1 6E MOV L,M Sound volume *8 in L 144 EEA2 2600 MVI H,:00 145 EEA4 29 DAD H *16 in HL 146 EEA5 EB XCHG Multiplier in DE 147 EEA6 218000 LXI H,:0080 Init.value 148 EEA9 05 L1E252 DCR B Decr. envelope duration 149 EEAA FAB1EE JM :EEB1 Jump if ready 150 EEAD 19 DAD D Add multiplier 151 EEAE C3A9EE JMP :EEA9 Again 152 EEB1 44 L1E253 MOV B,H New eff. volume in B 153 EEB2 E1 POP H 154 EEB3 23 INX H 155 EEB4 70 MOV M,B Set new basic volume 156 EEB5 C3BDEE JMP :EEBD 157 158 * If envelope not counted out: 159 160 EEB8 D1 L1E254 POP D 161 EEB9 23 INX H 162 EEBA 23 INX H 163 EEBB 23 INX H 164 EEBC 23 INX H 165 166 * Handle tremolo: 167 168 EEBD 46 L1E255 MOV B,M Get basic volume in B 169 EEBE 23 INX H 170 EEBF 7E MOV A,M Get tremolo count 171 EEC0 B7 ORA A 172 EEC1 CAEBEE JZ :EEEB Jump if no tremolo adj. 173 EEC4 C601 ADI :01 ) 174 EEC6 CE00 ACI :00 ) Incr tremolo count 175 EEC8 77 MOV M,A ) 176 EEC9 1F RAR 177 EECA 1F RAR 178 EECB 1F RAR 179 EECC D2DCEE JNC :EEDC No adj. if bit 2 of 180 is 0 181 EECF 04 INR B ) 182 EED0 04 INR B ) Else add 4 units to 183 EED1 04 INR B ) basic volume 184 EED2 04 INR B ) 185 EED3 1F RAR 186 EED4 00 NOP 187 EED5 DADCEE JC :EEDC No adjust if bit 2 of PAGE 04 DAI FIRMWARE 1EE0B-1EFFF V1.0 Rev.1 188 = 0 189 EED8 78 MOV A,B 190 EED9 D608 SUI :08 Else: basic vol. -2 units 191 EEDB 47 MOV B,A 192 * 193 EEDC 00 L1E256 NOP 194 EEDD 78 MOV A,B Get updated basic volume 195 EEDE 0600 MVI B,:00 196 EEE0 B7 ORA A 197 EEE1 FAEBEE JM :EEEB Jump if B1-FF 198 EEE4 060F MVI B,:0F 199 EEE6 B8 CMP B 200 EEE7 D2EBEE JNC :EEEB Jump if >=0F (max.value) 201 EEEA 47 MOV B,A 202 * 203 EEEB 23 L1E257 INX H Pnts to actual volume 204 EEEC 78 MOV A,B Get new basic volume 205 EEED 96 SUB M Minus actual volume 206 EEEE 07 RLC ) 207 EEEF 1F RAR ) 208 EEF0 3F CMC ) New actual volume is 209 EEF1 CE00 ACI :00 ) old one + 0.5 210 EEF3 07 RLC ) (difference +/- 1) 211 EEF4 1F RAR ) 212 EEF5 1F RAR ) 213 EEF6 86 ADD M ) 214 EEF7 77 MOV M,A Store in SCB 215 EEF8 47 MOV B,A and in B 216 EEF9 E5 PUSH H 217 EEFA C5 PUSH B 218 EEFB 119402 LXI D,:0294 Addr POROM 219 EEFE 2104FD LXI H,:FD04 Addr PORO 220 EF01 79 MOV A,C Get SCB count 221 EF02 0EF0 MVI C,:F0 Mask for vol. SCB0,SCB2 222 EF04 0F RRC 223 EF05 D212EF JNC :EF12 Jump if SCB0,SCB2 224 EF08 0E0F MVI C,:0F Mask for vol. SCB1,NCB 225 EF0A F5 PUSH PSW 226 EF0B 78 MOV A,B ) 227 EF0C 87 ADD A ) Actual volume into 228 EF0D 87 ADD A ) hinibble for SCB1 229 EF0E 87 ADD A ) and NCB 230 EF0F 87 ADD A ) 231 EF10 47 MOV B,A ) 232 EF11 F1 POP PSW 233 EF12 1F L1E258 RAR 234 EF13 D218EF JNC :EF18 Jump if SCB0,SCB1 235 EF16 13 INX D ) POR0M+1,POR0+1 236 EF17 23 INX H ) for SCB2,NCB 237 EF18 1A L1E259 LDAX D Get POR0M,POR1M 238 EF19 A1 ANA C Only reqd volume 239 EF1A B0 ORA B Update it 240 EF1B 12 STAX D Back in POR0M,POR1M 241 EF1C 77 MOV M,A and in POR0,POR1 242 EF1D C1 POP B 243 EF1E E1 POP H 244 EF1F 0C INR C SCB count +1 245 EF20 79 MOV A,C 246 EF21 FE04 CPI :04 247 EF23 CAA4EF JZ :EFA4 Ready if block was NCB 248 249 PAGE 05 DAI FIRMWARE 1EE0B-1EFFF V1.0 Rev.1 250 251 EF26 23 INX H 252 EF27 7E MOV A,M Get glissando flag 253 EF28 3D DCR A 254 EF29 FA8BEF JM :EF8B Ready if end period 255 reached 256 EF2C 23 INX H 257 EF2D 5E MOV E,M ) Get current period of 258 EF2E 23 INX H ) output in DE 259 EF2F 56 MOV D,M ) 260 EF30 E5 PUSH H 261 EF31 23 INX H 262 EF32 7E MOV A,M ) Get reqd final period 263 EF33 23 INX H ) in HL 264 EF34 66 MOV H,M ) 265 EF35 6F MOV L,A 266 EF36 C23BEF JNZ :EF3B Jump if end period not 267 reached 268 EF39 54 MOV D,H ) HL=DE if 'set freq' 269 EF3A 5D MOV E,L ) 270 EF3B CD14DE L1E260 CALL :DE14 Compare HL-DE 271 EF3E F5 PUSH PSW 272 EF3F D5 PUSH D 273 EF40 D244EF JNC :EF44 Jump if final period >= 274 current period 275 EF43 EB XCHG Else exchange values 276 EF44 CD1ADE L1E261 CALL :DE1A Calc difference in HL 277 EF47 D1 POP D 278 EF48 D5 PUSH D 279 EF49 E5 PUSH H 280 EF4A EB XCHG 281 EF4B 1E40 MVI E,:40 ) 282 EF4D 7D L1E262 MOV A,L ) 283 EF4E 17 RAL ) 284 EF4F 6F MOV L,A ) 285 EF50 7C MOV A,H ) 286 EF51 17 RAL ) HL = HL SHL 6 287 EF52 67 MOV H,A ) 288 EF53 7B MOV A,E ) 289 EF54 17 RAL ) 290 EF55 5F MOV E,A ) 291 EF56 D24DEF JNC :EF4D 292 EF59 6C MOV L,H ) HL = 1/64 orig. value 293 EF5A 63 MOV H,E ) 294 EF5B 7C MOV A,H 295 EF5C B5 ORA L 296 EF5D C261EF JNZ :EF61 297 EF60 23 INX H 298 EF61 D1 L1E263 POP D 299 EF62 CD14DE CALL :DE14 Compare HL-DE 300 EF65 0602 MVI B,:02 301 EF67 DA6DEF JC :EF6D Jump if DE > HL 302 EF6A 0600 MVI B,:00 303 EF6C EB XCHG 304 EF6D D1 L1E264 POP D 305 EF6E F1 POP PSW 306 EF6F D275EF JNC :EF75 307 EF72 CD26DE CALL :DE26 HL is its 2-compl. 308 EF75 19 L1E265 DAD D 309 EF76 EB XCHG 310 EF77 E1 POP H 311 EF78 72 MOV M,D ) Set new current period PAGE 06 DAI FIRMWARE 1EE0B-1EFFF V1.0 Rev.1 312 EF79 2B DCX H ) 313 EF7A 73 MOV M,E ) 314 EF7B 2B DCX H 315 EF7C 70 MOV M,B Set glissando flag 316 EF7D C5 PUSH B 317 EF7E 79 MOV A,C ) 318 EF7F 3D DCR A ) Calc offset for oscill. 319 EF80 87 ADD A ) address 320 EF81 4F MOV C,A ) 321 EF82 0600 MVI B,:00 322 EF84 2100FC LXI H,:FC00 Addr osc. channel 0 323 EF87 09 DAD B HL = addr current osc 324 EF88 73 MOV M,E ) Load oscillator 325 EF89 72 MOV M,D ) 326 EF8A C1 POP B 327 328 * Block done: 329 330 EF8B 110E00 L1E266 LXI D,:000E 331 EF8E E1 POP H Get startadr prev. block 332 EF8F 19 DAD D HL pnts to next block 333 EF90 C373EE JMP :EE73 Run next block 334 * 335 * RESTART ENVELOPE: 336 * 337 * Gets 1st volume of envelope. 338 * 339 * Entry: DE: Points to 2nd byte of envelope pointer 340 * of a SCB. 341 * Exit: A: Volume. 342 * HL: Address volume field in envelope. 343 * BCDEF preserved. 344 * 345 EF93 D5 L1E267 PUSH D Save pntr 346 EF94 13 INX D 347 EF95 1A LDAX D Get lobyte env pntr 348 EF96 6F MOV L,A in L 349 EF97 13 INX D 350 EF98 1A LDAX D Get hibyte env pntr 351 EF99 67 MOV H,A in H 352 EF9A D1 POP D Restore pntr 353 EF9B 7E MOV A,M Get volume in A 354 EF9C C9 RET 355 * 356 * IF SOUND OF BLOCK IS 'OFF': GOTO NEXT BLOCK: 357 * 358 EF9D 0C L1E268 INR C Update SCB count 359 EF9E 79 MOV A,C 360 EF9F FE04 CPI :04 All blocks done ? 361 EFA1 C28BEF JNZ :EF8B Next block if not 362 EFA4 E1 L1E269 POP H 363 EFA5 C9 RET 364 * 365 *************** 366 * BANK RETURN * 367 *************** 368 * 369 * Goto ROM bank 0. 370 * 371 * Entry: A: Current POROM. 372 * 373 EFA6 C1 BRET POP B PAGE 07 DAI FIRMWARE 1EE0B-1EFFF V1.0 Rev.1 374 EFA7 E63F ANI :3F Select ROM bank 0 375 EFA9 C308D8 JMP :D808 Load PORO/POROM 376 * 377 EFAC FF DATA :FF 378 EFAD FF DATA :FF 379 EFAE FF DATA :FF 380 EFAF FF DATA :FF 381 EFB0 FF DATA :FF 382 EFB1 FF DATA :FF 383 EFB2 FF DATA :FF 384 EFB3 FF DATA :FF 385 EFB4 FF DATA :FF 386 * 387 *************************************** 388 * LOADA: READ VARIABLE TYPE FROM TAPE * 389 *************************************** 390 * 391 * Reads 1 byte from tape. 392 * 393 * Exit: A: Variable type. 394 * DEHL preserved. 395 * 396 EFB5 E5 R1BB PUSH H 397 EFB6 D5 PUSH D 398 EFB7 213E01 LXI H,:013E Startaddr EBUF 399 EFBA 113F01 LXI D,:013F Next addr 400 EFBD CDD102 CALL :02D1 Read type from tape 401 EFC0 D2B3D2 JNC :D2B3 Evt run 'LOADING ERROR ..' 402 EFC3 3A3E01 LDA :013E Get var.type in A 403 EFC6 D1 POP D 404 EFC7 E1 POP H 405 EFC8 C9 RET 406 * 407 EFC9 FF DATA :FF 408 EFCA FF DATA :FF 409 EFCB FF DATA :FF 410 EFCC FF DATA :FF 411 EFCD FF DATA :FF 412 EFCE FF DATA :FF 413 EFCF FF DATA :FF 414 EFD0 FF DATA :FF 415 EFD1 FF DATA :FF 416 EFD2 FF DATA :FF 417 EFD3 FF DATA :FF 418 EFD4 FF DATA :FF 419 EFD5 FF DATA :FF 420 EFD6 FF DATA :FF 421 EFD7 FF DATA :FF 422 EFD8 FF DATA :FF 423 EFD9 FF DATA :FF 424 EFDA FF DATA :FF 425 EFDB FF DATA :FF 426 EFDC FF DATA :FF 427 EFDD FF DATA :FF 428 EFDE FF DATA :FF 429 EFDF FF DATA :FF 430 EFE0 FF DATA :FF 431 EFE1 FF DATA :FF 432 EFE2 FF DATA :FF 433 EFE3 FF DATA :FF 434 EFE4 FF DATA :FF 435 EFE5 FF DATA :FF PAGE 08 DAI FIRMWARE 1EE0B-1EFFF V1.0 Rev.1 436 EFE6 FF DATA :FF 437 EFE7 FF DATA :FF 438 EFE8 FF DATA :FF 439 EFE9 FF DATA :FF 440 EFEA FF DATA :FF 441 EFEB FF DATA :FF 442 EFEC FF DATA :FF 443 EFED FF DATA :FF 444 EFEE FF DATA :FF 445 EFEF FF DATA :FF 446 EFF0 FF DATA :FF 447 EFF1 FF DATA :FF 448 EFF2 FF DATA :FF 449 EFF3 FF DATA :FF 450 EFF4 FF DATA :FF 451 EFF5 FF DATA :FF 452 EFF6 FF DATA :FF 453 EFF7 FF DATA :FF 454 EFF8 FF DATA :FF 455 * 456 ************************* 457 * part of 'EXP' (1E667) * 458 ************************* 459 * 460 EFF9 B4 L1E272 ORA H 461 EFFA F2B8E6 JP :E6B8 462 EFFD C3ADE6 JMP :E6AD 463 * 464 * 465 * 466 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