CP/M RMAC ASSEM 1.1 #001 INITIAL PROGRAM LOADER AND GENERATOR V1.1 TITLE 'INITIAL PROGRAM LOADER AND GENERATOR V1.1' ; NAME ('IPLGEN') ; DATE 21-JUN-83 ; CONVERTED TO MAC/RMAC CODE 18 JULY 83 RHP ; MACLIB Z80 ; Z-80 CODING IS USED ; ; ASEG ; ; *** ASCII CONSTANTS *** ; 000D = CR EQU 0DH 000A = LF EQU 0AH 0007 = BELL EQU 07H 0024 = EOM EQU '$' 000A = RETRY EQU 10 0005 = BDOS EQU 0005H ; ; ; ; *** PORT ASSIGNMENTS *** ; 0050 = SCSI$BASE EQU 0050H ; SCSI INTERFACE BOARD BASE 0010 = QUAD$EIA EQU 0010H ; BASE PORT FOR QUAD. EIA BOARD 0014 = CRTSTATUS EQU QUAD$EIA+4 ; STATUS PORT FOR CONSOLE 0015 = CRTDATA EQU QUAD$EIA+5 ; DATA PORT FOR CONSOLE ; 0001 = TXRDY EQU 0001H ; TX. READY BIT IN 8251 USART 0002 = RXRDY EQU 0002H ; RX. READY BIT IN 8251 USART ; ; *** SCSI PORT ASSIGNMENTS *** ; ; * BIT,BYTE AND PORT ASSIGMENTS FOR * ; * SCSI HOST INTERFACE ADAPTOR * ; 0050 = DATAI EQU SCSI$BASE ; DATA IN REGISTER 0052 = DATAO EQU SCSI$BASE+2 ; DATA OUT REGISTER 0051 = BSTAT EQU SCSI$BASE+1 ; BUS STATUS 0050 = SELPORT EQU SCSI$BASE ; SELECT PORT ADR. 0051 = CLRINT EQU SCSI$BASE+1 ; CLR. INTRRUPT PORT 0053 = DMAPORT EQU SCSI$BASE+3 ; DMA ADDRESS PORT 0054 = CPARITY EQU SCSI$BASE+4 ; CLEAR PARITY PORT 0080 = BUSY EQU 80H ; CONTROLER BUSY BIT 0040 = CD EQU 40H ; COMMAND/DATA BIT 0020 = DIREC EQU 20H ; DIRECTON BIT 0010 = REQ EQU 10H ; REQUEST BIT 0008 = MSG EQU 08H ; END MESSAGE BIT 0004 = PERR EQU 04H ; PERR ERROR BIT 0002 = BDACK EQU 02H ; BOARD ACK. SIGNAL 0001 = LINT EQU 01H ; INTERUPTE BIT ; ; CSEG ; START: CP/M RMAC ASSEM 1.1 #002 INITIAL PROGRAM LOADER AND GENERATOR V1.1 0000 318E00 LXI SP,STACK ; SET UP THE STACK POINTER 0003 CDB200 CALL TXOUT 0006 0D0A DB CR,LF 0008 49504C4745 DB 'IPLGEN00 -- INITIAL PROGRAM BOOTER AND' 002E 2053595354 DB ' SYSTEM GENERATOR V1.1' 0044 0D0A0A DB CR,LF,LF 0047 464F522036 DB 'FOR 60K SYSTEMS',CR,LF,LF,LF 005A 4C294F4144 DB 'L)OAD OR M)AKE SYSTEM TRACK --->',EOM 007B CDC200 CALL CI ; GET ANSWER 007E FE4D CPI 'M' ; SEE IF MAKE SYSTEM 0080 CAC800 JZ MAKE$SYSTEM ; BRIF SO 0083 FE4C CPI 'L' ; SEE IF LOAD SYSTEM 0085 CA6D02 JZ LOAD$SYSTEM ; BRIF SO 0088 CDB200 CALL TXOUT 008B 0D0A0A DB CR,LF,LF 008E 4552524F52 DB 'ERROR: PLEASE TYPE "M" OR "L"' 00AB 0D0A0A24 DB CR,LF,LF,EOM 00AF C30000 JMP START ;* ;** ;* ;+ TXOUT: ;- 00B2 E3 XTHL ; HL @ DATA 00B3 7E MOV A,M ; A = DATA 00B4 23 INX H ; PUT BACK POINTER 00B5 E3 XTHL ; 00B6 FE24 CPI EOM ; END OF MESSAGE??? 00B8 C8 RZ ; RETURN IF SO 00B9 5F MOV E,A ; ELSE E = CHARACTER 00BA 0E02 MVI C,2 ; CONSOLE OUTPUT CODE 00BC CD0500 CALL BDOS ; DO THE BDOS STUFF 00BF C3B200 JMP TXOUT ; AND REPEAT ;* ;** ;* ;+ CI: ;- 00C2 0E01 MVI C,1 00C4 CD0500 CALL BDOS 00C7 C9 RET ;* ;** ;* ;+ MAKE$SYSTEM: ;- 00C8 CDB200 CALL TXOUT 00CB 0D0A0A DB CR,LF,LF 00CE 504C454153 DB 'PLEASE ENTER NAME OF GEN''ED CP/M SYSTEM --->',EOM 00FB 210000 LXI H,LINE$BUFFER ; HL @ LINE BUFFER 00FE 3650 MVI M,80 ; MAX. LINE SIZE = 80 CHARACTERS 0100 EB XCHG ; DE @ LINE BUFFER 0101 0E0A MVI C,10 ; READ CONSOLE BUFFER CP/M RMAC ASSEM 1.1 #003 INITIAL PROGRAM LOADER AND GENERATOR V1.1 0103 CD0500 CALL BDOS ; 0106 216800 LXI H,FCB ; CLEAR OUT FCB 0109 116900 LXI D,FCB+1 ; 010C 012100 LXI B,33 ; 010F 3600 MVI M,00 ; PRIME THE ROUTINE LDIR ; PERFORM THE OPERATION 0111+EDB0 DB 0EDH,0B0H 0113 116900 LXI D,FCB+1 ; DE @ FILENAME 0116 210100 LXI H,LINE$BUFFER+1 ; HL @ FILENAME LINE 0119 4E MOV C,M ; C = SIZE OF LINE 011A 23 INX H ; POINT TO DATA PART OF LINE 011B 0608 MVI B,8 ; B = SIZE OF FILENAME MS010: 011D 7E MOV A,M ; A = DATA FROM LINE 011E FE2E CPI '.' ; IS IT A DOT?? 0120 CA3201 JZ MS020 ; BRIF SO 0123 12 STAX D ; ELSE STUFF TO FCB 0124 23 INX H ; 0125 13 INX D ; INCREMENT POINTERS DJNZ MS010 ; 0126+10F5 DB 10H,MS010-$-1 MS030: 0128 7E MOV A,M ; SKIP PAST '.' 0129 FE2E CPI '.' ; 012B CA3201 JZ MS020 ; BRIF FOUND 012E 23 INX H ; 012F C32801 JMP MS030 ; AND COUNTINE ;* MS020: 0132 23 INX H ; POINT PAST '.' 0133 78 MOV A,B ; SEE IF ALL FILENAME IS FILED 0134 B7 ORA A ; 0135 CA3E01 JZ MS040 ; BRIF SO MS050: 0138 3E20 MVI A,' ' ; PAD WITH SPACES 013A 12 STAX D ; 013B 13 INX D ; DJNZ MS050 ; 013C+10FA DB 10H,MS050-$-1 MS040: 013E 010300 LXI B,3 ; LDIR ; TRNSFR REST OF FILE NAME 0141+EDB0 DB 0EDH,0B0H 0143 116800 LXI D,FCB ; TRY TO OPEN 0146 0E0F MVI C,15 ; 0148 CD0500 CALL BDOS ; 014B FEFF CPI 0FFH ; CHECK FOR ERROR 014D C28601 JNZ MS060 ; BRIF OK 0150 CDB200 CALL TXOUT ; 0153 0D0A0A DB CR,LF,LF 0156 4552524F52 DB 'ERROR: CANNOT OPEN FILE ',EOM LDED LINE$BUFFER+1 016F+ED5B DB 0EDH,5BH 0171+0100 DW LINE$BUFFER+1 0173 210200 LXI H,LINE$BUFFER+2 0176 1600 MVI D,0 CP/M RMAC ASSEM 1.1 #004 INITIAL PROGRAM LOADER AND GENERATOR V1.1 0178 19 DAD D 0179 3624 MVI M,'$' 017B 110200 LXI D,LINE$BUFFER+2 017E 0E09 MVI C,9 0180 CD0500 CALL BDOS 0183 C3C800 JMP MAKE$SYSTEM ;* MS060: 0186 CDB200 CALL TXOUT 0189 0D0A DB CR,LF 018B 4C4F414449 DB 'LOADING FILE ...',EOM 019C 218E00 LXI H,BUFFER MS070: 019F EB XCHG ; DE @ DMA BUFFER 01A0 D5 PUSH D ; SAVE 01A1 0E1A MVI C,26 ; SET DMA 01A3 CD0500 CALL BDOS ; 01A6 116800 LXI D,FCB ; DE @ FCB 01A9 0E14 MVI C,20 ; GO READ A RECORD 01AB CD0500 CALL BDOS ; PERFORM THE READ 01AE B7 ORA A ; CHECK FOR ERRORS 01AF C2BA01 JNZ MS080 ; BRIF DONE 01B2 E1 POP H ; INCREMENT DMA 01B3 118000 LXI D,128 ; 01B6 19 DAD D ; 01B7 C39F01 JMP MS070 ; ;* MS080: 01BA CDB200 CALL TXOUT ; 01BD 0D0A4F4B0D DB CR,LF,'OK',CR,LF,EOM 01C4 CDF801 CALL GET$DRIVE ; GO GET THE PROPER DRIVE CODE 01C7 210E09 LXI H,BUFFER+0880H ; START = BUFFER 01CA 225400 SHLD BEGIN ; 01CD E1 POP H ; END = LAST DMA 01CE 225200 SHLD LAST ; 01D1 3E03 MVI A,03 ; COMMAND IS WRITE 01D3 326000 STA COMMAND ; 01D6 CDC602 CALL DOIO ; AND DO THE I/O 01D9 CDB200 CALL TXOUT 01DC 0D0A0A DB CR,LF,LF 01DF 4F50455241 DB 'OPERATION COMPLETED',CR,LF,EOM 01F5 C30000 JMP 0000 ;* ;** ;* ;+ GET$DRIVE: ;- 01F8 CDB200 CALL TXOUT 01FB 0D0A DB CR,LF 01FD 454E544552 DB 'ENTER 0 (DRIVE #0) OR 1 (DRIVE #1) -->',EOM 0224 CDC200 CALL CI 0227 FE30 CPI '0' 0229 CA3602 JZ GD99 022C FE31 CPI '1' 022E C24102 JNZ GD010 CP/M RMAC ASSEM 1.1 #005 INITIAL PROGRAM LOADER AND GENERATOR V1.1 0231 3E20 MVI A,20H 0233 325800 STA DRIVE GD99: 0236 CDB200 CALL TXOUT 0239 0D0A DB CR,LF 023B 4F4B0D0A24 DB 'OK',CR,LF,EOM 0240 C9 RET ;* GD010: 0241 CDB200 CALL TXOUT 0244 0D0A DB CR,LF 0246 4552524F52 DB 'ERROR: PLEASE ENTER EITHER 0 OR 1',CR,LF,EOM 026A C3F801 JMP GET$DRIVE ;* ;** ;* ;+ LOAD$SYSTEM: ;- 026D CDB200 CALL TXOUT 0270 0D0A0A DB CR,LF,LF 0273 4C4F414420 DB 'LOAD SYSTEM FUNCTION SELECTED',CR,LF,EOM 0293 CDF801 CALL GET$DRIVE 0296 2100D4 LXI H,0D400H 0299 225400 SHLD BEGIN 029C 2100F7 LXI H,0F700H 029F 225200 SHLD LAST 02A2 3E01 MVI A,1 02A4 326000 STA COMMAND 02A7 CDB200 CALL TXOUT 02AA 0D0A0A DB CR,LF,LF 02AD 4C4F414449 DB 'LOADING SYSTEM ...',EOM 02C0 CDC602 CALL DOIO 02C3 C300EA JMP 0EA00H ;* ;** ;* ;+ DOIO: ;- 02C6 216000 LXI H,COMMAND 02C9 3A5800 LDA DRIVE 02CC B6 ORA M 02CD 77 MOV M,A LDED BEGIN 02CE+ED5B DB 0EDH,5BH 02D0+5400 DW BEGIN SDED DMA 02D2+ED53 DB 0EDH,53H 02D4+5A00 DW DMA 02D6 3E01 MVI A,1 02D8 326200 STA COMMAND+2 02DB 326400 STA COMMAND+4 DOIO10: 02DE 216000 LXI H,COMMAND 02E1 CD3903 CALL DOCMD CP/M RMAC ASSEM 1.1 #006 INITIAL PROGRAM LOADER AND GENERATOR V1.1 JRZ DOIO20 02E4+283D DB 28H,DOIO20-$-1 02E6 CDB200 CALL TXOUT 02E9 0D0A0A DB CR,LF,LF 02EC 4552524F52 DB 'ERROR: DISK I/O ERROR DETECTED, OPERATION ABORTED' 031D 0D0A24 DB CR,LF,EOM 0320 C30000 JMP 0000 ;* DOIO20: 0323 216200 LXI H,COMMAND+2 0326 34 INR M 0327 215B00 LXI H,DMA+1 032A 34 INR M 032B 2A5A00 LHLD DMA LDED LAST 032E+ED5B DB 0EDH,5BH 0330+5200 DW LAST 0332 B7 ORA A DSBC DE 0333+ED52 DB 0EDH,DE*8+42H 0335 DADE02 JC DOIO10 0338 C9 RET ;* ;** ;* ; ;* START OF PROTOCAL HANDLING ROUTNES * ; ;+ DOCMD: ;-OP: ISSUE COMMAND TO SCSI HOST ADAPTOR ;-PP: HL @ COMMAND BYTES TO SEND ;- @ACTSEC & @RPNTR ARE VALID ;-RC: NO - ZERO : ERROR IN COMMAND (A = ERROR BITS) ;- ZERO : COMMAND WAS EXECUTED SUCCESSFULLY ;- 0339 225C00 SHLD LCMD@ ; SAVE COMMAND @ 033C 3E0A MVI A,RETRY ; GET RETRY COUNT 033E 325E00 STA TRYCNTR ; RESET COUNTER 0341 D354 OUT CPARITY ; RESET PARITY ERROR DCMD1: 0343 C5 PUSH B ; SAVE COUNTER 0344 CDA903 CALL ?PUTDMA ; SET DMA ADDRESS 0347 CDB903 CALL ?SELECT ; GO SELECT CONTROLER 034A C1 POP B ; RECOVER BC ; WAIT: ; ;* HERE WE MUST WAIT FOR EXECUTION * ; 034B DB51 IN BSTAT ; A <--- BUSS STATUS 034D E650 ANI CD+REQ ; CHECK FOR DATA JRNZ WAIT ; BRIF STILL DATA 034F+20FA DB 20H,WAIT-$-1 0351 DB50 IN DATAI ; A <-- COMPLETION STATUS 0353 F5 PUSH PSW ; SAVE ENDING STATUS CP/M RMAC ASSEM 1.1 #007 INITIAL PROGRAM LOADER AND GENERATOR V1.1 WAIT1: 0354 DB51 IN BSTAT ; WAIT FOR REQ. AND MSG. 0356 E618 ANI REQ+MSG ; JRNZ WAIT1 ; 0358+20FA DB 20H,WAIT1-$-1 035A DB50 IN DATAI ; GET BYTE OF ZERO 035C F1 POP PSW ; RECOVER STATUS 035D E61F ANI 00011111B ; MASK OUT ERRORS JRNZ WAIT4 ; BRIF NOT OK 035F+200D DB 20H,WAIT4-$-1 0361 DB51 IN BSTAT ; CHECK FOR PARITY 0363 E604 ANI PERR ; 0365 D351 OUT CLRINT ; CLEAR INTERRUPT 0367 3EFF MVI A,0FFH ; JRNZ WAIT4 ; BRIF ERROR 0369+2003 DB 20H,WAIT4-$-1 036B AF XRA A ; EXIT WITH ZERO 036C C9 RET ; AND EXIT ;* ;* WAIT7: 036D F1 POP PSW ; CLEAR OUT STACK WAIT4: BIT 2,A ; HARDWARE BUSY?? 036E+CB57 DB 0CBH,2*8+A+40H JRZ WAIT6 ; BRIF NOT 0370+2827 DB 28H,WAIT6-$-1 0372 CDB200 CALL TXOUT 0375 0D DB CR 0376 504C454153 DB 'PLEASE WAIT, DRIVE IS SPINING UP',EOM JR WAIT5 ; AND CONTINUE 0397+1806 DB 18H,WAIT5-$-1 ;* WAIT6: 0399 215E00 LXI H,TRYCNTR ; SEE IF RETRY UP 039C 35 DCR M ; JRZ WAIT2 ; BRIF RETRY IS UP 039D+2806 DB 28H,WAIT2-$-1 WAIT5: 039F 2A5C00 LHLD LCMD@ ; RECOVER LAST COMMAND 03A2 C34303 JMP DCMD1 ; AND TRY AGAIN ;* WAIT2: 03A5 D351 OUT CLRINT ; CLEAR INTERRUPT 03A7 B7 ORA A ; EXIT WITH NON-ZERO 03A8 C9 RET ; AND EXIT ;* ;** ;* ;+ ?PUTDMA: ;-OP: SEND DMA ADDRESS TO HOST ADAPTER ;-PP: RPNTR HAS DMA ADDRESS ;- 03A9 3A5600 LDA HIDMA ; SET HI-BYTE 03AC D353 OUT DMAPORT ; HIGH BYTE ALWAYS ZERO CP/M RMAC ASSEM 1.1 #008 INITIAL PROGRAM LOADER AND GENERATOR V1.1 LDED DMA ; DE @ DMA ADDRESS 03AE+ED5B DB 0EDH,5BH 03B0+5A00 DW DMA 03B2 7A MOV A,D 03B3 D353 OUT DMAPORT ; SEND BYTE 1 03B5 7B MOV A,E 03B6 D353 OUT DMAPORT ; SEND BYTE 2 03B8 C9 RET ; AND EXIT ;* ;** ;* ;+ ?SELECT: ;-OP: SELECT CONTROLER ;- 03B9 DB51 IN BSTAT ; IS CONTROLER BUSY?? 03BB E680 ANI BUSY ; WAIT FOR NOT BUSY JRZ ?SELECT ; WAIT IF SO 03BD+28FA DB 28H,?SELECT-$-1 SEL2: 03BF 3E01 MVI A,01H ; SELECT CONTROLER #1 03C1 D352 OUT DATAO ; 03C3 D350 OUT SELPORT ; AND SELECT CONTROLER SEL1: 03C5 DB51 IN BSTAT ; WAIT FOR REQ 03C7 E610 ANI REQ ; JRNZ SEL1 ; 03C9+20FA DB 20H,SEL1-$-1 03CB 57 MOV D,A ; D=0, MARK FIRST COMMAND ; ;* NOW FALL ON THRU TO OUTPUT COMMAND BYTES * ; ;+ ?OUTCMD: ;-OP: ISSUE COMMAND BYTES TO HOST ADAPTOR ;-PP: HL @ COMMAND BYTES ;- 03CC DB51 IN BSTAT ; GRAB BUSS STATUS 03CE 4F MOV C,A ; SAVE STATUS 03CF E640 ANI CD ; SEE IF DATA 03D1 C0 RNZ ; EXIT IF DATA 03D2 79 MOV A,C ; CHECK FOR DIREC 03D3 E620 ANI DIREC ; 03D5 C8 RZ ; EXIT IF INPUT 03D6 3E12 MVI A,REQ+BDACK ; BIT 0,D ; SEE IF FIRST CMD. 03D8+CB42 DB 0CBH,0*8+D+40H JRNZ ?OC5 ; BRIF NOT 03DA+2002 DB 20H,?OC5-$-1 03DC 3E10 MVI A,REQ ; ELSE JUST CHECK FOR REQ. ?OC5: 03DE A1 ANA C ; CHECK FOR READY JRNZ ?OUTCMD ; BRIF NOT (1.75/1.17) 03DF+20EB DB 20H,?OUTCMD-$-1 ?OC1: CP/M RMAC ASSEM 1.1 #009 INITIAL PROGRAM LOADER AND GENERATOR V1.1 03E1 7E MOV A,M ; GET COMMAND BYTE (1.75/1.17) 03E2 D352 OUT DATAO ; SEND TO CONTROLER (2.75/1.83) 03E4 23 INX H ; POINT NEXT (1.5/1.0) 03E5 1601 MVI D,1 ; MARK NOT FIRST COMMAND JR ?OUTCMD ; AND DO IT AGAIN! 03E7+18E3 DB 18H,?OUTCMD-$-1 ;* ;** ;* ; ; DSEG 0000 LINE$BUFFER: DS 80+2 0052 0000 LAST: DW 00 0054 0000 BEGIN: DW 00 0056 0000 HIDMA: DW 00 0058 0000 DRIVE: DW 00 005A 0000 DMA: DW 00 005C 0000 LCMD@: DW 00 005E 0000 TRYCNTR: DW 00 0060 0000000000COMMAND: DW 00,00,00,00 0068 FCB: DS 36 008C 6400 DW 100 STACK: BUFFER: 008E END