Files
RomWBW/Source/CPM22/ccpb03.asm
b1ackmai1er 78f65522b7 Dev (#108)
* added hack to handle tunes

* quiet clean

* added chmod for execution

* suppress warnings

* Multi-boot fixes

* the windows build somehow thinks that these filesystems are cpm3.

* credit and primitive instructions

* Update sd.asm

Cosmetic fix.

* make compile shut up about conditionals

* Add bin2asm for linus and update build to process font files under linix

* fixed quoted double quote bug, added tests

* added tests

* added bin2asm for font file source creation

* Revert linux bin2asm font stuff

* added rule for font source generation

* build fonts

* added directory mapping cache.  if the same directory is being hit
as last run, we don't need to rebuild the map.  will likely break if
you are running more than one at a time, in that the cache will be
ineffective.  also, if the directory contents change, this will also break.

* removed strip.  breaks osx

* added directory tag so . isn't matched all over the place

* added real cache validation

* fixed build

* this file is copied from optdsk.lib or optcmd.lib

* install to ../HBIOS

* prerequisite verbosity

* diff soft failure and casefn speedup

* added lzsa

* added lzsa

* removed strip. breaks on osx

* added clobber

* added code to handle multiple platform rom builds with rom size override

* added align and 0x55 hex syntax

* default to hd64180

* added N8 capability

* added SBC_std.rom to default build

* added support for binary diff

* diff fixes

* clean, identical build.  font source generator emitted .align.  this does not match the windows build

* Upgrade NZCOM to latest

* Misc. Cleanup

* fixed expression parser bug : ~(1|2) returned 0xfe

* added diff build option

* Update Makefile

Makefile enhancement to better handle ncurses library from Bob Dunlop.

* Update sd.asm

Back out hack for uz80as now that Curt fixed it.

* Misc. Cleanup

* UNA Catchup

UNA support was lacking some of the more recent behavior changes.  This corrects most of it.

* Add github action for building RomWBW

* Bump Pre-release Version

* Update build.yml

Added "make clean" which will remove temporary files without removing final binary outputs.

* Update Makefile

Build all ROM variants by default in Linux/Mac build.

* Update Makefile

* Update Makefile

* Update Makefile

* Update Makefile

* Update Makefile

* Update Makefile

* Update Makefile

* Update Makefile

* Update Makefile

* Update for GitHub Build

Case issue in TASM includes showing up in GitHub build.  This should correct that.

* Added an gitignore files to exclude generated files

* Removed Tunes/clean.cmd and Tunes/ReadMe.txt - as make clean removes them

* Build.sh: marked as executable

chmod +x Build.sh

* Fix to HBIOS/build.sh

When adding files to rom disk, if files were missing, it would error out.

It appears the intent is to skip non-existing files.

Updated to log out correctly for missing files - and continue operation.

* Update Microsoft NASCOM BASIC.docx

Nascom manual, text version by Jan S (full name unknown)

* Fix issue with Apps/Tune not making

If dest directory does not exist, fails to make Apps

* Create ReadMe.txt

* Update Makefile

* Update Build.sh

* Make .gitignores for Tools/unix more specific

* cpmtools Update

Updated cpmtools applications (Windows only).  Removed hack in diskdefs that is no longer required.

* HBIOS Proxy Temp Stack Enhancement

Reuse the bounce buffer area as the temporary stack space required briefly in HBX_INVOKE when transitioning banks.  Increases size of temporary stack space to 64 bytes.

* Update ReadMe.txt

* HBIOS - clean up TMPSTK

* Update hbios.asm

Minor cosmetic changes.

* Build Process Updates

Minor udpates to build process to improve consistency between Windows and Mac/Linux builds.

* Update hbios.asm

Add improved interrupt protection to HBIOS PEEK, POKE, and BNKCPY functions.

* hbios - wrap hbx_bnkcpy

* hbios - adjust hbx_peek hbx_poke guards

* Update hbios.asm

Adjusted used of DI/EI for PEEK and POKE to regain a bit of INTSTK space.  Added code so that HB_INVBNK can be used as a flag indicating if HBIOS is active, $FF is inactive, anything else means active.

* Add HBIOS MuTex

* Initial Nascom basic ecb-vdu graphics

set and reset for 80x25b screen with 256 character mod

* Finalize Pre-release 34

Final support for FreeRTOS

* Update nascom.asm

Optimization, cleanup, tabs and white spaces

* IDE & PPIDE Cleanup

* Clean up

Make version include files common.

* Update Makefile

* Update Makefile

* Build Test

* Build Test

* Build Fixes

* Update nascom.asm

Cleanup

* Update nascom.asm

Optimization

* hbios - temp stack tweak

* Update hbios.asm

Comments on HBX_BUF usage.

* Update nascom.asm

Optimization

* Update nascom.asm

Setup ECB-VDU build option, remove debug code

* Update nascom.asm

Set default build. update initialization

* Update nascom.asm

Make CLS clear vdu screen

* Update nascom.asm

Fixup top screen line not showing

* Add SC131 Support

Also cleaned up some ReadMe files.

* HBIOS SCZ180 - remove mutex special files

* HBIOS SCZ180 - adjust mutex comment

* Misc. Cleanup

Includes some minor improvements to contents in some disk images.

* Delete FAT.COM

Changing case of FAT.COM extension to lowercase.

* Create FAT.com

Completing change of case in extension of FAT.com.

* Update Makefile

Remove ROM variants that just have the HBIOS MUTEX enabled.  Users can easily enable this in a custom build.

* Cleanup

Removed hack from Images Makefile.  Fixed use of DEFSERCFG in various places.

* GitHub CI Updates

Adds automation of build and release assets upon release.

* Prerelease 36

General cleanup

* Build Script Cleanups

* Config File Cleanups

* Update RomWBW Architecture

General refresh for v2.9.2

* Update vdu.asm

Removed a hack in VDU driver that has existed for 8 years.  :-)

* Fix CONSOLE Constant

Rename CIODEV_CONSOLE constant to CIO_CONSOLE because it is a unit code, not a device type code.

Retabify TastyBasic.

* Minor Bug Fixes

- Disk assignment edge case
- CP/M 3 accidental fall thru
- Cosmetic updates

* Update util.z80

* Documentation Cleanup

* Documentation Update

* Documentation Update

* Documentation Updates

* Documentation Updates

* Create Common.inc

* Documentation Updates

* Documentation Updates

* doc - a few random fixes

* Documentation Cleanup

* Fix IM 0 Build Error in ACIA

* Documentation Updates

* Documentation Cleanup

* Remove OSLDR

The OSLDR application was badly broken and almost impossible to fix with new expanded OS support.

* Bug Fixes

- Init RAM disk at boot under CP/M 3
- Fix ACR activation in TUNE

* FD Motor Timeout

- Made FDC motor timeout smaller and more consistent across different speed CPUs
- Added "boot" messaging to RTC

* Cleanup

* Cleanup

- Fix SuperZAP to work under NZCOM and ZPM3
- Finalize standard config files

* Minor Changes

- Slight change to ZAP configuration
- Added ZSDOS.ZRL to NZCOM image

* ZDE Upgrade

- Upgraded ZDE 1.6 -> 1.6a

* Config File Tuning

* Pre-release for Testing

* cfg - mutex consistent config language

* Bump to Version 3.0

* Update SD Card How-To

Thanks David!

* update ReadMe.md

