mirror of https://github.com/wwarthen/RomWBW.git
committed by
GitHub
196 changed files with 82532 additions and 48 deletions
Binary file not shown.
File diff suppressed because it is too large
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
@ -0,0 +1,369 @@ |
|||
BBC BASIC (Z80) |
|||
|
|||
Generic CP/M Version 3.00 |
|||
|
|||
(C) Copyright R.T.Russell 1982-1999 |
|||
|
|||
1. INTRODUCTION |
|||
|
|||
BBC BASIC (Z80) has been designed to be as compatible as possible with |
|||
Version 4 of the 6502 BBC BASIC resident in the BBC Micro Master series. |
|||
The language syntax is not always identical to that of the 6502 version, |
|||
but in most cases the Z80 version is more tolerant. |
|||
|
|||
BBC BASIC (Z80) is as machine independent as possible and, as supplied, |
|||
it will run on any CP/M 2.2 (or later) system using a Z80 processor |
|||
(checks are carried out to ensure that the processor is a Z80 and that |
|||
the version of CP/M is at least 2.2). It is minimally configured for an |
|||
ADM3a-compatible VDU. |
|||
|
|||
Few CP/M systems offer colour graphics of the quality provided as |
|||
standard on the BBC Microcomputer, and no software can provide colour |
|||
high-resolution graphics from a monochrome character-orientated computer. |
|||
However, many CP/M system users are interested in the advanced program |
|||
structures available from BBC BASIC and, within the limitations of the |
|||
host computer, BBC BASIC (Z80) provides the programming structures and |
|||
the non-graphic commands and functions specified for BBC BASIC. |
|||
|
|||
In order to make full use of the facilities available in BBC BASIC (Z80) |
|||
it is necessary to install a small patch to adapt it to the capabilities |
|||
of the host computer. The source code of the patch present in the |
|||
distribution version is supplied as BBCDIST.MAC. |
|||
|
|||
This documentation should be read in conjunction with a standard BBC |
|||
BASIC manual. Only those features which differ from the standard Acorn |
|||
versions are documented here. |
|||
|
|||
|
|||
2. MEMORY UTILISATION |
|||
|
|||
BBC BASIC (Z80) requires about 16 Kbytes of code space, resulting in a |
|||
value of PAGE of about &3E00. The remainder of the user memory is |
|||
available for BASIC programs, variables (heap) and stack. Depending on |
|||
the system configuration, HIMEM can have a value up to &FE00. |
|||
|
|||
|
|||
3. COMMANDS, STATEMENTS AND FUNCTIONS |
|||
|
|||
The syntax of BASIC commands, statements and functions is in most cases |
|||
identical to that of the BBC Micro version (BASIC 4). The few |
|||
differences are documented here: |
|||
|
|||
ADVAL |
|||
This function is not implemented. |
|||
|
|||
CALL |
|||
CALL sets up a table in RAM containing details of the parameters; the |
|||
processor's IX register is set to the address of this parameter table. |
|||
The other processor registers are initialised as follows: |
|||
|
|||
A is initialised to the least significant byte of A% |
|||
B is initialised to the least significant byte of B% |
|||
C is initialised to the least significant byte of C% |
|||
D is initialised to the least significant byte of D% |
|||
E is initialised to the least significant byte of E% |
|||
F is initialised to the least significant byte of F% |
|||
H is initialised to the least significant byte of H% |
|||
L is initialised to the least significant byte of L% |
|||
|
|||
The parameter types are: |
|||
|
|||
Code No. Parameter Type Example |
|||
0 Byte (8 bits) ?A% |
|||
4 Word (32 bits) !A% or A% |
|||
5 Real (40 bits) A |
|||
128 Fixed string $A% |
|||
129 Movable string A$ |
|||
|
|||
On entry to the subroutine the parameter table contains the following |
|||
values: |
|||
|
|||
Number of parameters 1 byte (at IX) |
|||
|
|||
Parameter type 1 byte (at IX+1) |
|||
Parameter address 2 bytes (at IX+2, IX+3, LSB first) |
|||
|
|||
Parameter type ) repeated as often as necessary |
|||
Parameter address ) |
|||
|
|||
Except in the case of a movable string (normal string variable), the |
|||
parameter address given is the absolute address at which the item is |
|||
stored. In the case of movable strings (type 129) it is the address of a |
|||
4-byte parameter block containing the current length, the maximum length |
|||
and the start address of the string (LSB first) in that order. |
|||
|
|||
Integer variables are stored in twos complement form with their least |
|||
significant byte first. |
|||
|
|||
Fixed strings are stored as the characters of the string followed by a |
|||
carriage return (&0D). |
|||
|
|||
Floating point variables are stored in binary floating point format with |
|||
their least significant byte first; the fifth byte is the exponent. The |
|||
mantissa is stored as a binary fraction in sign and magnitude format. |
|||
Bit 7 of the most significant byte is the sign bit and, for the purposes |
|||
of calculating the magnitude of the number, this bit is assumed to be set |
|||
to one. The exponent is stored as an integer in excess 127 format (to |
|||
find the exponent subtract 127 from the value in the fifth byte). |
|||
|
|||
If the exponent byte of a floating point number is zero, the number is an |
|||
integer stored in integer format in the mantissa bytes. Thus an integer |
|||
can be represented in two different ways in a real variable. For example |
|||
the value +5 can be stored as: |
|||
|
|||
05 00 00 00 00 Integer 5 |
|||
00 00 00 20 82 (0.5 + 0.125) * 2^3 |
|||
|
|||
COLOUR (COLOR) |
|||
This statement is not implemented. |
|||
|
|||
DRAW |
|||
This statement is not implemented. |
|||
|
|||
EDIT |
|||
A command to edit or concatenate and edit the specified program line(s). |
|||
The specified lines (including their line numbers) are listed as a single |
|||
line. By changing only the line number you can use EDIT to duplicate a |
|||
line. |
|||
|
|||
EDIT 230 |
|||
EDIT 200,230 |
|||
|
|||
The following control functions are active both in the EDIT mode and in |
|||
the immediate entry mode (i.e. at the BASIC prompt): |
|||
|
|||
Move the cursor one character position to the left |
|||
Move the cursor one character position to the right |
|||
Move the cursor to the start of the line |
|||
Move the cursor to the end of the line |
|||
Insert a space at the current cursor position |
|||
Delete the character at the current cursor position |
|||
Backspace and delete the character to the left of the cursor |
|||
Delete all characters to the left of the cursor |
|||
Delete all characters from the cursor to the end of the line |
|||
|
|||
The choice of which keys activate these functions is made when BBC BASIC |
|||
is configured for a particular system. The distribution version uses ^H, |
|||
^I, ^K, ^J, ^A, ^E, DEL (&7F), ^L and ^X. |
|||
|
|||
To exit EDIT mode and replace the edited line, type RETURN (ENTER). |
|||
|
|||
To abort the edit and leave the line unchanged, type ESCape. |
|||
|
|||
ENVELOPE |
|||
This statement is not implemented. |
|||
|
|||
GET |
|||
This function waits for a character to be typed at the keyboard, and |
|||
returns the ASCII code. |
|||
|
|||
GET can also be used to read data from a processor I/O port; full 16-bit |
|||
port addressing is available: |
|||
|
|||
N% = GET(X%) : REM input from port X% |
|||
|
|||
INKEY |
|||
This function waits for a specified maximum number of centiseconds for a |
|||
character to be typed at the keyboard. If no character is typed in that |
|||
time, the value -1 is returned. In the distribution version the delay is |
|||
determined by a simple software timing loop, and may be very inaccurate. |
|||
The customisation patch allows this to be adjusted to suit the system in |
|||
use. |
|||
|
|||
INPUT# |
|||
The format of data files is different from that used by the BBC Micro, in |
|||
part to improve compatibility with standard CP/M files. Numeric values |
|||
are stored as five bytes in the format documented under CALL; if the |
|||
fifth byte is zero the value is an integer. Strings are stored as the |
|||
characters of the string (in the correct order!) followed by a carriage |
|||
return (&0D). |
|||
|
|||
MODE |
|||
This statement is not implemented. |
|||
|
|||
MOVE |
|||
This statement is not implemented. |
|||
|
|||
PLOT |
|||
This statement is not implemented. |
|||
|
|||
POINT |
|||
This function is not implemented. |
|||
|
|||
PRINT# |
|||
The format of data files is different from that used by the BBC Micro, in |
|||
part to improve compatibility with standard CP/M files. Numeric values |
|||
are stored as five bytes in the format documented under CALL; if the |
|||
fifth byte is zero the value is an integer. Strings are stored as the |
|||
characters of the string (in the correct order!) followed by a carriage |
|||
return (&0D). |
|||
|
|||
PUT |
|||
A statement to output data to a processor port. Full 16-bit addressing |
|||
is available. |
|||
|
|||
PUT A%,N% : REM Output N% to port A% |
|||
|
|||
SOUND |
|||
This statement is not implemented. |
|||
|
|||
TIME |
|||
This pseudo-variable is not implemented in the distribution version, but |
|||
can be supported by means of the customisation patch. See BBCDIST.MAC. |
|||
|
|||
USR |
|||
As with CALL, the processor's registers are initialised as follows: |
|||
|
|||
A is initialised to the least significant byte of A% |
|||
B is initialised to the least significant byte of B% |
|||
C is initialised to the least significant byte of C% |
|||
D is initialised to the least significant byte of D% |
|||
E is initialised to the least significant byte of E% |
|||
F is initialised to the least significant byte of F% |
|||
H is initialised to the least significant byte of H% |
|||
L is initialised to the least significant byte of L% |
|||
|
|||
USR returns a 32-bit integer result composed of the processor's H, L, H' |
|||
and L' registers, with H being the most significant. |
|||
|
|||
|
|||
4. RESIDENT Z80 ASSEMBLER |
|||
|
|||
The in-line assembler is accessed in exactly the same way as the 6502 |
|||
assembler in the BBC Micro version of BBC BASIC. That is, '[' enters |
|||
assembler mode and ']' exits assembler mode. |
|||
|
|||
All standard Zilog mnemonics are accepted: ADD, ADC and SBC must be |
|||
followed by A or HL. For example, ADD A,C is accepted but ADD C is not. |
|||
However, the brackets around the port number in IN and OUT are optional. |
|||
Thus both OUT (5),A and OUT 5,A are accepted. The instruction IN F,(C) |
|||
is not accepted, but the equivalent code is produced from IN (HL),C |
|||
|
|||
The pseudo-ops DEFB, DEFW and DEFM are included. DEFM works like EQUS in |
|||
the 6502 version. |
|||
|
|||
|
|||
5. OPERATING SYSTEM INTERFACE |
|||
|
|||
The following resident Operating System ("star") commands are |
|||
implemented. They may be accessed directly (e.g. *BYE) or via the OSCLI |
|||
statement (OSCLI "BYE"). |
|||
|
|||
Control characters, lower-case characters, DEL and quotation marks may be |
|||
incorporated in filenames by using the 'escape' character '|'. However, |
|||
there is no equivalent to the BBC Microcomputer's '|!' to set bit 7. |
|||
|
|||
*BYE |
|||
Returns control to the operating system (CP/M). |
|||
|
|||
*CPM |
|||
Same as *BYE. |
|||
|
|||
*. [filespec] |
|||
*DIR [filespec] |
|||
List the files which match the (optional) ambiguous filespec. If the |
|||
filespec is omitted, all .BBC files are listed: |
|||
*DIR List all .BBC files on the disk |
|||
*DIR B:*.* List all files on disk B: |
|||
*.*.* List all files on the current disk |
|||
|
|||
*DRIVE d: |
|||
Select drive d as the default drive for subsequent disk operations. |
|||
|
|||
*ERA filespec |
|||
Erase (delete) the specified disk file or files. The extension defaults |
|||
to .BBC if omitted. |
|||
|
|||
*ESC [ON|OFF] |
|||
*ESC OFF disables the abort action of the ESCape key; after *ESC OFF the |
|||
ESCape key simply returns the ASCII code ESC (27). *ESC ON, or *ESC, |
|||
restores the normal action of the ESCape key. |
|||
|
|||
*EXEC filespec |
|||
Accept console input from the specified file instead of from the |
|||
keyboard. If the extension is omitted, .BBC is assumed. |
|||
|
|||
*LOAD filespec aaaa |
|||
Loads the specified file into memory at address aaaa. The load address |
|||
must be specified. If the extension is omitted, .BBC is assumed. |
|||
|
|||
*OPT [n] |
|||
Select the destination for console output characters. The value n is in |
|||
the range 0 to 2, as follows: |
|||
|
|||
0 Send characters to the console output |
|||
1 Send characters to the auxiliary output |
|||
2 Send characters to the printer (list) output |
|||
|
|||
*REN newfile=oldfile |
|||
*RENAME newfile=oldfile |
|||
Renames 'oldfile' as 'newfile'. If the extension is omitted, .BBC is |
|||
assumed. |
|||
|
|||
*RESET |
|||
Rest the disk system (CP/M function 13). This command does not close any |
|||
files nor does it perform any other housekeeping function. You should |
|||
use *RESET after you have changed a disk. |
|||
|
|||
*SAVE filespec aaaa bbbb |
|||
*SAVE filespec aaaa +llll |
|||
This command saves a specified range of memory to disk. The address range |
|||
is specified either as start (aaaa) and end+1 (bbbb) or as start (aaaa) |
|||
and length (llll). If the extension is omitted, .BBC is assumed. |
|||
|
|||
*SPOOL [filespec] |
|||
Copy all subsequent console output to the specified file. If the filename |
|||
is omitted, any current spool file is closed and spooling is terminated. |
|||
If the extension is omitted, .BBC is assumed. |
|||
|
|||
*TYPE filespec |
|||
Type the specified file to the screen. If the extension is omitted, .BBC |
|||
is assumed. |
|||
|
|||
*| comment |
|||
This is a comment line. Anything following the | is ignored. |
|||
|
|||
|
|||
6. ERROR MESSAGES AND CODES |
|||
|
|||
Untrappable: |
|||
|
|||
No room RENUMBER space |
|||
Silly LINE space |
|||
Sorry Bad program |
|||
|
|||
Trappable - BASIC: |
|||
|
|||
1 Out of range 24 Exp range |
|||
2 25 |
|||
3 26 No such variable |
|||
4 Mistake 27 Missing ) |
|||
5 Missing , 28 Bad HEX |
|||
6 Type mismatch 29 No such FN/PROC |
|||
7 No FN 30 Bad call |
|||
8 31 Arguments |
|||
9 Missing " 32 No FOR |
|||
10 Bad DIM 33 Can't match FOR |
|||
11 DIM space 34 FOR variable |
|||
12 Not LOCAL 35 |
|||
13 No PROC 36 No TO |
|||
14 Array 37 |
|||
15 Subscript 38 No GOSUB |
|||
16 Syntax error 39 ON syntax |
|||
17 Escape 40 ON range |
|||
18 Division by zero 41 No such line |
|||
19 String too long 42 Out of DATA |
|||
20 Too big 43 No REPEAT |
|||
21 -ve root 44 |
|||
22 Log range 45 Missing # |
|||
23 Accuracy lost |
|||
|
|||
Trappable - OS: |
|||
|
|||
190 Directory full 214 File not found |
|||
192 Too many open files 222 Channel |
|||
196 File exists 253 Bad string |
|||
198 Disk full 254 Bad command |
|||
200 Close error 255 CP/M error |
|||
204 Bad name |
|||
|
|||
@ -0,0 +1,225 @@ |
|||
TITLE BBCDIST.Z80 (C) R.T.RUSSELL 1982 |
|||
; |
|||
;BBC BASIC (Z80) - CP/M VERSION 2.30 & 3.00 |
|||
;(C) COPYRIGHT R.T.RUSSELL, 1982. |
|||
;ALL RIGHTS RESERVED. |
|||
; |
|||
;THIS PROGRAM ALLOWS THE USER TO ADAPT BBC BASIC TO THE |
|||
;PARTICULAR CHARACTERISTICS OF HIS SYSTEM HARDWARE ETC. |
|||
; |
|||
;THE PROGRAM RESIDES AT 100H FOR EASE OF LOADING. |
|||
;*** IT MUST NOT EXCEED 256 BYTES IN TOTAL LENGTH *** |
|||
; |
|||
;PLEASE NOTE THAT A Z80 PROCESSOR AND CP/M VERSION 2.2 |
|||
;OR LATER ARE REQUIRED. |
|||
; |
|||
;R.T.RUSSELL, 11-03-1984, 03-05-1989 |
|||
;ALTERNATE REGISTERS SAVED FOR BDOS CALL, 04-06-2000 |
|||
; |
|||
CPM EQU 5 |
|||
COLD EQU 200H |
|||
; |
|||
GLOBAL CLRSCN |
|||
GLOBAL PUTCSR |
|||
GLOBAL GETCSR |
|||
GLOBAL PUTIME |
|||
GLOBAL GETIME |
|||
GLOBAL GETKEY |
|||
GLOBAL BYE |
|||
; |
|||
ASEG |
|||
ORG 100H |
|||
; |
|||
;JUMP TABLE - BASIC makes calls to hardware-dependent |
|||
;features via this table: |
|||
; |
|||
JP INIT |
|||
CLRSCN: JP CLS ;CLEAR SCREEN |
|||
PUTCSR: JP PCSR ;SET CURSOR POSN. |
|||
GETCSR: JP GCSR ;READ CURSOR POSN. |
|||
PUTIME: JP PTIME ;SET ELAPSED TIME |
|||
GETIME: JP GTIME ;READ ELAPSED TIME |
|||
GETKEY: JP INKEY ;READ KEY (TIME LIMIT) |
|||
BYE: JP REBOOT ;RETURN TO CP/M |
|||
; |
|||
;THE CODE WHICH FOLLOWS IS A SKELETON VERSION SUITABLE |
|||
;FOR ANY CP/M SYSTEM. IT HAS BEEN CONFIGURED FOR A VT100 TO SOME DEGREE |
|||
;BY PETER SCHORN. |
|||
; |
|||
|
|||
PRSTR EQU 9 |
|||
|
|||
;INIT - Perform hardware initialisation (if any). |
|||
; |
|||
INIT: LD A,2 |
|||
INC A |
|||
LD DE,NOTZ80 |
|||
JP PE,FAIL |
|||
LD C,12 |
|||
CALL BDOS |
|||
OR A |
|||
LD DE,NOTV2 |
|||
JP NZ,COLD |
|||
FAIL: LD C,PRSTR |
|||
CALL BDOS |
|||
RST 0 |
|||
; |
|||
NOTZ80: DEFB 'Wrong processor$' |
|||
NOTV2: DEFB 'Wrong CP/M version$' |
|||
; |
|||
;REBOOT - Switch off interrupts and return to CP/M |
|||
; |
|||
REBOOT: RST 0 |
|||
; |
|||
;GTIME - Read elapsed-time clock. |
|||
; Outputs: DEHL = elapsed time (centiseconds) |
|||
; Destroys: A,D,E,H,L,F |
|||
; |
|||
GTIME: LD DE,0 |
|||
LD HL,0 |
|||
RET |
|||
; |
|||
;PTIME - Load elapsed-time clock. |
|||
; Inputs: DEHL = time to load (centiseconds) |
|||
; Destroys: A,D,E,H,L,F |
|||
; |
|||
PTIME: RET |
|||
; |
|||
;CLS - Clear screen for VT100. |
|||
; Destroys: A,D,E,H,L,F |
|||
; |
|||
CLS: PUSH BC ; save BC |
|||
LD C,PRSTR ; command for output string |
|||
LD DE,CLSSTR ; start address of string |
|||
CALL BDOS ; output to terminal |
|||
POP BC ; restore BC |
|||
RET |
|||
CLSSTR: DEFB 27,'[2J$' ; VT100 string for clear screen |
|||
|
|||
; |
|||
;INKEY - Sample keyboard with specified wait. |
|||
; This version uses a simple software timing loop. |
|||
; Modify to use hardware/interrupt timer if available. |
|||
; Inputs: HL = Time to wait (centiseconds) |
|||
; Outputs: Carry reset indicates time-out. |
|||
; If carry set, A = character typed. |
|||
; Destroys: A,D,E,H,L,F |
|||
; |
|||
INKEY: PUSH BC |
|||
PUSH HL |
|||
LD C,6 |
|||
LD E,0FFH |
|||
CALL BDOS ;CONSOLE INPUT |
|||
POP HL |
|||
POP BC |
|||
OR A |
|||
SCF |
|||
RET NZ ;KEY PRESSED |
|||
OR H |
|||
OR L |
|||
RET Z ;TIME-OUT |
|||
PUSH BC |
|||
LD A,-1 |
|||
LD BC,1250 ;DELAY CONSTANT |
|||
WAIT: DEC BC |
|||
CP B |
|||
JP NZ,WAIT ;WAIT FOR APPROX 10ms |
|||
POP BC |
|||
DEC HL |
|||
JR INKEY |
|||
; |
|||
;PCSR - Move cursor to specified position. |
|||
; Inputs: DE = horizontal position (LHS=0) |
|||
; HL = vertical position (TOP=0) |
|||
; called by TAB(column, row) |
|||
PCSR: LD B,L ; vertical = line (row) |
|||
CALL CONV ; normalized and convert to decimal |
|||
LD (LIN),HL ; and store into string |
|||
LD B,E ; horizontal = column |
|||
CALL CONV ; normalized and convert to decimal |
|||
LD (COL),HL ; and store into string |
|||
LD C,PRSTR ; output string command |
|||
LD DE,CURS ; start of string |
|||
JR BDOS ; output string to terminal |
|||
|
|||
; VT100 sequence for cursor positioning |
|||
CURS: DEFB 27, '[' |
|||
LIN: DEFW 0 ; high byte, low byte for decimal line |
|||
DEFB ';' |
|||
COL: DEFW 0 ; high byte, low byte for decimal column |
|||
DEFB 'H$' |
|||
|
|||
; convert binary B (0 <= B < 99, not checked) into B+1 in decimal. |
|||
; L = upper byte, H = lower byte. ready for LD (...), HL |
|||
; destroys A, B, L, H |
|||
; optimized for space over time |
|||
CONV: INC B ; normalize, home in VT100 is (1,1) |
|||
LD A,'0' ; A is counter for low byte of result |
|||
LD L,A ; L is counter for high byte of result |
|||
CONVLP: INC A ; now B times increment AL in decimal |
|||
CP '9'+1 ; low byte overflow? |
|||
JR NZ,CONT ; no, continue incrementing |
|||
LD A,'0' ; reset low byte |
|||
INC L ; and increment high byte |
|||
CONT: DJNZ CONVLP ; B times |
|||
LD H,A ; put low byte into right place |
|||
RET |
|||
|
|||
|
|||
;BDOS - Save the IX and IY and alternate registers |
|||
; before performing a CP/M function call. |
|||
; |
|||
BDOS: PUSH IX |
|||
PUSH IY |
|||
EXX |
|||
PUSH BC |
|||
PUSH DE |
|||
PUSH HL |
|||
EXX |
|||
EX AF,AF' |
|||
PUSH AF |
|||
EX AF,AF' |
|||
CALL CPM |
|||
EX AF,AF' |
|||
POP AF |
|||
EX AF,AF' |
|||
EXX |
|||
POP HL |
|||
POP DE |
|||
POP BC |
|||
EXX |
|||
POP IY |
|||
POP IX |
|||
RET |
|||
|
|||
|
|||
;GCSR - Return cursor coordinates. |
|||
; Outputs: DE = X coordinate (POS) |
|||
; HL = Y coordinate (VPOS) |
|||
; Destroys: A,D,E,H,L,F |
|||
; |
|||
GCSR: LD DE,0 |
|||
LD HL,0 |
|||
RET |
|||
; |
|||
IF $ GT 1F4H |
|||
ERROR 'INSUFFICIENT SPACE' |
|||
ENDIF |
|||
; |
|||
ORG 1F4H |
|||
; |
|||
DEFB 80 ;WIDTH |
|||
DEFB 'E' AND 1FH ;CURSOR UP |
|||
DEFB 'X' AND 1FH ;CURSOR DOWN |
|||
DEFB 'A' AND 1FH ;START OF LINE |
|||
DEFB 'F' AND 1FH ;END OF LINE |
|||
DEFB 'T' AND 1FH ;DELETE TO END OF LINE |
|||
DEFB 'H' AND 1FH ;BACKSPACE |
|||
DEFB 'U' AND 1FH ;CANCEL LINE |
|||
DEFB 'S' AND 1FH ;CURSOR LEFT |
|||
DEFB 'D' AND 1FH ;CURSOR RIGHT |
|||
DEFB 'G' AND 1FH ;DELETE CHARACTER |
|||
DEFB 'V' AND 1FH ;INSERT CHARACTER |
|||
; |
|||
FIN: END |
|||
|
|||
@ -0,0 +1,13 @@ |
|||
; patch BBCBASIC with BBCDIST |
|||
; need M80 and L80 |
|||
xsub |
|||
m80 =bbcdist/z |
|||
l80 bbcdist,bbcdist/n/e |
|||
ddt bbcbasic.org |
|||
ibbcdist.com |
|||
r |
|||
g0 |
|||
save 58 bbcbasic.com |
|||
era bbcdist.rel |
|||
era bbcdist.com |
|||
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,26 @@ |
|||
===== Aztec C II compiler v1.06D ===== |
|||
|
|||
Aztec C is a discontinued programming language for a variety of platforms |
|||
including MS-DOS, Apple II DOS 3.3 and PRoDOS, Commodore 64, Macintosh and |
|||
Amiga. This disk contains the CP/M version of that compiler. A cross-compiler |
|||
for MS-DOS or Windows XP is also available. |
|||
|
|||
For full documentation, see https://www.aztecmuseum.ca/ |
|||
|
|||
The user manual is available in the Doc directory |
|||
Aztec_C_1.06_User_Manual_Mar84.pdf |
|||
|
|||
== License == |
|||
|
|||
I herewith grant you a non-exclusive conditional licence to use any and |
|||
all of my work included with this compiler for whatever use you deem fit, |
|||
provided you do not take credit for my work, and that you leave my |
|||
copyright notices intact in all of it. |
|||
|
|||
I believe everything I have written to be correct. Regardless, I, Bill |
|||
Buckels, do not guarantee, or warranty, in whole or in part, any of this, |
|||
and further do not offer support for any of this. All of this is provided |
|||
as-is. |
|||
|
|||
Bill Buckels |
|||
bbuckels@mts.net |
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,9 @@ |
|||
main() |
|||
{ |
|||
char buf[80]; |
|||
printf("please enter your name: "); |
|||
gets(buf); |
|||
printf("hello, %s, welcome to the growing community of Aztec C users\n", buf); |
|||
} |
|||
|
|||
|
|||
@ -0,0 +1,267 @@ |
|||
libc.h |
|||
/* Copyright (C) 1981, 1982 by Manx Software Systems */ |
|||
|
|||
extern int errno; |
|||
#define FLT_FAULT 0 /* vector for floating-point faults */ |
|||
extern int (*Sysvec[])(); |
|||
|
|||
#define NULL 0 |
|||
#define EOF -1 |
|||
#define BUFSIZ 1024 |
|||
|
|||
#define _BUSY 0x01 |
|||
#define _ALLBUF 0x02 |
|||
#define _DIRTY 0x04 |
|||
#define _EOF 0x08 |
|||
#define _IOERR 0x10 |
|||
|
|||
typedef struct { |
|||
char *_bp; /* current position in buffer */ |
|||
char *_bend; /* last character in buffer + 1 */ |
|||
char *_buff; /* address of buffer */ |
|||
char _flags; /* open mode, etc. */ |
|||
char _unit; /* token returned by open */ |
|||
char _bytbuf; /* single byte buffer for unbuffer streams */ |
|||
int _buflen; /* length of buffer */ |
|||
} FILE; |
|||
|
|||
extern FILE Cbuffs[]; |
|||
extern char *Stdbufs; /* free list of buffers */ |
|||
long ftell(); |
|||
|
|||
#define stdin (&Cbuffs[0]) |
|||
#define stdout (&Cbuffs[1]) |
|||
#define stderr (&Cbuffs[2]) |
|||
#define getchar() agetc(stdin) |
|||
#define putchar(c) aputc(c, stdout) |
|||
#define feof(fp) (((fp)->_flags&_EOF)!=0) |
|||
#define ferror(fp) (((fp)->_flags&_IOERR)!=0) |
|||
#define clearerr(fp) ((fp)->_flags &= ~(_IOERR|_EOF)) |
|||
#define fileno(fp) ((fp)->_unit) |
|||
errno.h |
|||
extern int errno; |
|||
#define ENOENT -1 |
|||
#define E2BIG -2 |
|||
#define EBADF -3 |
|||
#define ENOMEM -4 |
|||
#define EEXIST -5 |
|||
#define EINVAL -6 |
|||
#define ENFILE -7 |
|||
#define EMFILE -8 |
|||
#define ENOTTY -9 |
|||
#define EACCES -10 |
|||
|
|||
#define ERANGE -20 |
|||
#define EDOM -21 |
|||
fcntl.h |
|||
#define O_RDONLY 0 |
|||
#define O_WRONLY 1 |
|||
#define O_RDWR 2 |
|||
#define O_CREAT 0x0100 |
|||
#define O_TRUNC 0x0200 |
|||
#define O_EXCL 0x0400 |
|||
#define O_APPEND 0x0800 |
|||
io.h |
|||
/* Copyright (C) 1982 by Manx Software Systems */ |
|||
/* |
|||
* if MAXCHAN is changed then the initialization of chantab in croot.c |
|||
* should be adjusted so that it initializes EXACTLY MAXCHAN elements of |
|||
* the array. If this is not done, the I/O library may exhibit |
|||
* strange behavior. |
|||
*/ |
|||
#define MAXCHAN 11 /* maximum number of I/O channels */ |
|||
|
|||
/* |
|||
* argument to device routines. |
|||
* this is a typedef to allow future redeclaration to guarantee |
|||
* enough space to store either a pointer or an integer. |
|||
*/ |
|||
typedef char *_arg; |
|||
|
|||
/* |
|||
* device control structure |
|||
*/ |
|||
struct device { |
|||
char d_read; |
|||
char d_write; |
|||
char d_ioctl; /* used by character special devices (eg CON:) */ |
|||
char d_seek; /* used by random I/O devices (eg: a file) */ |
|||
int (*d_open)(); /* for special open handling */ |
|||
}; |
|||
|
|||
/* |
|||
* device table, contains names and pointers to device entries |
|||
*/ |
|||
struct devtabl { |
|||
char *d_name; |
|||
struct device *d_dev; |
|||
_arg d_arg; |
|||
}; |
|||
|
|||
/* |
|||
* channel table: relates fd's to devices |
|||
*/ |
|||
struct channel { |
|||
char c_read; |
|||
char c_write; |
|||
char c_ioctl; |
|||
char c_seek; |
|||
int (*c_close)(); |
|||
_arg c_arg; |
|||
} ; |
|||
extern struct channel chantab[MAXCHAN]; |
|||
|
|||
struct fcb { |
|||
char f_driv; |
|||
char f_name[8]; |
|||
char f_type[3]; |
|||
char f_ext; |
|||
char f_resv[2]; |
|||
char f_rc; |
|||
char f_sydx[16]; |
|||
char f_cr; |
|||
unsigned f_record; char f_overfl; |
|||
}; |
|||
|
|||
struct fcbtab { |
|||
struct fcb fcb; |
|||
char offset; |
|||
char flags; |
|||
char user; |
|||
}; |
|||
|
|||
#define OPNFIL 15 |
|||
#define CLSFIL 16 |
|||
#define DELFIL 19 |
|||
#define READSQ 20 |
|||
#define WRITSQ 21 |
|||
#define MAKFIL 22 |
|||
#define SETDMA 26 |
|||
#define GETUSR 32 |
|||
#define READRN 33 |
|||
#define WRITRN 34 |
|||
#define FILSIZ 35 |
|||
#define SETREC 36 |
|||
|
|||
#define Wrkbuf ((char *)0x80) |
|||
math.h |
|||
double sin(), cos(), tan(), cotan(); |
|||
double asin(), acos(), atan(), atan2(); |
|||
double ldexp(), frexp(), modf(); |
|||
double floor(), ceil(); |
|||
double log(), log10(), exp(), sqrt(), pow(); |
|||
double sinh(), cosh(), tanh(), fabs(); |
|||
|
|||
#define HUGE 5.2e+151 |
|||
#define LOGHUGE 349.3 |
|||
#define TINY 7.5e-155 |
|||
#define LOGTINY -354.8 |
|||
setjmp.h |
|||
/* Copyright (C) 1983 by Manx Software Systems */ |
|||
#define JBUFSIZE (5*sizeof(int)) |
|||
|
|||
typedef char jmp_buf[JBUFSIZE]; |
|||
sgtty.h |
|||
/* Copyright (C) 1983 by Manx Software Systems */ |
|||
|
|||
#define TIOCGETP 0 /* read contents of tty control structure */ |
|||
#define TIOCSETP 1 /* set contents of tty control structure */ |
|||
#define TIOCSETN 1 /* ditto only don't wait for output to flush */ |
|||
|
|||
struct sgttyb { |
|||
char sg_erase; /* ignored */ |
|||
char sg_kill; /* ignored */ |
|||
short sg_flags; /* control flags */ |
|||
}; |
|||
|
|||
/* settings for flags */ |
|||
#define _VALID 0x3a |
|||
#define RAW 0x20 /* no echo or mapping of input/output BDOS(6) */ |
|||
#define CRMOD 0x10 /* map input CR to NL, output NL to CR LF */ |
|||
#define ECHO 0x08 /* ignored unless CBREAK is set */ |
|||
#define CBREAK 0x02 /* input using BDOS(1), unless echo off then */ |
|||
/* same as RAW */ |
|||
stdio.h |
|||
/* Copyright (C) 1982, 1984 by Manx Software Systems */ |
|||
#define fgetc getc |
|||
#define fputc putc |
|||
#define NULL 0 |
|||
#define EOF -1 |
|||
|
|||
#ifdef TINY |
|||
struct fcb { |
|||
char f_driv; |
|||
char f_name[8]; |
|||
char f_type[3]; |
|||
char f_ext; |
|||
char f_resv[2]; |
|||
char f_rc; |
|||
char f_sydx[16]; |
|||
char f_cr; |
|||
unsigned f_record; char f_overfl; |
|||
}; |
|||
|
|||
typedef struct { |
|||
char *_bp; |
|||
struct fcb _fcb; |
|||
char user; |
|||
} FILE; |
|||
|
|||
#else |
|||
|
|||
#define BUFSIZ 1024 |
|||
#define MAXSTREAM 11 |
|||
|
|||
#define _BUSY 0x01 |
|||
#define _ALLBUF 0x02 |
|||
#define _DIRTY 0x04 |
|||
#define _EOF 0x08 |
|||
#define _IOERR 0x10 |
|||
|
|||
typedef struct { |
|||
char *_bp; /* current position in buffer */ |
|||
char *_bend; /* last character in buffer + 1 */ |
|||
char *_buff; /* address of buffer */ |
|||
char _flags; /* open mode, etc. */ |
|||
char _unit; /* token returned by open */ |
|||
char _bytbuf; /* single byte buffer for unbuffer streams */ |
|||
int _buflen; /* length of buffer */ |
|||
} FILE; |
|||
|
|||
extern FILE Cbuffs[]; |
|||
FILE *fopen(); |
|||
long ftell(); |
|||
|
|||
#define stdin (&Cbuffs[0]) |
|||
#define stdout (&Cbuffs[1]) |
|||
#define stderr (&Cbuffs[2]) |
|||
#define getchar() agetc(stdin) |
|||
#define putchar(c) aputc(c, stdout) |
|||
#define feof(fp) (((fp)->_flags&_EOF)!=0) |
|||
#define ferror(fp) (((fp)->_flags&_IOERR)!=0) |
|||
#define clearerr(fp) ((fp)->_flags &= ~(_IOERR|_EOF)) |
|||
#define fileno(fp) ((fp)->_unit) |
|||
#define fflush(fp) flsh_(fp,-1) |
|||
#endif |
|||
ctype.h |
|||
/* Copyright (C) 1984 by Manx Software Systems */ |
|||
|
|||
extern char ctp_[]; |
|||
|
|||
#define isalpha(x) (ctp_[(x)+1]&0x03) |
|||
#define isupper(x) (ctp_[(x)+1]&0x01) |
|||
#define islower(x) (ctp_[(x)+1]&0x02) |
|||
#define isdigit(x) (ctp_[(x)+1]&0x04) |
|||
#define isxdigit(x) (ctp_[(x)+1]&0x08) |
|||
#define isalnum(x) (ctp_[(x)+1]&0x07) |
|||
#define isspace(x) (ctp_[(x)+1]&0x10) |
|||
#define ispunct(x) (ctp_[(x)+1]&0x40) |
|||
#define iscntrl(x) (ctp_[(x)+1]&0x20) |
|||
#define isprint(x) (ctp_[(x)+1]&0xc7) |
|||
#define isgraph(x) (ctp_[(x)+1]&0x47) |
|||
#define isascii(x) (((x)&0x80)==0) |
|||
|
|||
#define toascii(x) ((x)&127) |
|||
#define _tolower(x) ((x)|0x20) |
|||
#define _toupper(x) ((x)&0x5f) |
|||
|
|||
Binary file not shown.
File diff suppressed because it is too large
Binary file not shown.
File diff suppressed because it is too large
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Binary file not shown.
Binary file not shown.
@ -0,0 +1,404 @@ |
|||
r.c |
|||
/* Copyright (C) 1984 by Manx Software Systems */ |
|||
#include <stdio.h> |
|||
|
|||
main(argc, argv) |
|||
char **argv; |
|||
{ |
|||
register int (*func)(); |
|||
int (*prgload())(); |
|||
|
|||
if (argc < 2) { |
|||
fprintf(stderr, "usage: r progname args ...\n"); |
|||
exit(4); |
|||
} |
|||
++argv; |
|||
if ((func = prgload(*argv)) == 0) { |
|||
fprintf(stderr, "Cannot load program\n"); |
|||
exit(4); |
|||
} |
|||
(*func)(argc-1, argv); |
|||
} |
|||
|
|||
#define OVMAGIC 0xf1 |
|||
|
|||
struct header { |
|||
int magic; |
|||
unsigned ovaddr; |
|||
unsigned ovsize; |
|||
unsigned ovbss; |
|||
int (*ovbgn)(); |
|||
}; |
|||
|
|||
static int (*prgload(argv0))() |
|||
char *argv0; |
|||
{ |
|||
int fd; |
|||
char *topmem, *ovend, *sbrk(); |
|||
unsigned size; |
|||
struct header header; |
|||
char name[20]; |
|||
|
|||
strcpy(name, argv0); |
|||
strcat(name, ".ovr"); |
|||
if ((fd = open(name, 0)) < 0) |
|||
return 0; |
|||
if (read(fd, &header, sizeof header) < 0) |
|||
return 0; |
|||
/* check magic number on overlay file */ |
|||
if (header.magic != OVMAGIC || header.ovsize == 0) |
|||
return 0; |
|||
|
|||
topmem = sbrk(0); |
|||
ovend = header.ovaddr + header.ovsize + header.ovbss; |
|||
if (topmem < ovend) { |
|||
if (sbrk(ovend - topmem) == (char *)-1) |
|||
return 0; |
|||
} |
|||
if (read(fd, header.ovaddr, header.ovsize) < header.ovsize) |
|||
return 0; |
|||
close(fd); |
|||
return header.ovbgn; |
|||
} |
|||
crbegin.asm |
|||
; Copyright (C) 1983 by Manx Software Systems |
|||
; :ts=8 |
|||
public .ovbgn |
|||
extrn main_ |
|||
extrn _Uorg_, _Uend_ |
|||
bss saveret,2 |
|||
.ovbgn: |
|||
lxi h,_Uorg_ |
|||
lxi b,_Uend_-_Uorg_ |
|||
mvi e,0 |
|||
clrbss: |
|||
mov m,e |
|||
inx h |
|||
dcx b |
|||
mov a,c |
|||
ora b |
|||
jnz clrbss |
|||
; |
|||
pop h |
|||
shld saveret |
|||
call main_ |
|||
lhld saveret ;get return addr |
|||
pchl ;return to caller |
|||
end .ovbgn |
|||
rext.asm |
|||
extrn .begin |
|||
extrn execv_ |
|||
extrn execl_ |
|||
extrn agetc_ |
|||
extrn aputc_ |
|||
extrn atoi_ |
|||
extrn atol_ |
|||
extrn calloc_ |
|||
extrn Croot_ |
|||
extrn fdopen_ |
|||
extrn fgets_ |
|||
extrn fopen_ |
|||
extrn freopen_ |
|||
extrn format_ |
|||
extrn fprintf_ |
|||
extrn fputs_ |
|||
extrn fread_ |
|||
extrn fscanf_ |
|||
extrn fseek_ |
|||
extrn ftell_ |
|||
extrn fwrite_ |
|||
extrn getchar_ |
|||
extrn gets_ |
|||
extrn getw_ |
|||
extrn ioctl_ |
|||
extrn isatty_ |
|||
extrn lseek_ |
|||
extrn realloc_ |
|||
extrn malloc_ |
|||
extrn free_ |
|||
extrn creat_ |
|||
extrn open_ |
|||
extrn close_ |
|||
extrn posit_ |
|||
extrn printf_ |
|||
extrn fclose_ |
|||
extrn putchar_ |
|||
extrn puterr_ |
|||
extrn puts_ |
|||
extrn putw_ |
|||
extrn qsort_ |
|||
extrn rename_ |
|||
extrn scanfmt_ |
|||
extrn scanf_ |
|||
extrn setbuf_ |
|||
extrn sprintf_ |
|||
extrn sscanf_ |
|||
extrn ungetc_ |
|||
extrn unlink_ |
|||
extrn bios_ |
|||
extrn index_ |
|||
extrn movmem_ |
|||
extrn rindex_ |
|||
extrn sbrk_ |
|||
extrn rsvstk_ |
|||
extrn setjmp_ |
|||
extrn setmem_ |
|||
extrn strcat_ |
|||
extrn strncat_ |
|||
extrn strcmp_ |
|||
extrn strncmp_ |
|||
extrn strcpy_ |
|||
extrn strlen_ |
|||
extrn strncpy_ |
|||
extrn swapmem_ |
|||
extrn toupper_ |
|||
extrn tolower_ |
|||
extrn getusr_ |
|||
extrn setusr_ |
|||
extrn rstusr_ |
|||
extrn .dv,.ud |
|||
extrn .ml |
|||
mrext.asm |
|||
extrn .begin |
|||
extrn atof_ |
|||
extrn frexp_, ldexp_, modf_ |
|||
extrn ftoa_ |
|||
extrn asin_ |
|||
extrn acos_ |
|||
extrn arcsine_ |
|||
extrn atan2_ |
|||
extrn atan_ |
|||
extrn exp_ |
|||
extrn floor_ |
|||
extrn ceil_ |
|||
extrn log10_ |
|||
extrn log_ |
|||
extrn pow_ |
|||
extrn ran_ |
|||
extrn randl_ |
|||
extrn cos_ |
|||
extrn sin_ |
|||
extrn sinh_ |
|||
extrn cosh_ |
|||
extrn sqrt_ |
|||
extrn cotan_ |
|||
extrn tan_ |
|||
extrn tanh_ |
|||
|
|||
extrn execv_ |
|||
extrn execl_ |
|||
extrn agetc_ |
|||
extrn aputc_ |
|||
extrn atoi_ |
|||
extrn atol_ |
|||
extrn calloc_ |
|||
extrn Croot_ |
|||
extrn fdopen_ |
|||
extrn fgets_ |
|||
extrn fopen_ |
|||
extrn freopen_ |
|||
extrn format_ |
|||
extrn fprintf_ |
|||
extrn fputs_ |
|||
extrn fread_ |
|||
extrn fscanf_ |
|||
extrn fseek_ |
|||
extrn ftell_ |
|||
extrn fwrite_ |
|||
extrn getchar_ |
|||
extrn gets_ |
|||
extrn getw_ |
|||
extrn ioctl_ |
|||
extrn isatty_ |
|||
extrn lseek_ |
|||
extrn realloc_ |
|||
extrn malloc_ |
|||
extrn free_ |
|||
extrn creat_ |
|||
extrn open_ |
|||
extrn close_ |
|||
extrn posit_ |
|||
extrn printf_ |
|||
extrn fclose_ |
|||
extrn putchar_ |
|||
extrn puts_ |
|||
extrn putw_ |
|||
extrn qsort_ |
|||
extrn rename_ |
|||
extrn scanfmt_ |
|||
extrn scanf_ |
|||
extrn setbuf_ |
|||
extrn sprintf_ |
|||
extrn sscanf_ |
|||
extrn ungetc_ |
|||
extrn unlink_ |
|||
extrn bios_ |
|||
extrn index_ |
|||
extrn movmem_ |
|||
extrn rindex_ |
|||
extrn sbrk_ |
|||
extrn rsvstk_ |
|||
extrn setjmp_ |
|||
extrn setmem_ |
|||
extrn strcat_ |
|||
extrn strncat_ |
|||
extrn strcmp_ |
|||
extrn strncmp_ |
|||
extrn strcpy_ |
|||
extrn strlen_ |
|||
extrn strncpy_ |
|||
extrn swapmem_ |
|||
extrn toupper_ |
|||
extrn tolower_ |
|||
extrn getusr_ |
|||
extrn setusr_ |
|||
extrn rstusr_ |
|||
extrn .dv,.ud |
|||
extrn .ml |
|||
ovloader.c |
|||
/* Copyright (C) 1983, 1984 by Manx Software Systems */ |
|||
|
|||
#define OVMAGIC 0xf1 |
|||
|
|||
struct header { |
|||
int magic; |
|||
unsigned ovaddr; |
|||
unsigned ovsize; |
|||
unsigned ovbss; |
|||
int (*ovbgn)(); |
|||
}; |
|||
|
|||
static char *ovname; |
|||
|
|||
#asm |
|||
public ovloader |
|||
ovloader: |
|||
lxi h,2 |
|||
dad sp |
|||
mov e,m |
|||
inx h |
|||
mov d,m |
|||
xchg |
|||
shld ovname_ |
|||
; |
|||
call _ovld_ |
|||
pchl |
|||
#endasm |
|||
|
|||
static |
|||
_ovld() |
|||
{ |
|||
int fd, flag; |
|||
auto struct header hdr; |
|||
extern char *_mbot; |
|||
auto char filename[64]; |
|||
|
|||
flag = 0; |
|||
strcpy(filename, ovname); |
|||
for (;;) { |
|||
strcat(filename, ".ovr"); |
|||
if ((fd = open(filename, 0)) >= 0) |
|||
break; |
|||
if (flag++) |
|||
loadabort(10); |
|||
strcpy(filename, "a:"); |
|||
strcat(filename, ovname); |
|||
} |
|||
|
|||
if (read(fd, &hdr, sizeof hdr) != sizeof hdr) |
|||
loadabort(20); |
|||
|
|||
/* check magic number on overlay file */ |
|||
if (hdr.magic != OVMAGIC) |
|||
loadabort(30); |
|||
|
|||
if (_mbot < hdr.ovaddr+hdr.ovsize+hdr.ovbss) |
|||
loadabort(40); |
|||
|
|||
if (read(fd, hdr.ovaddr, hdr.ovsize) < hdr.ovsize) |
|||
loadabort(50); |
|||
close(fd); |
|||
return hdr.ovbgn; |
|||
} |
|||
|
|||
static |
|||
loadabort(code) |
|||
{ |
|||
char buffer[80]; |
|||
|
|||
sprintf(buffer, "Error %d loading overlay: %s$", code, ovname); |
|||
bdos(9, buffer); |
|||
exit(10); |
|||
} |
|||
ovbgn.asm |
|||
; Copyright (C) 1983, 1984 by Manx Software Systems |
|||
; :ts=8 |
|||
public .ovbgn, ovexit_ |
|||
extrn ovmain_ |
|||
extrn _Uorg_, _Uend_ |
|||
bss ovstkpt,2 |
|||
bss saveret,2 |
|||
bss bcsave,2 |
|||
bss ixsave,2 |
|||
bss iysave,2 |
|||
; |
|||
.ovbgn: |
|||
lxi h,_Uorg_ |
|||
lxi b,_Uend_-_Uorg_ |
|||
mvi e,0 |
|||
clrbss: |
|||
mov m,e |
|||
inx h |
|||
dcx b |
|||
mov a,c |
|||
ora b |
|||
jnz clrbss |
|||
; |
|||
mov h,b |
|||
mov l,c |
|||
shld bcsave |
|||
xra a |
|||
adi 3 |
|||
jpe savedone |
|||
db 221 |
|||
shld ixsave |
|||
db 253 |
|||
shld iysave |
|||
savedone: |
|||
pop h |
|||
shld saveret |
|||
pop d |
|||
lxi h,0 |
|||
dad sp |
|||
shld ovstkpt ;save stack pointer for ovexit |
|||
call ovmain_ |
|||
xchg ;save return value |
|||
ovret: |
|||
lhld saveret ;get return addr |
|||
push h ;place dummy overlay name ptr on stack |
|||
push h ;place return addr on stack |
|||
xchg ;restore return value to hl |
|||
ret ;return to caller |
|||
; |
|||
ovexit_: |
|||
lhld bcsave |
|||
mov b,h |
|||
mov c,l |
|||
xra a |
|||
adi 3 |
|||
jpe restdone |
|||
db 221 |
|||
lhld ixsave |
|||
db 253 |
|||
lhld iysave |
|||
restdone: |
|||
lxi h,2 ;get return value |
|||
dad sp |
|||
mov e,m |
|||
inx h |
|||
mov d,m |
|||
lhld ovstkpt ;restore original stack pointer |
|||
sphl |
|||
jmp ovret |
|||
end .ovbgn |
|||
|
|||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,4 @@ |
|||
as rext.asm |
|||
ln -ro r.com r.o rext.o -lc |
|||
pip r.lib=r.rsm[o],rbegin.o[o] |
|||
|
|||
@ -0,0 +1,73 @@ |
|||
extrn .begin |
|||
extrn execv_ |
|||
extrn execl_ |
|||
extrn agetc_ |
|||
extrn aputc_ |
|||
extrn atoi_ |
|||
extrn atol_ |
|||
extrn calloc_ |
|||
extrn Croot_ |
|||
extrn fdopen_ |
|||
extrn fgets_ |
|||
extrn fopen_ |
|||
extrn freopen_ |
|||
extrn format_ |
|||
extrn fprintf_ |
|||
extrn fputs_ |
|||
extrn fread_ |
|||
extrn fscanf_ |
|||
extrn fseek_ |
|||
extrn ftell_ |
|||
extrn fwrite_ |
|||
extrn getchar_ |
|||
extrn gets_ |
|||
extrn getw_ |
|||
extrn ioctl_ |
|||
extrn isatty_ |
|||
extrn lseek_ |
|||
extrn realloc_ |
|||
extrn malloc_ |
|||
extrn free_ |
|||
extrn creat_ |
|||
extrn open_ |
|||
extrn close_ |
|||
extrn posit_ |
|||
extrn printf_ |
|||
extrn fclose_ |
|||
extrn putchar_ |
|||
extrn puterr_ |
|||
extrn puts_ |
|||
extrn putw_ |
|||
extrn qsort_ |
|||
extrn rename_ |
|||
extrn scanfmt_ |
|||
extrn scanf_ |
|||
extrn setbuf_ |
|||
extrn sprintf_ |
|||
extrn sscanf_ |
|||
extrn ungetc_ |
|||
extrn unlink_ |
|||
extrn bios_ |
|||
extrn index_ |
|||
extrn movmem_ |
|||
extrn rindex_ |
|||
extrn sbrk_ |
|||
extrn rsvstk_ |
|||
extrn setjmp_ |
|||
extrn setmem_ |
|||
extrn strcat_ |
|||
extrn strncat_ |
|||
extrn strcmp_ |
|||
extrn strncmp_ |
|||
extrn strcpy_ |
|||
extrn strlen_ |
|||
extrn strncpy_ |
|||
extrn swapmem_ |
|||
extrn toupper_ |
|||
extrn tolower_ |
|||
extrn getusr_ |
|||
extrn setusr_ |
|||
extrn rstusr_ |
|||
extrn .dv,.ud |
|||
extrn .ml |
|||
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,332 @@ |
|||
croot.c |
|||
/* Copyright (C) 1981, 1982 by Manx Software Systems */ |
|||
/* Copyright (C) 1983 by Manx Software Systems */ |
|||
|
|||
#define MAXARGS 30 |
|||
static char *Argv[MAXARGS]; |
|||
static char Argbuf[128]; |
|||
static int Argc; |
|||
|
|||
Croot() |
|||
{ |
|||
register char *cp; |
|||
|
|||
movmem((char *)0x81, Argbuf, 127); |
|||
Argbuf[*(char *)0x80 & 0x7f] = 0; |
|||
Argv[0] = ""; |
|||
cp = Argbuf; |
|||
Argc = 1; |
|||
while (Argc < MAXARGS) { |
|||
while (*cp == ' ' || *cp == '\t') |
|||
++cp; |
|||
if (*cp == 0) |
|||
break; |
|||
Argv[Argc++] = cp; |
|||
while (*++cp) |
|||
if (*cp == ' ' || *cp == '\t') { |
|||
*cp++ = 0; |
|||
break; |
|||
} |
|||
} |
|||
main(Argc,Argv); |
|||
_exit(); |
|||
} |
|||
|
|||
exit(code) |
|||
{ |
|||
_exit(); |
|||
} |
|||
|
|||
getchar() |
|||
{ |
|||
register int c; |
|||
|
|||
if ((c = bdos(1)) == '\r') { |
|||
bdos(2,'\n'); |
|||
c = '\n'; |
|||
} else if (c == 0x1a) |
|||
c = -1; |
|||
return c; |
|||
} |
|||
|
|||
putchar(c) |
|||
{ |
|||
if (c == '\n') |
|||
bdos(2,'\r'); |
|||
bdos(2,c); |
|||
return c&255; |
|||
} |
|||
fprintf.c |
|||
/* Copyright (C) 1981,1982 by Manx Software Systems */ |
|||
/* Copyright (C) 1982 Thomas Fenwick */ |
|||
#include "stdio.h" |
|||
|
|||
static FILE *Stream; |
|||
|
|||
fprintf(stream,fmt,args) |
|||
FILE *stream; char *fmt; unsigned args; |
|||
{ |
|||
int fpsub(); |
|||
|
|||
Stream = stream; |
|||
return format(fpsub,fmt,&args); |
|||
} |
|||
|
|||
static |
|||
fpsub(c) |
|||
{ |
|||
return aputc(c,Stream); |
|||
} |
|||
printf.c |
|||
/* Copyright (C) 1981, 1982 by Manx Software Systems */ |
|||
/* Copyright (C) 1983 by Manx Software Systems */ |
|||
|
|||
printf(fmt,args) |
|||
char *fmt; unsigned args; |
|||
{ |
|||
int putchar(); |
|||
|
|||
format(putchar,fmt,&args); |
|||
} |
|||
|
|||
format(putsub, fmt, args) |
|||
register int (*putsub)(); register char *fmt; unsigned *args; |
|||
{ |
|||
register int c; |
|||
char *ps; |
|||
char s[8]; |
|||
static char *dconv(), *hexconv(); |
|||
|
|||
while ( c = *fmt++ ) { |
|||
if ( c == '%' ) { |
|||
switch ( c = *fmt++ ) { |
|||
case 'x': |
|||
ps = hexconv(*args++, s+7); |
|||
break; |
|||
case 'u': |
|||
ps = dconv(*args++, s+7); |
|||
break; |
|||
case 'd': |
|||
if ( (int)*args < 0 ) { |
|||
ps = dconv(-*args++, s+7); |
|||
*--ps = '-'; |
|||
} else |
|||
ps = dconv(*args++, s+7); |
|||
break; |
|||
case 's': |
|||
ps = *args++; |
|||
break; |
|||
case 'c': |
|||
c = *args++; |
|||
default: |
|||
goto deflt; |
|||
} |
|||
|
|||
while ( *ps ) |
|||
(*putsub)(*ps++); |
|||
|
|||
} else |
|||
deflt: |
|||
(*putsub)(c); |
|||
} |
|||
} |
|||
|
|||
static char * |
|||
dconv(n, s) |
|||
register char *s; register unsigned n; |
|||
{ |
|||
*s = 0; |
|||
do { |
|||
*--s = n%10 + '0'; |
|||
} while ( (n /= 10) != 0 ); |
|||
return s; |
|||
} |
|||
|
|||
static char * |
|||
hexconv(n, s) |
|||
register char *s; register unsigned n; |
|||
{ |
|||
*s = 0; |
|||
do { |
|||
*--s = "0123456789abcdef" [n&15]; |
|||
} while ( (n >>= 4) != 0 ); |
|||
return s; |
|||
} |
|||
fopen.c |
|||
/* Copyright (C) 1981, 1982 by Manx Software Systems */ |
|||
/* Copyright (C) 1983, 1984 by Manx Software Systems */ |
|||
#include "stdio.h" |
|||
#include "errno.h" |
|||
|
|||
#define MAXFILE 4 |
|||
#define RBUFSIZ 1024 |
|||
#define WBUFSIZ 1024 |
|||
#define RDNSCT (RBUFSIZ/128) |
|||
#define WRNSCT (WBUFSIZ/128) |
|||
|
|||
#define OPNFIL 15 |
|||
#define CLSFIL 16 |
|||
#define DELFIL 19 |
|||
#define READSQ 20 |
|||
#define WRITSQ 21 |
|||
#define MAKFIL 22 |
|||
#define SETDMA 26 |
|||
#define READRN 33 |
|||
#define WRITRN 34 |
|||
#define FILSIZ 35 |
|||
#define SETREC 36 |
|||
|
|||
static FILE Cbuffs[MAXFILE]; |
|||
static char writbuf[WBUFSIZ]; |
|||
static char readbuf[RBUFSIZ]; |
|||
static char *bufeof; |
|||
static FILE *curread; |
|||
static FILE *writfp; |
|||
|
|||
FILE * |
|||
fopen(name,mode) |
|||
char *name,*mode; |
|||
{ |
|||
register FILE *fp; |
|||
int user; |
|||
|
|||
fp = Cbuffs; |
|||
while ( fp->_bp ) { |
|||
if ( ++fp >= Cbuffs+MAXFILE ) { |
|||
errno = ENFILE; |
|||
return (NULL); |
|||
} |
|||
} |
|||
|
|||
if ((user = fcbinit(name,&fp->_fcb)) == -1) { |
|||
errno = EINVAL; |
|||
return NULL; |
|||
} |
|||
|
|||
if (user == 255) |
|||
user = getusr(); |
|||
fp->user = user; |
|||
setusr(user); |
|||
if (*mode == 'r') { |
|||
if (bdos(OPNFIL,&fp->_fcb) == 0xff) { |
|||
errno = ENOENT; |
|||
rstusr(); |
|||
return NULL; |
|||
} |
|||
fp->_bp = readbuf; |
|||
curread = 0; |
|||
} else { |
|||
if ( writfp ) |
|||
return NULL; |
|||
bdos(DELFIL, &fp->_fcb); |
|||
if (bdos(MAKFIL,&fp->_fcb) == 0xff) { |
|||
errno = ENOENT; |
|||
rstusr(); |
|||
return NULL; |
|||
} |
|||
fp->_bp = writbuf; |
|||
writfp = fp; |
|||
} |
|||
rstusr(); |
|||
fp->_fcb.f_overfl = fp->_fcb.f_record = 0; |
|||
return fp; |
|||
} |
|||
|
|||
fclose(ptr) |
|||
register FILE *ptr; |
|||
{ |
|||
register int err; |
|||
|
|||
err = 0; |
|||
if (ptr == writfp) { /* if writing flush buffer */ |
|||
err = flush(ptr->_bp - writbuf); |
|||
writfp = 0; |
|||
} else if (ptr == curread) |
|||
curread = 0; |
|||
setusr(ptr->user); |
|||
if (bdos(CLSFIL,&ptr->_fcb) == 0xff) |
|||
err = -1; |
|||
rstusr(); |
|||
ptr->_bp = 0; |
|||
return err; |
|||
} |
|||
|
|||
agetc(ptr) |
|||
register FILE *ptr; |
|||
{ |
|||
register int c; |
|||
|
|||
top: |
|||
if ((c = getc(ptr)) != EOF) { |
|||
switch (c &= 127) { |
|||
case 0x1a: |
|||
--ptr->_bp; |
|||
return EOF; |
|||
case '\r': |
|||
case 0: |
|||
goto top; |
|||
} |
|||
} |
|||
return c; |
|||
} |
|||
|
|||
getc(ptr) |
|||
register FILE *ptr; |
|||
{ |
|||
register int j; |
|||
|
|||
if (ptr != curread) { |
|||
readit: |
|||
curread = 0; /* mark nobody as current read */ |
|||
setusr(ptr->user); |
|||
if ((j = RDNSCT - blkrd(&ptr->_fcb,readbuf,RDNSCT)) == 0) |
|||
return -1; |
|||
rstusr(); |
|||
ptr->_fcb.f_record -= j; |
|||
bufeof = readbuf + j*128; |
|||
curread = ptr; |
|||
} |
|||
if (ptr->_bp >= bufeof) { |
|||
ptr->_fcb.f_record += (bufeof-readbuf) >> 7; |
|||
ptr->_bp = readbuf; |
|||
goto readit; |
|||
} |
|||
return *ptr->_bp++ & 255; |
|||
} |
|||
|
|||
aputc(c,ptr) |
|||
register int c; register FILE *ptr; |
|||
{ |
|||
c &= 127; |
|||
if (c == '\n') |
|||
if (putc('\r',ptr) == EOF) |
|||
return EOF; |
|||
return putc(c,ptr); |
|||
} |
|||
|
|||
putc(c,ptr) |
|||
int c; register FILE *ptr; |
|||
{ |
|||
*ptr->_bp++ = c; |
|||
if (ptr->_bp >= writbuf+WBUFSIZ) { |
|||
if (flush(WBUFSIZ)) |
|||
return EOF; |
|||
ptr->_bp = writbuf; |
|||
} |
|||
return (c&255); |
|||
} |
|||
|
|||
flush(len) |
|||
register int len; |
|||
{ |
|||
while (len & 127) |
|||
writbuf[len++] = 0x1a; |
|||
setusr(writfp->user); |
|||
if (len != 0 && blkwr(&writfp->_fcb,writbuf,len>>7) != 0) { |
|||
rstusr(); |
|||
return EOF; |
|||
} |
|||
rstusr(); |
|||
return 0; |
|||
} |
|||
|
|||
@ -0,0 +1,11 @@ |
|||
===== Microsoft Basic-80 Compiler v.5.30a ===== |
|||
|
|||
The Microsoft BASIC Compiler is a highly efficient programming tool that |
|||
converts BASIC programs from BASIC source code into machine code. This |
|||
provides much faster BASIC program execution than has previously been |
|||
possible. It can make programs run an average of 3 to 10 times faster than |
|||
programs run under BASIC-80. Compiled programs can be up to 30 times |
|||
faster than interpreted programs if maximum use of integer variables is |
|||
made. |
|||
|
|||
View BASCOM.HLP included in the disk image using HELP.COM for documentation. |
|||
Binary file not shown.
@ -0,0 +1,379 @@ |
|||
Introduction |
|||
Format notation |
|||
A sample session |
|||
Writing a Basic program to be compiled |
|||
Compiler-interpreter differences |
|||
New programming features |
|||
Second menu: Compiling, linking & loading, errors |
|||
:INTRODUCTION |
|||
|
|||
The Microsoft BASIC Compiler is a highly efficient programming tool that |
|||
converts BASIC programs from BASIC source code into machine code. This |
|||
provides much faster BASIC program execution than has previously been |
|||
possible. It can make programs run an average of 3 to 10 times faster than |
|||
programs run under BASIC-80. Compiled programs can be up to 30 times |
|||
faster than interpreted programs if maximum use of integer variables is |
|||
made. |
|||
:FORMAT NOTATION |
|||
|
|||
Wherever the format for a statement or command is given throughout this |
|||
HELP file, the following rules apply: |
|||
|
|||
1. Items in capital letters must be input as shown. |
|||
|
|||
2. Items in lower case letters enclosed in angle brackets ( < > ) |
|||
are to be supplied by the user. |
|||
|
|||
3. Items in sqare brackets ( [ ] ) are optional. |
|||
|
|||
4. All punctuation except angle brackets and square brackets |
|||
(i.e., commas, parentheses, semicolons, hyphens, and equal |
|||
signs) must be included where shown. |
|||
|
|||
5. Items followed by an ellipsis ( ... ) may be repeated any |
|||
number of times (up to the length of the line). |
|||
|
|||
6. Items separated by a vertical bar ( \ ) are mutually exclusive; |
|||
choose one. |
|||
:SAMPLE SESSION |
|||
|
|||
The following instructions will take you step by step through the compila- |
|||
tion process, from typing in the program to running the compiled version of |
|||
it. |
|||
|
|||
STEP 1: PRELIMINARIES |
|||
|
|||
Load BASIC-80 (NOT included in the BASCOM package) from disk. The program |
|||
will sign on and the letters |
|||
|
|||
ok |
|||
|
|||
will appear on the screen. Now enter: |
|||
|
|||
AUTO 100, 100 |
|||
|
|||
This command instructs BASIC-80 to automatically generate line numbers, |
|||
beginning with line 100 and incrementing by 100 each time you press ENTER. |
|||
|
|||
STEP 2: ENTER THE PROGRAM |
|||
|
|||
You are now ready to begin typing in your BASIC program. Anything that you |
|||
know runs in BASIC-80 will do. Alternatively, just read in a BASIC-80 |
|||
program you already use. |
|||
|
|||
STEP 3: SAVE THE PROGRAM |
|||
|
|||
In order for the compiler to process it, you must save your source program |
|||
in ASCII format. To do so, enter: |
|||
|
|||
SAVE "MYPROG",A |
|||
|
|||
There is now a BASIC program called MYPROG.BAS on your diskette that is |
|||
ready to be compiled. (A program that is not yet compiled is called the |
|||
source file.) |
|||
|
|||
Return to CP/M by typing SYSTEM. |
|||
|
|||
STEP 4: CHECK FOR ERRORS |
|||
|
|||
At this point, it is a good idea to check the program for syntax errors. |
|||
Removing syntax errors now will reduce the possibility of having to recom- |
|||
pile later. To do this, enter: |
|||
|
|||
BASCOM =MYPROG |
|||
|
|||
This command loads the BASIC Compiler and compiles the source file without |
|||
producing an object or listing file. If you have made any syntax errors, a |
|||
two-letter code will appear on the screen. If this happens, return to STEP |
|||
1, use the BASIC-80 interpreter again, and correct the errors. |
|||
|
|||
If no errors were encountered, you are ready to continue. |
|||
|
|||
STEP 5: COMPILE SOURCE FILE |
|||
|
|||
These commands instruct the BASIC Compiler to compile MYPROG.BAS, to put |
|||
the object in a file named MYPROG.REL, and to put the listing in a file |
|||
named MYPROG.LST. (.REL and .LST are default extensions supplied by the |
|||
BASIC Compiler.) |
|||
|
|||
There are now a relocatable object file called MYPROG.REL and a listing |
|||
file called MYPROG.LST on the disk. The object file contains the machine- |
|||
readable code generated by the compiler. The listing file contains the |
|||
BASIC program statements along with the machine language generated by each |
|||
statement. |
|||
|
|||
STEP 6: LOAD AND EXECUTE THE PROGRAM |
|||
|
|||
The LINK-80 linking loader is used to produce an executable program. To use |
|||
it, enter: |
|||
|
|||
L80 MYPROG,MYPROG/N/E |
|||
|
|||
This command runs LINK-80, which in turn loads the object file MYPROG.REL |
|||
into the correct memory locations, then writes it to disk as a .COM file. |
|||
During this process (which can take some time), runtime routines are drawn |
|||
from the BASLIB.REL runtime library. |
|||
|
|||
The compiled program which you stored on your own diskette can be run at |
|||
any time, all by itself, without using any part of the BASIC Compiler. It |
|||
works just like a standard CP/M command file. To execute, just enter: |
|||
|
|||
MYPROG |
|||
|
|||
The program should then work just as it did in the interpreter .. only much |
|||
faster. |
|||
:WRITING A BASIC PROGRAM TO BE COMPILED |
|||
|
|||
BASIC programs which are to be compiled are, for most part, written in just |
|||
the same way you have always written them to run with the interpreter. |
|||
However, there are some differences between the statements and commands |
|||
implemented in BASIC-80 and those implemented in the BASIC Compiler that |
|||
must be taken into consideration. |
|||
|
|||
The Compiler interacts with the console only to read compiler commands. |
|||
These specify what files are to be compiled. There is no "direct mode", as |
|||
with the MBASIC interpreter. Commands that are usually issued in the direct |
|||
mode with MBASIC are not implemented on the compiler. The following state- |
|||
ments and commands are not implemented and will generate an error message. |
|||
|
|||
AUTO CLEAR* CLOAD CSAVE CONT |
|||
DELETE EDIT LIST LLIST RENUM |
|||
SAVE LOAD MERGE NEW COMMON* |
|||
SYSTEM |
|||
* |
|||
(Note: Newer releases of the compiler which include the BRUN runtime module |
|||
do support CHAINing with COMMON and CLEAR with certain restrictions.) |
|||
|
|||
:FEATURES USED DIFFERENTLY BY THE BASIC COMPILER |
|||
|
|||
DEFINT/SNG/DBL/STR |
|||
The compiler does not "execute" DEFxxx statements; it reacts to the static |
|||
occurrence of these statements, regardless of the order in which program |
|||
lines are executed. A DEFxxx statement takes effect as soon as its line is |
|||
encountered. Once the type has been defined for a given letter, it remains |
|||
in effect until the end of the program or until a different DEfxxx state |
|||
ment with that letter takes effect. |
|||
|
|||
USRn Functions |
|||
USRn functions are significantly different from the interpreter versions. |
|||
The argument to the USRn function is ignored and an integer result is |
|||
returned in the HL registers. It is recommended that USRn functions be |
|||
replaced by the CALL statement. (See New BASIC Programming Features for |
|||
definition of CALL.) |
|||
|
|||
DIM and ERASE |
|||
The DIM statement is similar to the DEFxxx statement in that it is scanned |
|||
rather than executed. That is, DIM takes effect when its line is encoun- |
|||
tered. If the default dimension (10) has already been established for an |
|||
array variable and that variable is later encountered in a DIM statement, a |
|||
DD (redimensioned array) error results. There is no ERASE statement in the |
|||
compiler, so arrays cannot be erased and redimensioned. An ERASE statement |
|||
will produce a fatal error. |
|||
|
|||
Also note that the values of the subscripts in a DIM statement must be |
|||
integer constants; they may not be variables, arithmetic expressions, of |
|||
floating point values. For example, |
|||
|
|||
DIM A1(I) |
|||
DIM A1(3+4) |
|||
|
|||
are both illegal statements. |
|||
|
|||
END |
|||
During execution of a compiled program, an END statement closes files and |
|||
returns control to the operating system. The compiler assumes an END at the |
|||
end of the program, so it is not necessary to insert an END statement in |
|||
order to get proper program termination. |
|||
|
|||
FOR/NEXT |
|||
All FOR/NEXT loops must be statically nested with only 1 NEXT statement for |
|||
each FOR statement. |
|||
|
|||
ON ERROR GOTO/RESUME <line number> |
|||
If a program contains ON ERROR GOTO and RESUME <line number> statements, |
|||
the /E compilation switch must be used. If the RESUME NEXT, RESUME, or |
|||
RESUME 0 form is used, the /X switch must also be included. |
|||
|
|||
REM |
|||
REM statements or remarks starting with a single quotation mark do not make |
|||
up time or space during execution, and so may be used as freely as desired. |
|||
|
|||
STOP |
|||
The STOP statement is identical to the END statement. Open files are closed |
|||
and control returns to the operating system. |
|||
|
|||
TRON/TROFF |
|||
In order to use TRON/TROFF, the /D compilation switch must be used. Other- |
|||
wise, TRON and TROFF are ignored and a warning message is generated. |
|||
:NEW BASIC PROGRAMMING FEATURES |
|||
|
|||
The BASIC Compiler also adds new features that will add power and |
|||
efficiency to your programming. Keep in mind when utilizing these new |
|||
features that while they will compile with no problems, you cannot run a |
|||
program using these features with your interpreter, since BASIC-80 |
|||
doesn't recognize them. |
|||
|
|||
CALL Statement |
|||
The CALL Statement allows you to call and transfer flow to an assembly |
|||
language or FORTRAN subroutine. |
|||
|
|||
The format of the CALL Statement is: |
|||
|
|||
CALL <variable name> [(<argument list>)] |
|||
|
|||
where <variable name> and <ergument list> are supplied by you. |
|||
|
|||
<variable name> is the name of the subroutine you wish to call. This name |
|||
must be 1 to 6 characters long and must be recognized by LINK-80 as a |
|||
global symbol. (<variable name> must be the name of the subroutine in a |
|||
FORTRAN SUBROUTINE statement or a PUBLIC symbol in an assembly language |
|||
routine.) |
|||
|
|||
<argument list> is optional and contains the arguments that are passed to |
|||
the assembly language or FORTRAN subroutine. |
|||
|
|||
Example: 120 CALL MYROUT (I,J,K) |
|||
|
|||
CHAIN (or RUN) |
|||
The CHAIN and RUN statements both perform the same function: they allow you |
|||
to load a file from diskette into memory and run it. CHAIN (or RUN) closes |
|||
all open files and deletes the current contents of memory before loading |
|||
the designated program. The format of the CHAIN (or RUN) statement is as |
|||
follows: |
|||
|
|||
CHAIN <filename> |
|||
OR |
|||
RUN <filename> |
|||
|
|||
where <filename> is the name used when the file was saved. (With CP/M the |
|||
default extension .BAS is supplied.) |
|||
|
|||
WHILE...WEND |
|||
The WHILE...WEND statement is a conditional statement that executes a |
|||
series of statements in a loop as long as a given condition is true. |
|||
|
|||
The format of WHILE...WEND is: |
|||
|
|||
WHILE <expression> |
|||
- |
|||
- |
|||
<loop statements> |
|||
- |
|||
- |
|||
WEND |
|||
|
|||
where <expression> and <loop statements> are supplied by you. |
|||
|
|||
As long as <expression> is true (i.e., not zero), loop statements are |
|||
executed until the WEND statement is encountered. BASIC then returns to the |
|||
WHILE statement and checks "expression". If it is still true, the process |
|||
is repeated. If it is not true, execution resumes with the statement |
|||
following the WEND statement. |
|||
|
|||
WHILE/WEND loops may be nested to any level, as long as they are statically |
|||
nested. Each WEND will match the most recent WHILE. An unmatched WHILE |
|||
statement causes a "WHILE without WEND" error, and an unmatched WEND state- |
|||
ment causes a "WEND without WHILE" error. |
|||
|
|||
Example: |
|||
090 'BUBBLE SORT ARRAY A$ |
|||
100 FLIPS=1 'FORCE ONE PASS THRU LOOP |
|||
110 WHILE FLIPS |
|||
115 FLIPS=0 |
|||
120 FOR I=1 TO J=1 |
|||
130 IF A$(I)>A$(I+1) THEN |
|||
SWAP A$(I),A$(I+1):FLIPS=1 |
|||
140 NEXT I |
|||
150 WEND |
|||
|
|||
Double Precision Transendental Functions |
|||
SIN, COS, TAN, SQR, LOG, and EXP now return double precision results if |
|||
given double precision arguments. Exponentiation with double precision |
|||
operands will return double precision results. |
|||
|
|||
Long Variable Names |
|||
Variable names may be up to 40 characters long with all 40 characters |
|||
significant. Letters, numbers, and the decimal characters are allowed in |
|||
variable names, but the name must begin with a letter. Variable names may |
|||
also include all BASIC-80 commands, statements, function names, and |
|||
operator names. |
|||
|
|||
Expression Evaluation in the BASIC Compiler |
|||
During program compilation, when the BASIC Compiler evaluates expressions, |
|||
the operands of each operator are converted to the same type, that of the |
|||
most precise operand. For example, |
|||
|
|||
QR=J%+A!+Q |
|||
|
|||
causes J% to be converted to single precision and added to A!. This result |
|||
is coverted to single precision and added to Q. |
|||
|
|||
The Compiler is more limited than the interpreter in handling numeric |
|||
overflow. For example, when run on the interpreter the following program |
|||
|
|||
I%=20000 |
|||
J%=20000 |
|||
K%=-30000 |
|||
M%=I%+J%-K% |
|||
|
|||
yields 10000 for M%. That is, it adds I% to J% and, because the number is |
|||
too large, it converts the result into a floating point number. K% is then |
|||
converted to floating point nd subtracted. The result of 10000 is found, |
|||
and is converted back to integer and saved as M%. |
|||
|
|||
The Compiler, however, must make type conversion decisions during compila- |
|||
tion. It cannot defer until the actual values are known. Thus, the compiler |
|||
would generate code to perform the entire operation in integer mode. If the |
|||
/D switch were set, the error would be detected. otherwise, an incorrect |
|||
answer would be produced. |
|||
|
|||
In order to produce optimum efficiency in the compiled program, the |
|||
compiler may perform any number of valid algebraic transformations before |
|||
generating the code. For axample, the program |
|||
|
|||
I%=20000 |
|||
J%=-18000 |
|||
K%=20000 |
|||
M%=I%+J%+K% |
|||
|
|||
could produce an incorrect result when run. If the compiler actually per- |
|||
forms the arithmetic in the order shown, no overflow occurs. However, if |
|||
the compiler performs I%+K% first and then adds J%, an overflow will occur. |
|||
|
|||
The Compiler follows the rules of operator precedence and parenthetic |
|||
modification of such precedence, but no other guarantee of evaluation order |
|||
can be made. |
|||
|
|||
Using Integer Variables To Optimize Speed |
|||
In order to produce the fastest and most compact object code possible, make |
|||
use of integer variables. For example, this program |
|||
|
|||
FOR I=1 TO 10 |
|||
A(I)=0 |
|||
NEXT I |
|||
|
|||
can execute approximately 30 times faster by simply substituting "I%" for |
|||
"I". It is especially advantageous to use integer variables to compute |
|||
array subscripts. The generated code is significantly faster and more |
|||
compact. |
|||
|
|||
Maximum Line Length |
|||
The Compiler cannot accept a physical line that is more than 253 characters |
|||
in length. A logical statement, however, may contain as many physical lines |
|||
as desired. Use line feed to start a new physical line within a logical |
|||
statement. |
|||
::BASCOM2.HQP |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
a random file. |
|||
51 Internal error |
|||
An internal malfunc |
|||
@ -0,0 +1,691 @@ |
|||
Compiling a program |
|||
Compilation switches |
|||
Compile-time error messages |
|||
The LINK-80 linking loader |
|||
LINK-80 error messages |
|||
Storing your program on disk |
|||
Running your compiled program |
|||
Runtime error messages |
|||
Using M80 |
|||
:COMPILING A PROGRAM |
|||
|
|||
Is your BASIC program now saved in ASCII format on your diskette? (To save |
|||
your program in ASCII format when using the interpreter, add an "A" switch |
|||
to the "SAVE" command, as shown in SAMPLE SESSION, Step 3: |
|||
|
|||
SAVE "<filename>[.<ext>]",A |
|||
|
|||
Return to CP/M command level and enter: |
|||
|
|||
BASCOM |
|||
|
|||
BASIC will return the prompt: "*", informing you that the BASIC |
|||
Compiler is loaded and ready to accept a command. |
|||
|
|||
Now enter the command of the form: |
|||
|
|||
objfile,lstfile=source file |
|||
|
|||
where objfile is the relocatable object file, lstfile is the listing file, |
|||
and source file is the BASIC source program file. |
|||
|
|||
A command to BASIC conveys the name of the source file to be compiled, and |
|||
the names of the file(s) to be created. With CP/M filenames are up to eight |
|||
characters long with a three-character extension. The default filename |
|||
extensions supplied to CP/M are: |
|||
|
|||
REL Relocatable object file |
|||
LST Listing file |
|||
BAS BASIC source file |
|||
MAC MACRO-80 source file |
|||
FOR FORTRAN-80 source file |
|||
COB COBOL-80 source file |
|||
COM Executable command file |
|||
|
|||
If you have a multi-drive system, you can tell the compiler where to obtain |
|||
or put the files you are working with by adding a drive number to each |
|||
filename. For example: |
|||
|
|||
A:MYPROG.REL=B:TEST |
|||
|
|||
finds the program TEST.BAS on the diskette that is in drive B, compiles it, |
|||
and puts the object in MYPROG.REL (on the diskette that is in drive A). |
|||
|
|||
If a drive is NOT specified, the object and listing files are placed on the |
|||
diskette that is in the default drive. |
|||
|
|||
Either the object file or the listing file or both may be omitted. An |
|||
object file is created only if the lstfile field is filled. Therefore, if |
|||
you wish to omit either, simply leave its filename out of the command. |
|||
|
|||
Examples: |
|||
|
|||
TESTOBJ=TEST.BAS Compile the program TEST.BAS |
|||
and put object in TESTOBJ.REL |
|||
without producing listing file. |
|||
TEST,TEST=TEST Compile TEST.BAS, put object in |
|||
TEST.REL and listing in |
|||
TEST.LST. |
|||
,=TEST.BAS Compile TEST.BAS but produce no |
|||
object or listing file. Useful |
|||
for checking for errors. |
|||
RABBIT=TEST Compile the program TEST.BAS |
|||
and put object in RABBIT.REL |
|||
without producing listing file. |
|||
:BASIC COMPILATION SWITCHES |
|||
|
|||
You can specify special parameters to be used during compilation by adding |
|||
a switch to the end of the command string. Switches are always preceded by |
|||
a slash, and more than one switch may be used in the same command. An |
|||
example of the format would be: |
|||
|
|||
TEST,TEST=TEST/D/X |
|||
|
|||
The default switch settings used if you don't specify any switches are: |
|||
|
|||
/Z/4/T |
|||
|
|||
The available switches and their actions are as follows: |
|||
|
|||
SWITCH ACTION |
|||
|
|||
/E The /E switch tells the compiler that the program contains the ON |
|||
ERROR GOTO statement. If a RESUME statement other than RESUME |
|||
<line number> is used with the ON ERROR GOTO statement, use /X |
|||
instead (see below). To handle ON ERROR GOTO properly, in a |
|||
compiled environment, BASIC must generate some extra code for the |
|||
GOSUB and RETURN statements. Therefore, do not use this switch |
|||
unless your program contains the ON ERROR GOTO statement. The /E |
|||
switch also causes line numbers to be included in the binary |
|||
file, so runtime error messages will include the number of the |
|||
line in error. |
|||
|
|||
SWITCH ACTION |
|||
/X The /X switch tells the BASIC Compiler that the program contains |
|||
one or more RESUME, RESUME NEXT, or RESUME 0 statements. The /E |
|||
switch is assumed when the /X switch is specified. To handle |
|||
RESUME statements properly in a compiled environment, the |
|||
compiler must relinquish certain optimizations. Therefore, do not |
|||
use this switch unless your program contains RESUME statements |
|||
other than RESUME <line number>. The /X switch also causes line |
|||
numbers to be included in the binary file, so runtime error |
|||
messages will include the number of the line in error. |
|||
|
|||
/N The /N switch prevents listing of the generated code in symbolic |
|||
notation. If this switch is not set, the source listing produced |
|||
by the compiler will contain the object code generated by each |
|||
statement. |
|||
|
|||
SWITCH ACTION |
|||
|
|||
/D The /D switch causes debug/checking code to be generated at |
|||
runtime. This switch must be set if you want to use TRON/TROFF. |
|||
The BASIC Compiler generates somewhat larger and slower code in |
|||
order to perform the following checks: |
|||
1. Arithmetic overflow. All arithmetic operations, integer and |
|||
floating point, are checked for overflow and underflow. |
|||
2. Array bounds. All array references are checked to see if the |
|||
subscripts are within the bounds specified in the DIM state- |
|||
ment. |
|||
3. Line numbers are included in the generated binary so that |
|||
runtime errors can indicate the statement which contains the |
|||
error. |
|||
4. RETURN is checked for a prior GOSUB. |
|||
|
|||
/Z The /Z switch tells the compiler to use Z80 opcodes. |
|||
|
|||
SWITCH ACTION |
|||
|
|||
/S The /S switch forces the compiler to write long quoted strings |
|||
(i.e. more than 4 characters) to the binary file as they are |
|||
encountered. This allows large programs with many quoted strings |
|||
to compile in less memory. However, there are two disadvantages: |
|||
1. Memory space is wasted if identical, long quoted strings |
|||
appear in the program. |
|||
2. Code generated while the -S switch is set cannot be placed |
|||
in ROM. |
|||
|
|||
SWITCH ACTION |
|||
|
|||
/4 The /4 switch allows the compiler to use the lexical conventions |
|||
of Microsoft 4.51 Disk BASIC interpreter. That is, spaces are |
|||
insignificant, variables with imbedded reserved words are |
|||
illegal, variable names are restricted to two significant |
|||
characters, etc. this feature is useful if you wish to compile a |
|||
source program that was coded without spaces, and contains lines |
|||
such as |
|||
|
|||
FORI=ATOBSTEPC |
|||
|
|||
Without the /4 switch, the compiler would assign the variable |
|||
"ATOBSTEPC" to the variable FORI. With the /4 switch, it would |
|||
recognize it as a FOR statement. |
|||
|
|||
SWITCH ACTION |
|||
/C The /C switch tells the compiler to relax line numbering con- |
|||
straints. Whene /C is specified, line numbers may be in any |
|||
order, or they may be eliminated entirely. Lines are compiled |
|||
normally, but of course cannot be targets for GOTO's, GOSUB's, |
|||
etc. While /C is set, the underline character causes the |
|||
remainder of the physical line to be ignored, and the next |
|||
physical line is considered to be a continuation of the current |
|||
logical line. NOTE: /C and /4 may not be used together. |
|||
|
|||
/T Use 4.51 execution conventions |
|||
|
|||
/O (Newer versions only). Tells the compiler to construct a stand- |
|||
alone program instead of one requiring presence of the BRUN.COM |
|||
runtime module. This generates much bigger programs because all |
|||
of the runtime routines must be included. |
|||
:BASIC COMPILER ERROR MESSAGES |
|||
|
|||
The following errors may occur while a program is compiling. The BASIC |
|||
Compiler outputs the two-character code for the err, along with an arrow. |
|||
The arrow indicates where in the line the error occurred. In those cases |
|||
where the compiler has read ahead before it discovered an error, the arrow |
|||
points a few characters beyond the error, or at the end of the line. The |
|||
error codes are as follows: |
|||
|
|||
FATAL ERRORS |
|||
|
|||
CODE ERROR |
|||
SN Syntax Error. Caused by one of the following: |
|||
Illegal argument name |
|||
Illegal assignment target |
|||
Illegal constant format |
|||
Illegal debug request |
|||
Illegal DEFxxx character specification |
|||
Illegal expression syntax |
|||
Illegal function argument list |
|||
Illegal function name |
|||
|
|||
CODE ERROR |
|||
SN Syntax Error. Caused by one of the following: |
|||
Illegal function formal parameter |
|||
Illegal separator |
|||
Illegal format for statement number |
|||
Illegal subroutine syntax |
|||
Invalid character |
|||
Missing AS |
|||
Missing equal sign |
|||
Missing GOTO or GOSUB |
|||
Missing comma |
|||
Missing INPUT |
|||
Missing line number |
|||
Missing left parenthesis |
|||
Missing minus sign |
|||
Missing operand in expression |
|||
Missing right parenthesis |
|||
Missing semicolon |
|||
Name too long |
|||
Expected GOTO or GOSUB |
|||
|
|||
CODE ERROR |
|||
SN Syntax Error. Caused by one of the following: |
|||
String assignment required |
|||
String expression required |
|||
String variable required here |
|||
Illegal syntax |
|||
Variable required here |
|||
Wrong number of arguments |
|||
Formal parameters must be unique |
|||
Single variable only allowed |
|||
Missing TO |
|||
Illegal FOR loop index variable |
|||
Missin THEN |
|||
Missing BASE |
|||
Illegal subroutine name |
|||
OM Out of memory |
|||
Array too big |
|||
Data memory overflow |
|||
Too many statement numbers |
|||
Program memory overflow |
|||
|
|||
CODE ERROR |
|||
SQ Sequence Error |
|||
Duplicate statement number |
|||
Statement out of sequence |
|||
TM Type Mismatch |
|||
Data type conflict |
|||
Variables must be of same type |
|||
BS Bad Subscript |
|||
Illegal dimension value |
|||
Wrong number of subscripts |
|||
LL Line Too Long |
|||
UC Unrecognizable Command |
|||
Statement unrecognizable |
|||
Command not implemented |
|||
OV Math Overflow |
|||
/0 Division by Zero |
|||
DD Array Already Dimensioned |
|||
FN FOR/NEXT Error |
|||
FOR loop index variable already in use |
|||
FOR without NEXT |
|||
NEXT without FOR |
|||
|
|||
CODE ERROR |
|||
FD Function Already Defined |
|||
UF Function Not Defined |
|||
WE WHILE/WEND Error |
|||
WHILE without WEND |
|||
WEND without WHILE |
|||
/E Missing "/E" Switch |
|||
/X Missing "/X" Switch |
|||
|
|||
WARNING ERRORS |
|||
ND Array Not Dimensioned |
|||
SI Statement Ignored |
|||
Statement ignored |
|||
Unimplemented command |
|||
|
|||
If the BASIC Compiler informs you of any of these errors, return to the |
|||
source program for debugging and try again. |
|||
|
|||
If no errors were encountered during compilation, and if you so chose, you |
|||
now have an object file containing machine readable code on your diskette. |
|||
Also on your diskette is a listing file which contains the BASIC program |
|||
statements along with the machine language generated by each statement. |
|||
|
|||
The next step in the process is loading and executing the program with |
|||
LINK-80. |
|||
|
|||
:LINK-80 LINKING LOADER |
|||
|
|||
As demonstrated in SAMPLE SESSION, compiled BASIC object files are loaded |
|||
into memory and executed using the LINK-80 linking loader. The loader has |
|||
many uses. You may wish to simply load one compiled program and run it, or |
|||
you may load several programs, subprograms, or assembly language |
|||
subroutines at the same time. Programs may be loaded at user-specified |
|||
locations, and program areas and data areas may be separated in memory. A |
|||
memory image of the executable file produced by LINK-80 can be saved on |
|||
disk and run at a later time. |
|||
|
|||
RUNNING LINK-80 |
|||
|
|||
At CP/M command level, enter: |
|||
|
|||
L80 |
|||
|
|||
This loads LINK-80, which will respond with: * . The loader exits back |
|||
to CP/M if a CONTROL-C is typed after the asterisk. (The loader also exits |
|||
back to CP/M after an /E switch or /G switch is executed. More on these |
|||
switches later.) |
|||
|
|||
LINK-80 COMMAND FORMAT |
|||
|
|||
A command to LINK-80 is made up of the filename(s) of the file(s) to be |
|||
loaded. For example, to load the compiled program MYPROG.REL, enter: |
|||
|
|||
MYPROG |
|||
|
|||
(It is not necessary to type the default extension .REL.) This loads the |
|||
program but does not run it. Whenever LINK-80 loads a BASIC Compiler |
|||
program, it automatically searches the BASIC library for the necessary |
|||
routines and loads these as well. Therefore, BASLIB.REL must be on the |
|||
default drive during the loading process. |
|||
|
|||
To run MYPROG, enter: |
|||
|
|||
/G |
|||
|
|||
This is the "go" or execute switch. LINK-80 prints two numbers and a BEGIN |
|||
EXECUTION message. LINK-80 always returns to TRSDOS after a /G switch has |
|||
been executed. |
|||
|
|||
As you probably have guessed, it is not necessary to perform these |
|||
operations with separate commands. It is possible to type one command line |
|||
that runs LINK-80, loads MYPROG.REL and executes it. To do this, enter: |
|||
|
|||
L80 MYPROG/G |
|||
|
|||
MORE COMMANDS AND SWITCHES |
|||
|
|||
LINK-80 provides other capabilities besides loading and executing |
|||
programs, such as looking at output without saving the program or |
|||
resetting the loader so that you can correct a mistake. Switches are |
|||
used to inform LINK-80 that you wish to perform special tasks. |
|||
|
|||
Here is an example that loads and saves a program called TEST.REL. |
|||
|
|||
>L80 |
|||
*TEST,TEST/N/E |
|||
|
|||
The first part of the command (TEST) loads the program called TEST.REL. The |
|||
next part (TEST/N) saves a copy of the loaded program on disk in a file |
|||
called TEST.COM. The last part (/E) causes LINK-80 to exit back to CP/M. |
|||
|
|||
THE /N SWITCH |
|||
|
|||
Take note of the /N switch. This switch saves a memory image of the |
|||
executable file on disk. The default extension for the saved file is .COM, |
|||
and this file is called a "command file". Once saved on disk, you need only |
|||
type the filename at CP/M command level to run the program. The /N switch |
|||
must immediately follow the filename of each file you wish to save, and it |
|||
does not take effect until a /E or /G switch is done. |
|||
|
|||
The following example links several object files, saves the main program |
|||
image and executes the program TAXES.REL. |
|||
|
|||
>L80 |
|||
*SUB1,SUB2,TAXES/N,TAXES/G |
|||
|
|||
Two subroutines (SUB1) and (SUB2) and an object file (TAXES) are linked and |
|||
loaded. The program is executed and the command file TAXES.COM is saved on |
|||
disk. |
|||
|
|||
THE /R SWITCH |
|||
|
|||
Another handy switch is /R. It returns LINK-80 to it's initial state by |
|||
"unloading" whatever you've loaded. Use it to reset the loader if you've |
|||
made a typing mistake or loaded the wrong program. The /R switch takes |
|||
effect as soon as LINK-80 sees it, so if you enter it at any time while |
|||
LINK-80 is running, the loader will reset. For example: |
|||
|
|||
>L80 |
|||
*INVEN1 |
|||
*/R (oops-- meant to load INVEN2) |
|||
*INVEN2 (now only INVEN2 is loaded) |
|||
|
|||
SPECIAL SWITCHES |
|||
|
|||
For typical BASIC Compiler operation, only the above switches will be |
|||
needed. Some users may find that their applications require more |
|||
specialized capabilities. For this reason, the following switches are also |
|||
provided with LINK-80. |
|||
|
|||
In these examples, all programs have been loaded at the default origins |
|||
of CP/M. In special cases, the user may wish to specify the origins of |
|||
the programs and data that are loaded. LINK-80 provides special switches to |
|||
do this. |
|||
|
|||
/E:Name This is an optional form of the /E switch. Name is a global |
|||
symbol previously defined in one of the modules. LINK-80 |
|||
uses Name for the start address of the program. |
|||
|
|||
/G:Name This is an optional form of the /G switch. Name is a global |
|||
symbol previously defined in one of the modules. LINK-80 |
|||
uses Name for the start address of the program. |
|||
|
|||
/P and /D /P and /D allow the origin(s) to be set for the next program |
|||
loaded. /P and /D take effect when seen (not deferred), and |
|||
they have no effect on programs already loaded. The form is |
|||
/P:<address> or /D:<address>, where <address> is the desired |
|||
origin in the current typeout radix. (Default radix is |
|||
hexadecimal. /O sets radix to octal; /H to hex.) LINK-80 |
|||
does a default /P:<link origin> (i.e., 100h). |
|||
|
|||
If no /D is given, data areas are loaded before program |
|||
areas for each module. If a /D is given, All Data and Common |
|||
areas are loaded starting at the data origin and the program |
|||
area at the program origin. Example: |
|||
|
|||
*/P:200,FOO |
|||
DATA 200 300 |
|||
*/R |
|||
*/P:200-D:400,FOO |
|||
DATA 400 480 |
|||
PROGRAM 200 280 |
|||
|
|||
/U List the origin and end of the program and data area and all |
|||
undefined globals as soon as the current command line has |
|||
been interpreted. The program information is only printed if |
|||
a /D has been done. Otherwise, the program is stored in the |
|||
data area. |
|||
|
|||
/M List the origin and end of the program and data area, all |
|||
undefined globals and their values, and all undefined |
|||
globals followed by an asterisk. The program information is |
|||
only printed if a /D has been done. Otherwise, the program |
|||
is stored in the data area. |
|||
|
|||
/X If a filename/N was specified, /X will cause the file to be |
|||
saved in INTEL ascii HEX format with an extension of .HEX. |
|||
|
|||
/Y If a filename/N was specified, /Y will create a filename.SYM |
|||
file when /E is entered. This file contains the names and |
|||
addresses of all Globals for use with Digital Research's SID |
|||
and ZSID debuggers. |
|||
|
|||
SYSTEM LIBRARY SEARCHES |
|||
|
|||
Whenever a BASIC Compiler program is loaded, LINK-80 automatically searches |
|||
the BASIC Compiler library for the routines it needs and loads them. If you |
|||
gat an "Undefined" error, it means the compiler couldn't find something it |
|||
needed to finish compiling the program. Usually this is the name of a |
|||
subroutine that you forgot to load. |
|||
|
|||
If you are using the BASIC Compiler in conjunction with Microsoft's |
|||
FORTRAN-80, you may also be referencing some of FORTRAN's library routines. |
|||
For this reason, the /S switch is included in LINK-80 to force a search of |
|||
particular library modules. For example: |
|||
|
|||
*FORLIB/S,TEST/G |
|||
|
|||
Unless you are using FORLIB (supplied with FORTRAN-80), you should not need |
|||
the /S switch. |
|||
|
|||
|
|||
:LINK-80 ERROR MESSAGES |
|||
|
|||
LINK-80 has the following error messages: |
|||
|
|||
?No Start Address A /G switch was issued, but no main |
|||
program had been loaded. |
|||
|
|||
?Loading Error The last file given for input was |
|||
not a properly formatted LINK-80 |
|||
object file. |
|||
|
|||
?Out of Memory Not enough memory to load program. |
|||
|
|||
?Command Error Unrecognizable LINK-80 command. |
|||
|
|||
?<file> Not Found <file>, as given in the command string, |
|||
did not exist. |
|||
|
|||
%2nd COMMON larger The first definition of COMMON |
|||
block /XXXXXX/ was not the largest |
|||
definition. Reorder module loading |
|||
sequence or change COMMON block |
|||
definitions. |
|||
|
|||
%Mult. Def. Global YYYYYY |
|||
More than one definition for the |
|||
global (internal) symbol YYYYYY was |
|||
encountered during the loading |
|||
process. |
|||
|
|||
%Overlaying Program Area ,Start = xxxx |
|||
Data ,Public = <symbol name>(xxxx) |
|||
,External = <symbol name>(xxxx) |
|||
A /D or /P will cause already |
|||
loaded data to be destroyed. |
|||
|
|||
?Intersecting Program Area |
|||
Data The program and data area intersect |
|||
and an address or external chain |
|||
entry is in this intersection. The |
|||
final value cannot be converted to |
|||
a current value since it is in the |
|||
area intersection. |
|||
?Start Symbol - <name> - Undefined |
|||
After a /E: or /G: is given, the |
|||
symbol specified was not defined. |
|||
|
|||
Origin Above (Below) Loader Memory, Move Anyway (Y or N)? |
|||
After a /E or /G was given, either |
|||
the data or program area has an |
|||
origin or top which lies outside |
|||
loader memory (i.e., loader origin |
|||
to top of memory). If a Y CR is |
|||
given, LINK-80 will move the area |
|||
and continue. If anything else is |
|||
given, LINK-80 will exit. In either |
|||
case, if a /N was given, the image |
|||
will already have been saved. |
|||
|
|||
?Can't save Object File A disk error occurred when the file was being |
|||
saved. |
|||
:STORING YOUR PROGRAM ON DISKETTE |
|||
|
|||
Once it has been loaded by LINK-80, the object file is in a form that can |
|||
be executed by any CP/M computer. You can save this compiled program on |
|||
your own diskette so that it can be executed at a later time without using |
|||
the BASIC Compiler at all. |
|||
|
|||
The /N switch (discussed in the LINK-80 section) is the switch that causes |
|||
your object file to be saved. The default extension for the saved file is |
|||
.COM and this file is called a "command file". |
|||
|
|||
:RUNNING YOUR COMPILED PROGRAM |
|||
|
|||
Your compiled program (previously saved on your own diskette) can now be |
|||
executed any time you wish. When you are at CP/M command level the diskette |
|||
on which you saved your program is inserted into a drive, simply enter: |
|||
|
|||
<filename> |
|||
|
|||
At this point, your program should execute and your output should appear on |
|||
the screen. However, you may get a runtime error message. If you do, look |
|||
it up in the following list, and debug your program as best you can before |
|||
trying to store it on diskette again. |
|||
|
|||
|
|||
:RUNTIME ERROR MESSAGES |
|||
|
|||
The following errors may occur while a compiled program is executing. The |
|||
error numbers match those issued by the BASIC-80 interpreter. The compiler |
|||
runtime system prints long error messages followed by an address, unless |
|||
/D, /E, or /X is specified. In those cases the error message is followed by |
|||
the number of the line in which the error occurred. |
|||
|
|||
NUMBER MESSAGE |
|||
2 Syntax error |
|||
A line is encountered that contains an incorrect |
|||
sequence of characters in a DATA statement. |
|||
3 RETURN without GOSUB |
|||
A RETURN statement is encountered for which there |
|||
is no previous, unmatched GOSUB ststement. |
|||
4 Out of Data |
|||
A READ statement is executed when there are no |
|||
DATA statements with unread data remaining in the |
|||
program. |
|||
|
|||
NUMBER MESSAGE |
|||
|
|||
5 Illegal function call |
|||
A parameter that is out of range is passed to a |
|||
math or string function. An FC error may also |
|||
occur as the result of: |
|||
|
|||
1. a negative or unreasonably large subscript |
|||
2. a negative or zero argument with LOG |
|||
3. a negative argument to SQR |
|||
4. a negative mantissa with a non-integer |
|||
exponent |
|||
5. a call to a USR function for which the |
|||
starting address has not yet been given |
|||
6. an improper argument to ASC, CHR$, MID$, |
|||
LEFT$, RIGHT$, INP, OUT, WAIT, PEEK, POKE, |
|||
TAB, SPC, STRING$, SPACE$, INSTR, or |
|||
ON...GOTO |
|||
7. a string concatenation that is longer than |
|||
255 characters |
|||
|
|||
NUMBER MESSAGE |
|||
6 Floating overflow or integer overflow |
|||
The result of a calculation is too large to be |
|||
represented in BASIC-80's number format. If |
|||
underflow occurs, the result is zero and execution |
|||
continues without an error. |
|||
9 Subscript out of range |
|||
An array element is referenced with a subscript |
|||
that is outside the dimensions of the array. |
|||
11 Division by zero |
|||
A division by zero is encountered in an |
|||
expression, or the operation of involution results |
|||
in zero being raised to a negative power. Machine |
|||
infinity with the sign of the numerator is |
|||
supplied as the result of the division, or |
|||
positive machine infinity is supplied as the |
|||
result of the involution, and execution continues. |
|||
14 Out of string space |
|||
String variables exceed the allocated amount of |
|||
string space. |
|||
|
|||
NUMBER MESSAGE |
|||
20 RESUME without error |
|||
A RESUME statement is encountered before an error |
|||
trapping routine is entered. |
|||
21 Unprintable error |
|||
An error message is not available for the error |
|||
condition which exists. This is usually caused by |
|||
an ERROR with an undefined error code. |
|||
50 Field overflow |
|||
A FIELD statement is attempting to allocate more |
|||
bytes than were specified for the record length of |
|||
a random file. |
|||
51 Internal error |
|||
An internal malfunction has occurred in Disk |
|||
BASIC-80. Report to Microsoft the conditions under |
|||
which the message appeared. |
|||
52 Bad file number |
|||
A statement or command references a file with a |
|||
file number that is not OPEN or is out of the |
|||
range of file numbers specified at initialization. |
|||
|
|||
NUMBER MESSAGE |
|||
53 File not found |
|||
A RUN, CHAIN, KILL, or OPEN statement references a |
|||
file that does not exist on the current disk. |
|||
54 Bad file mode |
|||
An attempt is made to use PUT, GET, or LOF with a |
|||
sequential or to execute an OPEN with a file mode |
|||
other than I, O, R, D. |
|||
55 File already open |
|||
A sequential output mode OPEN is issued for a file |
|||
that is already open; or a KILL is given for a |
|||
file that is open. |
|||
57 Disk I/O error |
|||
An I/O error occurred on a disk I/O operation. It |
|||
is a fatal error, i.e., theoperating system cannot |
|||
recover from the error. |
|||
58 File already exists |
|||
The filename specified is identical to a filename |
|||
already in use on the disk. |
|||
61 Disk Full |
|||
All disk storage space is in use. |
|||
|
|||
NUMBER MESSAGE |
|||
62 Input past end |
|||
An INPUT statement is executed after all the data |
|||
in the file has been INPUT, or for a null (empty) |
|||
file. To avoid this error, use the EOF function to |
|||
detect the end of file. |
|||
63 Bad record number |
|||
In a PUT or GET statement, the record number is |
|||
either greater than the maximum allowed (32767) or |
|||
equal to zero. |
|||
64 Bad file name |
|||
An illegal form is used for the filename with RUN, |
|||
CHAIN, KILL, or OPEN (e.g., a filename with too |
|||
many characters). |
|||
67 Too many files |
|||
An attempt is made to create a new file (using |
|||
OPEN) when the directory is full. |
|||
::M80.HQP |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
d file is .COM, |
|||
and this file is called a "command file". Once saved |
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,17 @@ |
|||
00100 defint i-n |
|||
00200 recsiz%=32 |
|||
00300 open "R",1,"B:RANTEST.ASC",recsiz% |
|||
00400 for i=1 to 20 |
|||
00500 print #1, using "$$#,###.## ";1000*i,102.34*i*i |
|||
00600 put 1,i |
|||
00700 next i |
|||
00800 for i=1 to 20 |
|||
00900 get 1,i |
|||
01000 line input #1, prices$ |
|||
01100 print i,prices$ |
|||
01200 next i |
|||
01300 close 1 |
|||
01400 end |
|||
r i=1 to 20 |
|||
00900 get 1,i |
|||
01000 line input #1, prices |
|||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,54 @@ |
|||
Microsoft Basic-80 Compiler v.5.30a |
|||
|
|||
----------------------------------------------------------- |
|||
Example of a session: |
|||
----------------------------------------------------------- |
|||
|
|||
>MBASIC |
|||
|
|||
BASIC-80 Rev. 5.21 |
|||
[CP/M Version] |
|||
Copyright 1977-1981 (C) by Microsoft |
|||
Created: 28-Jul-81 |
|||
31800 Bytes free |
|||
Ok |
|||
10 PRINT "Hello World" |
|||
list |
|||
10 PRINT "Hello World" |
|||
Ok |
|||
RUN |
|||
Hello World |
|||
Ok |
|||
SAVE "HELLO",A |
|||
Ok |
|||
SYSTEM |
|||
|
|||
A>TYPE BAS.SUB |
|||
|
|||
BASCOM =$1 /E |
|||
L80 $1,$1/N/E |
|||
|
|||
A>SUPERSUB BAS HELLO |
|||
|
|||
SuperSUB V1.1 |
|||
|
|||
A>BASCOM =HELLO /E |
|||
|
|||
00000 Fatal Error(s) |
|||
24196 Bytes Free |
|||
|
|||
A>L80 HELLO,HELLO/N/E |
|||
|
|||
Link-80 3.44 09-Dec-81 Copyright (c) 1981 Microsoft |
|||
|
|||
Data 4000 4197 < 407> |
|||
|
|||
40207 Bytes Free |
|||
[4011 4197 65] |
|||
|
|||
A>hello |
|||
|
|||
Hello World |
|||
|
|||
|
|||
A> |
|||
@ -0,0 +1,2 @@ |
|||
00010 PRINT "This is an example of BASIC-80" |
|||
|
|||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,10 @@ |
|||
===== Microsoft Fortran-80 Compiler v.3.44 ===== |
|||
|
|||
This is Microsoft's implementation of the FORTRAN scientific-oriented high level |
|||
programming language. It was one of their early core languages developed for the |
|||
8-bit computers and later brought to the 8086 and IBM PC. In 1993 Microsoft |
|||
rebranded the product as Microsoft Fortran Powerstation. (Note: -80 refers to |
|||
the 8080/Z80 platform, not the language specification version) |
|||
|
|||
The user manual is available in the Doc directory, |
|||
Microsoft_FORTRAN-80_Users_Manual_1977.pdf |
|||
@ -0,0 +1,87 @@ |
|||
TITLE CPMIO CONSOLE I/O ROUTINES FOR CP/M |
|||
ENTRY $TTYIN,$TTYOT,$LNPTR,$CPMBF,$LINBF |
|||
TANDY EQU 0 |
|||
CPMSBC EQU 0 |
|||
; |
|||
IF2 |
|||
.PRINTX /CPMIO/ |
|||
IFT TANDY |
|||
.PRINTX/TANDY VERSION/ |
|||
ENDIF |
|||
IFT CPMSBC |
|||
.PRINTX/CPM SBC VERSION/ |
|||
ENDIF |
|||
IFF TANDY OR CPMSBC |
|||
.PRINTX/NORMAL CPM VERSION/ |
|||
ENDIF |
|||
ENDIF |
|||
; |
|||
IFT TANDY |
|||
CPMENT SET 4205H |
|||
ENDIF |
|||
IFF TANDY |
|||
CPMENT SET 5 |
|||
ENDIF |
|||
IFT CPMSBC |
|||
CPMENT SET 4005H |
|||
ENDIF |
|||
;CP/M CONSOLE OUTPUT ROUTINE |
|||
$TTYOT: PUSH B |
|||
PUSH D |
|||
PUSH H |
|||
PUSH PSW ;SAVE ALL REG'S |
|||
MVI C,2 ;CONSOLE OUTPUT |
|||
MOV E,A ;EXPECTS CHAR IN [E] |
|||
CALL CPMENT ;OUTPUT THE CHAR |
|||
POP PSW |
|||
POP H |
|||
POP D |
|||
POP B ;RESTORE STATE |
|||
RET |
|||
; |
|||
;CP/M CONSOLE INPUT ROUTINE |
|||
;NOTE: DON'T STOP PROGRAM IN INPUT WITH SWITCHES, COULD LEAVE |
|||
; GARB IN LINE IF THEN SAVED AND STARTED OVER. |
|||
$TTYIN: PUSH H ;SAVE [H,L] |
|||
LHLD $LNPTR ;POINT TO LAST CHAR |
|||
MOV A,M ;GET LAST CHAR |
|||
CPI 12Q ;FINISHED OFF LINE(LF)? |
|||
CZ GETLIN ;YES, GET ANOTHER |
|||
INX H ;POINT TO NEXT CHAR |
|||
MOV A,M ;GET IT |
|||
SHLD $LNPTR ;SAVE PTR |
|||
POP H ;RESTORE |
|||
RET |
|||
; |
|||
GETLIN: PUSH B |
|||
PUSH D ;SAVE OTHER REG'S |
|||
MVI C,12Q ;READ CONSOLE LINE |
|||
LXI D,$CPMBF ;PTR TO BUFFER |
|||
CALL CPMENT ;READ LINE FROM CONSOLE |
|||
LXI H,$CPMBF+1 ;POINT TO LENGTH OF LINE |
|||
MOV E,M ;GET LENGTH |
|||
MVI D,0 ;[D,E] = LENGTH |
|||
XCHG ;SAVE [H,L] IN [D,E] |
|||
DAD D ;GET PTR TO LAST CHAR |
|||
INX H |
|||
MVI M,15Q ;ADD <CR> |
|||
INX H |
|||
MVI A,12Q ;LINE FEED |
|||
CALL $TTYOT ;CPM DOESN'T GIVE ONE |
|||
MOV M,A ;AND <LF> |
|||
XCHG ;[H,L]=1ST CHAR -1 |
|||
POP D |
|||
POP B |
|||
RET |
|||
; |
|||
DSEG |
|||
$CPMBF: DB 80 ;LENGTH OF BUFFER |
|||
DB 0 ;LENGTH OF LINE |
|||
$LINBF: DB 12Q ;SO WORKS AT FIRST |
|||
DS 135 ;REST OF BUFFER FOR LINE |
|||
; |
|||
$LNPTR: DW $LINBF ;AT FIRST POINT TO <LF> IN FRONT |
|||
; ;TO FORCE READ OF LINE |
|||
; |
|||
END |
|||
|
|||
@ -0,0 +1,16 @@ |
|||
|
|||
--> FILE: CPMIO .MAC CRC = 71 D9 |
|||
--> FILE: CREF80 .COM CRC = BB F2 |
|||
--> FILE: DSKDRV .MAC CRC = 7A 3B |
|||
--> FILE: DTBF .MAC CRC = 26 3C |
|||
--> FILE: F80 .COM CRC = EF E2 |
|||
--> FILE: FCHAIN .MAC CRC = DA 61 |
|||
--> FILE: FORLIB .REL CRC = DA 31 |
|||
--> FILE: INIT .MAC CRC = 81 21 |
|||
--> FILE: IOINIT .MAC CRC = 51 55 |
|||
--> FILE: L80 .COM CRC = 15 DF |
|||
--> FILE: LIB .COM CRC = 24 15 |
|||
--> FILE: LPTDRV .MAC CRC = 0B 56 |
|||
--> FILE: LUNTB .MAC CRC = 71 25 |
|||
--> FILE: M80 .COM CRC = 69 DB |
|||
--> FILE: TTYDRV .MAC CRC = C2 85 |
|||
Binary file not shown.
@ -0,0 +1,860 @@ |
|||
TITLE DSKDRV - FORTRAN-80 DISK DRIVER |
|||
|
|||
.8080 |
|||
|
|||
MAXLUN EQU 10 ;MAX # OF LUN'S ALLOWED |
|||
|
|||
;BDOS FUNCTION CALLS, FCB OFFSETS |
|||
|
|||
BDOS EQU 5 ;CP/M BDOS ENTRY POINT |
|||
|
|||
.RSET EQU 13 ;DISK RESET |
|||
.SELCT EQU 14 ;SELECT DISK |
|||
.OPEN EQU 15 ;OPEN FILE |
|||
.CLOSE EQU 16 ;CLOSE FILE |
|||
.DELET EQU 19 ;DELETE FILE |
|||
.MAKE EQU 22 ;CREATE FILE |
|||
.STDMA EQU 26 ;SET DMA ADDRESS |
|||
|
|||
FCB.FT EQU 9 ;FILE TYPE |
|||
FCB.EX EQU 12 ;EXTENT BYTE |
|||
FCB.RC EQU 15 ;RECORD COUNT BYTE |
|||
FCB.NR EQU 32 ;NEXT RECORD BYTE |
|||
FCB.RR EQU 33 ;RANDOM RECORD NUMBER (2.X) |
|||
FCBLEN EQU 36 ;FCB SIZE |
|||
|
|||
SECSIZ EQU 128 ;SECTOR SIZE (RECORD LENGTH) |
|||
|
|||
; GLOBAL DEFINITIONS |
|||
|
|||
EXTRN $CPMVN,$CPMRF,$CPMWF,$BL,$BF,$ERR |
|||
EXTRN $IOERR,$REC,$UN,$LUNTB,$CLSFL |
|||
|
|||
ENTRY $DSKER,$FLFLG,$MEMRY,DSKDRV |
|||
|
|||
DSEG ;DATA AREA |
|||
|
|||
; I/O ERROR CODE DEFNS |
|||
|
|||
OBOVF EQU 016Q ;OUTPUT BUFFER LIMIT EXCEEDED |
|||
IRECER EQU 022Q ;INPUT RECORD TOO LONG |
|||
NOFILE EQU 236Q ;FILE NOT FOUND |
|||
FULERR EQU 237Q ;DISK FULL |
|||
LUNERR EQU 240Q ;LUN TOO LARGE |
|||
NOMEM EQU 241Q ;OUT-OF-MEMORY |
|||
|
|||
; I/O MODE DEFN BYTE |
|||
|
|||
MD.ALC EQU 80H ;80H ALLOCATED BUFFER AND FCB |
|||
MD.OPN EQU 40H ;40H FILE IS OPEN |
|||
MD.OUT EQU 20H ;20H IF OUTPUT |
|||
MD.BIN EQU 10H ;10H IF UNFORMATTED I/O |
|||
|
|||
MD.WRT EQU 08H ;08H WRITE-DATA-IN-BUFFER |
|||
MD.RND EQU 04H ;04H IF RANDOM I/O |
|||
|
|||
$FLFLG: DS MAXLUN ;I/O MODE BYTE FOR EACH LUN |
|||
$FLCNT: DS MAXLUN ;I/O BUFFER INDEX FOR EACH LUN |
|||
$FLBUF: DS MAXLUN*2 ;BUFFER LOCATION FOR EACH LUN |
|||
$FLFCB: DS MAXLUN*2 ;FCB LOCATION FOR EACH LUN |
|||
|
|||
$DSKER: DS 1 ;STATUS OF LAST I/O |
|||
CLSADR: DS 2 |
|||
|
|||
$MEMRY: DS 2 ;FOR LOADER TO STORE TOP OF MEM INTO |
|||
|
|||
CSEG ;CODE AREA |
|||
|
|||
FILTXT: DB "FORT",0 ;DEFAULT FILENAME TEXT |
|||
FILEXT: DB "DAT",0 |
|||
|
|||
PAGE |
|||
|
|||
; I/O DISPATCH TABLE |
|||
|
|||
; LUN'S 6 THRU MAXLUN POINT TO THIS TABLE VIA $LUNTB. |
|||
; AN EXPLICIT OPEN VIA CALL OPEN (<FILESPEC>) ALLOW |
|||
; OTHER UNITS TO USE THE DISK ALSO... |
|||
|
|||
DSKDRV: DW DSKFRD ;FORMATTED READ |
|||
DW DSKFWR ;FORMATTED WRITE |
|||
DW DSKURD ;UNFORMATTED READ |
|||
DW DSKUWR ;UNFORMATTED WRITE |
|||
DW DSKREW ;REWIND |
|||
DW $IOERR ;BACKSPACE (NOT SUPPORTED). |
|||
DW DSKCLS ;ENDFILE |
|||
|
|||
FNFERR: CALL $ERR |
|||
DB NOFILE ;FILE NOT FOUND |
|||
|
|||
DSKFUL: CALL $ERR |
|||
DB FULERR ;DISK FULL |
|||
|
|||
LUNOVF: CALL $ERR |
|||
DB LUNERR ;LUN TOO LARGE |
|||
|
|||
MEMERR: CALL $ERR |
|||
DB NOMEM ;OUT-OF-MEMORY |
|||
|
|||
;------------------------------------------------------ |
|||
; |
|||
; GET MODE BYTE(LUN) FROM $FLFLG |
|||
; |
|||
GTMODE: LXI H,$FLFLG-1 |
|||
LDA $UN ;GET UNIT # |
|||
MVI D,0 |
|||
MOV E,A |
|||
DAD D ;[HL] POINTS TO FLAG |
|||
MOV A,M ;GET FLAG |
|||
RET |
|||
;------------------------------------------------------ |
|||
; |
|||
; SET DMA TO DATA BUFFER(LUN) |
|||
; |
|||
SETBUF: PUSH B |
|||
PUSH D |
|||
CALL GETBUF ;GET BUFFER ADR |
|||
MVI C,.STDMA |
|||
CALL BDOS |
|||
POP D |
|||
POP B |
|||
RET |
|||
;------------------------------------------------------ |
|||
GETBUF: LDA $UN |
|||
ADD A |
|||
MOV E,A |
|||
MVI D,0 |
|||
LXI H,$FLBUF-2 |
|||
DAD D |
|||
MOV E,M |
|||
INX H |
|||
MOV D,M |
|||
RET |
|||
|
|||
;------------------------------------------------------ |
|||
; |
|||
; GET DATA.BUFFER.OFFSET(LUN) |
|||
; |
|||
GTBOFF: |
|||
LXI H,$FLCNT-1 |
|||
LDA $UN |
|||
MVI D,0 |
|||
MOV E,A |
|||
DAD D |
|||
MOV A,M ;GET OFFSET |
|||
RET |
|||
|
|||
;------------------------------------------------------ |
|||
; |
|||
; GET ADR OF FCB(LUN) IN [DE] |
|||
; |
|||
GTFCB: LXI H,$FLFCB-2 |
|||
LDA $UN |
|||
ADD A |
|||
MOV E,A |
|||
MVI D,0 |
|||
DAD D ;POINT TO ADR OF FCB |
|||
MOV E,M |
|||
INX H |
|||
MOV D,M |
|||
RET |
|||
|
|||
;------------------------------------------------------ |
|||
; |
|||
; GET READ/WRITE RECORD NUMBER FOR LUN |
|||
; ON RETURN: |
|||
; [HL] = FCB.RR(LUN) ADR OF RND REC NUM. |
|||
; [DE] = $REC 00 OR RND REC NUM. |
|||
; |
|||
GTREC: |
|||
CALL GTFCB |
|||
LXI H,FCB.RR |
|||
DAD D |
|||
XCHG |
|||
LHLD $REC |
|||
XCHG |
|||
RET |
|||
;------------------------------------------------------ |
|||
; ZERO FCB FROM EXTENT BYTE TO END. |
|||
; |
|||
CLRFCB: |
|||
CALL GTFCB |
|||
LXI H,FCB.EX |
|||
DAD D |
|||
LXI B,FCBLEN-FCB.EX |
|||
CLRFCL: |
|||
MOV M,B |
|||
INX H |
|||
DCR C |
|||
JNZ CLRFCL |
|||
RET |
|||
;------------------------------------------------------ |
|||
; COPY BYTES FROM [DE] TO [HL] UNTIL NULL (00). |
|||
; |
|||
CPYTXT: |
|||
MOV M,A ;COPY FROM [DE] TO [HL] |
|||
INX H ;UNTIL NULL. |
|||
INX D |
|||
LDAX D |
|||
ORA A |
|||
JNZ CPYTXT |
|||
RET |
|||
|
|||
PAGE |
|||
;------------------------------------------------------ |
|||
; |
|||
; OPNCHK - ASSURE THAT FILE IS OPEN AND BUFFERS ALLOCATED. |
|||
; IF NOT THEN: |
|||
; 1. ALLOCATE DATA BUFFER AND FCB FROM $MEMRY. |
|||
; 2. OPEN FILE WITH NAME OF FORT##.DAT WHERE: |
|||
; ## IS LOGICAL-UNIT-NUMBER (LUN) OF FILE. |
|||
|
|||
OPNCHK: |
|||
LDA $UN |
|||
CPI MAXLUN+1 ; |
|||
JNC LUNOVF ;LUN IS TOO LARGE |
|||
; ---------------- |
|||
PUSH B ;SAVE OPEN MODE REQUEST. |
|||
CALL GTMODE ;GET FLAG |
|||
ORA A ;ALLOCATED BUFFER,FCB? |
|||
CP ALCBUF ;NO, GET SPACE AND SET PTRS |
|||
; ---------------- |
|||
POP B ;GET I/O MODE IN [C] |
|||
ANI MD.OPN ;WAS OPEN? |
|||
CZ OPNFIL ;NO, OPEN FILE. |
|||
|
|||
;------------------------------------------------------ |
|||
; |
|||
; SETREC - SET UP RECORD NUMBER |
|||
; |
|||
SETREC: |
|||
CALL GTREC ;GET CURRENT & LAST RECORD NUMBERS |
|||
MOV A,D ;[DE] = $REC |
|||
ORA E ;IF RANDOM I/O |
|||
JNZ SETRND ;USE VALUE IN $REC |
|||
; ---------------- |
|||
MOV E,M ;..ELSE |
|||
INX H ;USE CURRENT RECORD |
|||
MOV D,M ;SET BY SEQ READ/WRITE. |
|||
PUSH D ;SAVE REC NO. |
|||
CALL GTMODE |
|||
ANI NOT MD.RND ;SET SEQUENTIAL MODE |
|||
MOV M,A |
|||
POP D ;RESTORE REC NO. |
|||
JMP SETSEQ |
|||
; ---------------- |
|||
SETRND: |
|||
CALL GTMODE |
|||
ANI MD.WRT ;WRITE-DATA-IN-BUFFER? |
|||
CNZ FRCOUT ;YES, FLUSH IT FIRST. |
|||
CALL GTMODE |
|||
ORI MD.RND ;SET RANDOM MODE |
|||
MOV M,A |
|||
CALL GTREC ;RESTORE REC NO'S. |
|||
DCX D ;ADJUST RANDOM REC NO. |
|||
MOV M,E |
|||
INX H ;STORE AT FCB.RR FOR NEXT I/O |
|||
MOV M,D |
|||
INX H |
|||
MVI M,0 |
|||
; ---------------- |
|||
SETSEQ: |
|||
LDA $CPMVN ;CP/M VERSION FLAG |
|||
ORA A ;VERSION 1.X ? |
|||
RZ ;NO, VERSION 2.X NOTHING ELSE NEEDED. |
|||
;------------------------------------------------------ |
|||
; |
|||
; SPLIT RANDOM RECORD INTO EXTENT AND RELATIVE RECORD |
|||
; FOR VERSION 1.X |
|||
; |
|||
SETV1: |
|||
MOV A,E |
|||
RAL |
|||
MOV A,D |
|||
RAL |
|||
MOV B,A |
|||
MOV A,E |
|||
ANI X'7F' |
|||
MOV C,A |
|||
; ---------------- |
|||
CALL GTFCB ;[DE] = ADR OF FCB(LUN) |
|||
LXI H,FCB.EX |
|||
DAD D |
|||
MOV A,M ;FETCH CURRENT EXTENT |
|||
CMP B |
|||
JZ SAMEXT ;IF SAME AS REQUESTED EXTENT |
|||
; |
|||
; CLOSE CURRENT EXTENT, OPEN REQUESTED ONE |
|||
; |
|||
PUSH B ;EXT/REC |
|||
PUSH D ;FCB ADR |
|||
LXI H,FCB.NR |
|||
DAD D |
|||
MVI M,0 ;ZERO THE RECORD NUMBER |
|||
LHLD $MEMRY ;GET SCRATCH BUFFER |
|||
XCHG ;FROM TOP OF HEAP FOR OPEN/CLOSE |
|||
MVI C,.STDMA |
|||
CALL BDOS |
|||
CALL GTMODE |
|||
ANI MD.OUT ;OPEN FOR OUTPUT? |
|||
JZ OPNXT ;NO, SKIP THIS CLOSE |
|||
POP D |
|||
PUSH D ;FCB |
|||
MVI C,.CLOSE |
|||
CALL BDOS |
|||
OPNXT: |
|||
POP D ;FCB |
|||
POP B ;EXT/REC |
|||
PUSH B |
|||
PUSH D |
|||
LXI H,FCB.EX |
|||
DAD D |
|||
MOV M,B ;SET NEW EXTENT NUMBER |
|||
MVI C,.OPEN |
|||
CALL BDOS |
|||
INR A |
|||
JNZ SKEXT ;IF IT EXISTS |
|||
POP D |
|||
PUSH D ;FCB |
|||
CALL MAKEXT ;CREATE NEW EXTENT |
|||
SKEXT: |
|||
POP D ;FCB |
|||
POP B ;EXT/REC |
|||
SAMEXT: |
|||
LXI H,FCB.NR |
|||
DAD D |
|||
MOV M,C ;SET RECORD NUMBER |
|||
RET |
|||
|
|||
PAGE |
|||
;------------------------------------------------------ |
|||
; ALLOCATE FCB AND BUFFER FOR UNIT . ALLOCATES UP FROM |
|||
; $MEMRY AND STORES PTRS IN TABLE. |
|||
|
|||
ALCBUF: PUSH H |
|||
LHLD $MEMRY ;GET CURRENT TOP |
|||
XCHG ;IN [DE] |
|||
; ---------------- |
|||
LXI H,-256 |
|||
DAD SP |
|||
MOV A,L |
|||
SUB E ;IF MEMTOP-256 < $MEMRY, |
|||
MOV A,H ;THEN GIVE OUT-OF-MEMORY |
|||
SBB D ;ERROR AND EXIT... |
|||
JC MEMERR |
|||
; ---------------- |
|||
LXI H,$FLBUF-2 |
|||
LDA $UN |
|||
ADD A |
|||
MVI B,0 |
|||
MOV C,A ;[BC]= 2*UNIT# |
|||
DAD B ;GET ADR OF PTR TO BUFFER |
|||
MOV M,E |
|||
INX H |
|||
MOV M,D ;STORE $MEMRY AS ADR |
|||
LXI H,SECSIZ |
|||
DAD D ;GET NEW TOP |
|||
PUSH H ;SAVE FCB ADR |
|||
CALL GTFCB ;GET [HL]=ENTRY+1 |
|||
POP D |
|||
PUSH D ;SAVE FCB ADR |
|||
MOV M,D |
|||
DCX H |
|||
MOV M,E ;STORE ADR OF FCB |
|||
LXI H,FCBLEN |
|||
DAD D ;GET NEW TOP OF ALLOC |
|||
SHLD $MEMRY ;STORE AWAY |
|||
; ---------------- |
|||
POP H ;FCB ADR. |
|||
MVI M,0 ;DEFAULT TO CURRENT DISK |
|||
INX H |
|||
LXI D,FILTXT ;DEFAULT NAME INITIALLY FORT##.DAT |
|||
LDAX D |
|||
CALL CPYTXT ;MOVE "FORT" TO FCB |
|||
LDA $UN |
|||
MOV B,A ;SAVE UNIT # |
|||
SUI 10 ;CARRY SET IF NOT UNIT 10 |
|||
SBB A |
|||
ADI "1" ;"1" IF 10 ELSE "0" |
|||
MOV M,A ;STORE DIGIT 1 OF # |
|||
MOV A,B |
|||
CPI 10 ;WAS IT 10? |
|||
JC SKPSTZ ;NO, DON'T SET ZERO |
|||
XRA A |
|||
SKPSTZ: ADI "0" ;GET 2ND DIGIT |
|||
INX H |
|||
MOV M,A |
|||
MVI A," " |
|||
INX H |
|||
MOV M,A |
|||
INX H |
|||
LXI D,FILEXT-1 ;EXTENSION |
|||
CALL CPYTXT ;MOVE "DAT" TO FCB |
|||
; ---------------- |
|||
POP H ;GET PTR TO FLAG |
|||
MVI A,MD.ALC ;NOW ALLOCATED. |
|||
MOV M,A ;SET FLAG |
|||
RET |
|||
|
|||
PAGE |
|||
;------------------------------------------------------ |
|||
; |
|||
; OPEN FILE GIVEN BY LUN AND CLEAR BUFFER INDEX. |
|||
; ENTRY: [DE] = ADR OF FCB |
|||
; EXIT: [HL] = ADR OF MODE BYTE |
|||
; [A] = MODE BYTE - ALLOCATED & OPEN. |
|||
; |
|||
OPNFIL: |
|||
PUSH B ;SAVE I/O MODE |
|||
CALL GTBOFF ;GET BUFFER.OFFSET(LUN) |
|||
MOV M,D ;CLEAR BUFFER INDEX |
|||
; ---------------- |
|||
LHLD $CLSFL |
|||
LXI D,CLSALL |
|||
MOV A,H |
|||
SUB D |
|||
JNZ STRADR ;NOT US, STORE ROUTINE ADR |
|||
MOV A,L |
|||
SUB E |
|||
JZ STRCLS ;US, DON'T STORE AGAIN |
|||
STRADR: SHLD CLSADR |
|||
STRCLS: XCHG |
|||
SHLD $CLSFL ;ON EXIT, CLOSE ALL FILES |
|||
CALL CLRFCB ;ZERO FCB & RECORD NUMBER. |
|||
CALL SETBUF ;SET DMA TO FILE BUFFER. |
|||
; ---------------- |
|||
POP B ;I/O MODE |
|||
PUSH B |
|||
MOV A,C |
|||
ANI MD.OUT |
|||
JZ OPNINP ;BRIF OPEN INPUT |
|||
;------------------------------------------------------ |
|||
; |
|||
; OPEN NEW FILE FOR OUTPUT OR RANDOM. |
|||
; |
|||
PUSH D ;SAVE FCB ADR |
|||
MVI C,.DELET ;DELETE OLD FILE |
|||
CALL BDOS |
|||
POP D |
|||
PUSH D |
|||
CALL MAKEXT ;CREATE NEW FILE. |
|||
POP D ;RESTORE FCB ADR |
|||
;------------------------------------------------------ |
|||
; |
|||
; OPEN EXISTING FILE FOR INPUT OR RANDOM. |
|||
; |
|||
OPNINP: |
|||
MVI C,.OPEN ;OPEN FILE |
|||
CALL BDOS |
|||
INR A |
|||
JZ FNFERR ;BRIF FILE NOT FOUND (FATAL). |
|||
|
|||
OPNDON: |
|||
CALL GTMODE |
|||
POP B ;GET I/O MODE. |
|||
MOV A,C |
|||
ORI MD.ALC+MD.OPN |
|||
MOV M,A ;MODE ALLOCATED/OPEN + I/O |
|||
RET |
|||
|
|||
;------------------------------------------------------ |
|||
; |
|||
; MAKE NEW FILE OR EXTENT. |
|||
; |
|||
MAKEXT: |
|||
MVI C,.MAKE ;CREATE NEW FILE |
|||
CALL BDOS |
|||
INR A |
|||
JZ DSKFUL ;BRIF DISK FULL ERROR. |
|||
RET |
|||
|
|||
PAGE |
|||
;------------------------------------------------------ |
|||
; |
|||
; REWIND UNIT # |
|||
; |
|||
DSKREW: CALL GTMODE |
|||
ANI MD.OPN ;FILE OPEN? |
|||
CNZ DSKCLS ;YES, CLOSE IT |
|||
NOCLOS: XRA A ;GOOD RETURN |
|||
RET |
|||
|
|||
;------------------------------------------------------ |
|||
; |
|||
; ENDFILE UNIT # |
|||
; |
|||
DSKCLS: CALL GTMODE |
|||
ADD A ;OPEN? |
|||
JP NOCLOS ;NO, DON'T CLOSE |
|||
MVI M,MD.ALC ;FLAG CLOSED NOW |
|||
ADD A ;OUTPUT FILE? |
|||
CM FRCBUF ;YES, DUMP LAST IF NEEDED |
|||
CALL GTFCB ;GET ADDR OF FCB |
|||
CALL SETBUF ;SET DMA ADR |
|||
MVI C,.CLOSE ;CLOSE FILE |
|||
CALL BDOS |
|||
XRA A ;NEVER AN ERROR |
|||
RET |
|||
|
|||
;------------------------------------------------------ |
|||
; |
|||
; CLOSE ALL FILES. CALLED FROM EXIT |
|||
; |
|||
CLSALL: LXI D,1 |
|||
CLSAL1: LXI H,$FLFLG-1 |
|||
DAD D |
|||
MOV A,M |
|||
ADD A ;SET MINUS IF OPEN |
|||
PUSH D ;SAVE UNIT # |
|||
MOV A,E |
|||
STA $UN ;SET UP FOR OTHERS |
|||
CM DSKCLS ;CLOSE FILE IF OPEN |
|||
POP D ;GET # BACK |
|||
INX D ;BUMP IT |
|||
LDA $LUNTB ;GET MAX LUN |
|||
CMP E ;DONE ALL? |
|||
JNZ CLSAL1 ;NO, DO NEXT |
|||
RET ;RETURN |
|||
|
|||
PAGE |
|||
;------------------------------------------------------ |
|||
; |
|||
; UNFORMATTED WRITE |
|||
; |
|||
DSKUWR: |
|||
MVI C,MD.OUT+MD.BIN |
|||
CALL OPNCHK ;OPEN IF NOT OPEN |
|||
LHLD $BF ;GET BUFFER ADR |
|||
PUSH H |
|||
XCHG |
|||
LHLD $BL ;GET LENGTH OF DATA |
|||
MVI H,0 ;# OF BYTES |
|||
XCHG |
|||
DAD D ;PTR TO 1ST TO CLEAR |
|||
XRA A |
|||
DCR E |
|||
DSKWCL: |
|||
INR E ;CLEARED REST OF BUFFER? |
|||
JM DSKUW1 ;YES, DONE |
|||
MOV M,A |
|||
INX H |
|||
JMP DSKWCL ;CLEAR END OF BUFFER |
|||
DSKUW1: |
|||
POP D ;GET BUFFER ADR |
|||
MVI C,.STDMA ;SET DMA TO BUFFER |
|||
CALL BDOS |
|||
CALL WRITE ;WRITE RECORD |
|||
ORA A ;ERROR? |
|||
RZ ;NO, GOOD RETURN |
|||
STC |
|||
RET |
|||
|
|||
PAGE |
|||
;------------------------------------------------------ |
|||
; |
|||
; UNFORMATTED READ |
|||
; |
|||
DSKURD: |
|||
MVI C,MD.BIN |
|||
CALL OPNCHK ;OPEN IF NEEDED |
|||
LHLD $BF |
|||
XCHG |
|||
MVI C,.STDMA ;SET DMA TO $BF |
|||
CALL BDOS |
|||
MVI A,128 |
|||
STA $BL ;ALWAYS 1 SECTOR |
|||
CALL READ ;READ RECORD INTO $BF |
|||
ORA A ;EOF OR GOOD |
|||
RZ |
|||
CPI 2 |
|||
CMC |
|||
RET |
|||
; |
|||
PAGE |
|||
;------------------------------------------------------ |
|||
; |
|||
; FORMATTED WRITE |
|||
; |
|||
DSKFWR: |
|||
MVI C,MD.OUT |
|||
CALL OPNCHK ;OPEN FILE IF NEEDED |
|||
XRA A |
|||
STA $DSKER ;CLEAR COUNT |
|||
LDA $BL ;GET # TO WRITE |
|||
ORA A |
|||
RZ ;IGNORE NULL BUFFERS |
|||
LDA $BL |
|||
ORA A |
|||
JP DSKFW0 |
|||
CALL $ERR ;WARN USER OF.. |
|||
DB OBOVF ;OUTPUT BUFFER LIMIT EXCEEDED |
|||
MVI A,127 ;AND TRUNCATE TO 127 BYTES. |
|||
DSKFW0: |
|||
CALL RNDCHK ;IF RND MODE, SET OFFSET TO 0. |
|||
LHLD $BF ;GET BUFFER PTR |
|||
DSKFW2: |
|||
PUSH PSW ;SAVE COUNT |
|||
MOV A,M |
|||
CALL DSKOUT ;SEND OUT BYTE |
|||
INX H ;INCREMENT BUFFER PTR |
|||
POP PSW ;RETRIEVE COUNT |
|||
DCR A ;DECREMENT COUNT |
|||
JNZ DSKFW2 ;ONE MORE TIME |
|||
; |
|||
DSKWDN: MVI A,15Q |
|||
CALL DSKOUT ;PUT OUT <CR> |
|||
CALL GTMODE ;MARK MODE BYTE WITH |
|||
ORI MD.WRT ;WRITE-DATA-IN-BUFFER. |
|||
MOV M,A |
|||
LDA $DSKER ;GET $DSKEROR STATUS |
|||
ORA A ;ERROR? |
|||
RZ ;NO |
|||
STC ;YES |
|||
RET |
|||
; |
|||
PAGE |
|||
;------------------------------------------------------ |
|||
; |
|||
; FORMATTED READ |
|||
; |
|||
DSKFRD: |
|||
MVI C,0 |
|||
CALL OPNCHK ;OPEN IF NEEDED |
|||
XRA A |
|||
STA $BL ;CLEAR LENGTH OF RECORD |
|||
STA $DSKER ;CLEAR $DSKEROR |
|||
CALL RNDCHK ;IF RND MODE, SET OFFSET TO 0. |
|||
DSKFR1: |
|||
CALL DSKIN ;GET CHAR |
|||
JC DSKRDN ;JUMP IF EOF |
|||
CPI 32Q ;CP/M EOF? |
|||
JZ DSKEOF ;YES |
|||
LHLD $BL |
|||
MVI H,0 |
|||
XCHG |
|||
LHLD $BF ;BASE |
|||
DAD D ;GET WHERE TO PUT BYTE |
|||
MOV M,A ;STORE CHAR |
|||
INX D ;BUMP OFFSET |
|||
XCHG |
|||
SHLD $BL ;UPDATE OFFSET |
|||
CPI 15Q ;<CR>? |
|||
JZ DSKRDN ;YES, HAVE RECORD |
|||
MOV A,L ;GET OFFSET |
|||
CPI 128 ;BUFFER FULL? |
|||
JC DSKFR1 ;NO, GET NEXT |
|||
CALL $ERR ;WARN USER OF.. |
|||
DB IRECER ;INPUT RECORD TOO LONG. |
|||
XRA A |
|||
RET |
|||
; |
|||
DSKRDN: LDA $DSKER ;GET STATUS |
|||
ORA A |
|||
RZ ;NO ERROR |
|||
CPI 2 |
|||
CMC |
|||
RET |
|||
DSKEOF: ORA A ;SET CC'S |
|||
RET |
|||
; |
|||
PAGE |
|||
;------------------------------------------------------ |
|||
; |
|||
; RESET BUFFER OFFSET IF RANDOM READ OR WRITE |
|||
; |
|||
RNDCHK: |
|||
PUSH PSW |
|||
CALL GTMODE |
|||
ANI MD.RND |
|||
JZ RNDCHX ;DO NOTHING IF SEQUENTIAL MODE. |
|||
CALL GTBOFF ;ELSE ZERO BUFFER OFFSET SO.. |
|||
MVI M,0 ;NEXT READ/WRITE STARTS AT BEGINNING. |
|||
RNDCHX: |
|||
POP PSW |
|||
RET |
|||
;------------------------------------------------------ |
|||
; |
|||
; DISK INPUT ROUTINE |
|||
; |
|||
DSKIN: |
|||
CALL GTBOFF ;BUFFER.OFFSET(LUN) |
|||
ORA A ;BUFFER EMPTY? |
|||
CZ REDBUF ;YES, REFIL |
|||
RC ;EOF |
|||
DCR M ;DECR. # LEFT |
|||
LXI H,$FLBUF-2 |
|||
DAD D |
|||
DAD D ;GET $FLBUF PTR |
|||
CMA |
|||
ADI 129 ;128-#LEFT=OFFSET |
|||
ADD M |
|||
MOV E,A |
|||
INX H |
|||
MVI A,0 |
|||
ADC M |
|||
MOV D,A |
|||
LDAX D ;GET CHAR |
|||
ORA A |
|||
RET |
|||
;------------------------------------------------------ |
|||
; |
|||
; READ BUFFER FROM DISK |
|||
; |
|||
REDBUF: PUSH H |
|||
PUSH D |
|||
CALL SETBUF |
|||
CALL READ ;READ RECORD |
|||
STA $DSKER ;STORE STATUS |
|||
ORA A |
|||
POP D |
|||
POP H |
|||
MVI A,128 ;FULL BUFFER |
|||
MOV M,A ;STORE COUNT |
|||
RZ ;IF NO ERROR |
|||
STC |
|||
RET |
|||
|
|||
;------------------------------------------------------ |
|||
; |
|||
; DISK OUTPUT ROUTINE |
|||
; |
|||
DSKOUT: PUSH H |
|||
PUSH PSW |
|||
CALL GTBOFF ;GET BUFFER OFFSET |
|||
ORA A ;BUFFER FULL? |
|||
CM DMPBUF ;YES, DUMP |
|||
INR M |
|||
LXI H,$FLBUF-2 |
|||
DAD D |
|||
DAD D ;POINT TO ADR OF BUFFER |
|||
ADD M |
|||
MOV E,A |
|||
INX H |
|||
MVI A,0 |
|||
ADC M |
|||
MOV D,A ;POINTS TO FREE |
|||
POP PSW ;GET CHAR BACK |
|||
STAX D ;STORE CHAR |
|||
POP H |
|||
RET |
|||
|
|||
;------------------------------------------------------ |
|||
; |
|||
; FORCE FORMATTED BUFFER OUT ON CLOSE |
|||
; |
|||
FRCBUF: ADD A ;UNFORMATTED I/O? |
|||
JM FRCOUT ;YES, FORCE OUT LAST IF NEEDED |
|||
MVI A,32Q |
|||
CALL DSKOUT ;SET END OF FILE |
|||
|
|||
FRCOUT: CALL GTBOFF ;BUFFER.OFFSET(LUN) |
|||
ORA A ;EMPTY? |
|||
MVI M,0 ;CLEAR OFFSET |
|||
RZ ;YES, DO NOTHING |
|||
PUSH PSW ;SAVE OFFSET |
|||
CALL GETBUF ;GET BUFFER ADR |
|||
POP PSW |
|||
MOV L,A |
|||
MVI H,0 |
|||
DAD D ;POINT TO 1ST UNUSED |
|||
CHKFIL: ORA A ;SET MINUS IF FULL |
|||
JM DMPBF1 ;NOTHING TO FILL |
|||
MVI M,0 ;CLEAR BYTE |
|||
INX H |
|||
INR A ;BUMP OFFSET |
|||
JMP CHKFIL |
|||
;------------------------------------------------------ |
|||
; |
|||
; DUMP BUFFER TO DISK |
|||
; |
|||
DMPBF1: |
|||
DCX H ;SO THAT DRIVE # ISN'T CLEARED |
|||
DMPBUF: |
|||
PUSH H |
|||
PUSH D |
|||
CALL SETBUF |
|||
CALL WRITE ;WRITE RECORD |
|||
STA $DSKER ;STORE STATUS |
|||
CALL GTMODE |
|||
ANI NOT MD.WRT ;CLEAR WRITE-DATA BIT |
|||
MOV M,A |
|||
POP D |
|||
POP H |
|||
XRA A |
|||
MOV M,A ;CLEAR BUFFER OFFSET |
|||
RET |
|||
|
|||
;------------------------------------------------------ |
|||
; |
|||
; READ RECORD/WRITE RECORD PRIMITIVES |
|||
; |
|||
READ: CALL GTFCB ;GET ADDR OF FCB |
|||
LDA $CPMRF ;CP/M 1.X OR 2.X |
|||
MOV C,A ;RANDOM READ FUNCTION |
|||
JMP IOCALL |
|||
|
|||
WRITE: CALL GTFCB ;GET ADDR OF FCB |
|||
LDA $CPMWF ;CP/M 1.X OR 2.X |
|||
MOV C,A ;RANDOM WRITE FUNCTION |
|||
|
|||
IOCALL: CALL BDOS ;DO APPROPRIATE FUNCTION |
|||
PUSH PSW ;SAVE ERROR RESULT |
|||
CALL GTREC ;POINT TO RECORD NUMBER |
|||
INR M ;UPDATE SEQUENTIAL |
|||
JNZ POPART ; RECORD NUMBER |
|||
INX H |
|||
INR M |
|||
|
|||
POPART: POP PSW ;RESTORE ERROR |
|||
RET |
|||
|
|||
PAGE |
|||
;------------------------------------------------------ |
|||
; |
|||
; CALL OPEN(UNIT #,FILENAME,DRIVE #) |
|||
; |
|||
ENTRY OPEN |
|||
EXT $IOINIT |
|||
|
|||
OPEN: LDA $LUNTB ;GET MAX LUN |
|||
DCR A |
|||
CMP M ;OUT OF RANGE? |
|||
JC LUNOVF ;YES, LUN TOO LARGE. |
|||
|
|||
MOV A,M ;FETCH LUN |
|||
STA $UN ;SET IT UP |
|||
PUSH D ;SAVE REGISTERS |
|||
PUSH B ;SAVE FILPTR |
|||
CALL $IOINIT ;INITIALIZE IF NOT ALREADY DONE |
|||
CALL GTMODE |
|||
ORA A ;ALLOCATED? |
|||
CP ALCBUF ;NO, ALLOCATE |
|||
POP B |
|||
CALL GTFCB |
|||
XCHG |
|||
POP D ;[DE]=NAME PTR |
|||
LDAX B ;GET DRIVE # |
|||
MOV M,A ;STORE DRIVE # |
|||
MVI B,11 ;COPY FILE NAME TO FCB |
|||
FILLOP: LDAX D |
|||
ORA A ;ZERO BYTE? |
|||
JZ FILLEN ;YES, LEAVE REST AS BEFORE |
|||
INX D |
|||
INX H |
|||
MOV M,A |
|||
DCR B ;FINISHED MOVING NAME? |
|||
JNZ FILLOP ;NO, DO REST |
|||
FILLEN: LDA $UN ;GET UNIT # |
|||
ADD A ;*2 FOR TABLE INDEX |
|||
MVI D,0 |
|||
MOV E,A |
|||
LXI H,$LUNTB ;INDEX INTO LUN TABLE |
|||
DAD D |
|||
LXI B,DSKDRV ;REPLACE CURRENT LUNTB ENTRY |
|||
MOV M,B ; WITH ADDRESS OF DISK DRIVER |
|||
DCX H ; DISPATCH ADDRESS |
|||
MOV M,C |
|||
RET |
|||
|
|||
END |
|||
|
|||
@ -0,0 +1,56 @@ |
|||
TITLE DTBF Runtime data buffer |
|||
; |
|||
TRSDOS EQU 0 |
|||
OASIS EQU 0 |
|||
; |
|||
IF2 |
|||
IFT TRSDOS |
|||
.PRINTX/TRSDOS VERSION/ |
|||
ENDIF |
|||
IFT OASIS |
|||
.PRINTX/OASIS VERSION/ |
|||
ENDIF |
|||
ENDIF |
|||
; |
|||
ENTRY $DTBF,$DTBF1,$DTBF3,$DTBF5,$DTBF7,$DTBF8,$DTBFA |
|||
; |
|||
DSEG |
|||
; |
|||
$DTBF: DS 1 ;DATA BUFFER |
|||
$DTBF1: DS 2 |
|||
$DTBF3: DS 2 |
|||
$DTBF5: DS 2 |
|||
$DTBF7: DS 1 |
|||
$DTBF8: DS 8 |
|||
$DTBFA: DS 145-16 |
|||
IFT TRSDOS |
|||
DS 115 ;TRSDOS USES UP TO 256 BYTE BUFFERS |
|||
ENDIF |
|||
IFT OASIS |
|||
DS 375 ;OASIS USES UP TO 512 BYTE BUFFERS |
|||
ENDIF |
|||
; |
|||
CSEG |
|||
ENTRY $FORLN,$UFMLN |
|||
; |
|||
$FORLN: |
|||
IFT TRSDOS |
|||
DW 256 |
|||
ENDIF |
|||
IFT OASIS |
|||
DW 512 |
|||
ENDIF |
|||
IFF TRSDOS OR OASIS |
|||
DW 132 |
|||
ENDIF |
|||
; |
|||
$UFMLN: |
|||
IFT TRSDOS |
|||
DW 256 |
|||
ENDIF |
|||
IFF TRSDOS |
|||
DW 128 |
|||
ENDIF |
|||
; |
|||
END |
|||
|
|||
Binary file not shown.
@ -0,0 +1,460 @@ |
|||
SUBTTL Global Equates,Temps,Defs |
|||
TITLE FCHAIN - Fortran CALL FCHAIN Statement |
|||
|
|||
ENTRY FCHAIN |
|||
EXTRN $CLSFL,$INIT,$IOERR |
|||
|
|||
CPM SET 0 ; True for CP/M |
|||
CPM42 SET 1 ; True for CP/M's at X'4200' |
|||
ISIS SET 0 ; True for ISIS-II |
|||
MOD1 SET 0 ; True for TRS-80 Mod-1 |
|||
MOD2 SET 0 ; True for TRS-80 Mod-2 |
|||
TEK SET 0 ; True for Tektronics |
|||
|
|||
CR SET 13 |
|||
LF SET 10 |
|||
|
|||
NAMLEN SET 11 ; Default Filename Length **3.36 |
|||
|
|||
IF MOD1 |
|||
NAMLEN SET 23 |
|||
ENDIF |
|||
IF MOD2 |
|||
NAMLEN SET 30 |
|||
ENDIF |
|||
|
|||
|
|||
IF CPM42 |
|||
CPM SET 1 |
|||
ENDIF |
|||
IF CPM |
|||
CPMWRM SET 0 ; CP/M Base ( & Warm Boot Addr) |
|||
ENDIF |
|||
IF CPM42 |
|||
CPMWRM SET 4200H |
|||
ENDIF |
|||
; ---- |
|||
IF CPM |
|||
C.EMSG SET 9 |
|||
C.OPEN SET 15 |
|||
C.READ SET 20 |
|||
C.BUFF SET 26 |
|||
CPMENT SET CPMWRM+5 ; CP/M Entry (BDOS Funct call addr) |
|||
TFCB SET CPMWRM+5CH |
|||
TBUFF SET CPMWRM+80H |
|||
TPA SET CPMWRM+100H |
|||
|
|||
;**3.36 DFTEXT: DB 'COM' |
|||
|
|||
ENDIF |
|||
; ================ |
|||
IF ISIS |
|||
CISIS SET 40H ;ISIS Entry Point |
|||
I.LOAD SET 6 ;Load Pgrm Function |
|||
ENDIF |
|||
; ================ |
|||
IF MOD1 |
|||
M.ABRT SET 4430H ;Error return to system |
|||
M.GET SET 13H ;Input a byte from an I/O device |
|||
M.OPEN SET 4424H ;Open an existing file |
|||
M.EXIT SET 402DH ;Normal return to system |
|||
ENDIF |
|||
; ================ |
|||
IF TEK |
|||
SRB SET 3 |
|||
T.CHAN SET SRB+1 ; Channel No. |
|||
T.LEN SET SRB+5 ; Filename Len |
|||
T.BPTR SET SRB+6 ; Address of Buffer |
|||
T.FNAM SET SRB+8 ; Filename Buffer |
|||
ENDIF |
|||
; ================ |
|||
IF2 |
|||
.PRINTX/Fortran CHAIN/ |
|||
IF CPM |
|||
.PRINTX/ For CPM/ |
|||
ENDIF |
|||
IF CPM42 |
|||
.PRINTX/ ..at 4200H/ |
|||
ENDIF |
|||
IF ISIS |
|||
.PRINTX/ For ISIS-II/ |
|||
ENDIF |
|||
IF MOD1 |
|||
.PRINTX/ For TRS80 Mod-1/ |
|||
ENDIF |
|||
IF MOD2 |
|||
.PRINTX/ For TRS80 Mod-2/ |
|||
ENDIF |
|||
IF TEK |
|||
.PRINTX/ For Tektronics/ |
|||
ENDIF |
|||
ENDIF |
|||
|
|||
PAGE |
|||
SUBTTL FCHAIN - Process a CALL FCHAIN statement |
|||
|
|||
; FCHAIN processes a CALL FCHAIN statement by the following steps: |
|||
; |
|||
; 1. Parse filename to see if valid |
|||
; |
|||
; 2. Open file in default OS File Control Block |
|||
; |
|||
; 3. Move a short program loader to top of memory |
|||
; and load new program |
|||
; |
|||
; SYNTAX: CALL FCHAIN ('<OS dependent filename> ') |
|||
|
|||
; ENTRY [HL] = FWA SDESC for Filename |
|||
; EXIT Start executing new program |
|||
; USES ALL |
|||
|
|||
FCHAIN: |
|||
IF CPM |
|||
LDAX D ;Get Drive no. |
|||
STA TFCB ;Put in TFCB |
|||
ENDIF |
|||
SHLD .NFWA ; Save FWA of Name |
|||
LXI H,CHN01 |
|||
PUSH H |
|||
LHLD $CLSFL |
|||
PCHL ; Close all Files |
|||
CHN01: |
|||
LXI B,CHN02 ; Addr to RET to.. |
|||
JMP $INIT ; Reset SP to top of ram |
|||
CHN02: |
|||
IF CPM |
|||
CALL .SNAM ; Go scan filename |
|||
LXI D,TBUFF ;Set DMA buffer |
|||
MVI C,C.BUFF |
|||
CALL CPMENT |
|||
LXI D,TFCB ;Open file |
|||
MVI C,C.OPEN |
|||
CALL CPMENT |
|||
INR A |
|||
JZ $IOERR ; **IO** Error - File not found |
|||
LXI H,0 |
|||
DAD SP |
|||
DCR H |
|||
MVI L,0 ;Get 1 page below user stack |
|||
LXI D,LOADER ;Move program loader to high memory |
|||
MVI B,ENDIPL-IPL |
|||
CALL $$MOV |
|||
MOV L,B ;[HL] = addr of loader |
|||
PUSH H ;For 'RET' to loader |
|||
LXI D,LOCTAB ;[DE] = addr of ADDRESS MODIFY TABLE |
|||
CHN03: LDAX D ;Get low byte address |
|||
ORA A ;Are we done? |
|||
JZ CHN04 ; Yes |
|||
MOV L,A ;[HL] = address to modify |
|||
MOV M,H ;Modify it with [H] |
|||
INX D |
|||
JMP CHN03 ;Keep looping |
|||
CHN04: LXI H,TPA ;[HL] = TPA address |
|||
RET ;'RET' to loader |
|||
ENDIF |
|||
; ================ |
|||
IF ISIS |
|||
LHLD .NFWA |
|||
XCHG ;[DE] = Strt of Name |
|||
LXI H,I.FNAM |
|||
MVI B,15 |
|||
CALL $$MOV ;Move Filename to FCB |
|||
MVI C,I.LOAD ;Load Function |
|||
LXI D,I.FCB |
|||
CALL CISIS ;Load next Pgm & Go |
|||
JMP $IOERR ; (Just in case) |
|||
ENDIF |
|||
; ================ |
|||
IF MOD1 |
|||
LXI H,0 ;Get stack address |
|||
DAD SP |
|||
MVI L,0 ;Get below user stack |
|||
DCR H |
|||
DCR H ;Blocking buffer address |
|||
DCR H ;Loader start address |
|||
PUSH H ;Save loader start address |
|||
MVI B,32 ;Blank fill 32 byte DCB |
|||
SPLOOP: DCX H |
|||
MVI M,' ' |
|||
DCR B |
|||
JNZ SPLOOP |
|||
POP B ;Loader start address |
|||
PUSH H ;Save DCB addr |
|||
LHLD .NFWA |
|||
XCHG ;[DE] = Strt of Filename |
|||
POP H |
|||
PUSH H ;[HL] = DCB addr |
|||
PUSH B ;Save loader start address |
|||
CALL .SNAM ;Scan Filename into DCB |
|||
MVI B,0 ;LRL = 256 |
|||
POP H ;Loader start address |
|||
POP D ;DCB (Filespec) address |
|||
PUSH D ;Save DCB address |
|||
PUSH H ;Save loader start address |
|||
INR H ;Blocking buffer address |
|||
CALL M.OPEN ;Open an existing file |
|||
JNZ $IOERR ;**IO** Err - Fnf. |
|||
|
|||
DCR H ;Top loader start address |
|||
LXI D,LOADER ;Loader start address |
|||
MVI B,ENDIPL-IPL ;Size of loader program |
|||
CALL $$MOV ;Move to top of memory |
|||
|
|||
POP H ;Loader start address |
|||
POP D ;DCB address |
|||
PCHL ;Run loader |
|||
ENDIF |
|||
; ================ |
|||
IF MOD2 |
|||
LHLD .NFWA ;[HL] points to name |
|||
PUSH H ;Save SOS |
|||
LXI B,NAMLEN ;[B]=0, [C]=Max Name Len |
|||
CHN03: |
|||
MOV A,M |
|||
CPI ' '+1 |
|||
JC CHN04 ;Brif EOS |
|||
INX H |
|||
INR B ;String Len+1 |
|||
DCR C ;Max len-1 |
|||
JNZ CHN03 |
|||
JMP $IOERR ;**IO** Error, Name too long |
|||
CHN04: |
|||
MVI M,CR ;Proper TRSDOS Terminator |
|||
POP H ;Get SOS |
|||
MVI A,37 ;Exeq TRSDOS cmnd, no ret |
|||
RST 1 ;Do it, [HL]=string, [B]=string len |
|||
JMP $IOERR ; (Who trusts Trash-DOS) |
|||
ENDIF |
|||
; ================ |
|||
IF TEK |
|||
LHLD .NFWA |
|||
XCHG ; [DE]=Filename STR |
|||
LXI H,T.FNAM ; [HL]=Filename Buffer |
|||
LXI B,NAMLEN ; [B]=0, [C]=Max Name Len |
|||
CHN03: |
|||
LDAX D |
|||
CPI ' '+1 |
|||
JC CHN04 ; Brif End-of-Name |
|||
MOV M,A |
|||
INX D |
|||
INX H |
|||
INR B ; Len+1 |
|||
DCR C ; Max-1 |
|||
JZ $IOERR ; **IO** Error if name too long.. |
|||
JMP CHN03 |
|||
CHN04: |
|||
MVI M,CR ; Store Terminator |
|||
MOV A,B |
|||
INR A ; Include CR in Len Cnt |
|||
STA T.LEN ; Store Filename Len in SRB |
|||
MVI A,18H ; Load Overlay & Execute |
|||
STA SRB |
|||
MVI A,4 |
|||
STA T.CHAN ; Store Chan 4 (Doc is unclear) |
|||
LXI D,T.FNAM |
|||
LXI H,T.BPTR |
|||
MOV M,D |
|||
INX H ; Store Fname Pntr in SRB |
|||
MOV M,E |
|||
MVI A,0FFH |
|||
OUT 0F7H ; Load Overlay & Execute |
|||
JMP $IOERR ; Should never happen |
|||
ENDIF |
|||
; ================ |
|||
|
|||
PAGE |
|||
SUBTTL Scan for valid Filename |
|||
|
|||
.SNAM: |
|||
IF CPM |
|||
LHLD .NFWA ; FWA of Filename |
|||
XCHG ; [DE] = name FWA |
|||
LXI H,TFCB+1 ; [HL] = FILE CTRL BLOCK |
|||
MVI B,NAMLEN |
|||
.COMMENT & **3.36 |
|||
.SNAM1: |
|||
LDAX D ; GET NAME CHAR |
|||
INX D |
|||
STA .NFWA ; Set '.' if user supplied Ext. |
|||
CPI '.' |
|||
JZ .SNAM3 ; Brif saw Ext |
|||
CPI ' '+1 |
|||
JC .SNAM3 ; Brif End-of-Name |
|||
MOV M,A ; PUT IN FCB |
|||
INX H |
|||
DCR B ; UNTIL STRING EXHAUSTED |
|||
JNZ .SNAM1 |
|||
.SNAM2: |
|||
LDAX D |
|||
INX D |
|||
STA .NFWA |
|||
CPI '.' ; Looking for Ext.. |
|||
JZ .SNAM4 |
|||
CPI ' '+1 ; or end of name |
|||
JNC .SNAM2 |
|||
JMP .SNAM4 ; Go copy user or default ext |
|||
.SNAM3: |
|||
MVI M,' ' |
|||
INX H |
|||
DCR B |
|||
JNZ .SNAM3 |
|||
.SNAM4: |
|||
MVI B,3 ; Scan Extention |
|||
LDA .NFWA |
|||
CPI '.' |
|||
JZ .SNAM5 ; Brif user supplied ext |
|||
LXI D,DFTEXT ; ..Else use default |
|||
**3.36 & |
|||
.SNAM5: |
|||
LDAX D |
|||
INX D |
|||
MOV M,A |
|||
INX H |
|||
DCR B |
|||
JNZ .SNAM5 |
|||
; ---------------- |
|||
MOV M,B ; Clear File EX |
|||
MOV A,B |
|||
STA TFCB+32 ; NR = 0 |
|||
RET |
|||
ENDIF |
|||
; ================ |
|||
IF MOD1 |
|||
MVI B,NAMLEN |
|||
.SNAM0: |
|||
LDAX D |
|||
CPI ' '+1 |
|||
JC .SNAM1 ;Brif EOS |
|||
MOV M,A |
|||
INX D |
|||
INX H |
|||
DCR B |
|||
JNZ .SNAM0 |
|||
JMP $IOERR ;**IO** Error if name too long |
|||
.SNAM1: |
|||
MVI M,CR ;Terminate with CR |
|||
RET |
|||
ENDIF |
|||
|
|||
PAGE |
|||
SUBTTL Relocated loader for CP/M & MOD1 |
|||
|
|||
IF CPM |
|||
LOCTAB: |
|||
DB (X0+2) AND 0FFH |
|||
DB (X1+1) AND 0FFH |
|||
DB (X2+2) AND 0FFH |
|||
DB (X3+2) AND 0FFH |
|||
DB 0 |
|||
|
|||
; ================ |
|||
LOADER: |
|||
.PHASE 0 |
|||
IPL: LXI D,TPA ;Program start address |
|||
PUSH D ;Save as return address |
|||
IPL1: XCHG ;[DE] = Next load address |
|||
PUSH D ;Save load address |
|||
MVI C,C.BUFF ;Set DMA address |
|||
CALL CPMENT |
|||
LXI D,TFCB ;Read record |
|||
MVI C,C.READ |
|||
CALL CPMENT |
|||
POP D ;Restore base address of record |
|||
ORA A |
|||
X0: JNZ IPLDON ;EOF |
|||
LXI H,128 ;[HL] = Record size |
|||
DAD D ;[HL] = Start of next record |
|||
X1: MVI A,IPL/256 ;Get hi byte of IPL address |
|||
CMP H ;Are we there? |
|||
X2: JNZ IPL1 ;No - continue loading program |
|||
X3: LXI D,OVFMSG ;Print '* OUT OF MEMORY*' |
|||
MVI C,C.EMSG |
|||
CALL CPMENT |
|||
JMP CPMWRM ;Reset and die |
|||
IPLDON: |
|||
XRA A |
|||
STA TBUFF ; 0 = No cmnd line passed |
|||
MVI A,' ' |
|||
STA TFCB+1 ; Clear TFCB for Utilities |
|||
LXI B,CPMWRM ; Push Warm Boot addr for |
|||
PUSH B ; Utilities that just return... |
|||
JMP TPA ;CLOSE FILE AND START PROG |
|||
OVFMSG: |
|||
DB CR,LF,'* Out of Memory *',CR,LF,'$' |
|||
ENDIPL: |
|||
.DEPHASE |
|||
ENDIF |
|||
; ================ |
|||
IF MOD1 |
|||
LOADER: |
|||
IPL: CALL M.GET ;Read character |
|||
JNZ M.ABRT ;In case of error |
|||
CPI 2 ;Is it EOF ? |
|||
.Z80 |
|||
JR Z,(IPL1) ;Get start address |
|||
.8080 |
|||
CPI 1 ;Is it data ? |
|||
JNZ M.ABRT ;Not data then error |
|||
CALL M.GET ;Length + 2 |
|||
DCR A |
|||
DCR A |
|||
MOV B,A ;Length |
|||
CALL M.GET ;Load address |
|||
JNZ M.ABRT ;In case of error |
|||
MOV L,A |
|||
CALL M.GET |
|||
JNZ M.ABRT ;In case of error |
|||
MOV H,A |
|||
|
|||
IPL0: CALL M.GET ;Get data |
|||
MOV M,A ;Put data in load address |
|||
INX H ;Increment load address |
|||
DCR B ;# of bytes left to load |
|||
.Z80 |
|||
JR NZ,(IPL0) |
|||
JR Z,(IPL) |
|||
.8080 |
|||
|
|||
IPL1: CALL M.GET ;Get second 2 (EOF) |
|||
CPI 2 |
|||
JNZ M.ABRT ;In case of error |
|||
CALL M.GET ;Get start address |
|||
JNZ M.ABRT ;In case of error |
|||
MOV L,A |
|||
CALL M.GET |
|||
JNZ M.ABRT ;In case of error |
|||
MOV H,A |
|||
PCHL ;Run program |
|||
ENDIPL: |
|||
|
|||
ENDIF |
|||
; ================ |
|||
IF CPM OR ISIS OR MOD1 |
|||
$$MOV: |
|||
LDAX D |
|||
MOV M,A |
|||
INX D |
|||
INX H |
|||
DCR B |
|||
JNZ $$MOV |
|||
RET |
|||
ENDIF |
|||
|
|||
DSEG |
|||
|
|||
.NFWA: DS 2 ; Temp for FWA of Filename |
|||
|
|||
IF ISIS |
|||
I.FCB: DW I.FNAM ;Pntr to Filename |
|||
DW 0 ;Bias field |
|||
DW 1 ;RETSW, Xfer control to new pgm |
|||
DW I.NTRY ;Pntr to Entry addr store |
|||
DW I.STAT ;Status |
|||
; -- |
|||
I.FNAM: DS 15 ;Filename |
|||
I.NTRY: DS 2 ;Entry Point Address |
|||
I.STAT: DS 2 ;Ret Status |
|||
ENDIF |
|||
|
|||
END |
|||
|
|||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,51 @@ |
|||
TITLE INIT - FORTRAN-80 RUNTIME INITIALIZATION |
|||
|
|||
.8080 |
|||
|
|||
ENTRY $INIT,$EC,$IOFLG,$CPMVN,$CPMWF,$CPMRF |
|||
EXTRN $CLSFL |
|||
|
|||
GTVRSF EQU 12 ;GET CP/M VERSION FUNCTION |
|||
.READS EQU 20 ;READ SEQUENTIAL FUNCTION (1.X) |
|||
.WRITS EQU 21 ;WRITE SEQUENTIAL FUNCTION (1.X) |
|||
.READR EQU 33 ;READ RANDOM FUNCTION (2.X) |
|||
.WRITR EQU 34 ;WRITE RANDOM FUNCTION (2.X) |
|||
|
|||
DSEG |
|||
|
|||
$CPMVN: DS 1 ;0FFH if CP/M 1.X, 00 if 2.X |
|||
$CPMRF: DS 1 ;CP/M Read function held here |
|||
$CPMWF: DS 1 ;CP/M WRITE FUNCTION HELD HERE |
|||
$EC: DS 1 ;ERROR COUNT - MAX 20 NON-FATAL ERRS |
|||
$IOFLG: DS 1 ;FLAG WHETHER I/O INIT HAS BEEN DONE |
|||
|
|||
CSEG |
|||
|
|||
CPMENT SET 5 |
|||
|
|||
$INIT: XRA A |
|||
STA $EC ;INITIALIZE ERROR COUNT TO 0 |
|||
STA $IOFLG ;INITIALIZE I/O FLAG |
|||
LXI H,RETINS ;INITIALIZE $CLSFL TO POINT TO "RET" |
|||
SHLD $CLSFL |
|||
|
|||
LHLD CPMENT+1 ;INITIALIZE STACK TO TOP OF MEMORY-1 |
|||
DCX H |
|||
SPHL |
|||
|
|||
PUSH B ;PUT RETURN ADDRESS ON STACK |
|||
MVI C,GTVRSF |
|||
CALL CPMENT ;GET CP/M VERSION NUMBER |
|||
SUI 20H-1 ;SET $CPMVN SUCH THAT |
|||
SBB A ;2.X = 00 AND |
|||
STA $CPMVN ;1.X = 0FFH.. |
|||
|
|||
LXI H,(.WRITS SHL 8)+.READS |
|||
JNZ SETVF ;1.X USES SEQUENTIAL I/O CALLS |
|||
LXI H,(.WRITR SHL 8)+.READR |
|||
SETVF: SHLD $CPMRF ;2.X USES RANDOM I/O CALLS |
|||
|
|||
RETINS: RET |
|||
|
|||
END |
|||
|
|||
@ -0,0 +1,41 @@ |
|||
TITLE IOINIT - FORTRAN-80 I/O FLAG & VARIABLE INIT |
|||
|
|||
.8080 |
|||
|
|||
ENTRY $IOINI |
|||
EXT $IOFLG,$LNPTR,$CPMBF,$LUNTB |
|||
EXT $FLFLG,$DSKER,$OPNFL |
|||
|
|||
$IOINI: LDA $IOFLG ;SEE IF WE'VE ALREADY BEEN CALLED |
|||
ORA A |
|||
RNZ |
|||
INR A ;SET NON-ZERO |
|||
STA $IOFLG |
|||
|
|||
LXI H,$CPMBF |
|||
MVI M,132+1 ;MAX CHRS TO READ FOR BDOS CALL |
|||
INX H |
|||
MVI M,0 ;ZERO NO. OF CHARS READ |
|||
INX H |
|||
SHLD $LNPTR ;PTR TO BEGINNING OF LINE |
|||
|
|||
MVI M,10 ;STORE LINE FEED AT BEG. OF LINE |
|||
|
|||
LDA $LUNTB ;GET NO. OF LUN'S |
|||
DCR A |
|||
MOV B,A ;SAVE LOOP COUNT |
|||
LXI H,$FLFLG ;INITIALIZE FLAGS FOR DSKDRV |
|||
XRA A |
|||
|
|||
FLGLOP: MOV M,A ;ZERO $FLFLG BYTE |
|||
INX H ;INCREMENT PTR |
|||
DCR B ;DECREMENT COUNT |
|||
JNZ FLGLOP ;NEXT |
|||
STA $DSKER |
|||
|
|||
XRA A |
|||
STA $OPNFL ;CLEAR $OPNFL FOR LPTDRV |
|||
RET |
|||
|
|||
END |
|||
|
|||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,112 @@ |
|||
TITLE LPTDRV - FORTRAN LINE PRINTER DRIVER |
|||
|
|||
.8080 |
|||
|
|||
ENTRY LPTDRV,$OPNFL |
|||
EXTRN $IOERR,$BF,$BL,$CLSFL |
|||
|
|||
DSEG |
|||
|
|||
$OPNFL: DB 0 |
|||
CLSADR: DS 2 |
|||
|
|||
CSEG |
|||
|
|||
LPTDRV: DW $IOERR |
|||
DW LPTFWR |
|||
DW $IOERR |
|||
DW LPTBWR |
|||
DW $IOERR |
|||
DW $IOERR |
|||
DW LPTCLS |
|||
|
|||
LPTCLS: LDA $OPNFL ;MAKE SURE ALREADY 'OPEN' |
|||
ORA A |
|||
JZ $IOERR |
|||
XRA A ;'CLOSE' BY SENDING |
|||
STA $OPNFL ; FORM FEED |
|||
OUTFF: MVI A,12 |
|||
JMP LPTOUT |
|||
|
|||
CLSLPT: LDA $OPNFL |
|||
ORA A |
|||
LHLD CLSADR |
|||
PUSH H |
|||
RZ |
|||
CALL OUTCR ;CR |
|||
OUTLF: MVI A,10 ;LF |
|||
JMP LPTOUT |
|||
|
|||
MAKOPN: LXI H,$OPNFL |
|||
MOV A,M |
|||
ORA A |
|||
RZ |
|||
INR M |
|||
SETCLS: LHLD $CLSFL |
|||
LXI D,CLSLPT |
|||
MOV A,L |
|||
SUB E |
|||
MOV A,H |
|||
SBB D |
|||
RZ |
|||
STORAD: SHLD CLSADR |
|||
XCHG |
|||
SHLD $CLSFL |
|||
RET |
|||
|
|||
LPTFWR: CALL MAKOPN |
|||
LDA $BL |
|||
ORA A |
|||
RZ ;NUTHIN HERE |
|||
|
|||
LHLD $BF |
|||
DCR A |
|||
MOV E,A ;INTO [E] FOR LPTLOP |
|||
MOV A,M |
|||
CPI '*' ;DO NOTHING? |
|||
JZ LPTNLF |
|||
CALL OUTCR ;OUTPUT CR |
|||
MOV A,M |
|||
CPI "+" |
|||
JZ LPTNLF |
|||
CPI "1" |
|||
JNZ LPTLF |
|||
CALL OUTFF ;FORM FEED |
|||
JMP LPTNLF |
|||
|
|||
LPTLF: CALL OUTLF |
|||
MOV A,M |
|||
CPI "0" |
|||
CZ OUTLF |
|||
|
|||
LPTNLF: INX H |
|||
MVI D,0 |
|||
|
|||
LPTLOP: MOV A,E |
|||
ORA D |
|||
RZ |
|||
MOV A,M |
|||
CALL LPTOUT |
|||
INX H |
|||
DCX D |
|||
JMP LPTLOP |
|||
|
|||
LPTBWR: CALL MAKOPN |
|||
LHLD $BL |
|||
XCHG |
|||
LHLD $BF |
|||
JMP LPTLOP |
|||
|
|||
OUTCR: MVI A,13 |
|||
|
|||
LPTOUT: PUSH H |
|||
PUSH D |
|||
MVI C,5 ;CP/M LPT OUT FUNCTION |
|||
MOV E,A |
|||
CALL 0005 |
|||
POP D |
|||
POP H |
|||
RET |
|||
|
|||
END |
|||
|
|||
@ -0,0 +1,23 @@ |
|||
TITLE LUNTB - APPLE CPM LUN TABLE |
|||
|
|||
; TTY I/O DRIVER |
|||
.8080 |
|||
|
|||
EXTRN TTYDRV,PUNRDR,LPTDRV,DSKDRV |
|||
|
|||
ENTRY $LUNTB |
|||
|
|||
$LUNTB: DB 11 ;TEN LUN'S |
|||
|
|||
DW TTYDRV ;1= TTY |
|||
DW LPTDRV ;2= PRINTER |
|||
DW TTYDRV ;3= TTY |
|||
DW PUNRDR ;4= PUNCH,READER |
|||
DW TTYDRV ;5= TTY |
|||
DW DSKDRV ;6= FORT06.DAT |
|||
DW DSKDRV ;7= FORT07.DAT |
|||
DW DSKDRV ;AND SO ON. |
|||
DW DSKDRV |
|||
DW DSKDRV |
|||
END |
|||
|
|||
Binary file not shown.
@ -0,0 +1,235 @@ |
|||
TITLE TTYDRV - FORTRAN-80 TTY I/O DRIVER |
|||
|
|||
.8080 |
|||
|
|||
EXTRN $IOERR,$BL,$BF,$ERR,$TTYIN,$TTYOT |
|||
|
|||
; TTY: & PUN:/RDR: DRIVER ENTRIES: |
|||
|
|||
ENTRY TTYDRV,PUNRDR |
|||
|
|||
; FORTRAN-80 UTILITY SUBROUTINES: |
|||
|
|||
ENTRY PUNCH,READER,GOTOXY,SCREEN |
|||
ENTRY HOME,INKEY,CONOUT |
|||
|
|||
DSEG |
|||
|
|||
DEVFLG: DB 0 |
|||
|
|||
CSEG |
|||
|
|||
PUNRDR: DW PUNFR ;FORMATTED READ |
|||
DW PUNFW ;FORMATTED WRITE |
|||
DW $IOERR ;UNFORMATTED READ |
|||
DW PUNUWR ;UNFORMATTED WRITE |
|||
DW NULL ;REWIND |
|||
DW NULL ;BACKSPACE |
|||
DW NULL ;ENDFILE |
|||
|
|||
TTYDRV: DW TTYFR ;SAME AS ABOVE |
|||
DW TTYFW |
|||
DW $IOERR |
|||
DW TTYUWR |
|||
DW NULL |
|||
DW NULL |
|||
DW NULL |
|||
|
|||
TTYFR: XRA A ;TTY = 0 |
|||
DB 1 ;SKIP 2 BYTES WITH 'LXI B,' |
|||
|
|||
PUNFR: MVI A,1 ;READER = 1 |
|||
STA DEVFLG ;DEVICE FLAG |
|||
|
|||
XRA A |
|||
MOV E,A ;ZERO LO BYTE OF $BL |
|||
STA $BL+1 ;ZERO HI BYTE |
|||
|
|||
LHLD $BF ;GET BUFFER ADDR |
|||
|
|||
DRV31: CALL INCHR ;GET A CHARACTER |
|||
DRV39: CPI 10 ;INGNORE LINE FEEDS |
|||
JZ DRV31 |
|||
|
|||
MOV M,A |
|||
|
|||
INX H |
|||
INR E |
|||
|
|||
CPI 13 ;TEST FOR END OF LINE |
|||
MOV A,E |
|||
STA $BL |
|||
RZ |
|||
|
|||
CPI 132 ;MAX 132 CHARS |
|||
JC DRV31 |
|||
|
|||
CALL $ERR ;GIVE 'INPUT RECORD TOO LONG' WARNING |
|||
DB 18 |
|||
|
|||
NULL: XRA A ;CLEAR CARRY AND ZERO FLAGS |
|||
RET |
|||
|
|||
TTYFW: XRA A ;TTY = 0 |
|||
DB 1 ;SKIP 2 WITH 'LXI B,' |
|||
|
|||
PUNFW: MVI A,1 ;PUNCH = 1 |
|||
STA DEVFLG |
|||
|
|||
LDA $BL ;GET BUFFER LENGTH |
|||
ORA A |
|||
RZ ;EMPTY BUFFER - JUST RETURN |
|||
|
|||
LHLD $BF ;BUFFER ADDRESS |
|||
DCR A |
|||
MOV E,A ;SAVE LENGTH IN [E] |
|||
|
|||
MOV A,M ;GET CARRIAGE CONTROL CHAR |
|||
CPI '*' ;DO NOTHING? |
|||
JZ TTYNOT |
|||
|
|||
CALL OUTCR ;PRINT A CARRIAGE RETURN |
|||
MOV A,M ;REGET FIRST CHAR |
|||
CPI '+' ;A '+' MEANS CR BUT NO LF |
|||
JZ TTYNOT |
|||
|
|||
CPI '1' ;A '1' MEANS CLEAR SCREEN/FORM FEED |
|||
JNZ TTYLFO |
|||
CALL HOM1 ;GO CLEAR SCREEN OR SEND FF CHAR |
|||
JMP TTYNOT |
|||
|
|||
TTYLFO: CALL OUTLF ;PRINT A LINE FEED
Š MOV A,M ;GET CARR CONTROL CHAR BACK |
|||
CPI '0' ;'0' MEANS DOUBLE SPACING |
|||
CZ OUTLF ;ANYTHING ELSE IS JUST SINGLE SPACING |
|||
|
|||
TTYNOT: INX H ;INCREMENT BUFFER POINTER |
|||
MVI D,0 ;HI BYTE OF COUNT = 0 |
|||
|
|||
TTYLOP: MOV A,E ;DONE SENDING CHARACTERS? |
|||
ORA D |
|||
RZ ;YES, RETURN |
|||
MOV C,M ;GET CHARACTER INTO [C] |
|||
CALL OUTCH ;SEND THE CHAR |
|||
INX H ;INC BUFFER PTR |
|||
DCX D ;DEC CHARACTER COUNT |
|||
JMP TTYLOP |
|||
|
|||
TTYUWR: XRA A |
|||
|
|||
DB 1 ;SKIP 2 WITH 'LXI B,' |
|||
|
|||
PUNUWR: MVI A,1 |
|||
STA DEVFLG |
|||
LHLD $BL ;GET NO. OF CHARS TO SEND |
|||
XCHG ;INTO [DE] |
|||
LHLD $BF ;GET BUFFER POINTER INTO [HL] |
|||
JMP TTYLOP ;AND GO SEND THEM |
|||
|
|||
OUTLF: MVI C,10 ;OUTPUT A LINE FEED |
|||
JMP OUTCH |
|||
|
|||
OUTCR: MVI C,13 ;OUTPUT A CARRIAGE RETURN |
|||
|
|||
OUTCH: LDA DEVFLG ;PRINT CHARACTER TO EITHER |
|||
ORA A ;TTY: OR PUN: DEVICE |
|||
MOV A,C |
|||
JNZ $PUNOT |
|||
JMP $TTYOT |
|||
|
|||
PUNCH: MOV A,M ;FORTRAN PUNCH SUBROUTINE |
|||
|
|||
$PUNOT: PUSH B |
|||
PUSH D |
|||
MVI C,4 ;CP/M PUNCH DEVICE OUTPUT |
|||
MOV E,A |
|||
GOCPM: PUSH H |
|||
CALL 5 |
|||
POP H |
|||
POP D |
|||
POP B |
|||
RET |
|||
|
|||
CONOUT: MOV A,M ;FORTRAN CONOUT SUBROUTINE |
|||
JMP $TTYOT |
|||
|
|||
READER: ;FORTRAN READER FUNCTION |
|||
|
|||
$RDRIN: PUSH B |
|||
PUSH D |
|||
MVI C,3 |
|||
JMP GOCPM |
|||
|
|||
INCHR: LDA DEVFLG ;GET CHAR FROM EITHER |
|||
ORA A ;TTY OR READER DEVICE |
|||
JNZ $RDRIN |
|||
JMP $TTYIN |
|||
|
|||
HOM1: LDA DEVFLG ;CLEAR SCREEN IF TTY, |
|||
ORA A ;SEND FF CHAR IF PUNCH |
|||
JZ HOME |
|||
MVI A,12 ;FF CHAR |
|||
JMP $PUNOT |
|||
|
|||
HOME: MVI A,1 ;CLEAR CONSOLE SCREEN |
|||
JMP DOFUN |
|||
|
|||
SCREEN: MOV A,M ;GET FUNCTION # |
|||
|
|||
DOFUN: PUSH H |
|||
LXI H,0F397H ;SSFTAB |
|||
ADD L ;POINT TO DESIRED FUN CHAR |
|||
MOV L,A |
|||
MOV A,M ;GET IT INTO A |
|||
ORA A ;REQUIRE LEAD-IN? |
|||
JP NOLDIN |
|||
PUSH PSW |
|||
LDA 0F397H ;YES, SO SEND IT FIRST |
|||
CALL $TTYOT |
|||
POP PSW |
|||
NOLDIN: CALL $TTYOT |
|||
POP H |
|||
RET |
|||
|
|||
GOTOXY: MVI A,7 ;DO CURSOR POSITION FUNCTION |
|||
CALL DOFUN |
|||
|
|||
LDAX D ;GET COORDS |
|||
MOV H,M ;H=X, L=Y |
|||
MOV L,A |
|||
|
|||
DCR L ;MAP 1..24,1..80 TO 0..23,0..79 |
|||
DCR H |
|||
|
|||
LDA 0F396H ;XY COORD OFFSET |
|||
ORA A |
|||
JP NORVS |
|||
|
|||
MOV E,L ;SWAP |
|||
MOV L,H |
|||
MOV H,E |
|||
|
|||
NORVS: MOV E,A ;SAVE IN [E] |
|||
ADD H ;ADD OFFSET |
|||
PUSH PSW ;SAVE CHAR |
|||
MOV A,E |
|||
ADD L ;OUTPUT FIRST COORD |
|||
CALL $TTYOT |
|||
POP PSW |
|||
MOV E,A ;OUTPUT SECOND COORD |
|||
JMP $TTYOT |
|||
|
|||
INKEY: MOV A,M ;GET PARAMETER |
|||
ORA A ;SEE WHAT IT IS |
|||
JZ INK1 ;ZERO - JUST TEST STATUS |
|||
|
|||
INKLP: CALL INK1 ;READ CONSOLE STATUS |
|||
ORA A |
|||
JZ INKLP ;WAIT UNTIL KEYPRESS |
|||
RET |
|||
|
|||
INK1: MVI C,6 ;CONSOLE STATUS CALL |
|||
MVI E,255 |
|||
JMP 5 ;GO TO BDOS |
|||
|
|||
END |
|||
|
|||
@ -0,0 +1,14 @@ |
|||
===== Games Disk for CP/M ===== |
|||
|
|||
This disk contains several games for CP/M including the Infocom games |
|||
Zork 1 through 3, Planetfall and Hitchhiker's Guide to the Galaxy. |
|||
|
|||
Nemesis and Dungeon Master is a Rogue-like game released in 1981. It is playable |
|||
on a text terminal using ASCII graphics to represent the dungeon. Only a few |
|||
thousand copies of the game were ever made, making it very rare. See |
|||
http://crpgaddict.blogspot.com/2019/03/game-322-nemesis-1981.html |
|||
|
|||
Colossal Cave Adventure is a CP/M port of the 1976 classic game originally |
|||
written by Will Crowther for the PDP-10 mainframe. See |
|||
https://en.wikipedia.org/wiki/Colossal_Cave_Adventure and |
|||
https://if50.substack.com/p/1976-adventure |
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue