home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
mbug
/
mbug060.arc
/
CPM#005.LBR
/
MAKEST20.ASM
< prev
next >
Wrap
Assembly Source File
|
1979-12-31
|
28KB
|
1,577 lines
xVersion equ '2'
yVersion equ '0'
;**** MAKEST Version x.y ****
;
;Copyright (c) Peter C. Cole March, 1985 Duncanville, TX
;All commercial rights reserved.
;Released for free distribution only. Not to be sold.
;**** Version Changes ****
;
;1.0 - Released March, 1985
;
;1.1 - Added "user selectable drive" and
; "display existing EXECST.COM command line".
;
;1.2 - Added "exit MAKEST only on command".
; DO NOT USE THIS VERSION.
;
;1.3 - Corrected problem of not sending proper end flag for
; Bdos function 47.
;
;1.4 - Corrected problem that MAKEST sometimes recognizes a one sector
; EXECST that was not made by MAKEST.
;
;1.5 - Corrected the "chain flag" of Bdos Function 47 (Chain to
; Program). It was incorrectly set to 0FFh. Now set to 0h.
; Made "Program Data Assembly Area" more straightforward.
;
;2.0 - Added on board editor and file name change capability.
;
PAGE
;**** Assembly Definations ****
NL: equ 0A0Dh ;new line
CPage: equ 5A1Bh ;clear page
MsgEnd: equ 0 ;message end flag
Bdos: equ 5 ;Bdos address
Stack1: equ 4000h ;Location of MAKEST and FileName stack
Temp: equ Stack1+2 ;Location to store temp string for editing
Existing: equ 4800h ;Location to store existing FileName program
org 100h
;**** Start Program ****
;Set stack
lxi sp,Stack1
;Set output delimiter
mvi c,110
mvi d,0
mvi e,MsgEnd
call Bdos
;Set Bdos error mode to "return and display error"
mvi c,45
mvi e,0FEh
call Bdos
;Set number of read/write sectors to 2
mvi c,44
mvi e,2
call Bdos
;Now continue with program
jmp BeginMsg
;**** Exit Program ****
Exit: jmp 0
PAGE
;**** Begin Message ****
BeginMsg: mvi c,9
lxi d,BM2
call Bdos
jmp BM10
èBM2: dw CPage
db '****************************** MAKEST Version '
db xVersion,'.',yVersion,' ******************************'
db 'Copyright (c) 1985 by Peter C. Cole'
dw NL
db 'Duncanville, Texas.'
dw NL
db 'All commercial rights reserved.'
dw NL
db 'Released for free distribution only. Not to be sold.'
dw NL
db '****************************************'
db '****************************************'
dw NL
db 'MAKEST will create or edit a "Command File" ' ;44
db 'on the disk drive of your choice.' ;33
dw NL
db 'A "Command File" is a file that when run ' ;41
db 'will send a command string to CP/M as ' ;38
dw NL
db 'if you had typed it in after the ' ;33
db 'system prompt. Normal use of MAKEST is to' ;41
dw NL
db 'create an EXECST file which is the first ' ;41
db 'file CP/M Plus looks for when it first' ;38
dw NL
db 'boots up. Use EXECST to ' ;24
db 'autoload a favorite program on boot up.' ;39
dw NL
db 'MAKEST will only run on the Osborne ' ;36
db 'Executive. ' ;11
dw NL,NL
db MsgEnd
PAGE
;**** Main Menu ****
Begin: call HomeIt
BM10: mvi c,9
lxi d,BM11
call Bdos
jmp BM12
BM11: db 'Please select:'
dw NL
db ' A,B,etc - Read this disk drive for an existing '
db MsgEnd
BM12: call FileName
mvi c,9
lxi d,BM13
call Bdos
jmp BM14
BM13: db ' command line.'
dw NL
db ' ^C or X - Exit to CP/M.'
dw NL
db ' 1 - Create a new '
db MsgEnd
BM14: call FileName
mvi c,9
lxi d,BM15è call Bdos
jmp BM16
BM15: db ' command line.'
dw NL
db ' 2 - Change to a different file name.'
dw NL
db ' <RETURN> - Edit the below command line (if any).'
dw NL
db ' W - Write the below command line (if any) to'
db ' a "to be selected" disk drive:'
dw NL,NL
db MsgEnd
BM16: mvi c,9
lxi d,String
call Bdos
mvi c,9
lxi d,BM20
call Bdos
jmp Wait
BM20: dw NL
db MsgEnd
PAGE
;**** Subroutine FileName ****
;Displays active file name
FileName: mvi c,9
lxi d,FN1
call Bdos
ret
FN1: db 'EXECST',0,0 ;allow for max. of 8 characters
db MsgEnd
;**** Subroutine Create ****
;Creates a fresh FCB
Create: lxi h,FcbRun
lxi d,FcbNew
mvi b,FcbEnd-FcbNew
Create1: ldax d
mov m,a
inx h
inx d
dcr b
jnz Create1
ret
;**** Subroutine HomeIt ****
;Homes cursor to just under Header and clears to end of page.
HomeIt: mvi c,9
lxi d,Clear
call Bdos
ret
Clear: db 1Bh,3Dh ;move cursor
db 27h,20h ;to just under header
db 1Bh,59h ;clear from cursor to endè db MsgEnd
PAGE
;**** Wait for key ****
Wait: mvi c,6
mvi e,0FDh
call Bdos
cpi 3 ;test if ^C
jz Exit
cpi 0Dh ;<RETURN>
jz ReEdit
cpi '1'
jz New
cpi '2'
jz Diff
ani 5Fh ;convert if small to cap.
cpi 'X' ;test if X
jz Exit
cpi 'W'
jz Write
cpi 'A' ;is it less than 'A'?
jc Wait ;jmp if yes (not A to P)
cpi 'Q' ;is it less than 'Q'?
jc ExistFile ;jmp if yes
jmp Wait ;sorry, not A to P.
;**** Open Existing File ****
;Convert to drive code and store
ExistFile: ani 1Fh
sta FcbNew
;Create FcbRun
call Create
;Clear screen
call HomeIt
PAGE
;Open Existing File
mvi c,15
lxi d,FcbRun
call Bdos
è;Test if file opened
ana a
jz FileExists ;jmp if file opened with no problem
mov a,h
cpi 0
jnz BadWait
;File not found. Give message.
mvi c,9
lxi d,NoFileMsg
call Bdos
jmp BadWait
NoFileMsg: dw NL,NL
db 'File not found.'
dw NL
db MsgEnd
;Test Existing file
FileExists: call TestFile
jnz BadWait
;Makest file - give message
mvi c,9
lxi d,MSmsg1
call Bdos
jmp MS2
MSmsg1: dw NL,NL
db 'Do you want to edit this file? (Y/N) '
db MsgEnd
PAGE
;Wait for Answer
MS2: mvi c,6
mvi e,0FDh
call Bdos
cpi 'Y'
jz ExistEdit
cpi 'y'
jz ExistEdit
jmp Begin
;Edit existing command string
ExistEdit: call HomeIt
lxi h,Existing+Buffer-Data
mvi m,126 ;only allow max of 126 char
xchg
call LineEdit
cpi 0
jz LoadBuffer
cpi 1
jz Begin
cpi 2
jz BadWait
jmp Begin
;Load from Makest file to "Buffer"
LoadBuffer:
lxi h,Buffer
lxi d,Existing+Buffer-Data
LB0: ldax d ;load max char
mov m,a
inx h
inx d
ldax d ;load char returned
mov m,a
inx h
inx d
LB1: ldax d ;load data
mov m,a
inx h
inx d
ana a ;is it end flag?
jnz LB1 ;jmp if no
jmp Begin
PAGE
;**** Routine New ****
;Create a string with no data
New: lxi h,Temp
mvi m,126
inx h
mvi m,0
inx h
mvi m,0
;Edit command string
jmp ReEdit2
;**** Routine ReEdit ****
;Move Buffer to new location
ReEdit: lxi h,Temp
lxi d,Buffer
ldax d ;Load max char
mov m,a
inx h
inx d
ldax d ;load char returned
mov m,a
inx h
inx d
ReEdit1: ldax d
mov m,a
inx h
inx d
ana a
jnz ReEdit1
;Edit command string
ReEdit2: call HomeIt
lxi h,Temp
mvi m,126
xchg
call LineEdit
cpi 0
jz ReEdit5
cpi 1
jz Begin
cpi 2
jz BadWait
jmp Begin
;Load new command line to Buffer
ReEdit5: lxi h,Buffer
lxi d,Temp
jmp LB0
PAGE
;**** Subroutine LineEdit ****
;
;DE = Start address of string to edit (set by user)
; 1st byte = maximum number of characters (set by user)
; Does not include end flag of 0.
; 2nd byte = total number of characters returned (set by LineEdit)
; Does not include end flag of 0.
; 3rd byte = zero if string has no data (set by user)
; 3rd byte = not zero if string has data (string must end with 0)
;
;Preload "WhichRow" with the row number to be used for the displayed line.
; 00h = 1st row (Top row of screen)
; 01h = 2nd row
; etc
; 17h = 24th row (Bottom row of screen)
;
;CP/M cursor is moved to far left so LineEdit can remove it.
;LineEdit Cursor will start at far left.
;Cursor will be inverse, blinking, full intensity.
;Non-cursor characters will be black background, full intensity.
;
;Nonprintable characters will not be allowed in string.
;
;MsgEnd must be 0h.
;
;Returns with accumulator set to:
; 0 - good edit. (2nd byte equals 0 to maximum characters in string)
; 1 - edit not wanted (ESC pushed)
; 2 - problem opening line (one line message given)
;
;"String" is location of data .
;"Line" is location of video ram.
;
LineMax: db 126 ;maximum number of characters allowed (max = 255)
;1st byte can be equal to or less than LineMax
WhichRow: db 17h ;row that line editor will use
StringStart: ds 2 ;start address of string to edit
StringBegin: ds 2 ;First char of string
String1st: ds 2 ;Address of char in string that is 1st char in line
StringCursor: ds 2 ;cursor location in string
LineBegin: ds 2 ;start address of line
LineCursor: ds 2 ;cursor location in line
PAGE
;Store start address of string
LineEdit: xchg
shld StringStart
;Make CP/M cursor start location same as LineEdit location
lda WhichRow
ani 24
sta CursorY
;Send Edit header
mvi c,9
lxi d,EditMsg
call Bdos
jmp Edit3
EditMsg: db 'You can use ! to chain several commands if needed. '
db 'Example: DIR A:!DIR B:'
dw NL
db 'Enter up to 126 characters. '
Edit1: dw NL,NL
db 'Use these keys for editing:'
dw NL,NL
db ' ^A - Go to far left.'
dw NL
db ' ^F - Go to far right.'
dw NL
db ' ^G or down arrow - delete character.'
dw NL
db ' ^- or ^left arrow - delete character on left.'
dw NL
db ' Use left and right arrow keys to move cursor.'
dw NL
db ' Only printable characters allowed.'
dw NL
db ' Push <ESC> to exit without new edit.'
dw NL
db ' Push <RETURN> when finished.'
db 1Bh,3Dh ;position cursor
CursorY db 0+32
CursorX db 0+32
db MsgEnd
;Create video bank start address
Edit3: ora a ;clear carry
lda WhichRow ;get row number
lxi h,0C000h ;preload hl for video bank address
rar ;get LSB of WhichRow for MSB of reg l
mov b,a ;store LSB's for reg h
mov a,l ;move LSB of WhichRow into MSB of reg l
rar
mov l,a
mov a,b ;get LSB's for reg h
ora h ;move MSB's of WhichRow into LSB's of reg h
mov h,a ;
shld LineBegin ;store line start address
PAGE
;Test if max desired ok
Edit5: lhld StringStart
mov c,m ;load max char's
inx h
mvi m,0 ;set to 0 char returned for now
inx h
lda LineMax ;load max allowed
cmp c ;test if equal to or less than
jz Edit8 ;ok (equal)
jnc Edit8 ;ok (less than)
;Max desired not ok - send message
mvi c,9
lxi d,Edit6
call Bdos
mvi a,2
ret
Edit6: db 'Maximum characters desired is more than that allowed.'
db MsgEnd
;Test if any nonprintable char found
Edit8:
mvi b,0 ;to keep track of number of char
lda LineMax ;to test if max exceeded
inr a ;account for end flag
mov c,a
Edit9: mov a,m
ana a
jz Edit20 ;jmp if end flag of 0 found
cpi ' '
jc Edit11 ;jmp if control char
cpi 7Fh
jnc Edit11 ;jmp if equal to or greater than 7Fh
inr b
dcr c
jz Edit16 ;jmp if max exceeded
inx h
jmp Edit9
;nonprintable char found
Edit11: mvi c,9
lxi d,Edit12
call Bdos
mvi a,2
ret
Edit12: db 'Sorry, this string has a nonprintable character.'
db MsgEnd
PAGE
;number of char's exceed limit
Edit16: mvi c,9
lxi d,Edit17
call Bdos
mvi a,2
ret
Edit17: db 'Sorry, this string is too long.'
db MsgEnd
;does string given exceed its own limit?
Edit20: lhld StringStart
mov a,m
cmp b
jnc Edit25 ;jmp if ok
;string given exceeds its own limit
mvi c,9
lxi d,Edit22
call Bdos
mvi a,2
ret
Edit22: db 'Sorry, this string exceeds its own maximum limit.'
db MsgEnd
;Load number of char's found
Edit25: lhld StringStart
inx h
mov m,b
;display line
lhld StringStart ;preload start address of string
inx h
inx h
shld StringBegin
shld String1st
shld StringCursor
lhld LineBegin ;preload start address of line
shld LineCursor
shld OldCursor
call Display
jmp Edit
PAGE
;** Subroutine Display **
OldCursor: ds 2
Bank: ds 1
;Turn on Video Bank
Display: in 0
sta Bank
ori 40h
out 0
;Turn off old cursor
lhld OldCursor
mov a,m
ani 01111111b ;turn off reverse video
mov m,a
mov a,h ;go to DXXX address
adi 10h
mov h,a
mov a,m
ani 11011111b ;turn off blink
mov m,a
;Load new line data until end flag
lhld String1st
xchg
lhld LineBegin
mvi b,80
Display1: ldax d
ana a ;test if 0 end flag
jz Display2 ;jmp if yes
mov m,a
inx h
inx d
dcr b
jnz Display1
;Finish with blanks
Display2: mvi a,' '
Display3: mov m,a
inx h
dcr b
jnz Display3
PAGE
;Turn on new cursor and store location as OldCursor
lhld LineCursor
shld OldCursor
mov a,m
ori 10000000b ;turn on inverse video
mov m,a
mov a,h ;go to DXXX address
adi 10h
mov h,a
mov a,m
ori 00100000b ;turn on blink
mov m,a
;Turn off Video Bank
lda Bank
out 0
ret
PAGE
;Wait for edit key
Edit: mvi c,6
mvi e,0FDh
call Bdos
cpi 1Bh ;ESC
jz ExitEdit
cpi 01h ;^A (CP/M to left edge)
jz LeftEdge
cpi 06h ;^F (CP/M to right edge)
jz RightEdge
cpi 07h ;^G (CP/M and WS delete character)
jz DeleteChar
cpi 0Ah ;^J (CP/M Arrow down)
jz DeleteChar
cpi 18h ;^X (WS Arrow down)
jz DeleteChar
cpi 1Fh ;^_ (WS delete character on left - also ^ arrow left)
jz DeleteLeft
cpi 7Fh ;DEL
jz DeleteLeft
cpi 04h ;^D (WS arrow right)
jz Right
cpi 0Ch ;^L (CP/M arrow right)
jz Right
cpi 13h ;^S (WS arrow left)
jz Left
cpi 08h ;^H (CP/M arrow left)
jz Left
cpi 0Dh ;^M (Carriage Return)
jz DoneEdit
cpi ' '
jc Edit ;jmp if control char
cpi 80h
jnc Edit ;jmp if equal to or greater than 80h
jmp EnterChar
;Return from Edit with flag of abandon edit
ExitEdit: mvi a,1
ret
;Return from Edit with flag of good new edit
DoneEdit: mvi a,0
ret
PAGE
;**** Routine Right ****
;move cursor right
;can String move right?
Right: lhld StringCursor
mov a,m
ana a
jz Edit ;jmp if no
;move String right
inx h
shld StringCursor
;can Line move right?
lhld LineCursor
mov a,l
cpi 4Fh
jz RightMove ;jmp if no
cpi 0CFh
jz RightMove ;jmp if no
;move Line right
inx h
shld LineCursor
;display new line
RightOut: call Display
jmp Edit
;move String right
RightMove: lhld String1st
inx h
shld String1st
jmp RightOut
PAGE
;**** Routine Left ****
;moves cursor left
;Can String move left?
Left: lhld StringBegin
xchg
lhld StringCursor
mov a,d
cmp h
jnz Left1 ;jmp if yes
mov a,e
cmp l
jnz Left1 ;jmp if yes
jmp Edit ;jmp if no
;Move String left
Left1 dcx h
shld StringCursor
;Can Line move left?
lhld LineCursor
mov a,l
cpi 0h
jz LeftMove ;jmp if no
cpi 80h
jz LeftMove ;jmp if no
;move Line left
dcx h
shld LineCursor
;display new line
LeftOut: call Display
jmp Edit
;move String left
LeftMove: lhld String1st
dcx h
shld String1st
jmp LeftOut
PAGE
;**** Routine RightEdge ****
;Moves cursor to far right edge
;Can String move right?
RightEdge: lhld LineCursor ;for top
push h
lhld String1st ;for de
xchg
lhld StringCursor ;for hl
mov a,m
cpi 0h
jz REout ;jmp if no
;Move StringCursor and LineCursor right
;Can LineCursor move right
RE1: xthl
mov a,l
cpi 4Fh
jz RE5 ;jmp if no
cpi 0CFh
jz RE5 ;jmp if no
;move LineCursor right
inx h
RE2: xthl
;move StringCursor right
inx h
;can String move right
mov a,m
cpi 0h
jnz RE1 ;jmp if yes
;load new values
RE3: shld StringCursor
xchg
shld String1st
pop h
shld LineCursor
;display new line
call Display
jmp Edit
PAGE
;Move StringCursor and String1st right
;Return LineCursor
RE5: xthl
;move StringCursor and String1st right
RE6: inx h
inx d
;can String move right
mov a,m
cpi 0h
jnz RE6 ;jmp if yes
jmp RE3
REout: pop h
jmp Edit
PAGE
;**** Routine LeftEdge ****
;Moves cursor to far left edge
;Can String move left?
LeftEdge:
lhld StringBegin ;for bc
mov b,h
mov c,l
lhld StringCursor
mov a,b
cmp h
jnz LE0 ;jmp if yes
mov a,c
cmp l
jnz LE0 ;jmp if yes
jmp Edit ;jmp if no
LE0: lhld LineCursor ;for top
push h
lhld String1st ;for de
xchg
lhld StringCursor ;for hl
;Move StringCursor and LineCursor left
;Can LineCursor move left
LE1: xthl
mov a,l
cpi 0h
jz LE5 ;jmp if no
cpi 80h
jz LE5 ;jmp if no
;move LineCursor left
dcx h
LE2: xthl
;move StringCursor left
dcx h
;can String move left
mov a,b
cmp h
jnz LE1 ;jmp if yes
mov a,c
cmp l
jnz LE1 ;jmp if yes
PAGE
;load new values
LE3: shld StringCursor
xchg
shld String1st
pop h
shld LineCursor
;display new line
call Display
jmp Edit
;Move StringCursor and String1st left
;Return LineCursor
LE5: xthl
;move StringCursor and String1st left
LE6: dcx h
dcx d
;can String move left
mov a,b
cmp h
jnz LE6 ;jmp if yes
mov a,c
cmp l
jnz LE6 ;jmp if yes
jmp LE3 ;jmp if no
PAGE
;**** Routine DeleteChar ****
;Deletes character cursor is on
;Is StringCursor at end?
DeleteChar:
lhld StringCursor
mov a,m
dcx h
ana a
jz Edit ;jmp if yes
;Delete data at cursor
DelChar1: inx h
inx h
mov a,m
dcx h
mov m,a
ana a ;is it last char
jnz DelChar1 ;jmp if no
;Decrement char count
lhld StringStart
inx h
mov a,m
dcr a
mov m,a
;Display new line
call Display
jmp Edit
PAGE
;**** Routine DeleteLeft ****
;Delete character on left of cursor
;Is StringCursor at end?
DeleteLeft:
lhld StringBegin
xchg
lhld StringCursor
mov a,d
cmp h
jnz DelLeft1 ;jmp if no
mov a,e
cmp l
jnz DelLeft1 ;jmp if no
jmp Edit ;jmp if yes
;Is LineCursor at end?
DelLeft1:
lhld LineCursor
mov a,l
cpi 0h
jz Edit ;jmp if yes
cpi 80h
jz Edit ;jmp if yes
;Decrement LineCursor position
dcx h
shld LineCursor
;Decrement StringCursor position
lhld StringCursor
dcx h
shld StringCursor
;Delete data at left of cursor
dcx h
DelLeft2: inx h
inx h
mov a,m
dcx h
mov m,a
ana a ;is it last char
jnz DelLeft2 ;jmp if no
;Decrement char count
lhld StringStart
inx h
mov a,m
dcr a
mov m,a
;Display new line
call Display
jmp Edit
PAGE
;**** Routine EnterChar ****
;Enter character at cursor position.
;Cursor and all to right moves right.
;Store character
EnterChar:
mov c,a ;char stored in c
;Is String full?
lhld StringStart
mov a,m
inx h
cmp m
jnz Char1 ;jmp if no
;Send bell
mvi c,2
mvi e,7h
call Bdos
jmp Edit
;Increment String count
Char1: mov a,m
inr a
mov m,a
;Increment StringCursor
lhld StringCursor
inx h
shld StringCursor
dcx h
;Move in new data
Char2: mov a,m ;get data for next
mov m,c ;write data
mov c,a ;set up for next
inx h
ana a ;is it last
jnz Char2 ;jmp if no
mov m,c ;write end flag
PAGE
;Can LineCursor move right?
lhld LineCursor
mov a,l
cpi 4Fh
jz Char5 ;jmp if no
cpi 0CFh
jz Char5 ;jmp if no
;move LineCursor right
inx h
shld LineCursor
;Display line
Char4: call Display
jmp Edit
;Increment String1st
Char5: lhld String1st
inx h
shld String1st
jmp Char4
;**** Routine BadWait ****
;Will wait for any key (sends message) and then jmp to Begin
BadWait: mvi c,9 ;send message
lxi d,BadOpen1
call Bdos
mvi e,0FDh ;wait for key
mvi c,6
call Bdos
jmp Begin
BadOpen1: dw NL,NL
db 'Push any key to continue.'
dw NLè db MsgEnd
PAGE
;**** Subroutine TestFile ****
;Test existing file found on disk
;If MAKEST file then return with Zero Flag set
;Send message
TestFile:
call FileName
mvi c,9
lxi d,FEmsg
call Bdos
jmp FEmsgOut
FEmsg: db ' exists on the selected drive.'
db MsgEnd
FEmsgOut: db 0
;Clear area for existing FileName
lxi h,Existing
lxi b,200h ;more than enough
ClearArea: mvi m,0
inx h
dcx b
mov a,b
ora c
jnz ClearArea
;Load existing file
mvi c,26 ;set DMA address
lxi d,Existing
call Bdos
mvi c,15 ;open existing file
lxi d,FcbRun
call Bdosè
mvi c,20 ;read sequential
lxi d,FcbRun
call Bdos
PAGE
;Test if embedded "MAKEST end message" is present
lxi h,Existing+0FFh-(+EndS9-EndS8) ;first load "MsgEnd" to
;byte before embedded message
mvi m,MsgEnd
inx h ;now set HL to first byte of embedded message
lxi d,EndS8
mvi b,EndS9-EndS8
Test: ldax d
cmp m
jnz NotFile ;jmp if embedded message not MAKEST's
inx h !inx d
dcr b
jnz Test
;This is a MAKEST file - Test if before Version 1.5
lxi h,Existing+EndS7-Data ;Get 'V'
mov a,m
cpi 'V'
jnz B15V ;jmp if before Version 1.5
;This is a MAKEST file of Version 1.5 or after - Send message
mvi c,9
lxi d,MFmsg1
call Bdos
jmp MF2
MFmsg1: dw NL
db 'This file was created by MAKEST '
db MsgEnd
MF2: mvi c,9 ;Send Version number
lxi d,Existing+EndS7-Data
call Bdos
MF3: mvi c,9
lxi d,MFmsg3
call Bdos
jmp MF4
MFmsg3: dw NL
db 'It',39,'s command line is:'
dw NL
db MsgEnd
MF4: mvi c,9 ;Send String message
lxi d,Existing+String-Data
call Bdos
xra a ;set zero flag
ret
èPAGE
;Not a MAKEST file - Send message
NotFile: mvi c,9
lxi d,NMmsg
call Bdos
mvi a,1 ;clear zero flag
ana a
ret
NMmsg: db 'This file was not made by MAKEST. '
dw NL
db MsgEnd
;File created before MAKEST Version 1.5 - Send message
B15V: mvi c,9
lxi d,B15Vmsg1
call Bdos
jmp MF3
B15Vmsg1: dw NL
db 'This file was made by MAKEST before Version 1.5 '
db 27,94,'It should be replaced.',27,113
db MsgEnd
PAGE
;**** Write File to Disk ****
;Is there data?
Write: lxi h,Buffer
inx h
mov a,m
ana a
jz Wait ;jmp if none
;Ask which drive to select
call HomeIt
mvi c,9
lxi d,Write2
call Bdos
jmp Write3
Write2: db 'Which drive do you want to write '
db MsgEnd
Write3: call FileName
mvi c,9
lxi d,Write5
call Bdos
jmp Write6
Write5: db ' to?'
dw NL
db 'Select A,B,etc. or <ESC> to return to main menu.'
dw NL
db MsgEnd
;Wait for key
Write6: mvi c,6
mvi e,0FDh
call Bdos
cpi 1Bh ;ESC
jz Begin
ani 5Fh ;convert from small to cap.
cpi 'A' ;is it less than 'A'?
jc Write6 ;jmp if yes
cpi 'Q' ;is it less than 'Q'
jc Write10 ;jmp if yes
jmp Write6 ;sorry, not A to P
;Convert to drive code and store
Write10: sta Write17 ;store drive letter
ani 1Fh
sta FcbNew
;Create FcbRun
call Create
PAGE
;Clear screen
Write11: call HomeIt
;Open New File
mvi c,22
lxi d,FcbRun
call Bdos
è;Test if file opened
ana a
jz Write40 ;jmp if file opened with no problem
mov a,h
cpi 8h
jz Write15
cpi 0
jnz BadWait
;No directory space available
mvi c,9
lxi d,Write12
call Bdos
jmp BadWait
Write12: dw NL,NL
db 'No directory space available.'
dw NL
db MsgEnd
;Ask if file to be overwritten?
Write15: call HomeIt
call FileName
mvi c,9
lxi d,Write16
call Bdos
jmp Write20
Write16: db ' already exists on drive '
Write17: db 'A: '
dw NL
db 'Do you wish to overwrite this file with your new '
db '"command" file? (Y/N) '
db MsgEnd
PAGE
;Wait for Erase Answer
Write20: mvi c,6
mvi e,0FDh
call Bdos
cpi 'Y'
jz Write22
cpi 'y'
jz Write22
jmp Begin
;Erase fileèWrite22: mvi c,19
lxi d,FcbRun
call Bdos
ana a ;test if erased
jz Write11 ;jmp if erased
mov a,h ;test if R/O
cpi 3
jz Write30 ;jmp if R/O
jmp BadWait
;Ask About Read/Only
Write30: mvi c,9
lxi d,Write31
call Bdos
jmp Write32
Write31: dw NL,NL
db 'The file is Read/Only. Overwrite? (Y/N) '
db MsgEnd
;Wait for answer
Write32: mvi c,6
mvi e,0FDh
call Bdos
cpi 'Y'
jz Write35
cpi 'y'
jz Write35
jmp Begin
;Erase Read/Only
Write35:lda FcbRun+9 ;set FCB to R/Wè ani 7Fh
sta FcbRun+9
mvi c,30 ;now set file on disk to R/W
lxi d,FcbRun
call Bdos
jmp Write22
PAGE
;**** Load End Flags into Data ****
;Get next address after String
Write40: mvi b,0 ;load number of char to bc
lda Buffer+1
mov c,a
lxi h,String ;load string start adr
dad b ;offset
;add end flag of 0h
mvi m,0
inx h
;add message end flag of $
mvi m,'$'
inx h
;**** Write Data to Disk ****
mvi c,26 ;set DMA address
lxi d,Data
call Bdos
mvi c,21 ;write data
lxi d,FcbRun
call Bdos
mvi c,16 ;close file
lxi d,FcbRun
call Bdos
jmp Begin
**** FCB "to be run" location ***
FcbRun: ds 1
db 'EXECST COM'
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
**** FCB "to be read" location ****
FcbNew: ds 1
db 'EXECST COM'
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
FcbEnd: ds 1
PAGE
**** Program Data Assembly Area ****
;Set Stack
Data: lxi sp,Stack1 ;0100h
;Get/Set System Control Block
;Without the following routine the system prompt may display on theè;same line last written to. This routine is the same format as found
;in the Osborne EXECST.COM. What it exactly does is unknown by this
;programmer. DR says that an offset of 3Ah is "Reserved for System Use".
mvi c,49 ;get/set System Control Block ;0103h
lxi d,SCB-Data+100h ;location of SCB Parameter Block
call Bdos
mvi l,0B5h
mov a,m
ori 2
mov m,a
;Move String to Default DMA
lxi h,String-Data+100h ;address of String when ;0111h
; Data moved to 100h
lxi d,80h ;Default DMA start address
Data3: mvi b,128 ;maximum character count of string
Data4: mov a,m ;get String
stax d ;store String
inx h ;go to next char
inx d ;go to next char
dcr b ;test if last char
jnz Data4-Data+100h ;address of Data4 when Data moved to 100h
;Chain String to Program
mvi c,47 ;chain to program ;0121h
mvi e,0h ;use default CCP values of drive and user number
jmp Bdos
;SCB Parameter Block
SCB: db 3Ah ;offset of SCB ;0128
db 0 ;"get" operation
;Development Area for String
Buffer: ds 2 ;2 bytes for number of characters in string ;012Ah
String: db 0 ;Start of string of characters to be chained. ;012Ch
db '$' ;At first command must be 0h then '$'.
ds 124 ;A total of 126 characters.
ds 2 ;String must end with 0h then '$'.
;Unused space
ds 36 ;01CAh
;Version number
EndS7: db 'Ver. ',xVersion,'.',yVersion,0,'$',0 ;01D0h
;Recognition message
EndS8: db 'This EXECST.COM was created by MAKEST' ;01DBh
EndS9: db 0 ;0200h
PAGE
;**** Routine Diff ****
;Change to a different file name
;Send message
Diff: call HomeIt
mvi c,9
lxi d,Diff1
call Bdos
jmp Diff2
Diff1: db 'What is the new file name to be?'
dw NL
db 'Enter up to an 8 character file name.'
dw NL
db MsgEnd
;Setup NewName
Diff2: lxi h,NewName
mvi m,8 ;8 characters max
inx h
inx h
mvi m,0 ;no data to start
jmp Diff4
NewName: ds 15
;Get file name
Diff4: lxi d,NewName
call NameEdit
cpi 0
jz Diff10
cpi 1
jz Begin
cpi 2
jz BadWait
jmp Begin
;Setup similar to LineEdit
NameEdit: xchg
shld StringStart
lda WhichRow
ani 24
sta CursorY
mvi c,9
lxi d,Edit1
call Bdos
jmp Edit3
PAGE
;Test if no data
Diff10: lda NewName+1
ana a
jz Begin ;Forget it if no data
;Convert small letters to caps
lxi h,NewName+2
Diff11: mov a,m
ana a
jz Diff13
cpi 'a'
jc Diff12 ;jmp if less than 'a'
cpi 'z'+1
jnc Diff12 ;jmp if greater than 'z'
sui 20h ;convert
mov m,a
Diff12: inx h
jmp Diff11
;Fill FcbRun file name with blanks
Diff13: mvi b,8
mvi a,' '
lxi h,FcbRun+1
Diff15: mov m,a
inx h
dcr b
jnz Diff15
;Move new file name to FcbRun
lxi h,NewName+2
lxi d,FcbRun+1
Diff17: mov a,m
ana a
jz Diff20
stax d
inx h
inx d
jmp Diff17
PAGE
;Fill FcbNew file name with blanks
Diff20: mvi b,8
mvi a,' '
lxi h,FcbNew+1
Diff21: mov m,a
inx h
dcr b
jnz Diff21
;Move new file name to FcbNew
lxi h,NewName+2
lxi d,FcbNew+1
Diff23: mov a,m
ana a
jz Diff25
stax d
inx h
inx d
jmp Diff23
;Fill FN1 file name with 0's
Diff25: mvi b,8
mvi a,0
lxi h,FN1
Diff27: mov m,a
inx h
dcr b
jnz Diff27
;Move new file name to FN1
lxi h,NewName+2
lxi d,FN1
Diff30: mov a,m
ana a
jz Diff33
stax d
inx h
inx d
jmp Diff30
;That's it. Lets go home.
Diff33: jmp Begin
end 100h