11
2 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
3+                                                      20:17  06/10/2018
4+                                                                                      PAGE 1
5
6
7
8                   ;***************************************************************
9                   ;*                                                             *
10                   ;* ALTAIR DISK BOOT LOADER                                     *
11                   ;* VERSION 4.1                                                 *
12                   ;*                                                             *
13                   ;* DISASSEMBLED BY MARTIN EBERHARD, 4 MARCH 2012               *
14                   ;* FROM AN EPROM WITH A PRINTED LABEL THAT SAID 'DBL 4.1'.     *
15                   ;* THIS EPROM WAS FOUND SOCKETED IN A MITS TURNKEY BOARD.      *
16                   ;*                                                             *
17                   ;* BECAUSE OF THE SLOW EPROM ACCESS TIME, THIS EPROM-BASED     *
18                   ;* PROGRAM FIRST COPIES ITSELF INTO RAM AT ADDRESS 2C00H       *
19                   ;* (RUNLOC), AND THEN EXECUTES THERE.                          *
20                   ;*                                                             *
21                   ;* ONCE IN RAM, THIS PROGRAM READS FROM THE DISK STARTING AT   *
22                   ;* TRACK 00, SECTOR 00. SECTOR DATA (WHICH INCLUDES THE ACTUAL *
23                   ;* DATA PAYLOAD, AS WELL AS HEADER AND TRAILER BYTES) IS FIRST *
24                   ;* LOADED INTO A RAM BUFFER IN MEMORY JUST AFTER THIS PROGRAM. *
25                   ;* THE DATA PAYLOAD THEN GETS MOVED INTO MEMORY STARTING AT    *
26                   ;* ADDRESS 0000H (DMAADR), CHECKING THE CHECKSUM ALONG THE WAY.*
27                   ;*                                                             *
28                   ;* EACH SECTOR HAS A 16-BIT VALUE IN ITS HEADER THAT IS THE    *
29                   ;* BYTE COUNT FOR THE FILE TO LOAD - THIS MANY BYTES ARE READ  *
30                   ;* FROM THE DISK. WHEN DONE (ASSUMING NO ERRORS), THIS PROGRAM *
31                   ;* JUMPS TO 0000 (DMAADR), TO EXECUTE THE LOADED CODE.         *
32                   ;*                                                             *
33                   ;* SECTORS ARE INTERLEAVED 2:1 ON THE DISK, THE EVEN SECTORS   *
34                   ;* ARE READ FIRST, AND THEN THE ODD SECTORS.                   *
35                   ;*                                                             *
36                   ;* WHEN DATA IS MOVED FROM THE RAM BUFFER TO ITS FINAL MEMORY  *
37                   ;* LOCATION, IT IS READ BACK TO VERIFY CORRECT WRITE. ANY      *
38                   ;* FAILURE WILL RESULT IN AN ABORT WITH A 'M' ERROR.           *
39                   ;*                                                             *
40                   ;* ANY READ ERRORS (EITHER A CHECKSUM ERROR OR AN INCORRECT    *
41                   ;* SYNC BYTE) WILL CAUSE A RETRY OF THE SECTOR READ. AFTER     *
42                   ;* 10H RETRIES, THIS PROGRAM WILL ABORT WITH A 'C' ERROR.      *
43                   ;*                                                             *
44                   ;* IF THE PROGRAM ABORTS BECAUSE OF AN ERROR, IT WILL ALSO     *
45                   ;* TURN THE FRONT PANEL 'INTE' LED ON.                         *
46                   ;*                                                             *
47                   ;*   DISK SECTOR FORMAT               BUFFER ADDRESS           *
48                   ;*     1 BYTE:   ?                       2CEBH                 *
49                   ;*     2 BYTES: 16-BIT FILE-SIZE         2CECH                 *
50                   ;*   128 BYTES: DATA PAYLOAD             2CEEH                 *
51                   ;*     1 BYTE:  SYNC (FFH)               2D6EH                 *
52                   ;*     1 BYTE:  CHECKSUM                 2D6FH                 *
53                   ;*     1 BYTE:  ?                        2D70H                 *
54                   ;*                                                             *
55                   ;* MODIFIED TO ASSEMBLE WITH INTEL 8080 CROSS ASSEMBLER        *
56                   ;* JULY 2018, UDO MUNK                                         *
57                   ;***************************************************************
58
591
60 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
61+                                                      20:17  06/10/2018
62+                                                                                      PAGE 2
63
64
65
66   0000            DMAADR  EQU     0000H           ;JUMPS HERE ONCE LOAD IS DONE
67   2C00            RUNLOC  EQU     2C00H           ;RELOCATE LOADER HERE
68
69   0010            RETRIES EQU     10H             ;MAX NUMBER OF RETRIES
70
71   00FF            SENSE   EQU     0FFH            ;FRONT PANEL SENSE SWITCHES
72
73                   ; 2SIO REGISTERS
74
75   0010            S2C0    EQU     10H     ;ACIA 0 CONTROL OUTPUT PORT
76   0010            S2S0    EQU     10H     ;ACIA 0 STATUS INPUT PORT
77   0011            S2T0    EQU     11H     ;ACIA 0 TX DATA REGISTER
78   0011            S2R0    EQU     11H     ;ACIA 0 RX DATA REGISTER
79   0012            S2C1    EQU     12H     ;ACIA 1 CONTROL OUTPUT PORT
80   0012            S2S1    EQU     12H     ;ACIA 1 STATUS INPUT PORT
81   0013            S2T1    EQU     13H     ;ACIA 1 TX DATA REGISTER
82   0013            S2R1    EQU     13H     ;ACIA 1 RX DATA REGISTER
83
84                   ; 2SIO EQUATES
85
86   0003            SIO2RST EQU     00000011B       ;MASTER RESET
87
88                   ; SIO REGISTERS
89
90   0000            SIOCTRL EQU     0               ;CONTROL PORT
91   0000            SIOSTAT EQU     0               ;STATUS
92   0001            SIOTXD  EQU     1               ;TRANSMIT DATA
93   0001            SIORXD  EQU     1               ;RECEUVE DATA
94
95                   ; PIO REGISTERS
96
97   0004            PIOCTRL EQU     4               ;CONTROL PORT
98   0004            PIOSTAT EQU     4               ;STATUS
99   0005            PIOTXD  EQU     5               ;TRANSMIT DATA
100   0005            PIORXD  EQU     5               ;RECEUVE DATA
101
102                   ; 4PIO REGISTERS
103
104   0020            P4CA0   EQU     20H             ;PORT 0 SECTION A CTRL/STATUS
105   0021            P4DA0   EQU     21H             ;PORT 0 SECTION A DATA
106   0022            P4CB0   EQU     22H             ;PORT 0 SECTION B CTRL/STATUS
107   0023            P4DB0   EQU     23H             ;PORT 0 SECTION B DATA
108
109                   ; DISK CONTROLLER INPUT EQUATES
110
111   0008            DSTAT   EQU     08H             ;DISK STATUS REGISTER
112   0002            MOVEOK  EQU             02H     ;HEAD MOVEMENT ALLOWED
113   0008            ENABLD  EQU             08H     ;0 MEANS CONTROLLER IS ENABLED
114   0040            TRACK0  EQU             40H     ;TRACK 0 DETECT
115
116   0009            DSECTR  EQU     09H             ;DISK SECTOR NUMBER
1171
118 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
119+                                                      20:17  06/10/2018
120+                                                                                      PAGE 3
121
122
123
124   0001            SECTRU  EQU             01H     ;SECTOR VALUE IS TRUE
125
126   000A            DDATA   EQU     0AH             ;READ DATA HERE
127
128                   ;DISK CONTROLLER OUTPUT EQUATES
129   0008            DSLCT   EQU     08H             ;SELECT DISK NO.
130   0080            DISABL  EQU             80H     ;DSLCT VALUE TO DISABLE ALL
131
132   0009            DCTRL   EQU     09H             ;DISK CONTROL REG
133   0001            STEPIN  EQU             01H     ;STEP IN
134   0002            STEPOT  EQU             02H     ;STEP OUT
135   0004            HDLOAD  EQU             04H     ;HEAD LOAD
136   0008            HDUNLD  EQU             08H     ;HEAD UNLOAD
137   0010            INTEN   EQU             10H     ;INTERRUPT ENABLE
138   0020            INTDE   EQU             20H     ;INTERRUPT DISABLE
139   0040            HCS     EQU             40H     ;HEAD CURRENT SWITCH
140   0080            WRITEN  EQU             80H     ;WRITE ENABLE
141
142
143                   ;***************************************************************
144                   ; CODE MOVER: MOVES LOADER INTO LOW MEMORY
145                   ;***************************************************************
146
147   FF00                    ORG     0FF00H
148
149   FF00   2113FF           LXI     H,RCODE         ;SOURCE
150   FF03   11002C           LXI     D,RUNLOC        ;DESTINATION
151   FF06   0EEB             MVI     C,EOP-RCODE     ;BYTE COUNT
152
153   FF08   7E       MLUP:   MOV     A,M             ;GET SOURCE BYTE
154   FF09   12               STAX    D               ;PUT IT IN PLACE
155   FF0A   23               INX     H               ;BUMP POINTERS
156   FF0B   13               INX     D
157   FF0C   0D               DCR     C               ;DONE YET?
158   FF0D   C208FF           JNZ     MLUP            ;NO: KEEP MOVING
159   FF10   C3002C           JMP     RUNLOC          ;YES: GO EXECUTE IT
160
161                   ;***************************************************************
162                   ; THE FOLLOWING LOADER CODE GETS RELOCATED TO 'RUNLOC' BY THE
163                   ; ABOVE MOVER. ALL ADDRESSES ARE ADJUSTED FOR WHERE THIS CODE
164                   ; WILL ACTUALY RUN.
165                   ;***************************************************************
166
167   FF13   F3       RCODE:  DI                      ;FRONT PANEL INTE LED OFF
168                                                   ;BECAUSE NO ERROR YET.
169
170                   ;CALCULATE CODE ADDRESS OFFSET FOR RELOCATED CODE
171
172   D313            OFFSET  EQU     RCODE-RUNLOC    ;SUBTRACT FROM ALL ADDRESSES
173
174                   ;---------------------------------------------------------------
1751
176 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
177+                                                      20:17  06/10/2018
178+                                                                                      PAGE 4
179
180
181
182                   ; INITIALIZATION
183                   ;---------------------------------------------------------------
184                   ;INITIALIZE 4PIO
185
186   FF14   AF               XRA     A               ;ACCESS DDR REGISTER, ETC.
187   FF15   D322             OUT     P4CB0
188
189   FF17   2F               CMA                     ;SET PORT B AS INPUT
190   FF18   D323             OUT     P4DB0
191
192   FF1A   3E2C             MVI     A,2CH           ;READY BIT ON E PULSE, ETC.
193   FF1C   D322             OUT     P4CB0
194
195                   ;INITIALIZE THE 2SIO. READ TEH SENSE SWITCHES TO DETERMINE THE
196                   ;NUMBER OF STOP BITS. IF SWITCH A12 IS UP, IT'S ONE STOP BIT.
197                   ;OTHERWISE. IT'S 2 STOP BITS. ALWAYS SET UP FOR 8-BIT DATA AND
198                   ;NO PARITY.
199
200   FF1E   3E03             MVI     A,SIO2RST       ;RESET COMMAND
201   FF20   D310             OUT     S2C0
202   FF22   DBFF             IN      SENSE           ;READ SENSE SWITCHES
203   FF24   E610             ANI     10H             ;GET STOP BIT SELECT FOR 2SIO
204   FF26   0F               RRC                     ;MAKE IT ACIA WORD SELECT 0
205   FF27   0F               RRC
206   FF28   C610             ADI     10H             ;WORD SELECT 2 FOR 8 BIT DATA
207   FF2A   D310             OUT     10H             ;8 BITS, 1-2 STOPS, NO PARITY
208
209                   ;SET UP THE STACK IN MEMORY AFTER THIS PROGRAM AND AFTER
210                   ;THE DISK DATA BUFFER
211
212   FF2C   31792D           LXI     SP,STACK        ;SET UP STACK
213
214                   ;WAIT FOR CONTROLLER TO BE ENABLED (INCLUDING DOOR SHUT)
215
216   FF2F   AF       WAITEN: XRA     A               ;SELECT DRIVE 0
217   FF30   D308             OUT     DSLCT
218
219   FF32   DB08             IN      DSTAT
220   FF34   E608             ANI     ENABLD          ;THIS BIT 0 WHEN ENABLED
221   FF36   C21C2C           JNZ     WAITEN-OFFSET   ;KEEP WAITING
222
223                   ;LOAD THE HEAD
224
225   FF39   3E04             MVI     A,HDLOAD
226   FF3B   D309             OUT     DCTRL
227   FF3D   C3382C           JMP     CHK00-OFFSET    ;ALREADY AT TRACK 00?
228
229                   ; STEP OUT ONE TRACK AT A TIME TO SEEK TRACK 00
230
231   FF40   DB08     SEEK00: IN      DSTAT           ;WAIT FOR HEAD MOVEMENT ALLOWED
232   FF42   E602             ANI     MOVEOK
2331
234 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
235+                                                      20:17  06/10/2018
236+                                                                                      PAGE 5
237
238
239
240   FF44   C22D2C           JNZ     SEEK00-OFFSET   ;KEEP WAITING
241
242   FF47   3E02             MVI     A,STEPOT        ;STEP OUT A TRACK
243   FF49   D309             OUT     DCTRL
244
245   FF4B   DB08     CHK00:  IN      DSTAT           ;ARE WE AT TRACK 0 ALREADY?
246   FF4D   E640             ANI     TRACK0
247   FF4F   C22D2C           JNZ     SEEK00-OFFSET   ;NO: KEEP STEPPING
248
249
250   FF52   110000           LXI     D,DMAADR        ;PUT DISK DATA STARTING HERE
251
252                   ;---------------------------------------------------------------
253                   ; READ DISK DATA UNTIL WE'VE READ AS MEANY BYTES AS INDICATED
254                   ; AS THE FILE SIZE IN THE SECTOR HEADERS, AND PUT IT AT (DE)
255                   ;---------------------------------------------------------------
256   FF55   0600     NXTRAC: MVI     B,0             ;INITIAL SECTOR NUMBER
257
258   FF57   3E10     NXTSEC: MVI     A,RETRIES       ;INITIALIZE RETRY COUNTER
259
260                   ;READ ONE SECTOR INTO THE BUFFER
261                   ; ON ENTRY:
262                   ;    A = RETRIES
263                   ;    B = SECTOR NUMBER
264                   ;   DE = MEMORY ADDRESS FOR SECTOR DATA
265
266   FF59   F5       RDSECT: PUSH    PSW             ;SAVE RETRY COUNTER
267   FF5A   D5               PUSH    D               ;SAVE DEST ADDRESS FOR RETRY
268   FF5B   C5               PUSH    B               ;SAVE B=SECTOR NUMBER
269   FF5C   D5               PUSH    D               ;SAVE DEST ADDRESS FOR MOVE
270   FF5D   118680           LXI     D,8086H         ;E=BYTES PER SECTOR, D=JUNK
271   FF60   21EB2C           LXI     H,BUFFER        ;HL POINTS TO DISK BUFFER
272
273                   ; WAIT UNTIL THE RIGHT SECTOR
274
275   FF63   DB09     WSECT:  IN      DSECTR          ;READ SECTOR STATUS
276   FF65   1F               RAR                     ;TEST BIT 0 = SECTRU
277   FF66   DA502C           JC      WSECT-OFFSET    ;SPIN UNTIL SECTOR IS READY
278
279   FF69   E61F             ANI     1FH             ;GET THE SECTOR NUMBER
280   FF6B   B8               CMP     B               ;IS IT THE ONE WE WANT?
281   FF6C   C2502C           JNZ     WSECT-OFFSET    ;NO: WAIT FOR OUR SECTOR
282
283                   ;---------------------------------------------------------------
284                   ; LOOP TO READ 128 + 6  BYTES FROM THE DISK AND PUT INTO THE RAM
285                   ; BUFFER. THIS READING IS DONE 2 BYTES AT A TIME FOR SPEED
286                   ;---------------------------------------------------------------
287   FF6F   DB08     DWAIT:  IN      DSTAT           ;DATA READY?
288   FF71   B7               ORA     A               ;MSB CLEARED WHEN READY
289   FF72   FA5C2C           JM      DWAIT-OFFSET
290
2911
292 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
293+                                                      20:17  06/10/2018
294+                                                                                      PAGE 6
295
296
297
298   FF75   DB0A             IN      DDATA           ;GET A BYTE OF DISK DATA
299   FF77   77               MOV     M,A             ;PUT IT IN MEMORY
300   FF78   23               INX     H               ;BUMP MEMORY POINTER
301   FF79   1D               DCR     E               ;BUMP & TEST BYTE COUNT
302   FF7A   CA722C           JZ      SECDON-OFFSET   ;QUIT IF BYTE COUNT = 0
303
304   FF7D   1D               DCR     E               ;BUMP & TEST BYTE COUNT AGAIN
305   FF7E   DB0A             IN      DDATA           ;GET ANOTHER BYTE OF DATA
306   FF80   77               MOV     M,A             ;PUT IT IN MEMORY
307   FF81   23               INX     H               ;BUMP MEMORY POINTER
308   FF82   C25C2C           JNZ     DWAIT-OFFSET    ;AGAIN, UNLESS BYTE COUNT = 0
309   FF85            SECDON:
310
311                   ;---------------------------------------------------------------
312                   ; MOVE THE DATA TO ITS FINAL LOCATION, AND CHECK THE CHECKSUM AS
313                   ; WE MOVE THE DATA. ALSO VERIFY THE MEMORY WRITE.
314                   ;---------------------------------------------------------------
315   FF85   E1               POP     H                       ;RECOVER DEST ADDRESS
316   FF86   11EE2C           LXI     D,BUFFER+3              ;START OF DATA PAYLOAD
317   FF89   018000           LXI     B,0080H                 ;B=INITIAL CHECKSUM,
318                                                           ;C=DATA BYTES/SECTOR
319
320   FF8C   1A       MOVLUP: LDAX    D               ;GET A BYTE FROM THE BUFFER
321   FF8D   77               MOV     M,A             ;WRITE IT TO RAM
322   FF8E   BE               CMP     M               ;SUCCESSFUL WRITE TO RAM?
323   FF8F   C2CB2C           JNZ     MEMERR-OFFSET   ;NO: GIVE UP
324
325   FF92   80               ADD     B               ;COMPUTE CHECKSUM
326   FF93   47               MOV     B,A
327
328   FF94   13               INX     D               ;BUMP SOURCE POINTER
329   FF95   23               INX     H               ;BUMP DESTINATION POINTER
330   FF96   0D               DCR     C               ;NEXT BYTE
331   FF97   C2792C           JNZ     MOVLUP-OFFSET   ;KEEP GOING THROUGH 128 BYTES
332
333
334   FF9A   1A               LDAX    D               ;THE NEXT BYTE MUST BE FF
335   FF9B   FEFF             CPI     0FFH
336   FF9D   C2902C           JNZ     RDDONE-OFFSET   ;OTHERWISE IT'S A BAD READ
337
338   FFA0   13               INX     D               ;THE NEXT BYTE IS THE CHECKSUM
339   FFA1   1A               LDAX    D
340   FFA2   B8               CMP     B               ;MATCH THE COMPUTED CHECKSUM?
341
342   FFA3   C1       RDDONE: POP     B               ;RESTORE SECTOR NUMBER
343   FFA4   EB               XCHG                    ;PUT MEMORY ADDRESS INTO DE
344                                                   ;AND BUFFER POINTER INTO HL
345   FFA5   C2C22C           JNZ     BADSEC-OFFSET   ;CHECKSUM ERROR OR MISSING FF?
346
347   FFA8   F1               POP     PSW             ;CHUCK OLD SECTOR NUMBER
348   FFA9   F1               POP     PSW             ;CHUCK OLD RAM ADDRESS
3491
350 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
351+                                                      20:17  06/10/2018
352+                                                                                      PAGE 7
353
354
355
356   FFAA   2AEC2C           LHLD    BUFFER+1        ;GET FILE BYTE COUNT FROM HEADER
357   FFAD   CDE52C           CALL    CMP16-OFFSET    ;COMPARE TO NEXT RAM ADDRESS
358   FFB0   D2BB2C           JNC     DONE-OFFSET     ;DONE IF ADDRESS > FILE SIZE
359
360                   ;---------------------------------------------------------------
361                   ; SET UP FOR NEXT SECTOR
362                   ; THE DISK HAS A 2:1 SECTOR INTERLEAVE -
363                   ; FIRST READ ALL THE EVEN SECTORS, THEN READ ALL THE ODD SECTORS
364                   ;---------------------------------------------------------------
365   FFB3   04               INR     B               ;BUMP SECTOR NUMBER BY 2
366   FFB4   04               INR     B
367   FFB5   78               MOV     A,B             ;LAST EVEN OR ODD SECTOR ALREADY?
368   FFB6   FE20             CPI     20H
369   FFB8   DA442C           JC      NXTSEC-OFFSET   ;NO: KEEP READING
370
371   FFBB   0601             MVI     B,1             ;START READING THE ODD SECTORS
372   FFBD   CA442C           JZ      NXTSEC-OFFSET   ;UNLESS WE FINISHED THEM TOO
373
374                   ; SEEK THE NEXT TRACK
375
376   FFC0   DB08     WAITHD: IN      DSTAT           ;WAIT UNTIL WE CAN MOVE THE HEAD
377   FFC2   E602             ANI     MOVEOK
378   FFC4   C2AD2C           JNZ     WAITHD-OFFSET
379
380   FFC7   3E01             MVI     A,STEPIN        ;SEND STEP-IN CMD TO CONTROLLER
381   FFC9   D309             OUT     DCTRL
382   FFCB   C3422C           JMP     NXTRAC-OFFSET   ;BEGINNING OF THE NEXT TRACK
383
384
385   FFCE   3E80     DONE:   MVI     A,DISABL        ;DISABLE DISKS
386   FFD0   D308             OUT     DSLCT
387   FFD2   C30000           JMP     DMAADR          ;GO EXECUTE WHAT WE LOADED
388
389                   ;---------------------------------------------------------------
390                   ; SECTOR ERROR:
391                   ; RESTORE TO BEGINNING OF SECTOR AND SEE IF WE CAN RETRY
392                   ;---------------------------------------------------------------
393   FFD5   D1       BADSEC: POP     D               ;RESTORE MEMORY ADDRESS
394   FFD6   F1               POP     PSW             ;GET RETRY COUNTER
395   FFD7   3D               DCR     A               ;BUMP RETRY COUNTER
396   FFD8   C2462C           JNZ     RDSECT-OFFSET   ;NOT ZERO: TRY AGAIN
397
398                   ; FALL INTO SECERR
399
400                   ;---------------------------------------------------------------
401                   ;ERROR ABORT ROUTINE: WRITE ERROR INFO TO MEMORY AT 0, HANG
402                   ;FOREVER, WRITING A ONE-CHARACTER ERROR CODE TO ALL OUTPUT PORTS
403                   ; ENTRY AT SECERR PRINTS 'C', SAVES BUFFER POINTER AT 0001H
404                   ;   THE BUFFER POINTER WILL BE 2D6EH IF IT WAS A SYNCHRONIZATION
405                   ;   ERROR, AND IT WILL BE 2D6FH IF IT WAS A CHECKSUM ERROR
406                   ; ENTRY AT MEMERR PRINTS 'M', SAVES OFFENDING ADDRESS AT 0001H
4071
408 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
409+                                                      20:17  06/10/2018
410+                                                                                      PAGE 8
411
412
413
414                   ; THE FRONT PANEL INTE LED GETS TURNED ON TO INDICATE AN ERROR.
415                   ;---------------------------------------------------------------
416   FFDB   3E43     SECERR: MVI     A,'C'           ;ERROR CODE
417
418   FFDD   01               DB      01              ;USE "LXI B" TO SKIP 2 BYTES
419
420   FFDE   3E4D     MEMERR: MVI     A,'M'           ;MEMORY ERROR
421
422   FFE0   FB               EI                      ;TURN FORNT PANEL INTE LED ON
423
424   FFE1   320000           STA     DMAADR          ;SAVE ERROR CODE AT 0000
425   FFE4   220100           SHLD    DMAADR+1        ;SAVE OFFENDING ADDRESS AT 0001
426
427   FFE7   47               MOV     B,A             ;SAVE EROR CODE FOR A MOMENT
428   FFE8   3E80             MVI     A,DISABL        ;DESELECT ALL DISKS
429   FFEA   D308             OUT     DSLCT
430   FFEC   78               MOV     A,B             ;RECOVER ERROR CODE
431
432                   ;HANG FOREVER, WRITING ERROR CODE (IN A) TO EVERY KNOWN PORT
433
434   FFED   D301     ERHANG: OUT     SIOTXD          ;WRITE ERROR CODE TO SIO
435   FFEF   D311             OUT     S2T0            ;WRITE ERROR CODE TO 2SIO
436   FFF1   D305             OUT     PIOTXD          ;WRITE ERROR CODE TO PIO
437   FFF3   D323             OUT     P4DB0           ;WRITE ERROR CODE TO 4PIO
438   FFF5   C3DA2C           JMP     ERHANG-OFFSET   ;HANG FOREVER
439
440                   ;---------------------------------------------------------------
441                   ; SUBROUTINE TO COMPARE DE    HL
442                   ; C SET IF HL>DE
443                   ;---------------------------------------------------------------
444   FFF8   7A       CMP16:  MOV     A,D             ;LOW BYTES EQUAL?
445   FFF9   BC               CMP     H
446   FFFA   C0               RNZ                     ;NO: RET WITH C CORRECT
447   FFFB   7B               MOV     A,E             ;HIGH BYTES EQUAL?
448   FFFC   BD               CMP     L
449   FFFD   C9               RET                     ;RETURN WITH RESULT IN C
450
451   FFFE            EOP:                            ;END OF PROGRAM CODE
452   FFFE   0000             DW      00H             ;FILLS THE EPROM OUT WITH 0
453
454                   ;---------------------------------------------------------------
455                   ;DISK BUFFER IN RAM AFTER RELOCATED LOADER
456                   ;---------------------------------------------------------------
457   2CEB                    ORG     2CEBH
458   2CEB            BUFFER: DS      132
459
460                   ;---------------------------------------------------------------
461                   ; AND FINALLY THE STACK, WHICH GROWS DOWNWARD
462                   ;---------------------------------------------------------------
463   2D6F                    DS      10              ;SPACE FOR STACK
464   2D79            STACK   EQU     $
4651
466 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
467+                                                      20:17  06/10/2018
468+                                                                                      PAGE 9
469
470
471
472
473                           END
474 NO PROGRAM ERRORS
4751
476 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
477+                                                      20:17  06/10/2018
478+                                                                                      PAGE 10
479
480
481
482                        SYMBOL TABLE
483
484  * 01
485
486  A      0007      B      0000      BADSE  FFD5      BUFFE  2CEB
487  C      0001      CHK00  FF4B      CMP16  FFF8      D      0002
488  DCTRL  0009      DDATA  000A      DISAB  0080      DMAAD  0000
489  DONE   FFCE      DSECT  0009      DSLCT  0008      DSTAT  0008
490  DWAIT  FF6F      E      0003      ENABL  0008      EOP    FFFE
491  ERHAN  FFED      H      0004      HCS    0040 *    HDLOA  0004
492  HDUNL  0008 *    INTDE  0020 *    INTEN  0010 *    L      0005
493  M      0006      MEMER  FFDE      MLUP   FF08      MOVEO  0002
494  MOVLU  FF8C      NXTRA  FF55      NXTSE  FF57      OFFSE  D313
495  P4CA0  0020 *    P4CB0  0022      P4DA0  0021 *    P4DB0  0023
496  PIOCT  0004 *    PIORX  0005 *    PIOST  0004 *    PIOTX  0005
497  PSW    0006      RCODE  FF13      RDDON  FFA3      RDSEC  FF59
498  RETRI  0010      RUNLO  2C00      S2C0   0010      S2C1   0012 *
499  S2R0   0011 *    S2R1   0013 *    S2S0   0010 *    S2S1   0012 *
500  S2T0   0011      S2T1   0013 *    SECDO  FF85      SECER  FFDB *
501  SECTR  0001 *    SEEK0  FF40      SENSE  00FF      SIO2R  0003
502  SIOCT  0000 *    SIORX  0001 *    SIOST  0000 *    SIOTX  0001
503  SP     0006      STACK  2D79      STEPI  0001      STEPO  0002
504  TRACK  0040      WAITE  FF2F      WAITH  FFC0      WRITE  0080 *
505  WSECT  FF63
506
507