Remove some odd `\`.

* Update ReadMe.txt

* Update ReadMe.md

* Update Generated Doc Files

* Improve XModem Startup

- Extended startup timeout for XM.COM so that it doesn't timeout so quickly while host is selecing a file to send.
- Updated SD Card How-To from David Reese.

* XModem Timing Refinements

* TMS Driver Z180 Improvements

- TMS driver udpated to insert Z180 I/O waitstates internally so other code can run at full speed.
- Updated How-To documents from David.
- Fixed TUNE app to properly restore Z180 I/O waitstates after manipulating them.

* CLRDIR and ZDE updates

- CLRDIR has been updated by Max Scane for CP/M 3 compatibility.
- A minor issue in the preconfigured ZDE VT100 terminal escape sequences was corrected.

* Fix Auto CRT Console Switch on CP/M 3

* Handle lack of RTC better

DSRTC driver now correctly returns an error if there is no RTC present.

* Minor RTC Updates

* Finalize v3.0.1

Cleanup release for v3.0

* New ROMLDR and INTRTC driver

- Refactored romldr.asm
- Added new periodic timer based RTC driver

* CP/M 3 Date Hack

- Hack to allow INTRTC to increment time without destroying the date

* Update romldr.asm

Work around minor Linux build inconsistency

* Update Apps for New Version

* Revert "Update Apps for New Version"

This reverts commit ad80432252.

* Revert "Update romldr.asm"

This reverts commit 4a9825cd57.

* Revert "CP/M 3 Date Hack"

This reverts commit 153b494e61.

* Revert "New ROMLDR and INTRTC driver"

This reverts commit d9bed4563e.

* Start v3.1 Development

* Update FDISK80.COM

Updated FDISK80 to allow reserving up to 256 slices.

* Update sd.asm

For Z180 CSIO, ensure that xmit is finished, before asserting CS for next transaction.

* Add RC2014 UART, Improve SD protocol fix

- RC2014 and related platforms will autodetect a UART at 0xA0 and 0xA8
- Ensure that CS fully brackets all SD I/O

* ROMLDR Improvements

.com files can now be started from CP/M and size of .com files has been reduced so they always fit.

* Update commit.yml

Run commit build in all branches

* Update commit.yml

Run commit build for master and dev branches

* Improved clock driver auto-detect/fallback

* SIO driver now CTC aware

The SIO driver can now use a CTC (if available) to provide much more flexible baud rate programming.

* CTC driver fine tuning

* Update xmdm125.asm

Fixed a small issue in core XM125 code that caused a file write error message to not be displayed when it should be.

* CF Card compatibility improvement

Older CF Cards did not reset IDE registers to defaults values when reset.  Implemented a work around.

* Update ACIA detection

ACIA should no longer be detected if there is also a UART module in the system.

* Handle CTC anomaly

Small update to accommodate CTC behavior that occurs when the CTC trigger is more than half the CTC clock.

* Update acia.asm

Updated ACIA detection to use primary ACIA port instead of phantom port.

* Update acia.asm

Fix bug in ACIA detection.

Thanks Alan!

* MacOS Build Improvement

Build script updated to improve compatibility with MacOS.

Credit to Fredrik Axtelius for this.

* HBIOS Makefile - use env vars for target

Allow build ROM targets to be restricted to just one platform thru use of ENV vars:

ROM_PLATFORM - if defined to a known platform, only this platform is build - defaults to std config
ROM_CONFIG - sets the desired platform config - defaults to std

if the above ENVs are not defined, builds all ROMs

* Added some more gitignores

* Whitespace changes (crlf)

* HBIOS: Force the assembly to fail for vdu drivers if function table count is not correct

* Whitespace: trailing whitespaces

* makefile: updated some make scripts to use  when calling subdir makefiles

* linux build: update to Build.sh fix for some platforms

The initialization of the Rom dat file used the pipe (|) operator to build an initial empty file.

But the pipe operator | may sometimes return a non-zero exit code for some linux platforms, if the
the streams are closed before dd has fully processed the stream.

This issue occured on a travis linux ubuntu image.

Solution was to change to redirection.

* Bump version

* Enhance CTC periodic timer

Add ability to use TIMER mode in CTC driver to generate priodic interrupts.

* HBIOS: Added support for sound drivers

New sound driver support with initial support for the SN76489 chip

New build configuration entry:
* SN76489ENABLE

Ports are currently locked in with:
* SN76489_PORT_LEFT       .EQU    $FC     ; PORTS FOR ACCESSING THE SN76489 CHIP (LEFT)
* SN76489_PORT_RIGHT      .EQU    $F8     ; PORTS FOR ACCESSING THE SN76489 CHIP (LEFT)

* Miscellaneous Cleanup

No functional changes.

Co-authored-by: curt mayer <curt@zen-room.org>
Co-authored-by: Wayne Warthen <wwarthen@gmail.com>
Co-authored-by: ed <linux@maidavale.org>
Co-authored-by: Dean Netherton <dnetherton@dius.com.au>
Co-authored-by: ed <ed@maidavale.org>
Co-authored-by: Phillip Stevens <phillip.stevens@gmail.com>
Co-authored-by: Dean Netherton <dean.netherton@gmail.com>
2020-04-24 06:17:22 +08:00

1265 lines
30 KiB
NASM

.title "Digital Research CCP, Version 2.2"
.page 49
MON .EQU 1 ;ADD THE CCP MON COMMAND
USRDSP .EQU 1 ;SHOW THE USER NUMBER
CHKU0B .EQU 0 ;CHECK FOR TRANSIENTS ON USER 0 TOO
ENDFIL .EQU 1 ;FILE FULL CCP SIZE
;
;**************************************************************
;*
;* C C P - C O N S O L E C O M M A N D P R O C E S S O R
;*
;**************************************************************
;*
IOBYTE: .EQU 3 ; I/O DEFINITION BYTE.
TDRIVE: .EQU 4 ; CURRENT DRIVE NAME AND USER NUMBER.
ENTRY: .EQU 5 ; ENTRY POINT FOR THE CP/M BDOS.
TFCB: .EQU 5CH ; DEFAULT FILE CONTROL BLOCK.
TBUFF: .EQU 80H ; I/O BUFFER AND COMMAND LINE STORAGE.
TBASE: .EQU 100H ; TRANSIANT PROGRAM STORAGE AREA.
;
; SET CONTROL CHARACTER .EQUATES.
;
CNTRLC: .EQU 03H ; CONTROL-C
CNTRLE: .EQU 05H ; CONTROL-E
BS: .EQU 08H ; BACKSPACE
TAB: .EQU 09H ; TAB
LF: .EQU 0AH ; LINE FEED
FF: .EQU 0CH ; FORM FEED
CR: .EQU 0DH ; CARRIAGE RETURN
CNTRLP: .EQU 10H ; CONTROL-P
CNTRLR: .EQU 12H ; CONTROL-R
CNTRLS: .EQU 13H ; CONTROL-S
CNTRLU: .EQU 15H ; CONTROL-U
CNTRLX: .EQU 18H ; CONTROL-X
CNTRLZ: .EQU 1AH ; CONTROL-Z (END-OF-FILE MARK)
DEL: .EQU 7FH ; RUBOUT
;
; SET ORIGIN FOR CP/M
;
NK .EQU 59 ;SYSTEM SIZE
BASE .EQU (NK*1024)-5000H
CCPO .EQU BASE+3400H ;CCP ORIGIN
BDOSO .EQU BASE+3C00H ;BDOS ORIGIN
BIOSO .EQU BASE+4A00H ;BIOS ORIGIN
.ORG CCPO
;
CBASE: JP COMMAND ; EXECUTE COMMAND PROCESSOR (CCP).
JP CLEARBUF ; ENTRY TO EMPTY INPUT BUFFER BEFORE STARTING CCP.
;
; STANDARD CP/M CCP INPUT BUFFER. FORMAT IS (MAX LENGTH),
; (ACTUAL LENGTH), (CHAR #1), (CHAR #2), (CHAR #3), ETC.
;
INBUFF: .DB 127 ; LENGTH OF INPUT BUFFER.
; N8VEM - if add any text after this point, change .DB 0 below to length
; and put a 0 after the text, and delete the same number of zeros after the dig
; so that inpoint ends up at the same spot
; INBUFF+1 is cleared on the next warm boot, so only runs once.
.DB 0 ;CURRENT LENGTH OF CONTENTS.
; .DB 17 ; Autoboot length of string
; .DB "SUPERSUB AUTOEXEC"
; .DB 0 ; zero at end
.DB "COPYRIGHT"
.DB " 1979 (C) BY "
.DB "DIGITAL RESEARCH "
.FILL ((INBUFF + 128) - $),055H
INPOINT:.DW INBUFF+2 ; INPUT LINE POINTER
NAMEPNT:.DW 0 ; INPUT LINE POINTER USED FOR ERROR MESSAGE. POINTS TO
; ;START OF NAME IN ERROR.
;
; ROUTINE TO PRINT (A) ON THE CONSOLE. ALL REGISTERS USED.
;
PRINT: LD E,A ; SETUP BDOS CALL.
LD C,2
JP ENTRY
;
; ROUTINE TO PRINT (A) ON THE CONSOLE AND TO SAVE (BC).
;
PRINTB: PUSH BC
CALL PRINT
POP BC
RET
;
; ROUTINE TO SEND A CARRIAGE RETURN, LINE FEED COMBINATION
; TO THE CONSOLE.
;
CRLF: LD A,CR
CALL PRINTB
LD A,LF
JP PRINTB
;
; ROUTINE TO SEND ONE SPACE TO THE CONSOLE AND SAVE (BC).
;
SPACE: LD A,' '
JP PRINTB
;
; ROUTINE TO PRINT CHARACTER STRING POINTED TO BE (BC) ON THE
; CONSOLE. IT MUST TERMINATE WITH A NULL BYTE.
;
PLINE: PUSH BC
CALL CRLF
POP HL
PLINE2: LD A,(HL)
OR A
RET Z
INC HL
PUSH HL
CALL PRINT
POP HL
JP PLINE2
;
; ROUTINE TO RESET THE DISK SYSTEM.
;
RESDSK: LD C,13
JP ENTRY
;
; ROUTINE TO SELECT DISK (A).
;
DSKSEL: LD E,A
LD C,14
JP ENTRY
;
; ROUTINE TO CALL BDOS AND SAVE THE RETURN CODE. THE ZERO
; FLAG IS SET ON A RETURN OF 0FFH.
;
ENTRY1: CALL ENTRY
LD (RTNCODE),A ; SAVE RETURN CODE.
INC A ; SET ZERO IF 0FFH RETURNED.
RET
;
; ROUTINE TO OPEN A FILE. (DE) MUST POINT TO THE FCB.
;
OPEN: LD C,15
JP ENTRY1
;
; ROUTINE TO OPEN FILE AT (FCB).
;
OPENFCB:XOR A ; CLEAR THE RECORD NUMBER BYTE AT FCB+32
LD (FCB+32),A
LD DE,FCB
JP OPEN
;
; ROUTINE TO CLOSE A FILE. (DE) POINTS TO FCB.
;
CLOSE: LD C,16
JP ENTRY1
;
; ROUTINE TO SEARCH FOR THE FIRST FILE WITH AMBIGUEOUS NAME
; (DE).
;
SRCHFST:LD C,17
JP ENTRY1
;
; SEARCH FOR THE NEXT AMBIGEOUS FILE NAME.
;
SRCHNXT:LD C,18
JP ENTRY1
;
; SEARCH FOR FILE AT (FCB).
;
SRCHFCB:LD DE,FCB
JP SRCHFST
;
; ROUTINE TO DELETE A FILE POINTED TO BY (DE).
;
DELETE: LD C,19
JP ENTRY
;
; ROUTINE TO CALL THE BDOS AND SET THE ZERO FLAG IF A ZERO
; STATUS IS RETURNED.
;
ENTRY2: CALL ENTRY
OR A ; SET ZERO FLAG IF APPROPRIATE.
RET
;
; ROUTINE TO READ THE NEXT RECORD FROM A S.EQUENTIAL FILE.
; (DE) POINTS TO THE FCB.
;
RDREC: LD C,20
JP ENTRY2
;
; ROUTINE TO READ FILE AT (FCB).
;
READFCB:LD DE,FCB
JP RDREC
;
; ROUTINE TO WRITE THE NEXT RECORD OF A S.EQUENTIAL FILE.
; (DE) POINTS TO THE FCB.
;
WRTREC: LD C,21
JP ENTRY2
;
; ROUTINE TO CREATE THE FILE POINTED TO BY (DE).
;
CREATE: LD C,22
JP ENTRY1
;
; ROUTINE TO RENAME THE FILE POINTED TO BY (DE). NOTE THAT
; THE NEW NAME STARTS AT (DE+16).
;
RENAM: LD C,23
JP ENTRY
;
; GET THE CURRENT USER CODE.
;
GETUSR: LD E,0FFH
;
; ROUTNE TO GET OR SET THE CURRENT USER CODE.
; IF (E) IS FF THEN THIS IS A GET, ELSE IT IS A SET.
;
GETSETUC:
LD C,32
JP ENTRY
;
; ROUTINE TO SET THE CURRENT DRIVE BYTE AT (TDRIVE).
;
SETCDRV:CALL GETUSR ; GET USER NUMBER
ADD A,A ; AND SHIFT INTO THE UPPER 4 BITS.
ADD A,A
ADD A,A
ADD A,A
LD HL,CDRIVE ; NOW ADD IN THE CURRENT DRIVE NUMBER.
OR (HL)
LD (TDRIVE),A ; AND SAVE.
RET
;
; MOVE CURRENTLY ACTIVE DRIVE DOWN TO (TDRIVE).
;
MOVECD: LD A,(CDRIVE)
LD (TDRIVE),A
RET
;
; ROUTINE TO CONVERT (A) INTO UPPER CASE ASCII. ONLY LETTERS
; ARE AFFECTED.
;
UPPER: CP 'A' ; CHECK FOR LETTERS IN THE RANGE OF 'A' TO 'Z'.
RET C
CP '{'
RET NC
AND 5FH ; CONVERT IT IF FOUND.
RET
;
; ROUTINE TO GET A LINE OF INPUT. WE MUST CHECK TO SEE IF THE
; USER IS IN (BATCH) MODE. IF SO, THEN READ THE INPUT FROM FILE
; ($$$.SUB). AT THE END, RESET TO CONSOLE INPUT.
;
GETINP: LD A,(BATCH) ; IF =0, THEN USE CONSOLE INPUT.
OR A
JP Z,GETINP1
;
; USE THE SUBMIT FILE ($$$.SUB) WHICH IS PREPARED BY A
; SUBMIT RUN. IT MUST BE ON DRIVE (A) AND IT WILL BE DELETED
; IF AND ERROR OCCURES (LIKE EOF).
;
LD A,(CDRIVE) ; SELECT DRIVE 0 IF NEED BE.
OR A
LD A,0 ; ALWAYS USE DRIVE A FOR SUBMIT.
CALL NZ,DSKSEL ; SELECT IT IF REQUIRED.
LD DE,BATCHFCB
CALL OPEN ; LOOK FOR IT.
JP Z,GETINP1 ; IF NOT THERE, USE NORMAL INPUT.
LD A,(BATCHFCB+15) ; GET LAST RECORD NUMBER+1.
DEC A
LD (BATCHFCB+32),A
LD DE,BATCHFCB
CALL RDREC ; READ LAST RECORD.
JP NZ,GETINP1 ; QUIT ON END OF FILE.
;
; MOVE THIS RECORD INTO INPUT BUFFER.
;
LD DE,INBUFF+1
LD HL,TBUFF ; DATA WAS READ INTO BUFFER HERE.
LD B,128 ; ALL 128 CHARACTERS MAY BE USED.
CALL HL2DE ; (HL) TO (DE), (B) BYTES.
LD HL,BATCHFCB+14
LD (HL),0 ; ZERO OUT THE 'S2' BYTE.
INC HL ; AND DECREMENT THE RECORD COUNT.
DEC (HL)
LD DE,BATCHFCB ; CLOSE THE BATCH FILE NOW.
CALL CLOSE
JP Z,GETINP1 ; QUIT ON AN ERROR.
LD A,(CDRIVE) ; RE-SELECT PREVIOUS DRIVE IF NEED BE.
OR A
CALL NZ,DSKSEL ; DON'T DO NEEDLESS SELECTS.
;
; PRINT LINE JUST READ ON CONSOLE.
;
LD HL,INBUFF+2
CALL PLINE2
CALL CHKCON ; CHECK CONSOLE, QUIT ON A KEY.
JP Z,GETINP2 ; JUMP IF NO KEY IS PRESSED.
;
; TERMINATE THE SUBMIT JOB ON ANY KEYBOARD INPUT. DELETE THIS
; FILE SUCH THAT IT IS NOT RE-STARTED AND JUMP TO NORMAL KEYBOARD
; INPUT SECTION.
;
CALL DELBATCH ; DELETE THE BATCH FILE.
JP CMMND1 ; AND RESTART COMMAND INPUT.
;
; GET HERE FOR NORMAL KEYBOARD INPUT. DELETE THE SUBMIT FILE
; INCASE THERE WAS ONE.
;
GETINP1:CALL DELBATCH ; DELETE FILE ($$$.SUB).
CALL SETCDRV ; RESET ACTIVE DISK.
LD C,10 ; GET LINE FROM CONSOLE DEVICE.
LD DE,INBUFF
CALL ENTRY
CALL MOVECD ; RESET CURRENT DRIVE (AGAIN).
;
; CONVERT INPUT LINE TO UPPER CASE.
;
GETINP2:LD HL,INBUFF+1
LD B,(HL) ; (B)=CHARACTER COUNTER.
GETINP3:INC HL
LD A,B ; END OF THE LINE?
OR A
JP Z,GETINP4
LD A,(HL) ; CONVERT TO UPPER CASE.
CALL UPPER
LD (HL),A
DEC B ; ADJUST CHARACTER COUNT.
JP GETINP3
GETINP4:LD (HL),A ; ADD TRAILING NULL.
LD HL,INBUFF+2
LD (INPOINT),HL ; RESET INPUT LINE POINTER.
RET
;
; ROUTINE TO CHECK THE CONSOLE FOR A KEY PRESSED. THE ZERO
; FLAG IS SET IS NONE, ELSE THE CHARACTER IS RETURNED IN (A).
;
CHKCON: LD C,11 ; CHECK CONSOLE.
CALL ENTRY
OR A
RET Z ; RETURN IF NOTHING.
LD C,1 ; ELSE GET CHARACTER.
CALL ENTRY
OR A ; CLEAR ZERO FLAG AND RETURN.
RET
;
; ROUTINE TO GET THE CURRENTLY ACTIVE DRIVE NUMBER.
;
GETDSK: LD C,25
JP ENTRY
;
; SET THE STABDARD DMA ADDRESS.
;
STDDMA: LD DE,TBUFF
;
; ROUTINE TO SET THE DMA ADDRESS TO (DE).
;
DMASET: LD C,26
JP ENTRY
;
; DELETE THE BATCH FILE CREATED BY SUBMIT.
;
DELBATCH:
LD HL,BATCH ; IS BATCH ACTIVE?
LD A,(HL)
OR A
RET Z
LD (HL),0 ; YES, DE-ACTIVATE IT.
XOR A
CALL DSKSEL ; SELECT DRIVE 0 FOR SURE.
LD DE,BATCHFCB ; AND DELETE THIS FILE.
CALL DELETE
LD A,(CDRIVE) ; RESET CURRENT DRIVE.
JP DSKSEL
;
; PRINT BACK FILE NAME WITH A '?' TO INDICATE A SYNTAX ERROR.
;
SYNERR: CALL CRLF ; END CURRENT LINE.
LD HL,(NAMEPNT) ; THIS POINTS TO NAME IN ERROR.
SYNERR1:LD A,(HL) ; PRINT IT UNTIL A SPACE OR NULL IS FOUND.
CP ' '
JP Z,SYNERR2
OR A
JP Z,SYNERR2
PUSH HL
CALL PRINT
POP HL
INC HL
JP SYNERR1
SYNERR2:LD A,'?' ; ADD TRAILING '?'.
CALL PRINT
CALL CRLF
CALL DELBATCH ; DELETE ANY BATCH FILE.
JP CMMND1 ; AND RESTART FROM CONSOLE INPUT.
;
; CHECK CHARACTER AT (DE) FOR LEGAL COMMAND INPUT. NOTE THAT THE
; ZERO FLAG IS SET IF THE CHARACTER IS A DELIMITER.
;
CHECK: LD A,(DE)
OR A
RET Z
CP ' ' ; CONTROL CHARACTERS ARE NOT LEGAL HERE.
JP C,SYNERR
RET Z ; CHECK FOR VALID DELIMITER.
CP '='
RET Z
CP '_'
RET Z
CP '.'
RET Z
CP ':'
RET Z
CP $3B
RET Z
CP '<'
RET Z
CP '>'
RET Z
RET
;
; GET THE NEXT NON-BLANK CHARACTER FROM (DE).
;
NONBLANK:
LD A,(DE)
OR A ; STRING ENDS WITH A NULL.
RET Z
CP ' '
RET NZ
INC DE
JP NONBLANK
;
; ADD (HL)=(HL)+(A)
;
ADDHL: ADD A,L
LD L,A
RET NC ; TAKE CARE OF ANY CARRY.
INC H
RET
;
; CONVERT THE FIRST NAME IN (FCB).
;
CONVFST:LD A,0
;
; FORMAT A FILE NAME (CONVERT * TO '?', ETC.). ON RETURN,
; (A)=0 IS AN UNAMBIGEOUS NAME WAS SPECIFIED. ENTER WITH (A) .EQUAL TO
; THE POSITION WITHIN THE FCB FOR THE NAME (EITHER 0 OR 16).
;
CONVERT:LD HL,FCB
CALL ADDHL
PUSH HL
PUSH HL
XOR A
LD (CHGDRV),A ; INITIALIZE DRIVE CHANGE FLAG.
LD HL,(INPOINT) ; SET (HL) AS POINTER INTO INPUT LINE.
EX DE,HL
CALL NONBLANK ; GET NEXT NON-BLANK CHARACTER.
EX DE,HL
LD (NAMEPNT),HL ; SAVE POINTER HERE FOR ANY ERROR MESSAGE.
EX DE,HL
POP HL
LD A,(DE) ; GET FIRST CHARACTER.
OR A
JP Z,CONVRT1
SBC A,'A'-1 ; MIGHT BE A DRIVE NAME, CONVERT TO BINARY.
LD B,A ; AND SAVE.
INC DE ; CHECK NEXT CHARACTER FOR A ':'.
LD A,(DE)
CP ':'
JP Z,CONVRT2
DEC DE ; NOPE, MOVE POINTER BACK TO THE START OF THE LINE.
CONVRT1:LD A,(CDRIVE)
LD (HL),A
JP CONVRT3
CONVRT2:LD A,B
LD (CHGDRV),A ; SET CHANGE IN DRIVES FLAG.
LD (HL),B
INC DE
;
; CONVERT THE BASIC FILE NAME.
;
CONVRT3:LD B,08H
CONVRT4:CALL CHECK
JP Z,CONVRT8
INC HL
CP '*' ; NOTE THAT AN '*' WILL FILL THE REMAINING
JP NZ,CONVRT5 ; FIELD WITH '?'.
LD (HL),'?'
JP CONVRT6
CONVRT5:LD (HL),A
INC DE
CONVRT6:DEC B
JP NZ,CONVRT4
CONVRT7:CALL CHECK ; GET NEXT DELIMITER.
JP Z,GETEXT
INC DE
JP CONVRT7
CONVRT8:INC HL ; BLANK FILL THE FILE NAME.
LD (HL),' '
DEC B
JP NZ,CONVRT8
;
; GET THE EXTENSION AND CONVERT IT.
;
GETEXT: LD B,03H
CP '.'
JP NZ,GETEXT5
INC DE
GETEXT1:CALL CHECK
JP Z,GETEXT5
INC HL
CP '*'
JP NZ,GETEXT2
LD (HL),'?'
JP GETEXT3
GETEXT2:LD (HL),A
INC DE
GETEXT3:DEC B
JP NZ,GETEXT1
GETEXT4:CALL CHECK
JP Z,GETEXT6
INC DE
JP GETEXT4
GETEXT5:INC HL
LD (HL),' '
DEC B
JP NZ,GETEXT5
GETEXT6:LD B,3
GETEXT7:INC HL
LD (HL),0
DEC B
JP NZ,GETEXT7
EX DE,HL
LD (INPOINT),HL ; SAVE INPUT LINE POINTER.
POP HL
;
; CHECK TO SEE IF THIS IS AN AMBIGEOUS FILE NAME SPECIFICATION.
; SET THE (A) REGISTER TO NON ZERO IF IT IS.
;
LD BC,11 ; SET NAME LENGTH.
GETEXT8:INC HL
LD A,(HL)
CP '?' ; ANY QUESTION MARKS?
JP NZ,GETEXT9
INC B ; COUNT THEM.
GETEXT9:DEC C
JP NZ,GETEXT8
LD A,B
OR A
RET
;
; CP/M COMMAND TABLE. NOTE COMMANDS CAN BE EITHER 3 OR 4 CHARACTERS LONG.
;
.IF MON
NUMCMDS:.EQU 7 ; NUMBER OF COMMANDS
.ELSE
NUMCMDS:.EQU 6 ; NUMBER OF COMMANDS
.ENDIF
CMDTBL: .DB "DIR "
.DB "ERA "
.DB "TYPE"
.DB "SAVE"
.DB "REN "
.DB "USER"
.IF MON
.DB "MON "
.ENDIF
CMDADR: .DW DIRECT
.DW ERASE
.DW TYPE
.DW SAVE
.DW RENAME
.DW USER
.IF MON
.DW MONITOR
.ENDIF
.DW UNKNOWN
;
; SEARCH THE COMMAND TABLE FOR A MATCH WITH WHAT HAS JUST
; BEEN ENTERED. IF A MATCH IS FOUND, THEN WE JUMP TO THE
; PROPER SECTION. ELSE JUMP TO (UNKNOWN).
; ON RETURN, THE (C) REGISTER IS SET TO THE COMMAND NUMBER
; THAT MATCHED (OR NUMCMDS+1 IF NO MATCH).
;
SEARCH: LD HL,CMDTBL
LD C,0
SEARCH1:LD A,C
CP NUMCMDS ; THIS COMMANDS EXISTS.
RET NC
LD DE,FCB+1 ; CHECK THIS ONE.
LD B,4 ; MAX COMMAND LENGTH.
SEARCH2:LD A,(DE)
CP (HL)
JP NZ,SEARCH3 ; NOT A MATCH.
INC DE
INC HL
DEC B
JP NZ,SEARCH2
LD A,(DE) ; ALLOW A 3 CHARACTER COMMAND TO MATCH.
CP ' '
JP NZ,SEARCH4
LD A,C ; SET RETURN REGISTER FOR THIS COMMAND.
RET
SEARCH3:INC HL
DEC B
JP NZ,SEARCH3
SEARCH4:INC C
JP SEARCH1
;
; SET THE INPUT BUFFER TO EMPTY AND THEN START THE COMMAND
; PROCESSOR (CCP).
;
CLEARBUF:
XOR A
LD (INBUFF+1),A ; SECOND BYTE IS ACTUAL LENGTH.
COMMAND:LD SP,CCPSTACK ; SETUP STACK AREA.
PUSH BC ; NOTE THAT (C) SHOULD BE .EQUAL TO:
LD A,C ; (UUUUDDDD) WHERE 'UUUU' IS THE USER NUMBER
RRA ; AND 'DDDD' IS THE DRIVE NUMBER.
RRA
RRA
RRA
AND 0FH ; ISOLATE THE USER NUMBER.
LD E,A
CALL GETSETUC ; AND SET IT.
CALL RESDSK ; RESET THE DISK SYSTEM.
LD (BATCH),A ; CLEAR BATCH MODE FLAG.
POP BC
LD A,C
AND 0FH ; ISOLATE THE DRIVE NUMBER.
LD (CDRIVE),A ; AND SAVE.
CALL DSKSEL ; ...AND SELECT.
LD A,(INBUFF+1)
OR A ; ANYTHING IN INPUT BUFFER ALREADY?
JP NZ,CMMND2 ; YES, WE JUST PROCESS IT.
;
; ENTRY POINT TO GET A COMMAND LINE FROM THE CONSOLE.
;
CMMND1: LD SP,CCPSTACK ; SET STACK STRAIGHT.
CALL CRLF ; START A NEW LINE ON THE SCREEN.
CALL GETDSK ; GET CURRENT DRIVE.
ADD A,'A'
CALL PRINT ; PRINT CURRENT DRIVE.
.IF USRDSP
CALL GETUSR ;GET CURRENT USER NUMBER
CP 10 ;TWO DIGITS?
JR C,CMMND3 ;NO
LD A,'1' ;PRINT LEADING '1'
CALL PRINT
CALL GETUSR ;GET CURRENT USER NUMBER
SUB 10 ;SUBTRACT 10
CMMND3: ADD A,'0'
CALL PRINT
.ENDIF
LD A,'>'
CALL PRINT ; AND ADD PROMPT.
CALL GETINP ; GET LINE FROM USER.
;
; PROCESS COMMAND LINE HERE.
;
CMMND2: LD DE,TBUFF
CALL DMASET ; SET STANDARD DMA ADDRESS.
CALL GETDSK
LD (CDRIVE),A ; SET CURRENT DRIVE.
CALL CONVFST ; CONVERT NAME TYPED IN.
CALL NZ,SYNERR ; WILD CARDS ARE NOT ALLOWED.
LD A,(CHGDRV) ; IF A CHANGE IN DRIVES WAS INDICATED,
OR A ; THEN TREAT THIS AS AN UNKNOWN COMMAND
JP NZ,UNKNOWN ; WHICH GETS EXECUTED.
CALL SEARCH ; ELSE SEARCH COMMAND TABLE FOR A MATCH.
;
; NOTE THAT AN UNKNOWN COMMAND RETURNS
; WITH (A) POINTING TO THE LAST ADDRESS
; IN OUR TABLE WHICH IS (UNKNOWN).
;
LD HL,CMDADR ; NOW, LOOK THRU OUR ADDRESS TABLE FOR COMMAND (A).
LD E,A ; SET (DE) TO COMMAND NUMBER.
LD D,0
ADD HL,DE
ADD HL,DE ; (HL)=(CMDADR)+2*(COMMAND NUMBER).
LD A,(HL) ; NOW PICK OUT THIS ADDRESS.
INC HL
LD H,(HL)
LD L,A
JP (HL) ; NOW EXECUTE IT.
;
; READ ERROR WHILE TYPEING A FILE.
;
RDERROR:LD BC,RDERR
JP PLINE
RDERR: .DB "Read Error",0
;
; REQUIRED FILE WAS NOT LOCATED.
;
NONE: LD BC,NOFILE
JP PLINE
NOFILE: .DB "No File",0
;
; DECODE A COMMAND OF THE FORM 'A>FILENAME NUMBER{ FILENAME}.
; NOTE THAT A DRIVE SPECIFIER IS NOT ALLOWED ON THE FIRST FILE
; NAME. ON RETURN, THE NUMBER IS IN REGISTER (A). ANY ERROR
; CAUSES 'FILENAME?' TO BE PRINTED AND THE COMMAND IS ABORTED.
;
DECODE: CALL CONVFST ; CONVERT FILENAME.
LD A,(CHGDRV) ; DO NOT ALLOW A DRIVE TO BE SPECIFIED.
OR A
JP NZ,SYNERR
LD HL,FCB+1 ; CONVERT NUMBER NOW.
LD BC,11 ; (B)=SUM REGISTER, (C)=MAX DIGIT COUNT.
DECODE1:LD A,(HL)
CP ' ' ; A SPACE TERMINATES THE NUMERAL.
JP Z,DECODE3
INC HL
SUB '0' ; MAKE BINARY FROM ASCII.
CP 10 ; LEGAL DIGIT?
JP NC,SYNERR
LD D,A ; YES, SAVE IT IN (D).
LD A,B ; COMPUTE (B)=(B)*10 AND CHECK FOR OVERFLOW.
AND 0E0H
JP NZ,SYNERR
LD A,B
RLCA
RLCA
RLCA ; (A)=(B)*8
ADD A,B ; .......*9
JP C,SYNERR
ADD A,B ; .......*10
JP C,SYNERR
ADD A,D ; ADD IN NEW DIGIT NOW.
DECODE2:JP C,SYNERR
LD B,A ; AND SAVE RESULT.
DEC C ; ONLY LOOK AT 11 DIGITS.
JP NZ,DECODE1
RET
DECODE3:LD A,(HL) ; SPACES MUST FOLLOW (WHY?).
CP ' '
JP NZ,SYNERR
INC HL
DECODE4:DEC C
JP NZ,DECODE3
LD A,B ; SET (A)=THE NUMERIC VALUE ENTERED.
RET
;
; MOVE 3 BYTES FROM (HL) TO (DE). NOTE THAT THERE IS ONLY
; ONE REFERENCE TO THIS AT (A2D5H).
;
MOVE3: LD B,3
;
; MOVE (B) BYTES FROM (HL) TO (DE).
;
HL2DE: LD A,(HL)
LD (DE),A
INC HL
INC DE
DEC B
JP NZ,HL2DE
RET
;
; COMPUTE (HL)=(TBUFF)+(A)+(C) AND GET THE BYTE THAT'S HERE.
;
EXTRACT:LD HL,TBUFF
ADD A,C
CALL ADDHL
LD A,(HL)
RET
;
; CHECK DRIVE SPECIFIED. IF IT MEANS A CHANGE, THEN THE NEW
; DRIVE WILL BE SELECTED. IN ANY CASE, THE DRIVE BYTE OF THE
; FCB WILL BE SET TO NULL (MEANS USE CURRENT DRIVE).
;
DSELECT:XOR A ; NULL OUT FIRST BYTE OF FCB.
LD (FCB),A
LD A,(CHGDRV) ; A DRIVE CHANGE INDICATED?
OR A
RET Z
DEC A ; YES, IS IT THE SAME AS THE CURRENT DRIVE?
LD HL,CDRIVE
CP (HL)
RET Z
JP DSKSEL ; NO. SELECT IT THEN.
;
; CHECK THE DRIVE SELECTION AND RESET IT TO THE PREVIOUS
; DRIVE IF IT WAS CHANGED FOR THE PRECEEDING COMMAND.
;
RESETDR:LD A,(CHGDRV) ; DRIVE CHANGE INDICATED?
OR A
RET Z
DEC A ; YES, WAS IT A DIFFERENT DRIVE?
LD HL,CDRIVE
CP (HL)
RET Z
LD A,(CDRIVE) ; YES, RE-SELECT OUR OLD DRIVE.
JP DSKSEL
;
;**************************************************************
;*
;* M O N I T O R C O M M A N D
;*
;**************************************************************
;
.IF MON
MONITOR:RST 38H
.ENDIF
;
;**************************************************************
;*
;* D I R E C T O R Y C O M M A N D
;*
;**************************************************************
;
DIRECT: CALL CONVFST ; CONVERT FILE NAME.
CALL DSELECT ; SELECT INDICATED DRIVE.
LD HL,FCB+1 ; WAS ANY FILE INDICATED?
LD A,(HL)
CP ' '
JP NZ,DIRECT2
LD B,11 ; NO. FILL FIELD WITH '?' - SAME AS *.*.
DIRECT1:LD (HL),'?'
INC HL
DEC B
JP NZ,DIRECT1
DIRECT2:LD E,0 ; SET INITIAL CURSOR POSITION.
PUSH DE
CALL SRCHFCB ; GET FIRST FILE NAME.
CALL Z,NONE ; NONE FOUND AT ALL?
DIRECT3:JP Z,DIRECT9 ; TERMINATE IF NO MORE NAMES.
LD A,(RTNCODE) ; GET FILE'S POSITION IN SEGMENT (0-3).
RRCA
RRCA
RRCA
AND 60H ; (A)=POSITION*32
LD C,A
LD A,10
CALL EXTRACT ; EXTRACT THE TENTH ENTRY IN FCB.
RLA ; CHECK SYSTEM FILE STATUS BIT.
JP C,DIRECT8 ; WE DON'T LIST THEM.
POP DE
LD A,E ; BUMP NAME COUNT.
INC E
PUSH DE
AND 03H ; AT END OF LINE?
PUSH AF
JP NZ,DIRECT4
CALL CRLF ; YES, END THIS LINE AND START ANOTHER.
PUSH BC
CALL GETDSK ; START LINE WITH ('A:').
POP BC
ADD A,'A'
CALL PRINTB
LD A,':'
CALL PRINTB
JP DIRECT5
DIRECT4:CALL SPACE ; ADD SEPERATOR BETWEEN FILE NAMES.
LD A,':'
CALL PRINTB
DIRECT5:CALL SPACE
LD B,1 ; 'EXTRACT' EACH FILE NAME CHARACTER AT A TIME.
DIRECT6:LD A,B
CALL EXTRACT
AND 7FH ; STRIP BIT 7 (STATUS BIT).
CP ' ' ; ARE WE AT THE END OF THE NAME?
JP NZ,DRECT65
POP AF ; YES, DON'T PRINT SPACES AT THE END OF A LINE.
PUSH AF
CP 3
JP NZ,DRECT63
LD A,9 ; FIRST CHECK FOR NO EXTENSION.
CALL EXTRACT
AND 7FH
CP ' '
JP Z,DIRECT7 ; DON'T PRINT SPACES.
DRECT63:LD A,' ' ; ELSE PRINT THEM.
DRECT65:CALL PRINTB
INC B ; BUMP TO NEXT CHARACTER PSOITION.
LD A,B
CP 12 ; END OF THE NAME?
JP NC,DIRECT7
CP 9 ; NOPE, STARTING EXTENSION?
JP NZ,DIRECT6
CALL SPACE ; YES, ADD SEPERATING SPACE.
JP DIRECT6
DIRECT7:POP AF ; GET THE NEXT FILE NAME.
DIRECT8:CALL CHKCON ; FIRST CHECK CONSOLE, QUIT ON ANYTHING.
JP NZ,DIRECT9
CALL SRCHNXT ; GET NEXT NAME.
JP DIRECT3 ; AND CONTINUE WITH OUR LIST.
DIRECT9:POP DE ; RESTORE THE STACK AND RETURN TO COMMAND LEVEL.
JP GETBACK
;
;**************************************************************
;*
;* E R A S E C O M M A N D
;*
;**************************************************************
;
ERASE: CALL CONVFST ; CONVERT FILE NAME.
CP 11 ; WAS '*.*' ENTERED?
JP NZ,ERASE1
LD BC,YESNO ; YES, ASK FOR CONFIRMATION.
CALL PLINE
CALL GETINP
LD HL,INBUFF+1
DEC (HL) ; MUST BE EXACTLY 'Y'.
JP NZ,CMMND1
INC HL
LD A,(HL)
CP 'Y'
JP NZ,CMMND1
INC HL
LD (INPOINT),HL ; SAVE INPUT LINE POINTER.
ERASE1: CALL DSELECT ; SELECT DESIRED DISK.
LD DE,FCB
CALL DELETE ; DELETE THE FILE.
INC A
CALL Z,NONE ; NOT THERE?
JP GETBACK ; RETURN TO COMMAND LEVEL NOW.
YESNO: .DB "All (Y/N)?",0
;
;**************************************************************
;*
;* T Y P E C O M M A N D
;*
;**************************************************************
;
TYPE: CALL CONVFST ; CONVERT FILE NAME.
JP NZ,SYNERR ; WILD CARDS NOT ALLOWED.
CALL DSELECT ; SELECT INDICATED DRIVE.
CALL OPENFCB ; OPEN THE FILE.
JP Z,TYPE5 ; NOT THERE?
CALL CRLF ; OK, START A NEW LINE ON THE SCREEN.
LD HL,NBYTES ; INITIALIZE BYTE COUNTER.
LD (HL),0FFH ; SET TO READ FIRST SECTOR.
TYPE1: LD HL,NBYTES
TYPE2: LD A,(HL) ; HAVE WE WRITTEN THE ENTIRE SECTOR?
CP 128
JP C,TYPE3
PUSH HL ; YES, READ IN THE NEXT ONE.
CALL READFCB
POP HL
JP NZ,TYPE4 ; END OR ERROR?
XOR A ; OK, CLEAR BYTE COUNTER.
LD (HL),A
TYPE3: INC (HL) ; COUNT THIS BYTE.
LD HL,TBUFF ; AND GET THE (A)TH ONE FROM THE BUFFER (TBUFF).
CALL ADDHL
LD A,(HL)
CP CNTRLZ ; END OF FILE MARK?
JP Z,GETBACK
CALL PRINT ; NO, PRINT IT.
CALL CHKCON ; CHECK CONSOLE, QUIT IF ANYTHING READY.
JP NZ,GETBACK
JP TYPE1
;
; GET HERE ON AN END OF FILE OR READ ERROR.
;
TYPE4: DEC A ; READ ERROR?
JP Z,GETBACK
CALL RDERROR ; YES, PRINT MESSAGE.
TYPE5: CALL RESETDR ; AND RESET PROPER DRIVE
JP SYNERR ; NOW PRINT FILE NAME WITH PROBLEM.
;
;**************************************************************
;*
;* S A V E C O M M A N D
;*
;**************************************************************
;
SAVE: CALL DECODE ; GET NUMERIC NUMBER THAT FOLLOWS SAVE.
PUSH AF ; SAVE NUMBER OF PAGES TO WRITE.
CALL CONVFST ; CONVERT FILE NAME.
JP NZ,SYNERR ; WILD CARDS NOT ALLOWED.
CALL DSELECT ; SELECT SPECIFIED DRIVE.
LD DE,FCB ; NOW DELETE THIS FILE.
PUSH DE
CALL DELETE
POP DE
CALL CREATE ; AND CREATE IT AGAIN.
JP Z,SAVE3 ; CAN'T CREATE?
XOR A ; CLEAR RECORD NUMBER BYTE.
LD (FCB+32),A
POP AF ; CONVERT PAGES TO SECTORS.
LD L,A
LD H,0
ADD HL,HL ; (HL)=NUMBER OF SECTORS TO WRITE.
LD DE,TBASE ; AND WE START FROM HERE.
SAVE1: LD A,H ; DONE YET?
OR L
JP Z,SAVE2
DEC HL ; NOPE, COUNT THIS AND COMPUTE THE START
PUSH HL ; OF THE NEXT 128 BYTE SECTOR.
LD HL,128
ADD HL,DE
PUSH HL ; SAVE IT AND SET THE TRANSFER ADDRESS.
CALL DMASET
LD DE,FCB ; WRITE OUT THIS SECTOR NOW.
CALL WRTREC
POP DE ; RESET (DE) TO THE START OF THE LAST SECTOR.
POP HL ; RESTORE SECTOR COUNT.
JP NZ,SAVE3 ; WRITE ERROR?
JP SAVE1
;
; GET HERE AFTER WRITING ALL OF THE FILE.
;
SAVE2: LD DE,FCB ; NOW CLOSE THE FILE.
CALL CLOSE
INC A ; DID IT CLOSE OK?
JP NZ,SAVE4
;
; PRINT OUT ERROR MESSAGE (NO SPACE).
;
SAVE3: LD BC,NOSPACE
CALL PLINE
SAVE4: CALL STDDMA ; RESET THE STANDARD DMA ADDRESS.
JP GETBACK
NOSPACE:.DB "No Space",0
;
;**************************************************************
;*
;* R E N A M E C O M M A N D
;*
;**************************************************************
;
RENAME: CALL CONVFST ; CONVERT FIRST FILE NAME.
JP NZ,SYNERR ; WILD CARDS NOT ALLOWED.
LD A,(CHGDRV) ; REMEMBER ANY CHANGE IN DRIVES SPECIFIED.
PUSH AF
CALL DSELECT ; AND SELECT THIS DRIVE.
CALL SRCHFCB ; IS THIS FILE PRESENT?
JP NZ,RENAME6 ; YES, PRINT ERROR MESSAGE.
LD HL,FCB ; YES, MOVE THIS NAME INTO SECOND SLOT.
LD DE,FCB+16
LD B,16
CALL HL2DE
LD HL,(INPOINT) ; GET INPUT POINTER.
EX DE,HL
CALL NONBLANK ; GET NEXT NON BLANK CHARACTER.
CP '=' ; ONLY ALLOW AN '=' OR '_' SEPERATOR.
JP Z,RENAME1
CP '_'
JP NZ,RENAME5
RENAME1:EX DE,HL
INC HL ; OK, SKIP SEPERATOR.
LD (INPOINT),HL ; SAVE INPUT LINE POINTER.
CALL CONVFST ; CONVERT THIS SECOND FILE NAME NOW.
JP NZ,RENAME5 ; AGAIN, NO WILD CARDS.
POP AF ; IF A DRIVE WAS SPECIFIED, THEN IT
LD B,A ; MUST BE THE SAME AS BEFORE.
LD HL,CHGDRV
LD A,(HL)
OR A
JP Z,RENAME2
CP B
LD (HL),B
JP NZ,RENAME5 ; THEY WERE DIFFERENT, ERROR.
RENAME2:LD (HL),B ; RESET AS PER THE FIRST FILE SPECIFICATION.
XOR A
LD (FCB),A ; CLEAR THE DRIVE BYTE OF THE FCB.
RENAME3:CALL SRCHFCB ; AND GO LOOK FOR SECOND FILE.
JP Z,RENAME4 ; DOESN'T EXIST?
LD DE,FCB
CALL RENAM ; OK, RENAME THE FILE.
JP GETBACK
;
; PROCESS RENAME ERRORS HERE.
;
RENAME4:CALL NONE ; FILE NOT THERE.
JP GETBACK
RENAME5:CALL RESETDR ; BAD COMMAND FORMAT.
JP SYNERR
RENAME6:LD BC,EXISTS ; DESTINATION FILE ALREADY EXISTS.
CALL PLINE
JP GETBACK
EXISTS: .DB "File Exists",0
;
;**************************************************************
;*
;* U S E R C O M M A N D
;*
;**************************************************************
;
USER: CALL DECODE ; GET NUMERIC VALUE FOLLOWING COMMAND.
CP 16 ; LEGAL USER NUMBER?
JP NC,SYNERR
LD E,A ; YES BUT IS THERE ANYTHING ELSE?
LD A,(FCB+1)
CP ' '
JP Z,SYNERR ; YES, THAT IS NOT ALLOWED.
CALL GETSETUC ; OK, SET USER CODE.
JP GETBACK1
;
;**************************************************************
;*
;* T R A N S I A N T P R O G R A M C O M M A N D
;*
;**************************************************************
;
UNKNOWN:LD A,(FCB+1) ; ANYTHING TO EXECUTE?
CP ' '
JP NZ,UNKWN1
LD A,(CHGDRV) ; NOPE, ONLY A DRIVE CHANGE?
OR A
JP Z,GETBACK1 ; NEITHER???
DEC A
LD (CDRIVE),A ; OK, STORE NEW DRIVE.
CALL MOVECD ; SET (TDRIVE) ALSO.
CALL DSKSEL ; AND SELECT THIS DRIVE.
JP GETBACK1 ; THEN RETURN.
;
; HERE A FILE NAME WAS TYPED. PREPARE TO EXECUTE IT.
;
UNKWN1: LD DE,FCB+9 ; AN EXTENSION SPECIFIED?
LD A,(DE)
CP ' '
JP NZ,SYNERR ; YES, NOT ALLOWED.
UNKWN2: PUSH DE
CALL DSELECT ; SELECT SPECIFIED DRIVE.
POP DE
LD HL,COMFILE ; SET THE EXTENSION TO 'COM'. LD HL,COMFILE
CALL MOVE3 ; MOVE 3 BYTES FROM (HL) TO (DE) TO ADD .COM
CALL OPENFCB ; AND OPEN THIS FILE.
.IF CHKU0B
JP NZ,UNKWNA ; GOT IT
LD E,0 ; TRY USER 0, THIS DRIVE
CALL GETSETUC ; OK, SET USER CODE.
CALL OPENFCB
JP NZ,UNKWNA ; GOT IT
LD HL,FCB ; SEE IF ON DRIVE B, USER 0
LD (HL),2
CALL OPENFCB
.ENDIF
JP Z,UNKWN9 ; NOPE
;
; LOAD IN THE PROGRAM.
;
UNKWNA: LD HL,TBASE ; STORE THE PROGRAM STARTING HERE.
UNKWN3: PUSH HL
EX DE,HL
CALL DMASET ; SET TRANSFER ADDRESS.
LD DE,FCB ; AND READ THE NEXT RECORD.
CALL RDREC
JP NZ,UNKWN4 ; END OF FILE OR READ ERROR?
POP HL ; NOPE, BUMP POINTER FOR NEXT SECTOR.
LD DE,128
ADD HL,DE
LD DE,CBASE ; ENOUGH ROOM FOR THE WHOLE FILE?
LD A,L
SUB E
LD A,H
SBC A,D
JP NC,UNKWN0 ; NO, IT CAN'T FIT.
JP UNKWN3
;
; GET HERE AFTER FINISHED READING.
;
UNKWN4: POP HL
DEC A ; NORMAL END OF FILE?
JP NZ,UNKWN0
CALL RESETDR ; YES, RESET PREVIOUS DRIVE.
CALL CONVFST ; CONVERT THE FIRST FILE NAME THAT FOLLOWS
LD HL,CHGDRV ; COMMAND NAME.
PUSH HL
LD A,(HL) ; SET DRIVE CODE IN DEFAULT FCB.
LD (FCB),A
LD A,16 ; PUT SECOND NAME 16 BYTES LATER.
CALL CONVERT ; CONVERT SECOND FILE NAME.
POP HL
LD A,(HL) ; AND SET THE DRIVE FOR THIS SECOND FILE.
LD (FCB+16),A
XOR A ; CLEAR RECORD BYTE IN FCB.
LD (FCB+32),A
LD DE,TFCB ; MOVE IT INTO PLACE AT(005CH).
LD HL,FCB
LD B,33
CALL HL2DE
LD HL,INBUFF+2 ; NOW MOVE THE REMAINDER OF THE INPUT
UNKWN5: LD A,(HL) ; LINE DOWN TO (0080H). LOOK FOR A NON BLANK.
OR A ; OR A NULL.
JP Z,UNKWN6
CP ' '
JP Z,UNKWN6
INC HL
JP UNKWN5
;
; DO THE LINE MOVE NOW. IT ENDS IN A NULL BYTE.
;
UNKWN6: LD B,0 ; KEEP A CHARACTER COUNT.
LD DE,TBUFF+1 ; DATA GETS PUT HERE.
UNKWN7: LD A,(HL) ; MOVE IT NOW.
LD (DE),A
OR A
JP Z,UNKWN8
INC B
INC HL
INC DE
JP UNKWN7
UNKWN8: LD A,B ; NOW STORE THE CHARACTER COUNT.
LD (TBUFF),A
CALL CRLF ; CLEAN UP THE SCREEN.
CALL STDDMA ; SET STANDARD TRANSFER ADDRESS.
CALL SETCDRV ; RESET CURRENT DRIVE.
CALL TBASE ; AND EXECUTE THE PROGRAM.
;
; TRANSIANT PROGRAMS RETURN HERE (OR REBOOT).
;
LD SP,BATCH ; SET STACK FIRST OFF.
CALL MOVECD ; MOVE CURRENT DRIVE INTO PLACE (TDRIVE).
CALL DSKSEL ; AND RESELECT IT.
JP CMMND1 ; BACK TO COMAND MODE.
;
; GET HERE IF SOME ERROR OCCURED.
;
UNKWN9: CALL RESETDR ; INPROPER FORMAT.
JP SYNERR
UNKWN0: LD BC,BADLOAD ; READ ERROR OR WON'T FIT.
CALL PLINE
JP GETBACK
BADLOAD:.DB "Bad Load",0
COMFILE:.DB "COM" ; COMMAND FILE EXTENSION.
;
; GET HERE TO RETURN TO COMMAND LEVEL. WE WILL RESET THE
; PREVIOUS ACTIVE DRIVE AND THEN EITHER RETURN TO COMMAND
; LEVEL DIRECTLY OR PRINT ERROR MESSAGE AND THEN RETURN.
;
GETBACK:CALL RESETDR ; RESET PREVIOUS DRIVE.
GETBACK1:
CALL CONVFST ; CONVERT FIRST NAME IN (FCB).
LD A,(FCB+1) ; IF THIS WAS JUST A DRIVE CHANGE REQUEST,
SUB ' ' ; MAKE SURE IT WAS VALID.
LD HL,CHGDRV
OR (HL)
JP NZ,SYNERR
JP CMMND1 ; OK, RETURN TO COMMAND LEVEL.
;
; CCP STACK AREA.
;
.DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
CCPSTACK: .EQU $ ;END OF CCP STACK AREA.
;
; BATCH (OR SUBMIT) PROCESSING INFORMATION STORAGE.
;
BATCH: .DB 0 ; BATCH MODE FLAG (0=NOT ACTIVE).
BATCHFCB:.DB 0,"$$$ SUB"
.DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
;
; FILE CONTROL BLOCK SETUP BY THE CCP.
;
FCB: .DB 0," ",0,0,0,0,0
.DB " ",0,0,0,0,0
RTNCODE:.DB 0 ; STATUS RETURNED FROM BDOS CALL.
CDRIVE: .DB 0 ; CURRENTLY ACTIVE DRIVE.
CHGDRV: .DB 0 ; CHANGE IN DRIVES FLAG (0=NO CHANGE).
NBYTES: .DW 0 ; BYTE COUNTER USED BY TYPE.
.IF ENDFIL
.FILL ((CCPO + 0800H) - $),055H
.ENDIF
.END