;MOVCPM.ASM BY DIGITAL RESEARCH ;DISASSEMBLED 3 DEC 84 RHP ;CONVERTED FOR DIGITAL RESEARCH 'MAC' ;MACROASSEMBLER 7 DEC 84 RHP ; ORG 00100H ; ; EQUATES ; WBOOT EQU 00000H BDOS EQU 00005H ;BDOS JUMP ENTRY POINT BDOSADR EQU 00006H ;ADDRESS OF BOTTOM OF BDOS FILNAM EQU 0005DH ;START OF FILE NAME IN FCB1+1 FCB2 EQU 0006DH ;START OF FCB 2 +1 STACK EQU 00800H CODEST EQU 00900H ;START OF CPM CODE (BOOT) SERNO EQU 01200H ;LOCATION OF SER# IN THE CCP CPMLG EQU 01700H ;LENGTH OF CPM CODE PRSTRG EQU 009H ; ;PROGRAM START ; START: JMP BEGIN ;GO TO REAL START OF PROGRAM ; ;COPYRIGHT NOTICE ; DB 'COPYRIGHT (C) DIGITAL RESEARCH, 1979 ' ; BEGIN: LXI SP,STACK ;SET STACK AT 800H LXI D,FILNAM ;POINT AT FILE NAME LDAX D ;GET CHARACTER CPI 020H ;IS IT A SPACE? JZ RAMCHK CPI 03FH ;IS IT A ? (WILDCARD) JZ RAMCHK ; ;CHECK FOR 2 ASCII NUMBERS AND CONVERT TO HEX ; LXI H,00000H ASCHEX: LDAX D ;GET CHARACTER INX D ;BUMP TO NEXT CHAR CPI 020H ;IS IT A SPACE? JZ BADMM ORA A JZ BADMM SBI 030H ;NUMBER 0-9? CPI 00AH JNC PMSG1 ;PRINT BAD MEMORY SIZE ; ;MULTIPLY HL BY 10 ; DAD H ;X2 PUSH H ;SAVE X2 DAD H ;X4 DAD H ;X8 POP B ;GET THE X2 DAD B ;X2+X8=X10 MOV C,A ;SAVE CHAR IN C MVI B,000H ;CLEAR B TO ZERO DAD B ;UPDATE HEX NO. JMP ASCHEX ;LOOP TIL DONE ; BADMM: MOV A,H ORA A JNZ PMSG1 ;PRINT BAD MEMORY SIZE MOV A,L CPI 010H JC PMSG1 ;PRINT BAD MEMORY SIZE MVI L,000H MOV H,A DAD H DAD H JMP SVHIRM ; PMSG1: LXI D,MESSG1 ;INVALID MEMORY SIZE CALL PRINT JMP WBOOT ; MESSG1: DB 00DH, 00AH DB 'INVALID MEMORY SIZE$' ; RAMCHK: LXI H,00000H RAMLUP: INR H JZ HIRAM ; ;SCAN MEMORY TO CHECK FOR RAM ; MOV A,M ;GET A CHARACTER CMA ;INVERT IT MOV M,A ;PUT IT BACK CMP M ;SET Z FLAG IF = ELSE NOT RAM CMA ;RIGHT SIDE UP MOV M,A ;PUT IT BACK THE WAY IT WAS JZ RAMLUP ;IF RAM, KEEP LOOKING ; ;IF HERE, THEN HL=END OF RAM ; HIRAM: MOV A,H ;ROUND OFF HI RAM ADDR ANI 0FCH ; TO NEAREST K MOV H,A ; SVHIRM: PUSH H ;SAVE HI RAM ADDR ON STACK ; LHLD BDOSADR ;MOVE BDOS ADDR TO STOR1 SHLD STORE1 POP H ;GET HI RAM ADDR AGAIN PUSH H ;BUT LEAVE IT ON THE STACK TOO MOV A,H ;GET HI BYTE OF RAM ADDR RRC ;CHANGE TO UNITS OF K RRC ANI 03FH ;<64K? JNZ SETMSZ ;SMALL ENOUGH MVI A,040H ;ELSE SET TO 64K SETMSZ: MOV B,A ;SAVE SIZE IN B LXI H,SCPMSZ ;POINT TO CPM SZ MSG MVI A,030H ;FILL WITH 00 ASCII MOV M,A ;STORE 0 INX H ;NEXT LOCATION MOV M,A ;STORE 0 SIZLUP: LXI H,SECCHR ;POINT TO SECOND CHAR INR M ;INCREMENT MEMORY MOV A,M ;READ THE CHAR CPI 03AH ;ASCII 9 OR LESS? JC SZLP1 MVI M,030H ;SET TO ASCII 0 DCX H ;POINT TO HI CHAR INR M ;INCREMENT MEMORY SZLP1: DCR B ;HAS MEM SIZE IN K JNZ SIZLUP LXI D,MESSG4 ;POINT TO CONSTRUCTING CPM MSG CALL PRINT ;PRINT CONSTRUCTING CPM MSG ; LXI H,STACK+1 ;POINT TO BOTTOM OF STACK ; MOV C,M ;GET MEMORY SIZE IN BC INX H MOV B,M ; PUSH B ;PUT MEMORY SIZE ON TOP OF STACK ; LXI H,CODEST ;POINT TO START OF CODE TO MOVE UPDCD: LXI D,SMALLK MOV A,B ;IS BC = 0? ORA C ;WHERE BC = MEMORY SIZE JZ WHAT2 ;IF SO GOTO WHAT2 DCX B ;DECREMENT MEM PTR PUSH B ;SAVE MEMORY POINTER MVI C,00FH PUSH H ;SAVE CODE POINTER NOT16: LDAX D CMP M JNZ INCOD INX D INX H DCR C ;COUNT 16 JZ WHAT1 JMP NOT16 ; DB 001H ;DUMMY BYTE ; SDELY: XRA A DELUP: DCR A ;SMALL DELAY HERE JNZ DELUP ; LXI H,076F3H ;LOAD STORE1 WITH F376H SHLD STORE1 ; LXI H,CHCALL ;CHANGE INSTRUCTION TO CALL MVI M,0CDH ; LXI D,ADRCH+1 ;NOW POINTS TO CHSER LXI H,00005H ;POINT TO SYNCH ERROR MSG DAD D ;NEW ADDRESS XCHG ;PUT MSG PTR IN DE JMP PRINT ;PRINT SYNCH ERROR MSG ; INCOD: POP H INX H POP B JMP UPDCD ; WHAT1: POP H POP B DCX H LXI D,SECCHR LDAX D MOV M,A DCX H DCX D LDAX D MOV M,A WHAT2: LXI B,STORE1 LDAX B CPI 006H MVI A,000H JNZ CHADR STAX B POP B POP H PUSH B MOV A,B ADI 003H MOV B,A MOV A,L SUB C MOV L,A MOV A,H SBB B MOV H,A SHLD STORE2 XCHG LXI H,CODEST POP B PUSH B LDA FCB2 CPI 020H JZ SHOVE DAD B JMP MOVDUN ; CHADR: LXI H,SDELY SHLD HANG+1 JMP HANG ; SHOVE: MOV A,B ;CHECK BYTES TO MOVE COUNT ORA C ;THROUGH YET? JZ MOVDUN ;DONE MOVING DCX B ;COUNT-1 MOV A,M ;GET BYTE TO MOVE STAX D ;POINT TO DESTINATION INX D ;NEXT DEST. INX H ;NEXT BYTE JMP SHOVE ;LOOP TIL DONE ; MOVDUN: POP B PUSH H LHLD STORE2 XCHG LXI H,START DAD D LDA FCB2 CPI 020H JZ RLCLP LXI D,CODEST RLCLP: MOV A,B ;CHECK BIT COUNTR ORA C ;RLOC DONE? ADRCH: JZ CHSER JMP MOREL ; MESSG2: DB 00DH, 00AH DB 'SYNCRONIZATION ERROR$' ; MOREL: DCX B ;DROP THE BYTE COUNT MOV A,E ;IS DE ADDR MOD 8 BYTES? ANI 007H ;IF SO NEED NEXT BIT MAP BYTE JNZ SAMBYT ;STILL ON SAM BIT MAP BYTE ; ;GET NEXT MAP BYTE VIA POINTER ON STACK ; XTHL ;SAVE HL & GET MAP PTR MOV A,M ;GET MAP BYTE INX H ;POINT TO NEXT BYTE XTHL ;REPLACE POINTER ON STACK MOV L,A ;MAP BYTE TO HOLDINO REG. ; SAMBYT: MOV A,L ;GET CURRENT BIT MAP BYTE RAL ;SHIFT ONE BIT MOV L,A ;SAVE FOR NEXT PASS JNC NOFFST ;0=NO OFFSET NEEDED LDAX D ;GET DEST BYTE ADD H ;ADD THE OFFSET STAX D ;PUT IT BACK JMP NOFFST ; ; NOFFST: INX D ;BUMP MOVED CODE BYTE COUNTER JMP RLCLP ;BACK FOR MORE BYTES ; ;MATCH SERIAL NO OF MOVCPM AND CCP ; CHSER: POP D ;CLEAN UP STACK LXI D,SERNO ;POINT TO SER NO IN CCP LHLD STORE1 ;GET LOCAL SER NO MVI C,006H ;CHECK 6 CHAR OF SERIAL NO. LOOP6: LDAX D ;GET CHAR OF SER NO CMP M ;COMPARE LOCAL SER NO JNZ CHADR ;NO MATCH CHANGE THE JUMP ADDR INX H ;NEXT CHAR LOC INX D ;NEXT CHAR CCP DCR C ;EXT CHAR COUNT JNZ LOOP6 ;IF C <> 0 THEN KEEP LOOPING ; ;HERE IMPLIES MATCHED SERIAL NUMBERS ; LDA FCB2 ;GET CHAR FROM FILE CONT BLK 2 CPI 020H ;IS IT A SPACE? JZ CBOOT ;YEAH, GOTO CBOOT MVI B,080H ;SET COUNTER LXI H,CODEST ;POINT TO CODE START ADDR MOVLUP: MOV A,M ;GET A CHAR OF CODE ORA A ;SET FLAGS JNZ BINDEC ;SOMETHING THERE INX H ;TRY NEXT ADDR DCR B ;COUNT DOWN JNZ MOVLUP ;STILL COUNTING, THEN LOOP XCHG LHLD STACK+1 ;LOAD HL WITH ADDR OF ? LXI B,0FF80H ;LOAD BC WITH 80FFH DAD B MOV B,H ;PUT HL IN BC MOV C,L LXI H,CODEST ;POINT TO START OF CODE MVBYT: MOV A,B ;CHK BYTE CNT ORA C ;ALL MOVED YET? JZ BINDEC DCX B ;DEC BYTES TO MOVE CNT LDAX D ;READ FROM DE MOV M,A ;PLACE IN HL INX D ;NEXT DE INX H ;NEXT HL JMP MVBYT ;LOOP TIL DONE ; DB 001H ;DUMMY BYTE ; HANG: JMP HANG ;OR JUMP A01FF ; BINDEC: LXI H,STACK+1 ;LOAD BC FROM TOP OF STACK ; MOV C,M ;LOAD BC FROM BOTTOM OF STACK INX H MOV B,M ; LXI H,CODEST ;POINT TO CODE START DAD B ;CALCULATE MEMORY SIZE MOV B,H ;UPDATE MSIZE IN K LXI H,SIZE1 ;POINT TO 1ST CHAR OF SIZE MVI A,030H ;LOAD ASCII 0 MOV M,A ;LOAD IT IN 1ST CHAR INX H ;POINT TO 2ND CHAR MOV M,A ;A ZERO THERE TOO NUMLUP: DCR B ;DECR MEMORY SIZE IN K JZ PTSIZ LXI H,SIZE2 ;POINT TO SECOND CHAR INR M ;INCR THE VALUE THERE MOV A,M ;GET THE VALUE CPI 03AH ;IS IT OVER 9? JC NUMLUP ;ELSE LOOP TO INCREASE MVI M,030H ;OR BACK TO 0 & BUMP 1ST# DCX H ;POINT TO 1ST INR M ;BUMP IT 10K JMP NUMLUP ;BACK TO 1K LOOP ; PTSIZ: LHLD SCPMSZ ;POINT TO CPM SIZE SHLD CPMSZ ;GET IT LXI D,MESSG3 ;POINT TO SYSGEN MSG CALL PRINT ;PRINT SYSGEN MESSAGE JMP WBOOT ; MESSG3: DB 00DH, 00AH DB 'READY FOR "SYSGEN" OR' DB 00DH, 00AH DB '"SAVE ' SIZE1: DB '0' SIZE2: DB '0' DB ' CPM' CPMSZ: DB '00' DB '.COM"$' ; CBOOT: LXI D,CPMLG ;LOAD THE LENGTH OF CPM LHLD STORE2 ;GET THE LOCATION OF CPM DAD D ;CALC THE START OF BIOS PCHL ;JUMP TO COLD BOOT ; PRINT: MVI C,PRSTRG ;PREPARE TO PRINT A STRING CHCALL: JMP BDOS ; GO DO IT ; STORE1: NOP NOP ; STORE2: NOP NOP ; MESSG4: DB 00DH, 00AH DB 'CONSTRUCTING ' SCPMSZ: DB '0' SECCHR: DB '0' SMALLK: DB 'k' DB ' CP/M vers 2.2$' ; END ;Label cross reference ;WBOOT Z013D Z0191 X033D ;BDOS Z0212 X0377 ;BDOSADR Y01A6 ;FILNAM Z012F ;FCB2 Y024E Y027A Y02D4 ;START T0276 ;BEGIN START ;ASCHEX A015C ;BADMM A0144 A0148 ;PMSG1 A014F A0161 A0167 ;MESSG1 T0172 ;RAMCHK A0135 A013A ;RAMLUP A019E ;HIRAM A0195 ;SVHIRM A016F ;SETMSZ A01B3 ;SIZLUP A01D0 ;SZLP1 A01C8 ;UPDCD A021D ;NOT16 A01FB ;SDELY T025A ;DELUP A0201 ;INCOD A01F2 ;WHAT1 A01F8 ;WHAT2 A01E8 ;CHADR A0234 A02CB ;SHOVE A0253 A026D ;MOVDUN A0257 A0265 ;RLCLP A027F A02BD ;ADRCH+1 T020F ;MOREL A028A ;SAMBYT A02A8 ;NOFFST A02B3 A02B9 ;CHSER A0287 ;LOOP6 A02D1 ;MOVLUP A02E8 ;MVBYT A0302 ;HANG A0260 ;HANG+1 D025D ;BINDEC A02E3 A02FA ;NUMLUP A0327 A032E ;PTSIZ A031D ;MESSG3 T0337 ;SIZE1 T0314 ;SIZE2 T0320 ;CPMSZ D0334 ;CBOOT A02D9 ;PRINT A0175 A01D6 A0217 A033A ;CHCALL T020A ;STORE1 D01A9 D0207 T022C D02C4 ;STORE2 D0245 D0272 D0370 ;MESSG4 T01D3 ;SCPMSZ T01B9 D0331 ;SECCHR T01C1 T0223 ;SMALLK T01E3 ;STACK Z012C ;STACK+1 Z01D9 Y02EC Z0309 ;CODEST Z01E0 Z0249 Z0282 Z02DE ; Z02F5 Z030F ;SERNO Z02C1 ;CPMLG Z036D ;Z76F3 Z0204 ;ZFF80 Z02EF