; ; ; ;============================================================= ; - CP/M MULTI-TRACK SYSTEM GENERATION UTILITY = ; USED FOR NORMAL OR LARGE ( > 2 SYSTEM TRACKS) = ; SYSTEM GENERATION. MAY BE USED IN PLACE OF = ; SYSGEN. = ; DONALD E. KILLEN REV 1.00 19 NOV 80 = ;============================================================= ; ; MENU / PROMPT DRIVEN, SIMILAR TO SYSGEN, EXCEPT THAT SGEN ; WILL ASK USER FOR THE NUMBER OF SYSTEM TRACKS TO WRITE. ; ; NOTE: REMEMBER TO TELL XBOOTXX.HEX HOW MANY TOTAL SECTORS ; ARE IN THE SYSTEM, NOT INCLUDING THE BOOT ITSELF ; (WHICH IS 1 SECTOR LONG). ; ;============================================================ ; TITLE S G E N - REV 1.00 - 19 NOV 1980 .Z80 .XLIST INCLUDE CLIB INCLUDE MACROZ .LIST .Z80 ; NSECTS EQU 26D ; NO. SECTORS ON A TRACK.. DMASTART EQU 900H ; BEGINNING DMA ADDRESS. ; CSEG ; ; START: SWIN OLDSP,NEWSP ; SAVE ALL REG & SETUP OWN STACK. ; RESTART: PRINT PRINT 'ENTER NUMBER OF SYSTEM TRACKS 1-9 (CR=2): ' CALL GETCH ; GET KEYBOARD CHAR (ASCII IN -A-, ; AND BINARY IN -B- ) LD E,A ; TEMP STASH ASCII VALUE IN E. LD (NTRKS),A ; STASH ASCII # TRACKS STORE NTRKSB,B ; .. & BINARY. LD A,E ; RESTORE ASCII VALUE IN A. CP CR ; IF CAR. RET., IT IS 2 TRACK SYSTEM. JR Z,TWOTRK CP '2' ; CHECK IF 2 TRACKS. JR Z,TWOTRK CP '3' ; CHECK IF GE THREE TRACKS. JP M,NTRK ; LESS THAN THREE, GO ON PRINT CHARIN ; GET RESPONSE CP 'Y' ; IS IT UC 'Y' ? JR Z,YESY ; HOP IF YES. SUB 20H ; SEE IF IT MIGHT BE LC 'Y' CP 'Y' JP NZ,RESTART ; USER UNSURE, SO START OVER. YESY: JR NTRK ; GO DO IT. TWOTRK: PRINT JR GOTOIT ; GO DO IT... ; NTRK: PRINT PRINT NTRKS,1,A ; PRINT # TRACKS. PRINT ' TRACK SYSTEM **' ; GOTOIT: PRINT CALL GETCH ; GET SOURCE DRIVE OR CODE. LD E,A ; TEMP STASH ASCII DRIVE CODE. LD (SCA),A ; ASCII SOURCE DRIVE # TO MEM STORE SOURCE,B ; & BINARY VALUE. LD A,E ; & RESTORE ASCII IN A. CP CR ; IF CR, SYSTEM CODE IS IN MEM. JR Z,INMEM ; -- SO HOP TO IT. CALL CHKALPHA ; SEE IF IT IS AN ALPHA CHAR. JR NZ,GOTOIT ; & ASK AGAIN IF NOT. ; ; ASSUMING IT IS ON A DISK, GET IT IN MEMORY. ; PRINT PRINT SCA,1,A ; PRINT SOURCE DRIVE NAME PRINT ' , TYPE CR TO READ *' CALL GETCH ; GET USER RESPONSE. CP CR JP NZ,RESTART ; HEY, IF USER DOESN'T ; TYPE IN A CR, HE MUST WANT SOMETHING. ; CALL GETSYS ; GET SYSTEM TO MEMORY AT 900H. ; ; WAS IN MEMORY, OR ELSE IT IS AFTER CALL TO GETSYS: ; INMEM: PRINT WR1: PRINT CALL GETCH ; GET DEST DRIVE LETTER.. OR CR. LD E,A ; TEMP STASH ASCII VALUE LD (DCA),A ; PUT ASCII IN MEM STORE DEST,B ; & BINARY, LD A,E ; & RESTORE ASCII IN A. CP CR ; IS IT A CR ? JP Z,NOWRIT ; IF SO, REBOOT CP/M. CALL CHKALPHA ; SEE IF IT IS REALLY ALPHA. JR NZ,WR1 ; & ASK AGAIN IF NOT. ; ; HERE WE HAVE SYSTEM IN MEMORY - WRITE TO DESTINATION. ; WR2: PRINT PRINT DCA,1,A ; PRINT DEST. DRIVE LETTER. PRINT ', TYPE CR TO WRITE, TAB TO REBOOT **' PRINT ; CR,LF CALL GETCH ; GET THE DECISION CP TAB ; IS IT TAB KEY ? JR Z,REBOOT ; IF YES, HOP TO BOOT (WARM) CP CR ; CHECK - IS IT A CR ? JR NZ,WR2 ; NO ? .. MUST WANT TO CHANGE MIND. ; CALL PUTSYS ; WRITE SYSTEM ON DESTINATION. ; PRINT PRINT DCA,1,A ; PRINT DESTINATION DRIVE LTR. PRINT ', - CR TO DO AGAIN, TAB TO REBOOT: ' CALL GETCH ; GET DECISION CP CR ; IS IT A CR ? JP Z,WR1 ; YES, SEE IF HE WANTS SAME DRIVE. CP TAB ; IS IT A TAB ? JR Z,REBOOT ; DO WARM BOOT IF YES. JP RESTART ; , OTHERWISE START ALL OVER. ; ; TIME TO REBOOT CP/M HERE: ; NOWRIT: REBOOT: SWOT OLDSP,NEWSP ; RESTORE CP/M REG & STACK.. CALLBIOS DWBOOT ; & DO A WARM BOOT FUNCTION. ; ; SHOULD NEVER GET HERE. ; JP 0000 ; DISASTER - DO COLD BOOT. ; ;============================================================ ; SUBROUTINES: ; ; GETSYS: USES - READS SYSTEM TO MEMORY. ; PUTSYS USES - WRITES SYSTEM TO DISK. ; ; BOTH USE = BINARY # TRACKS. ; ; BOTH USE CBIOS AND / OR BDOS (2.2) FUNCTIONS. ; ;============================================================ ; ; GET SYSTEM FROM TRACK 0, SECTOR 1 THRU SECTOR 26 OF LAST ; TRACK - TO MEMORY STARTING AT 900H. ; GETSYS: PUSHALL CALL INITRW ; INITIALIZE TRK, SEC, DMAADR. LD HL,SOURCE LD C,(HL) CALLBIOS DSELDSK ; SELECT SOURCE DRIVE. ; GET1: LD HL,CURTRK LD C,(HL) CALLBIOS DSETTRK ; SELECT TRACK ; GET2: LD HL,CURSEC LD C,(HL) CALLBIOS DSETSEC ; SELECT SECTOR TO READ. ; LD BC,(DMAADR) CALLBIOS DSETDMA ; SET TRANSFER ADDRESS. ; CALLBIOS DREAD ; READ THE SECTOR. ; CALL NXS ; NEXT SECTOR UNLESS LAST, JP Z,NXRDTK ; .. HOP IF LAST ON THIS TRACK. JP GET2 ; OTHERWISE DO THE NEXT ONE. ; NXRDTK: CALL NXT ; GO TO NEXT TRACK UNLESS LAST. JP Z,DONE ; HOP IF LAST TRACK, JP GET1 ; OTHERWISE DO NEXT TRACK. ; DONE: POPALL ; & RESTORE REGISTERS.. RET ; ; BUMP THE DMA ADDRESS BY 128: ; BUMP: LD HL,(DMAADR) LD DE,128D ADD HL,DE LD (DMAADR),HL RET ; ; NXT -- GO TO NEXT TRACK UNLESS LAST, IN WHICH CASE RET Z. ; NXT: LD A,(CURTRK) ; GET CURRENT TRACK NO. LD E,A ; TEMP STASH... LD HL,NTRKSB LD A,(HL) ; GET NO. OF LAST TRACK TO DO. SUB 1 ; DOING NTRKSB - 1 (FIRST IS 0).. CP E ; DID WE JUST FINISH LAST ONE ? JR Z,DONET ; HOP IF YES. LD A,E ; GET CURRENT TRK BACK & INC A ; OTHERWISE INCR. TRACK NO. LD (CURTRK),A ; & PUT IT IN MEM. LD A,1 ; SET CURRENT SECTOR LD (CURSEC),A ; .. EQUALS 1. CALL BUMP ; & INCR. DMA ADDRESS BY 128. BIT 0,A ; FORCE Z FLAG OFF. DONET: RET ; & RETURN... ; ; NXS -- GO TO NEXT SECTOR UNLESS LAST, IN WHICH CASE RET Z. ; NXS: LD A,(CURSEC) ; GET CURRENT SECTOR NO. LD B,NSECTS ; GET NO. SECTORS PER TRACK.. CP B ; DID WE JUST DO THE LAST ONE ? JR Z,DONES ; HOP IF YES. INC A ; OTHERWISE INCR. SECTOR NO. LD (CURSEC),A ; & PUT IT IN MEM. CALL BUMP ; & INCR. DMA ADDRESS BY 128. LD B,0FFH BIT 0,B ; FORCE Z FLAG OFF. DONES: RET ; & RETURN. ; ; INITIALIZE PARAMETERS FOR ENTRY TO PUTSYS & GETSYS - ; INITRW: XOR A ; GET A ZERO LD (CURTRK),A ; SET CURRENT (FIRST) TRACK # LD A,1 LD (CURSEC),A ; SET FIRST SECTOR NO. LD BC,DMASTART ; GET STARTING DMA ADDRESS. LD (DMAADR),BC ; & PUT IT IN MEM. RET ; ; ; ;============================================================ ; ; PUTSYS - JUST THE INVERSE OF GETSYS. ; PUTSYS: PUSHALL ; SAVE REGISTERS. CALL INITRW ; INITIALIZE TRK, SEC, DMAADR LD HL,DEST LD C,(HL) CALLBIOS DSELDSK ; SELECT DESTINATION DRIVE. ; PUT1: LD HL,CURTRK ; LD C,(HL) ; SELECT TRACK CALLBIOS DSETTRK ; SELECT TRACK. ; PUT2: LD HL,CURSEC LD C,(HL) CALLBIOS DSETSEC ; SELECT SECTOR. ; LD BC,(DMAADR) CALLBIOS DSETDMA ; SET TRANSFER ADDRESS. ; CALLBIOS DWRITE ; WRITE THE SECTOR. ; CALL NXS ; DO NEXT SECTOR UNLESS LAST. JP Z,NXWRTK ; HOP IF IT WAS LAST ON TRACK. JP PUT2 ; OTHERWISE, DO NEXT SECTOR. ; NXWRTK: CALL NXT ; DO NEXT TRACK UNLESS LAST. JP Z,DONE ; HOP (RETURN) IF LAST, JP PUT1 ; OTHERWISE, WRITE NEXT TRACK. ; ; SUBROUTINE TO GET CHARACTER FROM KEYBOARD AND TEST FOR ; VALIDITY (A-O) OR CONTROL CHARACTER (CR, TAB). ; ; RETURNS ASCII CHARACTER IN -A- AND ; BINARY EQUIVALENT IN -B- ; IF NOT (UC OR LC) A-O, ; THEN RETURNS B = 0FFH. ; GETCH: CHARIN ; GET CHARACTER TO -A- LD E,A ; STASH IT IN CP CR ; IS IT A CR ? JR Z,CONT ; HOP IF YES. CP TAB ; IS IT TAB KEY ? JR Z,CONT ; HOP IF YES. CP 3AH ; IS IT NUMERIC ? JP M,NUMBR ; HOP IF YES. CP 60H ; IS IT LOWER-CASE ? JP M,UCASE ; HOP IF UPPER CASE. SUB 20H ; CONVERT LC TO UC. LD E,A ; MODIFY STASH. UCASE: CP 41H ; IS IT (LESS THAN) 'A' ? JP M,TRYAGN ; IF YES, ILLEGAL CHAR, DO OVER. CP 4FH ; IS IT (GREATER THAN) 'O' ? JP P,TRYAGN ; IF YES, ILLEGAL, DO OVER. SUB 41H ; IS UC A-O; MAKE IT BINARY. JR OVER1 NUMBR: SUB 30H ; CONVERT NUMERIC TO BINARY. OVER1: LD B,A ; PUT BINARY IN LD A,E ; & RESTORE ASCII TO -A- RET ; TRYAGN: PRINT JR GETCH ; TRY AGAIN... ; CONT: LD B,0FFH ; WE HAVE CONTROL CHAR, SET B = FFH. RET ; & RETURN WITH ASCII IN -A-. ; ; CHECK FOR VALID UC OR LC ALPHA CHAR. ; PRESERVE . SET Z IF VALID ALPHA, NZ IF NOT. ; CHKALPHA: LD E,A ; PRESERVE CP 41H ; IS IT UC 'A' OR ABOVE ? JP M,BADA ; NO (IT IS PROB. NUMERIC) CP 5BH ; IS IT UC & BETWEEN A & Z ? JP M,OK2 CP 61H ; IS IT LC 'A' OR ABOVE ? JP M,BADA ; BETWEEN UC 'Z' & LC 'A' - DON'T USE. CP 7BH ; IS IT ABOVE LC 'Z' ? JP M,OK2 ; IF NOT, USE IT. BADA: CP 0FFH ; FORCE NZ FLAG. CHKEX: LD A,E ; RESTORE VALUE TO A. RET ; & RETURN. ; OK2: CP A ; SET THE Z FLAG, JR CHKEX ; & GO RETURN.. ; ; ;========================================================== ; ; DATA SEGMENT: ; DSEG ; SOURCE: DS 1 ; SOURCE DRIVE, BINARY SCA: DS 1 ; SOURCE DRIVE, ASCII DEST: DS 1 ; DESTINATION DRIVE, BINARY DCA: DS 1 ; DESTINATION DRIVE, ASCII NTRKS: DS 1 ; NO. TRACKS, ASCII NTRKSB: DS 1 ; NO. TRACKS, BINARY CURTRK: DS 1 ; CURRENT TRACK CURSEC: DS 1 ; CURRENT SECTOR DMAADR: DS 2 ; DISK MEM. ADDRESS (TRANSFER) ; OLDSP: DS 2 ; CALLER'S STACK POINTER TEMP. NEWSP: DW STACK ; NEW STACK POINTER... TSPO: DS 2 ; TEMP OLD SP TSPN: DS 2 ; TEMP NEW SP ; DS 128D ; STACK STACK EQU $ ; END ; ;