*************************************************************** * * * Module ID: CPMIO.LIB By: GLH/W6BSK * * Last Updated: 27 Apr 85 * * Function : Console IO Version : 1.00 * * Subroutines * * Entry: * * Exit : * * * *************************************************************** ; *** EQU Tables *** cr equ 0dh ; Carriage return lf equ 0ah ; Line feed ctrlz equ 1ah ; Operator interrupt rconf equ 01h ; Dump input from console wconf equ 02h ; Write A contents to console cstaf equ 0bh ; Check con: status drive equ 04h ; Current drive number rbuff equ 0ah ; Read a console line tbuff equ 80h ; Base page default buffer bdos equ 05h ; BDOS entry point versf equ 0ch ; CP/M version function vers3 equ 30h ; CP/M plus versf return org 100h ; TPA start address begin: lxi h,0 ; Clear HL before loading dad sp ; old stack pointer shld cpmsp ; and save it. lxi sp, stak ; Set new stack lda drive ; Get current drive sta drsave ; and save it mvi c,cstaf ; Get console status call bdos ora a jz begin1 ; No input, get some. mvi c,rconf ; Ignore any if present. begin1: call ccrlf call spmsg db ' Put your message here ',0 call ccrlf jmp start ; Go to main program entry point. ; Display message to console spmsg: xthl ; Load phony RET to HL regs xra a ; Clear flags etc. add m ; Move one message character inx h ; and point to next. xthl ; restore stack to return if done. rz ; Done if 00 in A. call conout ; If not done, display it Š jmp spmsg ; and continue. ; Do a CR/LF to console twocr: call ccrlf ccrlf: mvi a,cr call conout mvi a,lf conout: push b ; Display one character push d ; Push all regs push h mvi c,wconf ; Select the write function mov e,a ; and put in correct reg call bdos ; Do the function pop h pop d ; Pop all back. pop b ret ; Show spaces spaces: push b ; Enter with count in C mov c,a ; Save temp reg for count ora a ; Test for none jz space2 ; and quit if so. space1: mvi a, ' ' ; Load a space call conout dcr c jnz space1 ; Test countdown space2: pop b ; Clear stack ret ; Console operator interrupt opint: mvi c,cstaf ; Check for operator kill call bdos ora a ; Test if keypress rz ; Return if none. mvi c,rconf ; Was, check it. call bdos cpi ctrlz rnz done: lda drsav ; All done, check out. sta drive ; Restore current drive lhld cpmsp ; Get old stack pointer sphl ; load it, and go ret ; Input console message into buffer- cimsg: push b push d ; Push all regs push h lxi h,inbuf+1 ; Point to message start mvi m,0 ; and zero counter Š dcx h ; Back to length cell mvi m,80 ; and set max line xchg ; Input pointer to DE- mvi c,rbuff ; Set read buffer function call bdos ; and do it. lxi h,inbuf+1 ; Point to counter mov e,m ; and save it mvi d,0 ; Clear upper byte dad d ; and add length to start inx h ; add one more for end mvi m,0 ; and set 00 to end it. pop h pop d ; Restore them all pop b ret ; (Y)es or (N)o from console getyn: call spmsg ; Prompt for input db ' (Y/N)?: ',0 ; This is the prompt. call cimsg ; Read an input line call ccrlf ; and do a CR/LF lda inbuf+2 ; Use first character only. ani 5fh ; Make upper case only cpi 'Y' rz cpi 'N' jnz getyn xra a ret ; Message out to console comsg: mov a,m ora a ; Test for 00 rz call conout inx x jmp comsg ; Local storage area drsav db 0 ; Current drive storage cpmsp dw 0 ; Old stack pointer inbuf ds 83 ; Line input buffer org 200h stak: equ $ Š * CPMMAP program begins here * start: call ccrlf call ramtop ; Get top of RAM address call spmsg ; Report db ' RAM top is: ',0 call co6bhd ; in binary, hex and decimal call ccrlf mvi c,versf ; Only V1.x, 2.x allowed call bdos ; so filter out Plus. mov a,h ora a ; Tell us if unable to show jnz cpmerr mov a,l cpi vers3 ; Squeal also if Plus. jnc cpmerr lhld 1 ; Get CBIOS entry address dcx h dcx h ; which is 3 less than cold dcx h ; boot address. call spmsg db 'CBIOS is at: ',0 call co6bhd call ccrlf lhld 6 ; Get BDOS entry address from lxi d,0-6 ; location 6. Actual BDOS start dad d ; is 6 cells earlier. call spmsg db 'BDOS is at: ',0 call co6bhd call ccrlf lxi d,0-800hd ; CCP is 800 cells below BDOS. dad d call spmsg db 'CCP is at: ',0 call co6bhd call ccrlf jmp done cpmerr: call ccrlf call spmsg db 'Unable to map this version.',0 call ccrlf jmp done ramtop: lxi h,2000h ; Move to above program lxi d,1024 ; Test 1k byte increments mvi c,56 ; but stop after 64k. ramto1: mov b,m ; Move memory to B reg xra a ; Clear to write 00 mov m,a ; Write it cmp m ; Get there? mov m,b ; Restore original value jnz ramto3 ; Jump if failed write. Š dcr a ; Make FF in accum mov m,a ; now write 1's cmp m ; Written? mov m,b ; Write in original value jnz ramto3 ramto2: dad d dcr c ; Try next block jnz ramto1 ramto3: dcx h ; Back up one location ret ; and that is RAMtop.