; ; ; ;============================================================= ; - 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 ; ;