
PAGE 01    DAI FIRMWARE 3EC45-3EDF8  V1.0  Rev.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: A=1, CY=0
034                 *
035                 ************************************
036                 * DECREMENT HL, COMPARE HL WITH DE *
037                 ************************************
038                 *
039                 * HL = HL - 1.
040                 *
041                 * Exit: AF corrupted, BCDEHL preserved.
042                 *       HL was 0: CY=1, Z=1.
043                 *       Else:     New 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.0  Rev.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.0  Rev.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.0  Rev.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.0  Rev.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.0  Rev.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.0  Rev.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.0  Rev.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.0  Rev.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
