├── .gitignore ├── ADVGRP.ASM ├── BIBOOT.ASM ├── BIMISC.ASM ├── BINTRP.H ├── BIPRTU.ASM ├── BIPTRG.ASM ├── BISTRS.ASM ├── CALL86.ASM ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── DSKCOM.ASM ├── FIVEO.ASM ├── GENGRP.ASM ├── GIO86.ASM ├── GIO86U ├── GIOCAS.ASM ├── GIOCOM.ASM ├── GIOCON.ASM ├── GIODSK.ASM ├── GIOKYB.ASM ├── GIOLPT.ASM ├── GIOSCN.ASM ├── GIOTBL.ASM ├── GWBASIC.LNK ├── GWDATA.ASM ├── GWEVAL.ASM ├── GWINIT.ASM ├── GWLIST.ASM ├── GWMAIN.ASM ├── GWRAM.ASM ├── GWSTS.ASM ├── IBMRES.ASM ├── IBMRES.H ├── ITSA86.ASM ├── KANJ86.ASM ├── LICENSE ├── MACLNG.ASM ├── MAKEFILE ├── MATH1.ASM ├── MATH2.ASM ├── MSDOSU ├── NEXT86.ASM ├── OEM.ASM ├── OEM.H ├── README.md ├── SCNDRV.ASM ├── SCNEDT.ASM └── SECURITY.md /.gitignore: -------------------------------------------------------------------------------- 1 | MATH.ASM 2 | *.OBJ 3 | GWBASIC.EXE 4 | -------------------------------------------------------------------------------- /BIBOOT.ASM: -------------------------------------------------------------------------------- 1 | ; [ This translation created 10-Feb-83 by Version 4.3 ] 2 | 3 | .RADIX 8 ; To be safe 4 | 5 | CSEG SEGMENT PUBLIC 'CODESG' 6 | ASSUME CS:CSEG 7 | 8 | INCLUDE OEM.H 9 | 10 | TITLE BIBOOT - Initialization File for ASM86 BASICs 11 | COMMENT * 12 | 13 | --------- --- ---- -- --------- ----------- 14 | COPYRIGHT (C) 1982 BY MICROSOFT CORPORATION 15 | --------- --- ---- -- --------- ----------- 16 | 17 | by Niklas Traub 18 | * 19 | INCLUDE GIO86U 20 | .SALL 21 | 22 | CPM86=0 23 | 24 | INCLUDE MSDOSU 25 | 26 | PAGE 27 | SUBTTL ASM86 Version 28 | ; 29 | ; There is a problem with running the ASM86 sources for BASIC as they 30 | ; stand. MSDOS puts a 100 hex byte control block at the beginning of the 31 | ; EXE file and sets up the ES register to point to it. BASIC, however, 32 | ; expects this block to be at 0 in the code segment. The quick and dirty 33 | ; solution is to copy the block into the code segment before doing anything 34 | ; else. This module is included in the linker file list AFTER all others, 35 | ; but is executed first since it is defined as the entry point. 36 | ; A 100H bytes are copied from ES:0 to CS:0 and then jump is done to 37 | ; the START label. To accomodate the block, BINTRP should have an ORG 100H 38 | ; before any code. 39 | ; 40 | ; NOTE: Never convert the EXE file to a COM file. COM files have the CS 41 | ; register pointing to the control block on entry, so all offsets 42 | ; for immediate values will be off by 100H. 43 | ; 44 | EXTRN START:NEAR 45 | 46 | ;BIBOOT - ASM86 Version Specific Initialization 47 | ;Entry - ES:0 pointing to start of control block. 48 | ; DS:0 pointing to start of control block. 49 | ; 50 | BIBOOT: 51 | MOV CX,CS ; Get BASIC's segment 52 | MOV ES,CX ; Make it the destination segment 53 | XOR SI,SI ; Start at ES:0 54 | XOR DI,DI ; Destination is CS:0 55 | MOV CX,200O ; There are 100H bytes to move 56 | CLD 57 | REP MOVSW 58 | MOV CX,DS ; Restore segment registers 59 | MOV ES,CX 60 | JMP START 61 | CSEG ENDS 62 | ; 63 | ; Last label in data segment. Is used by BASIC to initialize TXTTAB, etc. 64 | ; 65 | DSEG SEGMENT PUBLIC 'DATASG' 66 | ASSUME DS:DSEG 67 | PUBLIC LSTVAR 68 | LSTVAR LABEL WORD 69 | DSEG ENDS 70 | CSEG SEGMENT PUBLIC 'CODESG' 71 | ASSUME CS:CSEG 72 | CSEG ENDS 73 | END BIBOOT ; BIBOOT is the entry point. 74 | ; 75 | -------------------------------------------------------------------------------- /BINTRP.H: -------------------------------------------------------------------------------- 1 | ; 2 | ; Include file for BINTRP.ASM 3 | ; 4 | 5 | INCLUDE OEM.H ; General definitions 6 | 7 | MOVRI MACRO B,C,D,E 8 | DB 271O ; "LXI B" 9 | DB C 10 | DB B 11 | DB 272O ; "LXI D" 12 | DB E 13 | DB D 14 | ENDM 15 | 16 | ; 17 | ; Reserve word table generating Macros 18 | ; 19 | un_def MACRO RESWRD 20 | %OUT +++ Undefined reserved word - &RESWRD 21 | ENDM 22 | 23 | T MACRO RESWRD 24 | QQ=QQ+1 25 | $&RESWRD=QQ 26 | ENDM 27 | 28 | Q MACRO RESWRD 29 | IFDEF $&RESWRD 30 | $F=0 31 | IRPC XX, 32 | IF $F 33 | $Q="&XX&" 34 | DB "&XX&" 35 | ENDIF 36 | IFE $F-1 37 | .XLIST 38 | ENDIF 39 | $F=$F+1 40 | ENDM 41 | .LIST 42 | ORG $-1 43 | DB $Q+128D 44 | DB $&RESWRD 45 | ELSE 46 | un_def RESWRD 47 | ENDIF 48 | ENDM 49 | 50 | QF MACRO RESWRD 51 | IFDEF $&RESWRD 52 | $F=0 53 | IRPC XX, 54 | IF $F 55 | $Q="&XX&" 56 | DB "&XX&" 57 | ENDIF 58 | IFE $F-1 59 | .XLIST 60 | ENDIF 61 | $F=$F+1 62 | ENDM 63 | .LIST 64 | ORG $-1 65 | DB $Q+128D 66 | DB $&RESWRD-128D 67 | ELSE 68 | un_def RESWRD 69 | ENDIF 70 | ENDM 71 | 72 | DERMAK MACRO X 73 | PUBLIC DER&X 74 | DER&X: MOV DL,OFFSET ERR&X 75 | DB 271O ; LXI B over next error 76 | ENDM 77 | ; 78 | ; Dispatch table generating Macros. We have to play games with the 79 | ; external declarations as ASM86 won't allow something to be declared 80 | ; external during pass 2. Instead we build a chain of dummy macros 81 | ; that could generate the declaration for all potentially external 82 | ; reserve word dispatch addresses. 83 | ; 84 | 85 | ; 86 | ; play games with a possible external. Create a new 87 | ; macro for the symbol and text, and string it together 88 | ; with a central invoker 89 | ; 90 | IF1 91 | ?i=0 92 | ENDIF 93 | 94 | ?z0 macro ; Bottom of the chain 95 | endm 96 | 97 | ; 98 | ; add an external declaration to S with type NEAR if it is not defined 99 | ; 100 | add_ext macro s 101 | IFNDEF ?&s 102 | ?i = ?i + 1 103 | def_mac ?z&%?i,?z&%(?i-1),s 104 | ENDIF 105 | endm 106 | 107 | ; 108 | ; define a macro called that possibly externals S:NEAR and then calls macro n 109 | ; 110 | def_mac macro m,n,s 111 | m macro 112 | ifndef s 113 | extrn s:NEAR 114 | endif 115 | purge m 116 | n 117 | endm 118 | s macro 119 | endm 120 | endm 121 | 122 | ; 123 | ; call the macro chain 124 | ; 125 | do_ext macro 126 | expand_mac ?z%?i 127 | endm 128 | 129 | expand_mac macro m 130 | m 131 | endm 132 | ; 133 | R MACRO RESWRD 134 | IFNDEF RESWRD 135 | add_ext RESWRD 136 | ENDIF 137 | DW RESWRD 138 | QQ=QQ+1 139 | $&RESWRD=QQ 140 | ENDM 141 | 142 | R2 MACRO RESWRD,RESDSP 143 | IFNDEF RESDSP 144 | add_ext RESDSP 145 | ENDIF 146 | DW RESDSP 147 | QQ=QQ+1 148 | $&RESWRD=QQ 149 | ENDM 150 | ; 151 | PAGE 152 | -------------------------------------------------------------------------------- /BIPRTU.ASM: -------------------------------------------------------------------------------- 1 | ; [ This translation created 10-Feb-83 by Version 4.3 ] 2 | 3 | .RADIX 8 ; To be safe 4 | 5 | CSEG SEGMENT PUBLIC 'CODESG' 6 | ASSUME CS:CSEG 7 | 8 | INCLUDE OEM.H 9 | 10 | TITLE BIPRTU BASIC Interpreter PRINT USING Driver/WHG 11 | 12 | .RADIX 10 13 | 14 | TRSHHC=0 15 | NECPPC=0 16 | 17 | SUBTTL PRINT USING DRIVER 18 | ; 19 | ; COME HERE AFTER THE "USING" CLAUSE IN A PRINT STATEMENT 20 | ; IS RECOGNIZED. THE IDEA IS TO SCAN THE USING STRING UNTIL 21 | ; THE VALUE LIST IS EXHAUSTED, FINDING STRING AND NUMERIC 22 | ; FIELDS TO PRINT VALUES OUT OF THE LIST IN, 23 | ; AND JUST OUTPUTING ANY CHARACTERS THAT AREN'T PART OF 24 | ; A PRINT FIELD. 25 | ; 26 | DSEG SEGMENT PUBLIC 'DATASG' ; Data segment externs 27 | ASSUME DS:DSEG 28 | EXTRN FACLO:WORD 29 | 30 | EXTRN USFLG:WORD 31 | DSEG ENDS 32 | 33 | ; Code segment ( terminated by END at bottom of file ) 34 | 35 | EXTRN CHRGTR:NEAR,SYNCHR:NEAR 36 | EXTRN CHKSTR:NEAR,CRDO:NEAR,FCERR:NEAR,FRETM2:NEAR,FRMCHK:NEAR 37 | EXTRN FRMEVL:NEAR 38 | EXTRN OUTDO:NEAR,PUFOUT:NEAR,SNERR:NEAR,STROUT:NEAR,STRPRT:NEAR 39 | EXTRN LEFTUS:NEAR 40 | PUBLIC PRINUS 41 | CSTRNG=134O 42 | CURNCY=44O ;USE DOLLAR SIGN AS DEFAULT 43 | 44 | PRINUS: CALL FRMCHK ;EVALUATE THE "USING" STRING 45 | CALL CHKSTR ;MAKE SURE IT IS A STRING 46 | CALL SYNCHR 47 | DB OFFSET 73O ;MUST BE DELIMITED BY A SEMI-COLON 48 | XCHG BX,DX ;[D,E]=TEXT POINTER 49 | MOV BX,FACLO ;GET POINTER TO "USING" STRING DESCRIPTOR 50 | JMP SHORT INIUS ;DONT POP OFF OR LOOK AT USFLG 51 | REUSST: MOV AL,BYTE PTR USFLG ;DID WE PRINT OUT A VALUE LAST SCAN? 52 | OR AL,AL ;SET CC'S 53 | JZ SHORT FCERR3 ;NO, GIVE ERROR 54 | POP DX ;[D,E]=POINTER TO "USING" STRING DESCRIPTOR 55 | XCHG BX,DX ;[D,E]=TEXT POINTER 56 | INIUS: PUSH BX ;SAVE THE POINTER TO "USING" STRING DESCRIPTOR 57 | XOR AL,AL ;INITIALLY INDICATE THERE ARE MORE 58 | ;VALUES IN THE VALUE LIST 59 | MOV BYTE PTR USFLG,AL ;RESET THE FLAG THAT SAYS VALUES PRINTED 60 | INC AL ;TURN THE ZERO FLAG OFF 61 | ;TO INDICATE THE VALUE LIST HASN'T ENDED 62 | PUSHF ;SAVE FLAG INDICATING WHETHER THE VALUE 63 | ;LIST HAS ENDED 64 | PUSH DX ;SAVE THE TEXT POINTER INTO THE VALUE LIST 65 | MOV CH,BYTE PTR [BX] ;[B]=LENGTH OF THE "USING" STRING 66 | INC CH ;Is the using string null? 67 | DEC CH 68 | FCERR3: JNZ SHORT ??L000 69 | JMP FCERR ;IF SO, "ILLEGAL FUNCTION CALL" 70 | ??L000: 71 | INC BX ;[H,L]=POINTER AT THE "USING" STRING'S 72 | MOV BX,[BX] ;DATA 73 | JMP SHORT PRCCHR ;GO INTO THE LOOP TO SCAN 74 | ;THE "USING" STRING 75 | ;NECPPC does not have string formatter 76 | ; because of ROM space 77 | BGSTRF: MOV DL,CH ;SAVE THE "USING" STRING CHARACTER COUNT 78 | PUSH BX ;SAVE THE POINTER INTO THE "USING" STRING 79 | MOV CL,LOW 2 ;THE \\ STRING FIELD HAS 2 PLUS 80 | ;NUMBER OF ENCLOSED SPACES WIDTH 81 | LPSTRF: MOV AL,BYTE PTR [BX] ;GET THE NEXT CHARACTER 82 | INC BX ;ADVANCE THE POINTER AT THE "USING" STRING 83 | ;DATA 84 | CMP AL,LOW OFFSET CSTRNG ;THE FIELD TERMINATOR? 85 | JNZ SHORT ??L001 86 | JMP ISSTRF ;GO EVALUATE A STRING AND PRINT 87 | ??L001: 88 | CMP AL,LOW " " ;A FIELD EXTENDER? 89 | JNZ SHORT NOSTRF ;IF NOT, ITS NOT A STRING FIELD 90 | INC CL ;INCREMENT THE FIELD WIDTH 91 | ;SEE IF THERE ARE MORE CHARACTERS 92 | DEC CH 93 | JNZ SHORT LPSTRF ;KEEP SCANNING FOR THE FIELD TERMINATOR 94 | ; 95 | ; SINCE STRING FIELD WASN'T FOUND, THE "USING" STRING 96 | ; CHARACTER COUNT AND THE POINTER INTO IT'S DATA MUST 97 | ; BE RESTORED AND THE "\" PRINTED 98 | ; 99 | NOSTRF: POP BX ;RESTORE THE POINTER INTO "USING" STRING'S DATA 100 | MOV CH,DL ;RESTORE THE "USING" STRING CHARACTER COUNT 101 | MOV AL,LOW OFFSET CSTRNG ;RESTORE THE CHARACTER 102 | ; 103 | ; HERE TO PRINT THE CHARACTER IN [A] SINCE IT WASN'T PART OF ANY FIELD 104 | ; 105 | NEWUCH: CALL PLSPRT ;IF A "+" CAME BEFORE THIS CHARACTER 106 | ;MAKE SURE IT GETS PRINTED 107 | CALL OUTDO ;PRINT THE CHARACTER THAT WASN'T 108 | ;PART OF A FIELD 109 | 110 | 111 | 112 | PRCCHR: XOR AL,AL ;SET [D,E]=0 SO IF WE DISPATCH 113 | MOV DL,AL ;SOME FLAGS ARE ALREADY ZEROED 114 | MOV DH,AL ;DON'T PRINT "+" TWICE 115 | PLSFIN: CALL PLSPRT ;ALLOW FOR MULTIPLE PLUSES 116 | ;IN A ROW 117 | MOV DH,AL ;SET "+" FLAG 118 | MOV AL,BYTE PTR [BX] ;GET A NEW CHARACTER 119 | INC BX 120 | CMP AL,LOW "!" ;CHECK FOR A SINGLE CHARACTER 121 | JNZ SHORT ??L002 122 | JMP SMSTRF ;STRING FIELD 123 | ??L002: 124 | CMP AL,LOW "#" ;CHECK FOR THE START OF A NUMERIC FIELD 125 | JZ SHORT NUMNUM ;GO SCAN IT 126 | CMP AL,LOW "&" ;SEE IF ITS A VARIABLE LENGTH STRING FIELD 127 | JNZ SHORT ??L003 128 | JMP VARSTR ;GO PRINT ENTIRE STRING 129 | ??L003: 130 | DEC CH ;ALL THE OTHER POSSIBILITIES 131 | ;REQUIRE AT LEAST 2 CHARACTERS 132 | JNZ SHORT ??L004 133 | JMP REUSIN ;IF THE VALUE LIST IS NOT EXHAUSTED 134 | ??L004: 135 | ;GO REUSE "USING" STRING 136 | CMP AL,LOW "+" ;A LEADING "+" ? 137 | MOV AL,LOW 8 ;SETUP [D] WITH THE PLUS-FLAG ON IN 138 | JZ SHORT PLSFIN ;CASE A NUMERIC FIELD STARTS 139 | DEC BX ;POINTER HAS ALREADY BEEN INCREMENTED 140 | MOV AL,BYTE PTR [BX] ;GET BACK THE CURRENT CHARACTER 141 | INC BX ;REINCREMENT THE POINTER 142 | CMP AL,LOW "." ;NUMERIC FIELD WITH TRAILING DIGITS 143 | JZ SHORT DOTNUM ;IF SO GO SCAN WITH [E]= 144 | ;NUMBER OF DIGITS BEFORE THE "."=0 145 | CMP AL,LOW "_" ;CHECK FOR LITERAL CHARACTER DECLARATION 146 | JNZ SHORT ??L005 147 | JMP LITCHR 148 | ??L005: 149 | CMP AL,LOW OFFSET CSTRNG ;CHECK FOR A BIG STRING FIELD STARTER 150 | JZ SHORT BGSTRF ;GO SEE IF IT REALLY IS A STRING FIELD 151 | CMP AL,BYTE PTR [BX] ;SEE IF THE NEXT CHARACTER MATCHES THE 152 | ;CURRENT ONE 153 | JNZ SHORT NEWUCH ;IF NOT, CAN'T HAVE $$ OR ** SO ALL THE 154 | ;POSSIBILITIES ARE EXHAUSTED 155 | CMP AL,LOW OFFSET CURNCY ;IS IT $$ ? 156 | JZ SHORT DOLRNM ;GO SET UP THE FLAG BIT 157 | CMP AL,LOW "*" ;IS IT ** ? 158 | JNZ SHORT NEWUCH ;IF NOT, ITS NOT PART 159 | ;OF A FIELD SINCE ALL THE POSSIBILITIES 160 | ;HAVE BEEN TRIED 161 | INC BX ;CHECK FOR $ 162 | MOV AL,CH ;SEE IF THE "USING" STRING IS LONG 163 | CMP AL,LOW 2 ;ENOUGH FOR THE SPECIAL CASE OF 164 | JB SHORT NOTSPC ; **$ 165 | MOV AL,BYTE PTR [BX] 166 | CMP AL,LOW OFFSET CURNCY ;IS THE NEXT CHARACTER $ ? 167 | NOTSPC: MOV AL,LOW 32 ;SET THE ASTERISK BIT 168 | JNZ SHORT SPCNUM ;IF IT NOT THE SPECIAL CASE, DON'T 169 | ;SET THE DOLLAR SIGN FLAG 170 | DEC CH ;DECREMENT THE "USING" STRING CHARACTER COUNT 171 | ;TO TAKE THE $ INTO CONSIDERATION 172 | INC DL ;INCREMENT THE FIELD WIDTH FOR THE 173 | ;FLOATING DOLLAR SIGN 174 | DB 276O ; SKIP ;"CPI" OVER THE NEXT BYTE 175 | ;MVI SI, IN 8086 176 | DOLRNM: XOR AL,AL ;CLEAR [A] 177 | ADD AL,LOW 16 ;SET BIT FOR FLOATING DOLLAR SIGN FLAG 178 | INC BX ;POINT BEYOND THE SPECIAL CHARACTERS 179 | SPCNUM: INC DL ;SINCE TWO CHARACTERS SPECIFY 180 | ;THE FIELD SIZE, INITIALIZE [E]=1 181 | ADD AL,DH ;PUT NEW FLAG BITS IN [A] 182 | MOV DH,AL ;INTO [D]. THE PLUS FLAG MAY HAVE 183 | ;ALREADY BEEN SET 184 | NUMNUM: INC DL ;INCREMENT THE NUMBER OF DIGITS BEFORE 185 | ;THE DECIMAL POINT 186 | MOV CL,LOW 0 ;SET THE NUMBER OF DIGITS AFTER 187 | ;THE DECIMAL POINT = 0 188 | DEC CH ;SEE IF THERE ARE MORE CHARACTERS 189 | JZ SHORT ENDNUS ;IF NOT, WE ARE DONE SCANNING THIS 190 | ;NUMERIC FIELD 191 | MOV AL,BYTE PTR [BX] ;GET THE NEW CHARACTER 192 | INC BX ;ADVANCE THE POINTER AT THE "USING" STRING DATA 193 | CMP AL,LOW "." ;DO WE HAVE TRAILING DIGITS? 194 | JZ SHORT AFTDOT ;IF SO, USE SPECIAL SCAN LOOP 195 | CMP AL,LOW "#" ;MORE LEADING DIGITS ? 196 | JZ SHORT NUMNUM ;INCREMENT THE COUNT AND KEEP SCANNING 197 | CMP AL,LOW 54O ;DOES HE WANT A COMMA 198 | ;EVERY THREE DIGITS? 199 | JNZ SHORT FINNUM ;NO MORE LEADING DIGITS, CHECK FOR ^^^ 200 | MOV AL,DH ;TURN ON THE COMMA BIT 201 | OR AL,LOW 64 202 | MOV DH,AL 203 | JMP SHORT NUMNUM ;GO SCAN SOME MORE 204 | ; 205 | ; HERE WHEN A "." IS SEEN IN THE "USING" STRING 206 | ; IT STARTS A NUMERIC FIELD IF AND ONLY IF 207 | ; IT IS FOLLOWED BY A "#" 208 | ; 209 | DOTNUM: MOV AL,BYTE PTR [BX] ;GET THE CHARACTER THAT FOLLOWS 210 | CMP AL,LOW "#" ;IS THIS A NUMERIC FIELD? 211 | MOV AL,LOW "." ;IF NOT, GO BACK AND PRINT "." 212 | JZ SHORT ??L006 213 | JMP NEWUCH 214 | ??L006: 215 | MOV CL,LOW 1 ;INITIALIZE THE NUMBER OF 216 | ;DIGITS AFTER THE DECIMAL POINT 217 | INC BX 218 | AFTDOT: INC CL ;INCREMENT THE NUMBER OF DIGITS 219 | ;AFTER THE DECIMAL POINT 220 | DEC CH ;SEE IF THE "USING" STRING HAS MORE 221 | JZ SHORT ENDNUS ;CHARACTERS, AND IF NOT, STOP SCANNING 222 | MOV AL,BYTE PTR [BX] ;GET THE NEXT CHARACTER 223 | INC BX 224 | CMP AL,LOW "#" ;MORE DIGITS AFTER THE DECIMAL POINT? 225 | JZ SHORT AFTDOT ;IF SO, INCREMENT THE COUNT AND KEEP 226 | ;SCANNING 227 | ; 228 | ; CHECK FOR THE "^^^^" THAT INDICATES SCIENTIFIC NOTATION 229 | ; 230 | FINNUM: PUSH DX ;SAVE [D]=FLAGS AND [E]=LEADING DIGITS 231 | MOV DX,OFFSET NOTSCI ;PLACE TO GO IF ITS NOT SCIENTIFIC 232 | PUSH DX ;NOTATION 233 | MOV DH,BH ;REMEMBER [H,L] IN CASE 234 | MOV DL,BL ;ITS NOT SCIENTIFIC NOTATION 235 | CMP AL,LOW "^" ;IS THE FIRST CHARACTER "^" ? 236 | JZ SHORT $+3 237 | RET 238 | CMP AL,BYTE PTR [BX] ;IS THE SECOND CHARACTER "^" ? 239 | JZ SHORT $+3 240 | RET 241 | INC BX 242 | CMP AL,BYTE PTR [BX] ;IS THE THIRD CHARACTER "^" ? 243 | JZ SHORT $+3 244 | RET 245 | INC BX 246 | CMP AL,BYTE PTR [BX] ;IS THE FOURTH CHARACTER "^" ? 247 | JZ SHORT $+3 248 | RET 249 | INC BX 250 | MOV AL,CH ;WERE THERE ENOUGH CHARACTERS FOR "^^^^" 251 | SUB AL,LOW 4 ;IT TAKES FOUR 252 | JNB SHORT $+3 253 | RET 254 | POP DX ;POP OFF THE NOTSCI RETURN ADDRESS 255 | POP DX ;GET BACK [D]=FLAGS [E]=LEADING DIGITS 256 | MOV CH,AL ;MAKE [B]=NEW CHARACTER COUNT 257 | INC DH ;TURN ON THE SCIENTIFIC NOTATION FLAG 258 | INC BX 259 | JMP SHORT ENDNUS 260 | NOTSCI: XCHG BX,DX ;RESTORE THE OLD [H,L] 261 | POP DX ;GET BACK [D]=FLAGS [E]=LEADING DIGITS 262 | ENDNUS: MOV AL,DH ;IF THE LEADING PLUS FLAG IS ON 263 | DEC BX 264 | INC DL ;INCLUDE LEADING "+" IN NUMBER OF DIGITS 265 | AND AL,LOW 8 ;DON'T CHECK FOR A TRAILING SIGN 266 | JNZ SHORT ENDNUM ;ALL DONE WITH THE FIELD IF SO 267 | ;IF THERE IS A LEADING PLUS 268 | DEC DL ;NO LEADING PLUS SO DON'T INCREMENT THE 269 | ;NUMBER OF DIGITS BEFORE THE DECIMAL POINT 270 | MOV AL,CH 271 | OR AL,AL ;SEE IF THERE ARE MORE CHARACTERS 272 | JZ SHORT ENDNUM ;IF NOT, STOP SCANNING 273 | MOV AL,BYTE PTR [BX] ;GET THE CURRENT CHARACTER 274 | SUB AL,LOW "-" ;TRAIL MINUS? 275 | JZ SHORT SGNTRL ;SET THE TRAILING SIGN FLAG 276 | CMP AL,LOW OFFSET "+"-"-" ;A TRAILING PLUS? 277 | JNZ SHORT ENDNUM ;IF NOT, WE ARE DONE SCANNING 278 | MOV AL,LOW 8 ;TURN ON THE POSITIVE="+" FLAG 279 | SGNTRL: ADD AL,LOW 4 ;TURN ON THE TRAILING SIGN FLAG 280 | ADD AL,DH ;INCLUDE WITH OLD FLAGS 281 | MOV DH,AL 282 | DEC CH ;DECREMENT THE "USING" STRING CHARACTER 283 | ;COUNT TO ACCOUNT FOR THE TRAILING SIGN 284 | ENDNUM: POP BX ;[H,L]=THE OLD TEXT POINTER 285 | POPF ;POP OFF FLAG THAT SAYS WHETHER THERE 286 | ;ARE MORE VALUES IN THE VALUE LIST 287 | JZ SHORT FLDFIN ;IF NOT, WE ARE DONE WITH THE "PRINT" 288 | PUSH CX ;SAVE [B]=# OF CHARACTERS REMAINING IN 289 | ;"USING" STRING AND [C]=TRAILING DIGITS 290 | PUSH DX ;SAVE [D]=FLAGS AND [E]=LEADING DIGITS 291 | CALL FRMEVL ;READ A VALUE FROM THE VALUE LIST 292 | POP DX ;[D]=FLAGS & [E]=# OF LEADING DIGITS 293 | POP CX ;[B]=# CHARACTER LEFT IN "USING" STRING 294 | ;[C]=NUMBER OF TRAILING DIGITS 295 | PUSH CX ;SAVE [B] FOR ENTERING SCAN AGAIN 296 | PUSH BX ;SAVE THE TEXT POINTER 297 | MOV CH,DL ;[B]=# OF LEADING DIGITS 298 | MOV AL,CH ;MAKE SURE THE TOTAL NUMBER OF DIGITS 299 | ADD AL,CL ;DOES NOT EXCEED TWENTY-FOUR 300 | CMP AL,LOW 25 301 | JNAE SHORT ??L007 302 | JMP FCERR ;IF SO, "ILLEGAL FUNCTION CALL" 303 | ??L007: 304 | MOV AL,DH ;[A]=FLAG BITS 305 | OR AL,LOW 128 ;TURN ON THE "USING" BIT 306 | CALL PUFOUT ;PRINT THE VALUE 307 | EXTRN DSOUT:NEAR 308 | CALL DSOUT ;PRINT FROM THE DATA SEGMENT 309 | FNSTRF: POP BX ;GET BACK THE TEXT POINTER 310 | DEC BX ;SEE WHAT THE TERMINATOR WAS 311 | CALL CHRGTR 312 | STC ;SET FLAG THAT CRLF IS DESIRED 313 | JZ SHORT CRDNUS ;IF IT WAS A END-OF-STATEMENT 314 | ;FLAG THAT THE VALUE LIST ENDED 315 | ;AND THAT CRLF SHOULD BE PRINTED 316 | MOV BYTE PTR USFLG,AL ;FLAG THAT VALUE HAS BEEN PRINTED. 317 | ;DOESNT MATTER IF ZERO SET, [A] 318 | ;MUST BE NON-ZERO OTHERWISE 319 | CMP AL,LOW 73O ;A SEMI-COLON? 320 | JZ SHORT SEMUSN ;A LEGAL DELIMITER 321 | CMP AL,LOW 54O ;A COMMA ? 322 | JZ SHORT ??L008 323 | JMP SNERR ;THE DELIMETER WAS ILLEGAL 324 | ??L008: 325 | SEMUSN: CALL CHRGTR ;IS THERE ANOTHER VALUE? 326 | CRDNUS: POP CX ;[B]=CHARACTERS REMAINING IN "USING" STRING 327 | XCHG BX,DX ;[D,E]=TEXT POINTER 328 | POP BX ;[H,L]=POINT AT THE "USING" STRING 329 | PUSH BX ;DESCRIPTOR. RESAVE IT. 330 | PUSHF ;SAVE THE FLAG THAT INDICATES 331 | ;WHETHER OR NOT THE VALUE LIST TERMINATED 332 | PUSH DX ;SAVE THE TEXT POINTER 333 | ; 334 | ; SINCE FRMEVL MAY HAVE FORCED GARBAGE COLLECTION 335 | ; WE HAVE TO USE THE NUMBER OF CHARACTERS ALREADY SCANNED 336 | ; AS AN OFFSET TO THE POINTER TO THE "USING" STRING'S DATA 337 | ; TO GET A NEW POINTER TO THE REST OF THE CHARACTERS TO 338 | ; BE SCANNED 339 | ; 340 | MOV AL,BYTE PTR [BX] ;GET THE "USING" STRING'S LENGTH 341 | SUB AL,CH ;SUBTRACT THE NUMBER OF CHARACTERS 342 | ;ALREADY SCANNED 343 | INC BX ;[H,L]=POINTER AT 344 | MOV DH,LOW 0 ;SETUP [D,E] AS A DOUBLE BYTE OFFSET 345 | MOV DL,AL 346 | MOV BX,[BX] ;THE "USING" STRING'S STRING DATA 347 | ADD BX,DX ;ADD ON THE OFFSET TO GET 348 | ;THE NEW POINTER 349 | CHKUSI: MOV AL,CH ;[A]=THE NUMBER OF CHARACTERS LEFT TO SCAN 350 | OR AL,AL ;SEE IF THERE ARE ANY LEFT 351 | JZ SHORT ??L009 352 | JMP PRCCHR ;IF SO, KEEP SCANNING 353 | ??L009: 354 | JMP SHORT FINUSI ;SEE IF THERE ARE MORE VALUES 355 | REUSIN: CALL PLSPRT ;PRINT A "+" IF NECESSARY 356 | CALL OUTDO ;PRINT THE FINAL CHARACTER 357 | FINUSI: POP BX ;POP OFF THE TEXT POINTER 358 | POPF ;POP OFF THE INDICATOR OF WHETHER OR NOT 359 | ;THE VALUE LIST HAS ENDED 360 | JZ SHORT ??L010 361 | JMP REUSST ;IF NOT, REUSE THE "USING" STRING 362 | ??L010: 363 | FLDFIN: JNB SHORT ??L011 364 | CALL CRDO ;IF NOT COMMA OR SEMI-COLON 365 | ??L011: 366 | ;ENDED THE VALUE LIST 367 | ;PRINT A CRLF 368 | POP SI ;XTHL 369 | XCHG SI,BX 370 | PUSH SI ;SAVE THE TEXT POINTER 371 | ;[H,L]=POINT AT THE "USING" STRING'S 372 | ;DESCRIPTOR 373 | CALL FRETM2 ;FINALLY FREE IT UP 374 | POP BX ;GET BACK THE TEXT POINTER 375 | EXTRN FINPRT:NEAR 376 | JMP FINPRT ;ZERO [PTRFIL] 377 | ; 378 | ; HERE TO HANDLE A LITERAL CHARACTER IN THE USING STRING PRECEDED 379 | ; BY "_" 380 | ; 381 | LITCHR: CALL PLSPRT ;PRINT PREVIOUS "+" IF ANY 382 | DEC CH ;DECREMENT COUNT FOR ACTUAL CHARACTER 383 | MOV AL,BYTE PTR [BX] ;FETCH LITERAL CHARACTER 384 | INC BX 385 | CALL OUTDO 386 | JMP SHORT CHKUSI ;GO SEE IF USING STRING ENDED 387 | 388 | ; 389 | ; HERE TO HANDLE VARIABLE LENGTH STRING FIELD SPECIFIED WITH "&" 390 | ; 391 | VARSTR: MOV CL,LOW 0 ;SET LENGTH TO 0 TO FLAG VARIABLE LENGTH 392 | JMP SHORT ISSTR1 393 | ;NECPPC does not have string formatter 394 | ; because of ROM space 395 | ; 396 | ; HERE WHEN THE "!" INDICATING A SINGLE CHARACTER 397 | ; STRING FIELD HAS BEEN SCANNED 398 | ; 399 | SMSTRF: MOV CL,LOW 1 ;SET THE FIELD WIDTH TO 1 400 | JMP SHORT ISSTR1 401 | ISSTRF: POP AX ;GET RID OF THE [H,L] THAT WAS BEING 402 | ;SAVED IN CASE THIS WASN'T A STRING FIELD 403 | ISSTR1: DEC CH ;DECREMENT THE "USING" STRING CHARACTER COUNT 404 | CALL PLSPRT ;PRINT A "+" IF ONE CAME BEFORE THE FIELD 405 | POP BX ;TAKE OFF THE TEXT POINTER 406 | POPF ;TAKE OF THE FLAG WHICH SAYS 407 | ;WHETHER THERE ARE MORE VALUES IN THE 408 | ;VALUE LIST 409 | JZ SHORT FLDFIN ;IF THERE ARE NO MORE VALUES 410 | ;THEN WE ARE DONE 411 | PUSH CX ;SAVE [B]=NUMBER OF CHARACTERS YET TO 412 | ;BE SCANNED IN "USING" STRING 413 | CALL FRMEVL ;READ A VALUE 414 | CALL CHKSTR ;MAKE SURE ITS A STRING 415 | POP CX ;[C]=FIELD WIDTH 416 | PUSH CX ;RESAVE [B] 417 | PUSH BX ;SAVE THE TEXT POINTER 418 | MOV BX,FACLO ;GET A POINTER TO THE DESCRIPTOR 419 | MOV CH,CL ;[B]=FIELD WIDTH 420 | MOV CL,LOW 0 ;SET UP FOR "LEFT$" 421 | MOV AL,CH ;GET FIELD WITH IN [A] 422 | PUSH AX ;SAVE THE FIELD WIDTH FOR SPACE PADDING 423 | MOV AL,CH ;SEE IF VARIABLE LENGTH FIELD 424 | OR AL,AL 425 | JZ SHORT ??L012 426 | CALL LEFTUS 427 | ??L012: 428 | CALL STRPRT ;PRINT THE STRING 429 | MOV BX,FACLO ;SEE IF IT NEEDS TO BE PADDED 430 | POP AX ;[A]=FIELD WIDTH 431 | OR AL,AL ;IF FIELD LENGTH IS 0 MUST BE "&" SO 432 | JNZ SHORT ??L013 433 | JMP FNSTRF ;DONT PRINT ANY TRAILING SPACES 434 | ??L013: 435 | SUB AL,BYTE PTR [BX] ;[A]=AMOUNT OF PADDING NEEDED 436 | MOV CH,AL 437 | MOV AL,LOW " " ;SETUP THE PRINT CHARACTER 438 | INC CH ;DUMMY INCREMENT OF NUMBER OF SPACES 439 | UPRTSP: DEC CH ;SEE IF MORE SPACES 440 | JNZ SHORT ??L014 441 | JMP FNSTRF ;NO, GO SEE IF THE VALUE LIST ENDED AND 442 | ??L014: 443 | ;RESUME SCANNING 444 | CALL OUTDO ;PRINT A SPACE 445 | JMP SHORT UPRTSP ;AND LOOP PRINTING THEM 446 | ; 447 | ; WHEN A "+" IS DETECTED IN THE "USING" STRING 448 | ; IF A NUMERIC FIELD FOLLOWS A BIT IN [D] SHOULD 449 | ; BE SET, OTHERWISE "+" SHOULD BE PRINTED. 450 | ; SINCE DECIDING WHETHER A NUMERIC FIELD FOLLOWS IS VERY 451 | ; DIFFICULT, THE BIT IS ALWAYS SET IN [D]. 452 | ; AT THE POINT IT IS DECIDED A CHARACTER IS NOT PART 453 | ; OF A NUMERIC FIELD, THIS ROUTINE IS CALLED TO SEE 454 | ; IF THE BIT IN [D] IS SET, WHICH MEANS 455 | ; A PLUS PRECEDED THE CHARACTER AND SHOULD BE 456 | ; PRINTED. 457 | ; 458 | PLSPRT: PUSH AX ;SAVE THE CURRENT CHARACTER 459 | MOV AL,DH ;CHECK THE PLUS BIT 460 | OR AL,AL ;SINCE IT IS THE ONLY THING THAT COULD 461 | ;BE TURNED ON 462 | MOV AL,LOW "+" ;SETUP TO PRINT THE PLUS 463 | JZ SHORT ??L015 464 | CALL OUTDO ;PRINT IT IF THE BIT WAS SET 465 | ??L015: 466 | POP AX ;GET BACK THE CURRENT CHARACTER 467 | RET 468 | CSEG ENDS 469 | END 470 | -------------------------------------------------------------------------------- /BIPTRG.ASM: -------------------------------------------------------------------------------- 1 | ; [ This translation created 10-Feb-83 by Version 4.3 ] 2 | 3 | .RADIX 8 ; To be safe 4 | 5 | CSEG SEGMENT PUBLIC 'CODESG' 6 | ASSUME CS:CSEG 7 | 8 | INCLUDE OEM.H 9 | 10 | TITLE BIPTRG BASIC Interpreter pointer get routines/WHG/PGA 11 | 12 | .RADIX 10 13 | 14 | PC8A=0 15 | TRSHHC=0 16 | NECPPC=0 17 | OLVPPC=0 18 | 19 | SUBTTL DIMENSION & VARIABLE SEARCHING - PTRGET 20 | 21 | DSEG SEGMENT PUBLIC 'DATASG' ; Data Segment 22 | ASSUME DS:DSEG 23 | EXTRN ARYTA2:WORD,ARYTAB:WORD,DIMFLG:WORD,STREND:WORD 24 | EXTRN SUBFLG:WORD,TEMP2:WORD,TEMP3:WORD,VALTYP:WORD,VARTAB:WORD 25 | EXTRN DSEGZ:WORD 26 | EXTRN NAMBUF:WORD,NAMCNT:WORD,NAMTMP:WORD 27 | EXTRN OPTVAL:WORD 28 | EXTRN PARM1:WORD,PRMFLG:WORD,PRMLEN:WORD,DEFTBL:WORD,NOFUNS:WORD 29 | EXTRN FAC:WORD,FACLO:WORD 30 | DSEG ENDS ; End of data degment externals 31 | 32 | ; Code Segment ( terminated by END at bottom of file ) 33 | 34 | 35 | EXTRN BLTU:NEAR,ERRBS:NEAR,ERROR:NEAR,FCERR:NEAR 36 | EXTRN GETSTK:NEAR,INTIDX:NEAR,ISLET:NEAR,ISLET2:NEAR,OMERR:NEAR 37 | EXTRN REASON:NEAR,SNERR:NEAR 38 | EXTRN REDDY:NEAR,POPHRT:NEAR,ERRDD:NEAR,RETVAR:NEAR,UMULT:NEAR 39 | 40 | EXTRN CHRGTR:NEAR,DCOMPR:NEAR,SYNCHR:NEAR 41 | EXTRN GETYPR:NEAR 42 | EXTRN LOPFD1:NEAR,LOPFND:NEAR 43 | PUBLIC NOTFDD,NOTFNS 44 | 45 | PUBLIC PTRGET,BSERR,PTRGT2,DIM,NOARYS 46 | PAGE 47 | DIMCON: DEC BX ;SEE IF COMMA ENDED THIS VARIABLE 48 | CALL CHRGTR 49 | JNZ SHORT $+3 50 | RET ;IF TERMINATOR, GOOD BYE 51 | CALL SYNCHR 52 | DB OFFSET 44 ;MUST BE COMMA 53 | ; 54 | ; THE "DIM" CODE SETS DIMFLG AND THEN FALLS INTO THE VARIABLE 55 | ; SEARCH ROUTINE. THE VARIABLE SEARCH ROUTINE LOOKS AT 56 | ; DIMFLG AT THREE DIFFERENT POINTS: 57 | ; 58 | ; 1) IF AN ENTRY IS FOUND, DIMFLG BEING ON INDICATES 59 | ; A "DOUBLY DIMENSIONED" VARIABLE 60 | ; 2) WHEN A NEW ENTRY IS BEING BUILT DIMFLG'S BEING ON 61 | ; INDICATES THE INDICES SHOULD BE USED FOR 62 | ; THE SIZE OF EACH INDICE. OTHERWISE THE DEFAULT 63 | ; OF TEN IS USED. 64 | ; 3) WHEN THE BUILD ENTRY CODE FINISHES, ONLY IF DIMFLG IS 65 | ; OFF WILL INDEXING BE DONE 66 | ; 67 | DIM: MOV CX,OFFSET DIMCON ;PLACE TO COME BACK TO 68 | PUSH CX 69 | MOV AL,LOW 200 70 | JMP SHORT PTRGT1 71 | ;MUST TURN THE MSB ON 72 | ; 73 | ; ROUTINE TO READ THE VARIABLE NAME AT THE CURRENT TEXT POSITION 74 | ; AND PUT A POINTER TO ITS VALUE IN [D,E]. [H,L] IS UPDATED 75 | ; TO POINT TO THE CHARACTER AFTER THE VARIABLE NAME. 76 | ; VALTYP IS SETUP. NOTE THAT EVALUATING SUBSCRIPTS IN 77 | ; A VARIABLE NAME CAN CAUSE RECURSIVE CALLS TO PTRGET SO AT 78 | ; THAT POINT ALL VALUES MUST BE STORED ON THE STACK. 79 | ; ON RETURN, [A] DOES NOT REFLECT THE VALUE OF THE TERMINATING CHARACTER 80 | ; 81 | PTRGET: XOR AL,AL ;MAKE [A]=0 82 | PTRGT1: 83 | MOV BYTE PTR DIMFLG,AL ;FLAG IT AS SUCH 84 | MOV CL,BYTE PTR [BX] ;GET FIRST CHARACTER IN [C] 85 | PTRGT2: 86 | CALL ISLET ;CHECK FOR LETTER 87 | JAE SHORT ??L000 88 | JMP SNERR ;MUST HAVE A LETTER 89 | ??L000: 90 | XOR AL,AL 91 | MOV CH,AL ;ASSUME NO SECOND CHARACTER 92 | MOV BYTE PTR NAMCNT,AL ;ZERO NAMCNT 93 | INC BX ;INCRMENT TEXT POINTER 94 | MOV AL,BYTE PTR [BX] ;GET CHAR 95 | CMP AL,LOW "." ;IS IT A DOT? 96 | JB SHORT NOSEC ;TOO SMALL FOR ANYTHING REASONABLE 97 | JZ SHORT ISSEC ;"." IS VALID VAR CHAR 98 | CMP AL,LOW OFFSET "9"+1 ;TOO BIG FOR NUMERIC? 99 | JAE SHORT PTRGT3 ;YES 100 | CMP AL,LOW "0" ;IN RIGHT RANGE? 101 | JAE SHORT ISSEC ;YES, WAS NUMERIC 102 | PTRGT3: CALL ISLET2 ;SET CARRY IF NOT ALPHABETIC 103 | JB SHORT NOSEC ;ALLOW ALPHABETICS 104 | ISSEC: MOV CH,AL ;IT IS A NUMBER--SAVE IN B 105 | PUSH CX ;SAVE [B,C] 106 | MOV CH,LOW 255 ;[B] COUNTS THE CHARACTERS PAST #2 107 | MOV DX,OFFSET NAMBUF-1 ;THE PLACE TO PUT THE CHARACTERS 108 | VMORCH: OR AL,LOW 128D ;EXTRA CHARACTERS MUST HAVE THE HIGH BIT ON 109 | ;SO ERASE CAN SCAN BACKWARDS OVER THEM 110 | INC CH ;INCREASE THE CHACRACTER COUNT 111 | MOV DI,DX 112 | STOSB ;AND STORE INTO THE BUFFER 113 | INC DX ;AND UPDATE THE BUFFER POINTER 114 | INC BX ;INCREMENT TEXT POINTER 115 | MOV AL,BYTE PTR [BX] ;GET CHAR 116 | CMP AL,LOW OFFSET "9"+1 ;TOO BIG? 117 | JAE SHORT VMORC1 ;YES 118 | CMP AL,LOW "0" ;IN RANGE FOR DIGIT 119 | JAE SHORT VMORCH ;YES, VALID CHAR 120 | VMORC1: CALL ISLET2 ;AS ARE ALPHABETICS 121 | JAE SHORT VMORCH 122 | CMP AL,LOW "." ;DOTS ALSO OK 123 | JZ SHORT VMORCH ;SO EAT IT 124 | MOV AL,CH ;CHECK FOR MAXIMUM COUNT 125 | CMP AL,LOW OFFSET NAMLEN-1 ;LIMITED TO SIZE OF NAMBUF ONLY 126 | JNAE SHORT ??L001 127 | JMP SNERR ;MUST BE BAD SYNTAX 128 | ??L001: 129 | POP CX ;GET BACK THE STORED [B,C] 130 | MOV BYTE PTR NAMCNT,AL ;ALWAYS SET UP COUNT OF EXTRAS 131 | MOV AL,BYTE PTR [BX] ;RESTORE TERMINATING CHAR 132 | NOSEC: 133 | CMP AL,LOW OFFSET "%"+1 ;NOT A TYPE INDICATOR 134 | JAE SHORT TABTYP ;THEN DONT CHECK THEM 135 | MOV DX,OFFSET HAVTYP ;SAVE JUMPS BY USING RETURN ADDRESS 136 | PUSH DX 137 | MOV DH,LOW 2 ;CHECK FOR INTEGER 138 | CMP AL,LOW "%" 139 | JNZ SHORT $+3 140 | RET 141 | INC DH ;CHECK FOR STRING 142 | CMP AL,LOW "$" 143 | JNZ SHORT $+3 144 | RET 145 | INC DH ;CHECK FOR SINGLE PRECISION 146 | CMP AL,LOW "!" 147 | JNZ SHORT $+3 148 | RET 149 | MOV DH,LOW 8 ;ASSUME ITS DOUBLE PRECISION 150 | CMP AL,LOW "#" ;CHECK THE CHARACTER 151 | JNZ SHORT $+3 152 | RET ;WHEN WE MATCH, SETUP VALTYP 153 | POP AX ;POP OFF NON-USED HAVTYP ADDRESS 154 | TABTYP: MOV AL,CL ;GET THE STARTING CHARACTER 155 | AND AL,LOW 127 ;GET RID OF THE USER-DEFINED 156 | ;FUNCTION BIT IN [C] 157 | MOV DL,AL ;BUILD A TWO BYTE OFFSET 158 | MOV DH,LOW 0 159 | PUSH BX ;SAVE THE TEXT POINTER 160 | MOV BX,OFFSET DEFTBL-"A" ;SEE WHAT THE DEFAULT IS 161 | ADD BX,DX 162 | MOV DH,BYTE PTR [BX] ;GET THE TYPE OUT OF THE TABLE 163 | POP BX ;GET BACK THE TEXT POINTER 164 | DEC BX ;NO MARKING CHARACTER 165 | HAVTYP: MOV AL,DH ;SETUP VALTYP 166 | MOV BYTE PTR VALTYP,AL 167 | CALL CHRGTR ;READ PAST TYPE MARKER 168 | MOV AL,BYTE PTR SUBFLG ;GET FLAG WHETHER TO ALLOW ARRAYS 169 | DEC AL ;IF SUBFLG=1, "ERASE" HAS CALLED 170 | JNZ SHORT ??L002 171 | JMP ERSFIN ;PTRGET, AND SPECIAL HANDLING MUST BE DONE 172 | ??L002: 173 | JS SHORT ??L003 174 | JMP NOARYS ;NO ARRAYS ALLOWED 175 | ??L003: 176 | MOV AL,BYTE PTR [BX] ;GET CHAR BACK 177 | SUB AL,LOW "(" ;ARRAY PERHAPS (IF SUBFLG SET NEVER WILL MATCH) 178 | JNZ SHORT ??L004 179 | JMP ISARY ;IT IS! 180 | ??L004: 181 | SUB AL,LOW OFFSET "["-")"+1 ;SEE IF LEFT BRACKET 182 | JNZ SHORT ??L005 183 | JMP ISARY ;IF SO, OK SUBSCRIPT 184 | ??L005: 185 | NOARYS: XOR AL,AL ;ALLOW PARENS AGAIN 186 | MOV BYTE PTR SUBFLG,AL ;SAVE IN FLAG LOCATION 187 | PUSH BX ;SAVE THE TEXT POINTER 188 | MOV AL,BYTE PTR NOFUNS ;ARE FUNCTIONS ACTIVE? 189 | OR AL,AL 190 | MOV BYTE PTR PRMFLG,AL ;INDICATE IF PARM1 NEEDS SEARCHING 191 | JZ SHORT SNFUNS ;NO FUNCTIONS SO NO SPECIAL SEARCH 192 | MOV BX,PRMLEN ;GET THE SIZE TO SEARCH 193 | MOV DX,OFFSET PARM1 ;GET THE BASE OF THE SEARCH 194 | ADD BX,DX ;[H,L]= PLACE TO STOP SEARCHING 195 | MOV ARYTA2,BX ;SET UP STOPPING POINT 196 | XCHG BX,DX ;[H,L]=START [D,E]=END 197 | JMP LOPFND 198 | NOTFNS: MOV AL,BYTE PTR PRMFLG ;HAS PARM1 BEEN SEARCHED 199 | OR AL,AL 200 | JZ SHORT SMKVAR ;IF SO, CREATE VARIABLE 201 | XOR AL,AL ;FLAG PARM1 AS SEARCHED 202 | MOV BYTE PTR PRMFLG,AL 203 | SNFUNS: MOV BX,ARYTAB ;STOPPING POINT IS [ARYTA2] 204 | MOV ARYTA2,BX 205 | MOV BX,VARTAB ;SET UP STARTING POINT 206 | JMP LOPFND 207 | 208 | ; THIS ENTRY POINT IS FOR THOSE CALLERS WHO WANT TO RETURN 209 | ; FROM PTRGET WITHOUT CREATING A SYMBOL TABLE ENTRY IF THE 210 | ; VARIABLE IS NOT FOUND IN THE SYMBOL TABLE. PTRGET THEN RETURNS 211 | ; THROUGH VARNOT AND RETURNS WITH [D,E]=0 AND [A]=0 212 | PUBLIC PTRGTN,PTRGTR 213 | PTRGTN: CALL PTRGET ;CALL PTRGET 214 | PTRGTR: RET ;DONT CHANGE THIS SEQUENCE AS RETURN 215 | ;ADDRESS IS CHECKED FOR 216 | 217 | ; THIS IS EXIT FOR VARPTR AND OTHERS 218 | VARNOT: 219 | XOR AL,AL ;MAKE SURE [AL]=0 220 | MOV DH,AL ;ZERO [D,E] 221 | MOV DL,AL 222 | POP CX ;GET RID OF PUSHED [D,E] 223 | POP SI ;XTHL 224 | XCHG SI,BX 225 | PUSH SI ;PUT RETURN ADDRESS BACK ON STACK 226 | RET ;RETURN FROM PTRGET 227 | 228 | SMKVAR: POP BX ;[H,L]= TEXT POINTER 229 | POP SI ;XTHL 230 | XCHG SI,BX 231 | PUSH SI ;[H,L]= RETURN ADDRESS 232 | PUSH DX ;SAVE CURRENT VARIABLE TABLE POSITION 233 | MOV DX,OFFSET PTRGTR ;ARE WE RETURNING TO PTRGTN? 234 | CMP BX,DX ;COMPARE 235 | JZ SHORT VARNOT ;YES. 236 | MOV DX,OFFSET RETVAR ;DID EVAL CALL US? 237 | CMP BX,DX ;IF SO, DON'T MAKE A NEW VARIABLE 238 | POP DX ;RESTORE THE POSITION 239 | JZ SHORT FINZER ;MAKE FAC ZERO (ALL TYPES) AND SKIP RETURN 240 | POP SI ;XTHL 241 | XCHG SI,BX 242 | PUSH SI ;PUT RETURN ADDRESS BACK 243 | PUSH BX ;PUT THE TEXT POINTER BACK 244 | PUSH CX ;SAVE THE LOOKS 245 | MOV AL,BYTE PTR VALTYP ;GET LENGTH OF SYMBOL TABLE ENTRY 246 | MOV CH,AL ;[B]=VALTYP 247 | MOV AL,BYTE PTR NAMCNT ;INCLUDE EXTRA CHARACTERS IN SIZE 248 | ADD AL,CH 249 | INC AL ;AS WELL AS THE EXTRA CHARACTER COUNT 250 | MOV CL,AL ;[B,C]=LENGTH OF THIS VARIABLE 251 | PUSH CX ;SAVE THE VALTYP ON THE STACK 252 | MOV CH,LOW 0 ;[B]=0 253 | INC CX ;MAKE THE LENGTH INCLUDE 254 | ;THE LOOKS TOO 255 | INC CX 256 | INC CX 257 | MOV BX,STREND ;THE CURRENT END OF STORAGE 258 | PUSH BX ;SAVE THIS # 259 | ADD BX,CX ;ADD ON THE AMOUNT OF SPACE 260 | ;EXTRA NOW BEING USED 261 | POP CX ;POP OFF HIGH ADDRESS TO MOVE 262 | PUSH BX ;SAVE NEW CANDIDATE FOR STREND 263 | CALL BLTU ;BLOCK TRANSFER AND MAKE SURE 264 | ;WE ARE NOT OVERFLOWING THE 265 | ;STACK SPACE 266 | POP BX ;[H,L]=NEW STREND 267 | MOV STREND,BX ;STORE SINCE WAS OK 268 | ;THERE WAS ROOM, AND BLOCK TRANSFER 269 | ;WAS DONE, SO UPDATE POINTERS 270 | MOV BX,CX ;GET BACK [H,L] POINTING AT THE END 271 | ;OF THE NEW VARIABLE 272 | MOV ARYTAB,BX ;UPDATE THE ARRAY TABLE POINTER 273 | ZEROER: DEC BX ;[H,L] IS RETURNED POINTING TO THE 274 | MOV BYTE PTR [BX],LOW 0 ;END OF THE VARIABLE SO WE 275 | CMP BX,DX ;ZERO BACKWARDS TO [D,E] WHICH 276 | JNZ SHORT ZEROER ;POINTS TO THE START OF THE VARIABLE 277 | POP DX ;[E]=VALTYP 278 | MOV BYTE PTR [BX],DH ;VALTYP IS IN HIGH ORDER 279 | INC BX 280 | POP DX 281 | MOV [BX],DX 282 | INC BX ;PUT DESCRIPTION OF THIS VARIABLE 283 | ;INTO MEMORY 284 | CALL NPUTSB ;SAVE THE EXTRA CHARACTERS IN THE NAME 285 | XCHG BX,DX ;POINTER AT VARIABLE INTO [D,E] 286 | INC DX ;POINT AT THE VALUE 287 | POP BX ;RESTORE THE TEXT POINTER 288 | RET 289 | ; 290 | ; MAKE ALL TYPES ZERO AND SKIP RETURN 291 | ; 292 | FINZER: 293 | EXTRN $DZERO:NEAR 294 | CALL $DZERO ;Really clear the entire FAC since 295 | ;the 8086 math package doesn't 296 | ;treat a number as zero just because 297 | ;its exponent is zero like to 8080 298 | ;math package does. 299 | CALL GETYPR ;SEE IF ITS A STRING 300 | JNZ SHORT POPHR2 ;IF NOT, DONE 301 | MOV BX,OFFSET DSEGZ ;ZERO IN THE DATA SEGMENT 302 | MOV FACLO,BX ;POINTING AT A ZERO 303 | POPHR2: POP BX ;GET THE TEXT POINTER 304 | RET ;RETURN FROM EVAL 305 | 306 | 307 | PAGE 308 | SUBTTL MULTIPLE DIMENSION CODE 309 | 310 | ; 311 | ; FORMAT OF ARRAYS IN CORE 312 | ; 313 | ; DESCRIPTOR 314 | ; LOW BYTE = SECOND CHARCTER (200 BIT IS STRING FLAG) 315 | ; HIGH BYTE = FIRST CHARACTER 316 | ; LENGTH OF ARRAY IN CORE IN BYTES (DOES NOT INCLUDE DESCRIPTOR) 317 | ; NUMBER OF DIMENSIONS 1 BYTE 318 | ; FOR EACH DIMENSION STARTING WITH THE FIRST A LIST 319 | ; (2 BYTES EACH) OF THE MAX INDICE+1 320 | ; THE VALUES 321 | ; 322 | ISARY: PUSH BX ;SAVE DIMFLG AND VALTYP FOR RECURSION 323 | MOV BX,DIMFLG 324 | POP SI ;XTHL 325 | XCHG SI,BX 326 | PUSH SI ;TEXT POINTER BACK INTO [H,L] 327 | MOV DH,AL ;SET # DIMENSIONS =0 328 | DSEG SEGMENT PUBLIC 'DATASG' 329 | EXTRN SARYFL:WORD 330 | DSEG ENDS 331 | DEC AL ;SARYFL=^O377 - tells CALL that array element 332 | MOV BYTE PTR SARYFL,AL ;has been scanned. 333 | INDLOP: PUSH DX ;SAVE NUMBER OF DIMENSIONS 334 | PUSH CX ;SAVE LOOKS 335 | MOV DX,OFFSET NAMCNT ;POINT AT THE AREA TO SAVE 336 | MOV SI,DX 337 | MOV AL,[SI] ;GET LENGTH 338 | OR AL,AL ;IS IT ZERO? 339 | JZ SHORT SHTNAM ;YES, SHORT NAME 340 | XCHG BX,DX ;SAVE THE TEXT POINTER IN [D,E] 341 | ADD AL,LOW 2 ;WE WANT SMALLEST INT .GE.(NAMCNT+1)/2 342 | RCR AL,1 343 | MOV CL,AL ;SEE IF THERE IS ROOM TO SAVE THIS STUFF 344 | CALL GETSTK 345 | MOV AL,CL ;RESTORE COUNT OF PUSHES 346 | LPPSNM: MOV CL,BYTE PTR [BX] ;GET VALUES TO PUSH 347 | INC BX 348 | MOV CH,BYTE PTR [BX] 349 | INC BX 350 | PUSH CX ;AND DO THE SAVE 351 | DEC AL ;[A] TIMES 352 | JNZ SHORT LPPSNM 353 | PUSH BX ;SAVE THE ADDRESS TO STORE TO 354 | MOV AL,BYTE PTR NAMCNT ;SAVE THE NUMBER OF BYTES FOR A COUNT 355 | PUSH AX 356 | XCHG BX,DX ;RESTORE THE TEXT POINTER 357 | CALL INTIDX ;EVALUATE INDICE INTO [D,E] 358 | POP AX ;COUNT TELLING HOW MUCH TO RESTORE 359 | MOV NAMTMP,BX ;SAVE THE TEXT POINTER 360 | POP BX ;THE PLACE TO RESTORE TO 361 | ADD AL,LOW 2 ;CALCULATE BYTE POPS AGAIN 362 | RCR AL,1 363 | LPLNAM: POP CX 364 | DEC BX 365 | MOV BYTE PTR [BX],CH 366 | DEC BX 367 | MOV BYTE PTR [BX],CL 368 | DEC AL ;LOOP [A] TIMES POPING NAME BACK INTO NAMBUF 369 | JNZ SHORT LPLNAM 370 | MOV BX,NAMTMP 371 | JMP SHORT LNGNAM ;WAS LONG ONE 372 | SHTNAM: CALL INTIDX ;EVALUATE IT 373 | XOR AL,AL ;MAKE SURE NAMCNT=0 374 | MOV BYTE PTR NAMCNT,AL 375 | LNGNAM: 376 | MOV AL,BYTE PTR OPTVAL ;SEE WHAT THE OPTION BASE IS 377 | OR AL,AL 378 | JZ SHORT OPTB0 ;IF BASE 0 DO NOTHING 379 | OR DX,DX ;CHECK FOR 0 SUBSCRIPT 380 | ;WHICH IS ILLEGAL IN BASE 1 381 | JNZ SHORT ??L006 382 | JMP BSERR 383 | ??L006: 384 | DEC DX ;ADJUST SUBSCRIPT 385 | OPTB0: 386 | POP CX ;POP OFF THE LOOKS 387 | POP AX ; POP PSW 388 | XCHG AL,AH 389 | SAHF ;[A] = NUMBER OF DIMENSIONS SO FAR 390 | XCHG BX,DX ;[D,E]=TEXT POINTER 391 | ;[H,L]=INDICE 392 | POP SI ;XTHL 393 | XCHG SI,BX 394 | PUSH SI ;PUT THE INDICE ON THE STACK 395 | ;[H,L]=VALTYP & DIMFLG 396 | PUSH BX ;RESAVE VALTYP AND DIMFLG 397 | XCHG BX,DX ;[H,L]=TEXT POINTER 398 | INC AL ;INCREMENT # OF DIMENSIONS 399 | MOV DH,AL ;[D]=NUMBER OF DIMENSIONS 400 | MOV AL,BYTE PTR [BX] ;GET TERMINATING CHARACTER 401 | CMP AL,LOW 44 ;A COMMA SO MORE INDICES FOLLOW? 402 | JNZ SHORT ??L007 403 | JMP INDLOP ;IF SO, READ MORE 404 | ??L007: 405 | CMP AL,LOW ")" ;EXPECTED TERMINATOR? 406 | JZ SHORT DOCHRT ;DO CHRGET FOR NEXT ONE 407 | CMP AL,LOW "]" ;BRACKET? 408 | JZ SHORT ??L008 409 | JMP SNERR ;NO, GIVE ERROR 410 | ??L008: 411 | DOCHRT: CALL CHRGTR 412 | SUBSOK: MOV TEMP2,BX ;SAVE THE TEXT POINTER 413 | POP BX ;[H,L]= VALTYP & DIMFLG 414 | MOV DIMFLG,BX ;SAVE VALTYP AND DIMFLG 415 | MOV DL,LOW 0 ;WHEN [D,E] IS POPED INTO PSW, WE 416 | ;DON'T WANT THE ZERO FLAG TO BE SET, SO 417 | ;"ERASE" WILL HAVE A UNIQUE CONDITION 418 | PUSH DX ;SAVE NUMBER OF DIMENSIONS 419 | PUBLIC ERSFIN 420 | JMP SHORT LOPFD0 421 | ERSFIN: PUSH BX ;SAVE THE TEXT POINTER 422 | LAHF ; PUSH PSW 423 | XCHG AL,AH 424 | PUSH AX 425 | XCHG AL,AH ;SAVE A DUMMY NUMBER OF DIMENSIONS 426 | ;WITH THE ZERO FLAG SET 427 | LOPFD0: 428 | ; 429 | ; AT THIS POINT [B,C]=LOOKS. THE TEXT POINTER IS IN TEMP2. 430 | ; THE INDICES ARE ALL ON THE STACK, FOLLOWED BY THE NUMBER OF DIMENSIONS. 431 | ; 432 | MOV BX,ARYTAB ;[H,L]=PLACE TO START THE SEARCH 433 | JMP LOPFD1 434 | PUBLIC ARYEXT 435 | ARYEXT: 436 | ;AND TRY AGAIN 437 | MOV AL,BYTE PTR DIMFLG ;SEE IF CALLED BY "DIM" 438 | OR AL,AL ;ZERO MEANS NO 439 | EXTRN DDERR:NEAR 440 | JZ SHORT ??L009 441 | JMP DDERR ;PRESERVE [D,E], AND DISPATCH TO 442 | ??L009: 443 | ;"REDIMENSIONED VARIABLE" ERROR 444 | ;IF ITS "DIM" CALLING PTRGET 445 | ; 446 | ; TEMP2=THE TEXT POINTER 447 | ; WE HAVE LOCATED THE VARIABLE WE WERE LOOKING FOR 448 | ; AT THIS POINT [H,L] POINTS BEYOND THE SIZE TO THE NUMBER OF DIMENSIONS 449 | ; THE INDICES ARE ON THE STACK FOLLOWED BY THE NUMBER OF DIMENSIONS 450 | ; 451 | POP AX ; POP PSW 452 | XCHG AL,AH 453 | SAHF ;[A]=NUMBER OF DIMENSIONS 454 | MOV CX,BX ;SET [B,C] TO POINT AT NUMBER OF DIMENSIONS 455 | JNZ SHORT ??L010 456 | JMP POPHRT ;"ERASE" IS DONE AT THIS POINT, SO RETURN 457 | ??L010: 458 | ;TO DO THE ACTUAL ERASURE 459 | SUB AL,BYTE PTR [BX] ;MAKE SURE THE NUMBER GIVEN NOW AND 460 | ;AND WHEN THE ARRAY WAS SET UP ARE THE 461 | ;SAME 462 | JNZ SHORT ??L011 463 | JMP GETDEF ;JUMP OFF AND READ 464 | ??L011: 465 | ;THE INDICES.... 466 | 467 | BSERR: MOV DX,OFFSET ERRBS ;"SUBSCRIPT OUT OF RANGE" 468 | JMP ERROR 469 | ; 470 | ; HERE WHEN VARIABLE IS NOT FOUND IN THE ARRAY TABLE 471 | ; 472 | ; BUILDING AN ENTRY: 473 | ; 474 | ; PUT DOWN THE DESCRIPTOR 475 | ; SETUP NUMER OF DIMENSIONS 476 | ; MAKE SURE THERE IS ROOM FOR THE NEW ENTRY 477 | ; REMEMBER VARPTR 478 | ; TALLY=4 (VALTYP FOR THE EXTENDED) 479 | ; SKIP 2 LOCS FOR LATER FILL IN -- THE SIZE 480 | ; LOOP: GET AN INDICE 481 | ; PUT NUMBER +1 DOWN AT VARPTR AND INCREMENT VARPTR 482 | ; TALLY= TALLY * NUMBER+1 483 | ; DECREMENT NUMBER-DIMS 484 | ; JNZ LOOP 485 | ; CALL REASON WITH [H,L] REFLECTING LAST LOC OF VARIABLE 486 | ; UPDATE STREND 487 | ; ZERO BACKWARDS 488 | ; MAKE TALLY INCLUDE MAXDIMS 489 | ; PUT DOWN TALLY 490 | ; IF CALLED BY DIMENSION, RETURN 491 | ; OTHERWISE INDEX INTO THE VARIABLE AS IF IT 492 | ; WERE FOUND ON THE INITIAL SEARCH 493 | ; 494 | NOTFDD: 495 | MOV AL,BYTE PTR VALTYP ;GET VALTYP OF NEW VAR 496 | MOV BYTE PTR [BX],AL ;PUT DOWN THE VARIABLE TYPE 497 | INC BX 498 | MOV DL,AL 499 | MOV DH,LOW 0 ;[D,E]=SIZE OF ONE VALUE (VALTYP) 500 | POP AX ; POP PSW 501 | XCHG AL,AH 502 | SAHF ;[A]=NUMBER OF DIMENSIONS 503 | JNZ SHORT ??L012 504 | JMP PTRRNZ ;CALLED BY CHAIN, JUST RETURN NON-ZERO 505 | ??L012: 506 | MOV BYTE PTR [BX],CL ;PUT DOWN THE DESCRIPTOR 507 | INC BX 508 | MOV BYTE PTR [BX],CH 509 | CALL NPUTSB ;STORE THE EXTRA CHARACTERS IN THE TABLE 510 | INC BX 511 | MOV CL,AL ;[C]=NUMBER OF TWO BYTE ENTRIES NEEDED 512 | ;TO STORE THE SIZE OF EACH DIMENSION 513 | CALL GETSTK ;GET SPACE FOR DIMENSION ENTRIES 514 | INC BX ;SKIP OVER THE SIZE LOCATIONS 515 | INC BX 516 | MOV TEMP3,BX ;SAVE THE LOCATION TO PUT THE SIZE 517 | ;IN -- POINTS AT THE NUMBER OF DIMENSIONS 518 | MOV BYTE PTR [BX],CL ;STORE THE NUMBER OF DIMENSIONS 519 | INC BX 520 | MOV AL,BYTE PTR DIMFLG ;CALLED BY DIMENSION? 521 | RCL AL,1 ;SET CARRY IF SO 522 | MOV AL,CL ;[A]=NUMBER OF DIMENSIONS 523 | LOPPTA: 524 | JB SHORT POPDIM 525 | LAHF 526 | PUSH AX 527 | MOV AL,BYTE PTR OPTVAL ;GET THE OPTION BASE 528 | XOR AL,LOW 11 ;MAP 0 TO 11 AND 1 TO 10 529 | MOV CL,AL ;[B,C]=DEFAULT DIMENSION 530 | MOV CH,LOW 0 531 | POP AX 532 | SAHF 533 | JAE SHORT NOTDIM ;DEFAULT DIMENSIONS TO TEN 534 | POPDIM: POP CX ;POP OFF AN INDICE INTO [B,C] 535 | LAHF 536 | INC CX ;ADD ONE TO IT FOR THE ZERO ENTRY 537 | SAHF 538 | NOTDIM: MOV BYTE PTR [BX],CL ;PUT THE MAXIMUM DOWN 539 | LAHF 540 | PUSH AX ;SAVE THE NUMBER OF DIMENSIONS AND 541 | ;DIMFLG (CARRY) 542 | INC BX 543 | MOV BYTE PTR [BX],CH 544 | INC BX 545 | CALL UMULT ;MULTIPLY [B,C]=NEWMAX BY CURTOL=[D,E] 546 | POP AX 547 | SAHF ;GET THE NUMBER OF DIMENSIONS AND 548 | ;DIMFLG (CARRY) BACK 549 | DEC AL ;DECREMENT THE NUMBER OF DIMENSIONS LEFT 550 | JNZ SHORT LOPPTA ;HANDLE THE OTHER INDICES 551 | LAHF 552 | PUSH AX ;SAVE DIMFLG (CARRY) 553 | MOV CH,DH ;[B,C]=SIZE 554 | MOV CL,DL 555 | XCHG BX,DX ;[D,E]=START OF VALUES 556 | ADD BX,DX ;[H,L]=END OF VALUES 557 | JAE SHORT ??L013 558 | JMP OMERR ;OUT OF MEMORY POINTER BEING GENERATED? 559 | ??L013: 560 | CALL REASON ;SEE IF THERE IS ROOM FOR THE VALUES 561 | MOV STREND,BX ;UPDATE THE END OF STORAGE 562 | ZERITA: DEC BX ;ZERO THE NEW ARRAY 563 | MOV BYTE PTR [BX],LOW 0 564 | CMP BX,DX ;BACK AT THE BEGINNING? 565 | JNZ SHORT ZERITA ;NO, ZERO MORE 566 | XOR AL,AL ;MAKE SURE [AL]=0 567 | INC CX ;ADD ONE TO THE SIZE TO INCLUDE 568 | ;THE BYTE FOR THE NUMBER OF DIMENSIONS 569 | MOV DH,AL ;[D]=ZERO 570 | MOV BX,TEMP3 ;GET A POINTER AT THE NUMBER OF DIMENSIONS 571 | MOV DL,BYTE PTR [BX] ;[E]=NUMBER OF DIMENSIONS 572 | XCHG BX,DX ;[H,L]=NUMBER OF DIMENSIONS 573 | ADD BX,BX ;[H,L]=NUMBER OF DIMENSIONS TIMES TWO 574 | ADD BX,CX ;ADD ON THE SIZE 575 | ;TO GET THE TOTAL NUMBER OF BYTES USED 576 | XCHG BX,DX ;[D,E]=TOTAL SIZE 577 | DEC BX ;BACK UP TO POINT TO LOCATION TO PUT 578 | DEC BX ;THE SIZE OF THE ARRAY IN BYTES IN. 579 | MOV [BX],DX 580 | INC BX 581 | INC BX ;PUT DOWN THE SIZE 582 | POP AX 583 | SAHF ;GET BACK DIMFLG (CARRY) AND SET [A]=0 584 | JB SHORT FINNOW 585 | ; 586 | ; AT THIS POINT [H,L] POINTS BEYOND THE SIZE TO THE NUMBER OF DIMENSIONS 587 | ; STRATEGY: 588 | ; NUMDIM=NUMBER OF DIMENSIONS 589 | ; CURTOL=0 590 | ; INLPNM:GET A NEW INDICE 591 | ; POP NEW MAX INTO CURMAX 592 | ; MAKE SURE INDICE IS NOT TOO BIG 593 | ; MUTLIPLY CURTOL BY CURMAX 594 | ; ADD INDICE TO CURTOL 595 | ; NUMDIM=NUMDIM-1 596 | ; JNZ INLPNM 597 | ; USE CURTOL*4 (VALTYP FOR EXTENDED) AS OFFSET 598 | ; 599 | GETDEF: MOV CH,AL ;[B,C]=CURTOL=ZERO 600 | MOV CL,AL 601 | MOV AL,BYTE PTR [BX] ;[A]=NUMBER OF DIMENSIONS 602 | INC BX ;POINT PAST THE NUMBER OF DIMENSIONS 603 | DB 266O ; SKIP ;"MVI D," AROUND THE NEXT BYTE 604 | INLPNM: POP BX ;[H,L]= POINTER INTO VARIABLE ENTRY 605 | MOV DX,[BX] ;[D,E]=MAXIMUM FOR THE CURRENT INDICE 606 | INC BX 607 | INC BX 608 | POP SI ;XTHL 609 | XCHG SI,BX 610 | PUSH SI ;[H,L]=CURRENT INDICE 611 | ;POINTER INTO THE VARIABLE GOES ON THE STACK 612 | PUSH AX ;SAVE THE NUMBER OF DIMENSIONS 613 | CMP BX,DX ;SEE IF THE CURRENT INDICE IS TOO BIG 614 | JNAE SHORT ??L014 615 | JMP BSERR ;IF SO "BAD SUBSCRIPT" ERROR 616 | ??L014: 617 | CALL UMULT ;CURTOL=CURTOL*CURRENT MAXIMUM 618 | ADD BX,DX ;ADD THE INDICE TO CURTOL 619 | POP AX ;GET THE NUMBER OF DIMENSIONS IN [A] 620 | DEC AL ;SEE IF ALL THE INDICES HAVE BEEN PROCESSED 621 | MOV CX,BX ;[B,C]=CURTOL IN CASE WE LOOP BACK 622 | JNZ SHORT INLPNM ;PROCESS THE REST OF THE INDICES 623 | MOV AL,BYTE PTR VALTYP ;SEE HOW BIG THE VALUES ARE 624 | ;AND MULTIPLY BY THAT SIZE 625 | MOV CX,BX ;SAVE THE ORIGINAL VALUE FOR MULTIPLYING 626 | ;BY THREE 627 | ADD BX,BX ;MULTIPLY BY TWO AT LEAST 628 | SUB AL,LOW 4 ;FOR INTEGERS AND STRINGS 629 | ;NO MORE MULTIPLYING BY TWO 630 | JB SHORT SMLVAL 631 | ADD BX,BX ;NOW MULTIPLIED BY FOUR 632 | OR AL,AL ;RE-GEN CONDITION CODES 633 | JZ SHORT DONMUL ;IF SINGLE ALL DONE 634 | ADD BX,BX ;BY EIGHT FOR DOUBLES 635 | SMLVAL: 636 | OR AL,AL ;FIX CC'S FOR Z-80 637 | JP SHORT ??L015 638 | JMP DONMUL ;FOR STRINGS 639 | ??L015: 640 | ADD BX,CX ;ADD IN THE ORIGINAL 641 | DONMUL: 642 | POP CX ;POP OFF THE ADDRESS OF WHERE THE VALUES 643 | ;BEGIN 644 | ADD BX,CX ;ADD IT ONTO CURTOL TO GET THE 645 | ;PLACE THE VALUE IS STORED 646 | XCHG BX,DX ;RETURN THE POINTER IN [D,E] 647 | FINNOW: MOV BX,TEMP2 ;REGET THE TEXT POINTER 648 | RET 649 | PTRRNZ: STC ;RETURN WITH NON-ZERO IN [A] 650 | SBB AL,AL ;AND CONDITION CODES SET 651 | POP BX ;RESTORE TEST POINTER 652 | RET 653 | 654 | ; 655 | ; LONG VARIABLE NAME SUBROUTINES. AFTER THE NORMAL 2 CHARACTER NAME 656 | ; THE COUNT OF ADDITIONAL CHARACTERS IS STORED. FOLLOWING THIS 657 | ; COMES THE CHARACTFRS IN ORDER WITH THE HIGH BIT TURNED ON SO A BACKWARD 658 | ; SCAN IS POSSIBLE 659 | ; 660 | PUBLIC IADAHL 661 | IADAHL: MOV AL,BYTE PTR [BX] ;GET THE CHARACTER COUNT 662 | INC BX 663 | ADDAHL: PUSH CX ;ADD [A] TO [H,L] 664 | MOV CH,LOW 0 665 | MOV CL,AL 666 | ADD BX,CX 667 | POP CX ;RESTORE THE SAVED [B,C] 668 | RET 669 | NPUTSB: PUSH CX ;THIS ROUTINE STORE THE "LONG" NAME AT [H,L] 670 | PUSH DX 671 | LAHF 672 | PUSH AX 673 | MOV DX,OFFSET NAMCNT ;POINT AT DATA TO SAVE 674 | MOV SI,DX 675 | MOV AL,[SI] ;GET THE COUNT 676 | MOV CH,AL 677 | INC CH ;[B]= NUMBER OF BYTES TO SAVE 678 | SLPLNG: MOV SI,DX 679 | MOV AL,[SI] ;FETCH STORE VALUE 680 | INC DX 681 | INC BX ;MOVE UP TO STORE NAME INTO TABLE 682 | MOV BYTE PTR [BX],AL ;DO THE STORE 683 | DEC CH ;AND REPEAT [B] TIMES 684 | JNZ SHORT SLPLNG ;FOR THE COUNT AND DATA 685 | POP AX 686 | SAHF 687 | POP DX 688 | POP CX 689 | RET 690 | 691 | PAGE 692 | CSEG ENDS 693 | END 694 | -------------------------------------------------------------------------------- /CALL86.ASM: -------------------------------------------------------------------------------- 1 | ; [ This translation created 10-Feb-83 by Version 4.3 ] 2 | 3 | .RADIX 8 ; To be safe 4 | 5 | CSEG SEGMENT PUBLIC 'CODESG' 6 | ASSUME CS:CSEG 7 | 8 | INCLUDE OEM.H 9 | 10 | TITLE CALL86 8086 CALL Statement 11 | .SALL 12 | .RADIX 8 13 | 14 | 15 | EXTRN VMOVFM:NEAR,FRQINT:NEAR,PTRGET:NEAR,GETSTK:NEAR 16 | EXTRN CHRGTR:NEAR,SYNCHR:NEAR,CHRGT2:NEAR,FCERR:NEAR 17 | DSEG SEGMENT PUBLIC 'DATASG' 18 | ASSUME DS:DSEG 19 | EXTRN SUBFLG:WORD,SARYFL:WORD,TEMP:WORD,TEMPA:WORD,SAVSEG:WORD 20 | EXTRN ARYTAB:WORD 21 | DSEG ENDS 22 | 23 | ; This is the CALL [([,]..)] 24 | ; Stragegy: 25 | ; 26 | ; 1.) Make sure suboutine name is simple var, get value & save it 27 | ; 28 | ; 2.) Evaluate params & stuff pointers on stack 29 | ; 30 | ; 3.) CALL suboutine with return address on stack 31 | ; 32 | ; The CALLS statement is the same as CALL, except for each parameter 33 | ; it pushes Segment and Offset, not just Offset. 34 | 35 | PUBLIC CALLS,CALLSL 36 | 37 | CALLSL: CLC ;Clear-carry, (PUSH Segment adr of parms) 38 | JMP SHORT CALLS1 39 | CALLS: STC ;Set-carry, (don't PUSH Segment adr of parms) 40 | CALLS1: PUSHF 41 | EXTRN PRODIR:NEAR ;Don't allow CALL as direct statement in 42 | CALL PRODIR ;protected environment 43 | MOV BYTE PTR SUBFLG,LOW 200O ;say we want to scan only a simple 44 | CALL PTRGET ;scan var and search symbol table 45 | MOV BYTE PTR SARYFL,LOW 0 ;clear Scanned-Array-Element-Flag 46 | PUSH BX ;save text pointer 47 | MOV BX,DX ;get pointer to var in BX 48 | CALL VMOVFM ;load variable into FAC 49 | CALL FRQINT ;make it an integer 50 | MOV WORD PTR TEMPA,BX ;save text pointer 51 | MOV CL,LOW 32D ;get max # of parameters 52 | CALL GETSTK ;see if there is that much stack space 53 | POP BX ;get back text pointer 54 | CALL CHRGT2 ;eat character after var name 55 | JZ CALLST ;end of statement, no parameter list 56 | CALL SYNCHR ;check for open paren 57 | DB 50O ; ( 58 | GETPAR: PUSH WORD PTR ARYTAB ;save pointer to start of array var data 59 | CALL PTRGET ;scan parameter variable 60 | POP CX ;[CX]=old value of ARYTAB 61 | CMP CX,WORD PTR ARYTAB ;if = old, no undefined simples were referenced 62 | JE NONEWS ;Branch if New Simple Var not encountered 63 | CMP BYTE PTR SARYFL,LOW 0 ;Z-FLAG if no Array elements have been parsed 64 | ; by PTRGET 65 | JZ NONEWS 66 | JMP FCERR ;Undefined scalers can't be passed after array 67 | ;elements since the addr of the array element 68 | ;changes when the new scaler is added. 69 | NONEWS: POPF ;restore Carry=CALL/CALLS flag 70 | JB SHTPRM ;Branch if CALL (not CALLS) 71 | PUSH DS ;save Segment of Parameter on stack 72 | SHTPRM: PUSH DX ;save Offset of parameter on stack 73 | PUSHF ;re-save CALL/CALLS flag 74 | MOV AL,BYTE PTR 0[BX] ;get terminator 75 | CMP AL,LOW "," ;comma? 76 | JNZ ENDPAR ;no, must be end of the param list 77 | CALL CHRGTR ;scan next char 78 | JMP SHORT GETPAR ;scan next parm 79 | ENDPAR: CALL SYNCHR ;check for terminating right paren 80 | DB 51O ; ) 81 | CALLST: MOV WORD PTR TEMP,BX ;save text pointer 82 | POPF ;discard CALL/CALLS flag 83 | PUSH CS ;save BASIC code segment 84 | MOV AX,OFFSET CALLRT ;where to return to 85 | PUSH AX 86 | PUSH WORD PTR SAVSEG ;save subroutine segment 87 | PUSH WORD PTR TEMPA ;save subroutine address 88 | DB 313O ; Do a long return to call the subroutine 89 | ; 90 | CALLRT: MOV BX,WORD PTR TEMP ;get back text pointer 91 | RET ;return to newstt 92 | ; 93 | CSEG ENDS 94 | END 95 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Microsoft GW-BASIC Interpreter Contributor Guidance 2 | 3 | The files in this repo are for historical reference only and will remain read-only and unmodified in their original state. 4 | 5 | Please **do not** send Pull Requests suggesting any modifications to the source files. 6 | -------------------------------------------------------------------------------- /GENGRP.ASM: -------------------------------------------------------------------------------- 1 | ; [ This translation created 10-Feb-83 by Version 4.3 ] 2 | 3 | .RADIX 8 ; To be safe 4 | 5 | CSEG SEGMENT PUBLIC 'CODESG' 6 | ASSUME CS:CSEG 7 | 8 | INCLUDE OEM.H 9 | 10 | TITLE GENGRP GENERALIZED GRAPHICS /WHG 11 | 12 | .RADIX 10 13 | 14 | CLIPPL=0 15 | WINDOW=0 16 | VIEW=0 17 | TILE=0 18 | HAL=0 19 | PC8A=0 20 | MODEL3=0 21 | TSHIBA=0 22 | ALPCPM=0 23 | HALL4=0 24 | CLIPPL=PC8A OR TRSER2 OR MODEL3 25 | WINDOW=PC8A 26 | VIEW=PC8A OR TRSER2 OR MODEL3 27 | LINEST=0 ;LINE STYLE SWITCH 28 | LINEST=PC8A OR TRSER2 OR MODEL3 29 | ; 30 | ; SYSTEM DEPENDENT SWITCHES: 31 | ; 32 | 33 | COMMENT * 34 | 35 | THESE ARE THE GENERAL GRAPHICS ROUTINES THAT ASSUME THE "MACHINE 36 | INDEPENDENT" GRAPHICS INTERFACE. THEY DEAL WITHIN A 16-BIT 37 | GRAPHICS COORDINATE SYSTEM FOR BOTH X AND Y. ATTRIBUTES RANGE FROM 38 | 0 TO 255. 39 | 40 | * 41 | ; 42 | ; THESE ARE THE RAM LOCATIONS REQUIRED TO SUPPORT THIS PACKAGE 43 | ; NOTE THAT ALL OF THESE ARE LOCAL TO THIS CODE EXCEPT 44 | ; FORCLR AND BAKCLR WHICH NEED TO BE SET UP BY THE MACHINE DEPENDENT 45 | ; CODE EITHER AS CONSTANTS OR THROUGH A COLOR TYPE COMMAND 46 | ; NOTE THAT MAXUPD AND MINUPD ARE 3 BYTE CELLS WITH A JMP IN THE 47 | ; FIRST BYTE TO BE SET UP BY GRFINI OR INITIALIZED AT STARTUP 48 | ; 49 | ;In GW versions, GETFBC is the OEM interface 50 | EXTRN GETFBC:NEAR ;for FORCLR and BAKCLR (OEM vars) 51 | EXTRN PIXSIZ:NEAR ;Get bits/pixel (0=no graphics available) 52 | DSEG SEGMENT PUBLIC 'DATASG' 53 | ASSUME DS:DSEG 54 | EXTRN GXPOS:WORD,GYPOS:WORD 55 | DSEG ENDS 56 | DSEG SEGMENT PUBLIC 'DATASG' 57 | EXTRN GRPACX:WORD,GRPACY:WORD 58 | DSEG ENDS 59 | DSEG SEGMENT PUBLIC 'DATASG' 60 | EXTRN MAXDEL:WORD,MINDEL:WORD,MINUPD:WORD,MAXUPD:WORD 61 | DSEG ENDS 62 | DSEG SEGMENT PUBLIC 'DATASG' 63 | EXTRN ATRBYT:WORD ;External form of the current attribute 64 | DSEG ENDS 65 | ; used by PAINT for default 66 | ; 67 | ; THESE ARE THE ROUTINES CALLED INSIDE THE BASIC INTERPRETER 68 | ; AND THE SYNTAX TOKEN DEFINITIONS REFERENCED 69 | ; 70 | EXTRN GETIN2:NEAR,GETBYT:NEAR,CHRGTR:NEAR,$STEP:NEAR,FCERR:NEAR 71 | EXTRN CHRGT2:NEAR 72 | EXTRN MINUTK:NEAR 73 | EXTRN SYNCHR:NEAR 74 | ; 75 | PUBLIC HLFDE,SCAND,ATRSCN,SCAN1,DOGRPH,XCHGX,XCHGY,XDELT,YDELT 76 | ; THESE ARE THE ENTRY POINTS INTO THE MACHINE DEPENDENT GRAPHICS 77 | ; ROUTINES. THEY FOLLOW STANDARD CONVENTIONS TO AVOID MODIFICATIONS 78 | ; TO CODE IN THIS PACKAGE FOR SPECIFIC IMPLEMENTATIONS 79 | ; 80 | EXTRN SCALXY:NEAR,MAPXYC:NEAR,UPC:NEAR,DOWNC:NEAR,LEFTC:NEAR 81 | EXTRN RIGHTC:NEAR 82 | EXTRN READC:NEAR,SETATR:NEAR,NSETCX:NEAR 83 | EXTRN FETCHC:NEAR,STOREC:NEAR,SETC:NEAR 84 | 85 | PAGE 86 | SUBTTL SCAN A COORDINATE - SCAN1 AND SCAND 87 | 88 | ; 89 | ; ALLOW A COORDINATE OF THE FORM (X,Y) OR STEP(X,Y) 90 | ; THE LATTER IS RELATIVE TO THE GRAPHICS AC. 91 | ; THE GRAPHICS AC IS UPDATED WITH THE NEW VALUE 92 | ; RESULT IS RETURNED WITH [B,C]=X AND [D,E]=Y 93 | ; CALL SCAN1 TO GET FIRST IN A SET OF TWO PAIRS SINCE IT ALLOWS 94 | ; A NULL ARGUMENT TO IMPLY THE CURRENT AC VALUE AND 95 | ; IT WILL SKIP A "@" IF ONE IS PRESENT 96 | ; 97 | SCAN1: MOV AL,BYTE PTR [BX] ;GET THE CURRENT CHARACTER 98 | CMP AL,LOW "@" ;ALLOW MEANINGLESS "@" 99 | JNZ SHORT ??L000 100 | CALL CHRGTR ;BY SKIPPING OVER IT 101 | ??L000: 102 | MOV CX,0 ;ASSUME NO COODINATES AT ALL (-SECOND) 103 | MOV DH,CH 104 | MOV DL,CL 105 | CMP AL,LOW OFFSET MINUTK ;SEE IF ITS SAME AS PREVIOUS 106 | JZ SHORT SCANN ;USE GRAPHICS ACCUMULATOR 107 | ; 108 | ; THE STANDARD ENTRY POINT 109 | ; 110 | SCAND: MOV AL,BYTE PTR [BX] ;GET THE CURRENT CHARACTER 111 | CMP AL,LOW OFFSET $STEP ;IS IT RELATIVE? 112 | PUSHF ;REMEMBER 113 | JNZ SHORT ??L001 114 | CALL CHRGTR ;SKIP OVER $STEP TOKEN 115 | ??L001: 116 | CALL SYNCHR 117 | DB OFFSET "(" ;SKIP OVER OPEN PAREN 118 | CALL GETIN2 ;SCAN X INTO [D,E] 119 | PUSH DX ;SAVE WHILE SCANNING Y 120 | CALL SYNCHR 121 | DB OFFSET 44D ;SCAN COMMA 122 | CALL GETIN2 ;GET Y INTO [D,E] 123 | CALL SYNCHR 124 | DB OFFSET ")" 125 | POP CX ;GET BACK X INTO [B,C] 126 | POPF ;RECALL IF RELATIVE OR NOT 127 | SCANN: PUSH BX ;SAVE TEXT POINTER 128 | MOV BX,GRPACX ;GET OLD POSITION 129 | JZ SHORT SCXREL ;IF ZERO,RELATIVE SO USE OLD BASE 130 | MOV BX,0 ;IN ABSOLUTE CASE, JUST Y USE ARGEUMENT 131 | SCXREL: LAHF 132 | ADD BX,CX ;ADD NEW VALUE 133 | RCR SI,1 134 | SAHF 135 | RCL SI,1 136 | MOV GRPACX,BX ;UPDATE GRAPHICS ACCUMLATOR 137 | MOV GXPOS,BX ;STORE SECOND COORDINTE FOR CALLER 138 | MOV CX,BX ;RETURN X IN BC 139 | MOV BX,GRPACY ;GET OLDY POSITION 140 | JZ SHORT SCYREL ;IF ZERO, RELATIVE SO USE OLD BASE 141 | MOV BX,0 ;ABSOLUTE SO OFFSET BY 0 142 | SCYREL: ADD BX,DX 143 | MOV GRPACY,BX ;UPDATE Y PART OF ACCUMULATOR 144 | MOV GYPOS,BX ;STORE Y FOR CALLER 145 | XCHG BX,DX ;RETURN Y IN [D,E] 146 | POP BX ;GET BACK THE TEXT POINTER 147 | RET 148 | PAGE 149 | SUBTTL PSET,PRESET,POINT 150 | ; 151 | ; THESE ARE THE STATEMENT AND FUNCTION ENTRY POINTS DEFINED BY THIS 152 | ; PACKAGE. THE APPROPRIATE ENTRIES MUST BE SELECTED IN THE 153 | ; RESERVED WORD TABLES TO GET BASIC TO DISPATCH TO THESE ROUTINES 154 | ; 155 | PUBLIC PSET,PRESET,POINT 156 | 157 | ; 158 | ; PSET (X,Y)[,ATTRIBUTE] DEFAULT ATTRIBUTE TO FORCLR 159 | ; PRESET (X,Y)[,ATTRIBUTE] DEFAULT ATTIBUTE TO BAKCLR 160 | ; 161 | PRESET: PUSH BX ;Push text pointer 162 | STC ;Flag to get graphics colors 163 | CALL GETFBC ;Get forground/background colors 164 | MOV AL,BL ;Get background color 165 | JMP PPRSET 166 | 167 | PSET: PUSH BX ;Push text pointer 168 | STC ;Flag to get graphics colors 169 | CALL GETFBC ;Get forground/background colors 170 | PPRSET: POP BX ;Retrieve text pointer 171 | PSETC: PUSH AX ;SAVE DEFAULT ATTRIBUTE 172 | CALL SCAND ;SCAN A SINGLE COORDINATE 173 | POP AX ;GET BACK DEFAULT ATTRIBUTE 174 | CALL ATRENT ;SCAN POSSIBLE ATTRIBUTE 175 | PUSH BX ;SAVE TEXT POINTER 176 | CALL SCALXY ;SCALE INTO BOUNDS 177 | JAE SHORT PSTNOT ;NO PSET IF NOT IN BOUNDS 178 | CALL MAPXYC ;MAP INTO A "C" 179 | CALL SETC ;ACTUALLY DO THE SET 180 | PSTNOT: POP BX 181 | RET 182 | 183 | ; 184 | ; POINT (X,Y) RETURNS THE ATTRIBUTE STORED AT THAT POINT 185 | ; IT RETURNS -1 IF THE POINT IS OUT OF BOUNDS 186 | ; 187 | POINT: 188 | CALL CHRGTR ;POINT IS RECOGNIZED IN EVAL 189 | ;SO NEED TO SKIP ONE MORE CHAR 190 | PUSH BX ;Save the text pointer. 191 | CALL FETCHC ;Preserve the graphics cursor, GXPOS, 192 | POP DX ;and GYPOS across the POINT function 193 | PUSH BX ;so cases like 194 | PUSH AX ;LINE (x1,y1)-(x2,y2),POINT(x3,y3) will 195 | MOV BX,GYPOS ;work correctly. 196 | PUSH BX 197 | MOV BX,GXPOS 198 | PUSH BX 199 | MOV BX,GRPACY 200 | PUSH BX 201 | MOV BX,GRPACX 202 | PUSH BX 203 | XCHG BX,DX ;Put the text pointer back in HL. 204 | CALL SCAND ;READ THE SPECIFICATION OF THE POINT 205 | PUSH BX ;SAVE THE TEXT POINTER 206 | CALL SCALXY ;SCALE THE POINT 207 | MOV BX,OFFSET 0-1 ;ASSUME ILLEGAL POINT 208 | JAE SHORT PNTNOT ;NOT LEGAL - RETURN -1 209 | CALL MAPXYC 210 | CALL READC ;READ OUT THE ATTRIBUTE 211 | MOV BL,AL 212 | MOV BH,LOW 0 213 | EXTRN MAKINT:NEAR 214 | PNTNOT: CALL MAKINT 215 | POP DX ;Restore text pointer 216 | POP BX 217 | MOV GRPACX,BX 218 | POP BX 219 | MOV GRPACY,BX 220 | POP BX ;Restore GXPOS, GYPOS, and the graphics 221 | MOV GXPOS,BX ;cursor. 222 | POP BX 223 | MOV GYPOS,BX 224 | POP AX 225 | POP BX 226 | PUSH DX 227 | CALL STOREC 228 | POP BX ;Retrieve the text pointer and return. 229 | RET 230 | ; 231 | ; ATTRIBUTE SCAN 232 | ; LOOK AT THE CURRENT POSITION AND IF THERE IS AN ARGUMENT READ IT AS 233 | ; THE 8-BIT ATTRIBUTE VALUE TO SEND TO SETATR. IF STATEMENT HAS ENDED 234 | ; OR THERE IS A NULL ARGUMENT, SEND FORCLR TO SETATR 235 | ; 236 | ATRSCN: PUSH BX ;Save text pointer 237 | STC ;Flag to get graphics colors 238 | CALL GETFBC ;Get forground/background colors 239 | POP BX ;Retrieve text pointer 240 | ATRENT: PUSH CX ;SAVE THE CURRENT POINT 241 | PUSH DX 242 | MOV DL,AL ;SAVE DEFAULT ATTRIBUTE IN [E] 243 | DEC BX ;SEE IF STATEMENT ENDED 244 | CALL CHRGTR 245 | JZ SHORT ATRFIN ;USE DEFAULT 246 | CALL SYNCHR 247 | DB OFFSET 44D ;INSIST ON COMMA 248 | CMP AL,LOW 44D ;ANOTHER COMMA FOLLOWS? 249 | JZ SHORT ATRFIN ;IF SO, NULL ARGUMENT SO USE DEFAULT 250 | CALL GETBYT ;GET THE BYTE 251 | ATRFIN: MOV AL,DL ;GET ATTRIBUTE INTO [A] 252 | PUSH BX ;SAVE THE TEXT POINTER 253 | ATRFI2: 254 | PUSH AX ;Save the attribute 255 | CALL PIXSIZ ;Test for graphics capability 256 | OR AL,AL 257 | JNZ SHORT ??L002 258 | JMP FCERR ;Graphics not available 259 | ??L002: 260 | POP AX ;Restore the attributeA 261 | CALL SETATR ;SET THE ATTRIBUTE AS THE CURRENT ONE 262 | JAE SHORT ??L003 263 | JMP FCERR ;ILLEGAL ATTRIBUTES GIVE FUNCTION CALL 264 | ??L003: 265 | MOV BYTE PTR ATRBYT,AL ;Store legal atribute 266 | POP BX 267 | POP DX ;GET BACK CURRENT POINT 268 | POP CX 269 | JMP CHRGT2 270 | 271 | PAGE 272 | SUBTTL UTILITY ROUTINES FOR LINE CODE 273 | 274 | ; 275 | ; XDELT SETS [H,L]=ABS(GXPOS-[B,C]) AND SETS CARRY IF [B,C].GT.GXPOS 276 | ; ALL REGISTERS EXCEPT [H,L] AND [A,PSW] ARE PRESERVED 277 | ; NOTE: [H,L] WILL BE A DELTA BETWEEN GXPOS AND [B,C] - ADD 1 FOR AN X "COUNT" 278 | ; 279 | XDELT: MOV BX,GXPOS ;GET ACCUMULATOR POSITION 280 | MOV AL,BL 281 | SUB AL,CL 282 | MOV BL,AL ;DO SUBTRACT INTO [H,L] 283 | MOV AL,BH 284 | SBB AL,CH 285 | MOV BH,AL 286 | CNEGHL: JNAE SHORT $+3 287 | RET ;IF NO CARRY, NO NEED TO NEGATE COUNT 288 | PUBLIC NEGHL 289 | NEGHL: XOR AL,AL ;STANDARD [H,L] NEGATE 290 | SUB AL,BL 291 | MOV BL,AL 292 | SBB AL,BH 293 | SUB AL,BL 294 | MOV BH,AL 295 | STC ;FLAG THAT NEGATE TOOK PLACE 296 | RET 297 | ; 298 | ; YDELT SETS [H,L]=ABS(GYPOS-[D,E]) AND SETS CARRY IF [D,E].GT.GYPOS 299 | ; ALL REGISTERS EXCEPT [H,L] AND [A,PSW] ARE PRESERVED 300 | ; 301 | YDELT: MOV BX,GYPOS 302 | MOV AL,BL 303 | SUB AL,DL 304 | MOV BL,AL 305 | MOV AL,BH 306 | SBB AL,DH 307 | MOV BH,AL 308 | JMP SHORT CNEGHL 309 | ; 310 | ; XCHGX EXCHANGES [B,C] WITH GXPOS 311 | ; XCHGY EXCHANGES [D,E] WITH GYPOS 312 | ; XCHGAC PERFORMS BOTH OF THE ABOVE 313 | ; NONE OF THE OTHER REGISTERS IS AFFECTED 314 | ; 315 | XCHGY: PUSH BX 316 | MOV BX,GYPOS 317 | XCHG BX,DX 318 | MOV GYPOS,BX 319 | POP BX 320 | RET 321 | XCHGAC: CALL XCHGY 322 | XCHGX: PUSH BX 323 | PUSH CX 324 | MOV BX,GXPOS 325 | POP SI ;XTHL 326 | XCHG SI,BX 327 | PUSH SI 328 | MOV GXPOS,BX 329 | POP CX 330 | POP BX 331 | RET 332 | PAGE 333 | SUBTTL LINE COMMAND 334 | ; 335 | ; LINE [(X1,Y1)]-(X2,Y2) [,ATTRIBUTE[,B[F]]] 336 | ; DRAW A LINE FROM (X1,Y1) TO (X2,Y2) EITHER 337 | ; 1. STANDARD FORM -- JUST A LINE CONNECTING THE 2 POINTS 338 | ; 2. ,B=BOXLINE -- RECTANGLE TREATING (X1,Y1) AND (X2,Y2) AS OPPOSITE CORNERS 339 | ; 3. ,BF= BOXFILL -- FILLED RECTANGLE WITH (X1,Y1) AND (X2,Y2) AS OPPOSITE CORNERS 340 | ; 341 | PUBLIC GLINE 342 | GLINE: 343 | CALL SCAN1 ;SCAN THE FIRST COORDINATE 344 | PUSH CX ;SAVE THE POINT 345 | PUSH DX 346 | CALL SYNCHR 347 | DB OFFSET MINUTK ;MAKE SURE ITS PROPERLY SEPERATED 348 | CALL SCAND ;SCAN THE SECOND SET 349 | CALL ATRSCN ;SCAN THE ATTRIBUTE 350 | POP DX ;GET BACK THE FIRST POINT 351 | POP CX 352 | JZ SHORT DOLINE ;IF STATEMENT ENDED ITS A NORMAL LINE 353 | CALL SYNCHR 354 | DB OFFSET 44D ;OTHERWISE MUST HAVE A COMMA 355 | CALL SYNCHR 356 | DB OFFSET "B" ;AND A "B" 357 | JNZ SHORT ??L004 358 | JMP BOXLIN ;IF JUST "B" THE NON-FILLED BOX 359 | ??L004: 360 | CALL SYNCHR 361 | DB OFFSET "F" ;MUST BE FILLED BOX 362 | DOBOXF: PUSH BX ;SAVE THE TEXT POINTER 363 | CALL SCALXY ;SCALE FIRST POINT 364 | CALL XCHGAC ;SWITCH POINTS 365 | CALL SCALXY ;SCALE SECOND POINT 366 | CALL YDELT ;SEE HOW MANY LINES AND SET CARRY 367 | JNB SHORT ??L005 368 | CALL XCHGY ;MAKE [D,E] THE SMALLEST Y 369 | ??L005: 370 | INC BX ;MAKE [H,L] INTO A COUNT 371 | PUSH BX ;SAVE COUNT OF LINES 372 | CALL XDELT ;GET WIDTH AND SMALLEST X 373 | JNB SHORT ??L006 374 | CALL XCHGX ;MAKE [B,C] THE SMALLEST X 375 | ??L006: 376 | INC BX ;MAKE [H,L] INTO A WIDTH COUNT 377 | PUSH BX ;SAVE WIDTH COUNT 378 | CALL MAPXYC ;MAP INTO A "C" 379 | POP DX ;GET WIDTH COUNT 380 | POP CX ;GET LINE COUNT 381 | BOXLOP: PUSH DX ;SAVE WIDTH 382 | PUSH CX ;SAVE NUMBER OF LINES 383 | CALL FETCHC ;LOOK AT CURRENT C 384 | PUSH AX ;SAVE BIT MASK OF CURRENT "C" 385 | PUSH BX ;SAVE ADDRESS 386 | XCHG BX,DX ;SET UP FOR NSETCX WITH COUNT 387 | CALL NSETCX ;IN [H,L] OF POINTS TO SETC 388 | POP BX ;GET BACK STARTING C 389 | POP AX ;ADDRESS AND BIT MASK 390 | CALL STOREC ;SET UP AS CURRENT "C" 391 | CALL DOWNC ;MOVE TO NEXT LINE DOWN IN Y 392 | POP CX ;GET BACK NUMBER OF LINES 393 | POP DX ;GET BACK WIDTH 394 | DEC CX ;COUNT DOWN LINES 395 | MOV AL,CH 396 | OR AL,CL ;SEE IF ANY LEFT 397 | JNZ SHORT BOXLOP ;KEEP DRAWING MORE LINES 398 | POP BX 399 | RET 400 | DOLINE: PUSH CX ;SAVE COORDINATES 401 | PUSH DX 402 | PUSH BX ;SAVE TEXT POINTER 403 | CALL DOGRPH 404 | MOV BX,GRPACX ;RESTORE ORIGINAL SECOND COORDINATE 405 | MOV GXPOS,BX 406 | MOV BX,GRPACY ;FOR BOXLIN CODE 407 | MOV GYPOS,BX 408 | POP BX ;RESTORE TEXT POINTER 409 | POP DX 410 | POP CX 411 | RET 412 | BOXLIN: PUSH BX ;SAVE TEXT POINTER 413 | MOV BX,GYPOS 414 | PUSH BX ;SAVE Y2 415 | PUSH DX ;SAVE Y1 416 | XCHG BX,DX ;MOVE Y2 TO Y1 417 | CALL DOLINE ;DO TOP LINE 418 | POP BX ;MOVE Y1 TO Y2 419 | MOV GYPOS,BX 420 | XCHG BX,DX ;RESTORE Y1 TO [D,E] 421 | CALL DOLINE 422 | POP BX ;GET BACK Y2 423 | MOV GYPOS,BX ;AND RESTORE 424 | MOV BX,GXPOS ;GET X2 425 | PUSH CX ;SAVE X1 426 | MOV CX,BX ;SET X1=X2 427 | CALL DOLINE 428 | POP BX 429 | MOV GXPOS,BX ;SET X2=X1 430 | MOV CX,BX ;RESTORE X1 TO [B,C] 431 | CALL DOLINE 432 | POP BX ;RESTORE THE TEXT POINTER 433 | RET 434 | ; 435 | ; DOGRPH DRAWS A LINE FROM ([B,C],[D,E]) TO (GXPOS,GYPOS) 436 | ; 437 | DOGRPH: 438 | CALL SCALXY ;CHEATY SCALING - JUST TRUNCATE FOR NOW 439 | CALL XCHGAC 440 | CALL SCALXY 441 | DOGRP2: CALL YDELT ;GET COUNT DIFFERENCE IN [H,L] 442 | JNB SHORT ??L007 443 | CALL XCHGAC ;IF CURRENT Y IS SMALLER NO EXCHANGE 444 | ??L007: 445 | PUSH DX ;SAVE Y1 COORDINATE 446 | PUSH BX ;SAVE DELTA Y 447 | CALL XDELT 448 | XCHG BX,DX ;PUT DELTA X INTO [D,E] 449 | MOV BX,OFFSET RIGHTC ;ASSUME X WILL GO RIGHT 450 | JAE SHORT LINCN2 451 | MOV BX,OFFSET LEFTC 452 | LINCN2: POP SI ;XTHL 453 | XCHG SI,BX 454 | PUSH SI ;PUT ROUTINE ADDRESS ON STACK AND GET DELTA Y 455 | CMP BX,DX ;SEE WHICH DELTA IS BIGGER 456 | JAE SHORT YDLTBG ;YDELTA IS BIGGER OR EQUAL 457 | 458 | MOV MINDEL,BX ;SAVE MINOR AXIS DELTA (Y) 459 | POP BX ;GET X ACTION ROUTINE 460 | MOV MAXUPD+1,BX ;SAVE IN MAJOR ACTION ADDRESS 461 | MOV BX,OFFSET DOWNC ;ALWAYS INCREMENT Y 462 | MOV MINUPD+1,BX ;WHICH IS THE MINOR AXIS 463 | XCHG BX,DX ;[H,L]=DELTA X=MAJOR DELTA 464 | JMP SHORT LINCN3 ;MERGE WITH YDLTBG CASE AND DO DRAW 465 | 466 | YDLTBG: POP SI ;XTHL 467 | XCHG SI,BX 468 | PUSH SI ;ACTION ROUTINE FOR X INTO [H,L] 469 | ;SAVE DELTA Y ON THE STACK 470 | MOV MINUPD+1,BX ;SAVE ADDRESS OF MINOR AXIS UPDATE 471 | MOV BX,OFFSET DOWNC ;Y IS ALWAYS INCREMENT MODE 472 | MOV MAXUPD+1,BX ;SAVE AS MAJOR AXIS UPDATE 473 | XCHG BX,DX ;[H,L]=DELTA X 474 | MOV MINDEL,BX ;SAVE MINOR DELTA 475 | POP BX ;[H,L]=DELTA Y=MAJOR DELTA 476 | 477 | LINCN3: POP DX ;GET BACK Y1 478 | 479 | ; MAJOR AXIS IS ONE WITH THE LARGEST DELTA 480 | ; MINOR IS THE OTHER 481 | ; READY TO DRAW NOW 482 | ; MINUPD+1=ADDRESS TO GO TO UPDATE MINOR AXIS COORDINATE 483 | ; MAXUPD+1=ADDRESS TO GO TO UPDATE MAJOR AXIS COORDINATE 484 | ; [H,L]=MAJOR AXIS DELTA=# OF POINTS-1 485 | ; MINDEL=DELTA ON MINOR AXIS 486 | ; 487 | ; IDEA IS 488 | ; SET SUM=MAJOR DELTA/2 489 | ; [B,C]=# OF POINTS 490 | ; MAXDEL=-MAJOR DELTA (CONVENIENT FOR ADDING) 491 | ; LINE LOOP (LINLP3): 492 | ; DRAW AT CURRENT POSITION 493 | ; UPDATE MAJOR AXIS 494 | ; SUM=SUM+MINOR DELTA 495 | ; IF SUM.GT.MAJOR DELTA THEN UPDATE MINOR AND SUM=SUM-MAJOR DELTA 496 | ; DECREMENT [B,C] AND TEST FOR 0 -- LOOP IF NOT 497 | ; END LOOP 498 | 499 | PUSH BX ;SAVE FOR SETTING UP COUNT 500 | MOV MAXDEL,BX ;SAVE MAJOR DELTA FOR SUMMING 501 | CALL MAPXYC ;GET POSITION INTO BITMSK AND [H,L] 502 | POP DX 503 | PUSH DX ;START SUM AT MAXDEL/2 504 | CALL HLFDE 505 | POP CX ;GET COUNT IN [B,C] 506 | INC CX ;NUMBER OF POINTS IS DELTA PLUS ONE 507 | EXTRN LINLP3:NEAR 508 | JMP LINLP3 509 | 510 | 511 | HLFDE: MOV AL,DH 512 | OR AL,AL ;CLEAR CARRY 513 | RCR AL,1 ;SCALE MEANS SHIFTING RIGHT ONE 514 | MOV DH,AL 515 | MOV AL,DL 516 | RCR AL,1 517 | MOV DL,AL 518 | RET 519 | 520 | PAGE 521 | PAGE 522 | SUBTTL Graphics Initialization 523 | 524 | PUBLIC GRPINI,GRPRST ;Graphics Initialization routine 525 | 526 | EXTRN GRPSIZ:NEAR ;Get screen pixel dimension routine (OEM) 527 | DSEG SEGMENT PUBLIC 'DATASG' 528 | EXTRN DRWSCL:WORD,DRWANG:WORD 529 | DSEG ENDS 530 | 531 | ;GRPRST resets graphics. It is called at CLEARC and during INIT 532 | ;Entry - none 533 | ;Exit - all registers preserved 534 | ; 535 | GRPRST: PUSH AX 536 | PUSH CX 537 | PUSH BX 538 | XOR AL,AL 539 | MOV BYTE PTR DRWSCL,AL ;Draw scale init 540 | MOV BYTE PTR DRWANG,AL ;Draw angle init 541 | CALL GRPINI ;Center the graphics cursor 542 | STC 543 | CALL GETFBC ;Get foreground/background colors 544 | CALL SETATR ;Set the default DRAW color 545 | POP BX 546 | POP CX 547 | POP AX 548 | RET 549 | 550 | ;GRPINI - center the graphics cursor. This routine has been documented to 551 | ;OEMs for versions of GW BASIC which are translated to ASM86. 552 | ;Entry - none 553 | ;Exit - none 554 | ; 555 | GRPINI: CALL GRPSIZ ;Get screen pixel dimensions 556 | PUSH CX ;B,C has X dimension 557 | POP BX ;Move X dimension to H 558 | INC BX ;Adjust for zero relative 559 | INS86 321,353 ;;SHR BX,1 560 | MOV GRPACX,BX ;Store as previous position 561 | PUSH DX ;D,E has Y dimension 562 | POP BX ;Move Y dimension to H 563 | INC BX 564 | INS86 321,353 ;;SHR BX,1 565 | MOV GRPACY,BX ;Store as previous position 566 | RET 567 | 568 | CSEG ENDS 569 | END 570 | -------------------------------------------------------------------------------- /GIO86U: -------------------------------------------------------------------------------- 1 | ; [ This translation created 12-Jan-83 by Version 4.3 ] 2 | 3 | SUBTTL GIO86U - Device Independent I/O Constants and Macros 4 | 5 | COMMENT * 6 | 7 | --------- --- ---- -- --------- 8 | COPYRIGHT (C) 1982 BY MICROSOFT 9 | --------- --- ---- -- --------- 10 | 11 | Programmer: Tom Corbett, Microsoft Inc. 12 | 13 | * 14 | 15 | ROFFST MACRO NAME,SIZE ;define record macro 16 | NAME=_OFFST 17 | _OFFST=_OFFST+SIZE 18 | ENDM 19 | 20 | 21 | ;ASCII character definitions 22 | ; 23 | ASCCTC=3D ;CTL-C 24 | ASCBS=8D ;backspace 25 | ASCTAB=9D ;Tab 26 | ASCLF=10D ;Line Feed 27 | ASCCR=13D ;Carriage Return 28 | ASCCTS=19D ;CTL-S 29 | ASCCTZ=26D ;Control Z (End-of-file for some devices) 30 | ASCESC=27D ;Escape 31 | ASCSPC=32D ;Space 32 | 33 | ;Special File ID's (identified by 1st byte of file) 34 | ; 35 | BINFID=255D ;files created by SAVE "fn" 36 | PROFID=254D ;files created by SAVE "fn",P 37 | BSVFID=253D ;files created by BSAVE "fn" 38 | 39 | ;Generalized I/O Function Codes: 40 | ; 41 | _OFFST=0 ;initialize count 42 | ROFFST G_EOF,2 ;test EOF for file opened to this device 43 | ROFFST G_LOC,2 ;LOC 44 | ROFFST G_LOF,2 ;LOF 45 | ROFFST G_CLS,2 ;perform special CLOSE functions for this device 46 | ROFFST G_SWD,2 ;set device width 47 | ROFFST G_RND,2 ;GET/PUT random record from/to this device 48 | ROFFST G_OPN,2 ;perform special OPEN functions for this device 49 | ROFFST G_SIN,2 ;input 1 byte from file opened on this device 50 | ROFFST G_SOT,2 ;output 1 byte to file opened on this device 51 | ROFFST G_GPS,2 ;POS 52 | ROFFST G_GWD,2 ;get device width 53 | ROFFST G_SCW,2 ;set device column width 54 | ROFFST G_GCW,2 ;get device column width 55 | ROFFST G_BIN,2 ;block input from file opened on this device 56 | ROFFST G_BOT,2 ;block output to file opened on this device 57 | 58 | 59 | PAGE 60 | -------------------------------------------------------------------------------- /GIOCAS.ASM: -------------------------------------------------------------------------------- 1 | ; [ This translation created 10-Feb-83 by Version 4.3 ] 2 | 3 | .RADIX 8 ; To be safe 4 | 5 | CSEG SEGMENT PUBLIC 'CODESG' 6 | ASSUME CS:CSEG 7 | 8 | INCLUDE OEM.H 9 | 10 | TITLE GIOCAS - Cassette Machine Independent Device Driver Code 11 | 12 | COMMENT * 13 | 14 | --------- --- ---- -- --------- 15 | COPYRIGHT (C) 1981 BY MICROSOFT 16 | --------- --- ---- -- --------- 17 | 18 | Written by: Len Oorthuys 19 | 20 | * 21 | INCLUDE GIO86U 22 | INCLUDE MSDOSU 23 | .SALL 24 | 25 | 26 | EXTRN DERDNA:NEAR 27 | PUBLIC MOTOR 28 | MOTOR: JMP DERDNA ;Device unavailable error 29 | 30 | 31 | CSEG ENDS 32 | END 33 | 34 | -------------------------------------------------------------------------------- /GIOCON.ASM: -------------------------------------------------------------------------------- 1 | ; [ This translation created 10-Feb-83 by Version 4.3 ] 2 | 3 | .RADIX 8 ; To be safe 4 | 5 | CSEG SEGMENT PUBLIC 'CODESG' 6 | ASSUME CS:CSEG 7 | 8 | INCLUDE OEM.H 9 | 10 | TITLE GIOCON - Machine Independent CONS: Device Support 11 | 12 | COMMENT * 13 | 14 | --------- --- ---- -- --------- 15 | COPYRIGHT (C) 1982 BY MICROSOFT 16 | --------- --- ---- -- --------- 17 | 18 | * 19 | INCLUDE GIO86U 20 | .SALL 21 | 22 | CPM86=0 ;CPM86 23 | 24 | ;This module becomes NULL if CONSSW is 0 25 | ; 26 | INCLUDE MSDOSU ;MSDOS Constant Definitions 27 | 28 | 29 | 30 | PUBLIC CONDSP,_RET,CONSOT 31 | 32 | EXTRN DERBFM:NEAR,PDCBAX:NEAR 33 | EXTRN DEVBOT:NEAR,DEVBIN:NEAR 34 | 35 | PAGE 36 | SUBTTL CONS (Raw-CRT output Dispatch Table and Routines) 37 | 38 | ;Console Dispatch Table 39 | ; 40 | CONDSP: 41 | DW (DERBFM) ;test EOF for file opened to this device 42 | DW (DERBFM) ;LOC 43 | DW (DERBFM) ;LOF 44 | DW (_RET) ;perform special CLOSE functions for this device 45 | DW (DERBFM) ;set device width 46 | DW (DERBFM) ;GET/PUT random record from/to this device 47 | DW (CONOPN) ;perform special OPEN functions for this device 48 | DW (DERBFM) ;input 1 byte from file opened on this device 49 | DW (CONSOT) ;output 1 byte to file opened on this device 50 | DW (CONGPS) ;POS 51 | DW (CONGWD) ;get device width 52 | DW (_RET) ;set device comma width 53 | DW (_RET) ;get device comma width 54 | DW (DEVBIN) ;block input from file opened on this device 55 | DW (DEVBOT) ;block output to file opened on this device 56 | 57 | ;CONOPN - perform any device dependent open functions. 58 | ; Entry - [AL]= device id 59 | ; 0 if default device, 60 | ; 1..n for Disk A:, B:, ... 61 | ; -1..-n for non-disk devices 62 | ; [BX] = file number (0..n) 63 | ; [CX] = random record size if [FILMOD] = random 64 | ; (if [CX] = 0, use default record size) 65 | ; [DI] = device offset (2=SCND, 4=SCRN, etc.) 66 | ; [FILMOD] = file mode 67 | ; MD.SQI = 1 ;sequential input 68 | ; MD.SQO = 2 ;sequential output 69 | ; MD.RND = 3 ;random 70 | ; MD.APP = 4 ;append 71 | ; [FILNAM] = filename 72 | ; [FILEXT] = 1..3 byte filename extension 73 | ; Exit - [SI] points to new FDB 74 | ; FDB is linked into FDB chain with all standard 75 | ; fields initialized. 76 | ; All other registers are preserved. 77 | ; 78 | 79 | EXTRN INIFDB:NEAR 80 | 81 | CONOPN: 82 | MOV AH,LOW OFFSET MD_SQO ;allow open for output only 83 | MOV DX,255D ;initial file column position=0 84 | ;initial file width=255 85 | JMP INIFDB 86 | 87 | ;CONGPS - return current file position. 88 | ; Entry - SI points to File-Data-Block. 89 | ; Exit - [AH] = current file column. (0-relative) 90 | ; All other registers preserved 91 | ; 92 | CONGPS: MOV AH,LOW 0 93 | _RET: RET 94 | 95 | ;CONGWD - get device width 96 | ; Exit - [AH] = device width as set by xxxSWD 97 | ; All other registers preserved 98 | ; 99 | CONGWD: 100 | MOV AH,LOW 255D ;infinite width 101 | RET 102 | 103 | ;CONSOT - Write one byte to the console. 104 | ; 105 | ;ENTRY - AL = Character to output 106 | ;EXIT - All registers except SI and DI are preserved. 107 | ; 108 | CONSOT: PUSH AX 109 | PUSH BX 110 | PUSH CX 111 | PUSH DX 112 | CMP AL,LOW 255D 113 | JZ CONSOX ;Don't allow outputing FFH 114 | MOV DL,AL 115 | CALLOS C_DCIO ;Direct Console I/O 116 | CONSOX: JMP PDCBAX ;Pop DX,CX,BX,AX and RET 117 | 118 | CSEG ENDS 119 | END 120 | -------------------------------------------------------------------------------- /GIOLPT.ASM: -------------------------------------------------------------------------------- 1 | ; [ This translation created 10-Feb-83 by Version 4.3 ] 2 | 3 | .RADIX 8 ; To be safe 4 | 5 | CSEG SEGMENT PUBLIC 'CODESG' 6 | ASSUME CS:CSEG 7 | 8 | INCLUDE OEM.H 9 | 10 | TITLE GIOLPT - Line Printer Machine Independent Device Driver Code 11 | 12 | COMMENT * 13 | 14 | --------- --- ---- -- --------- 15 | COPYRIGHT (C) 1982 BY MICROSOFT 16 | --------- --- ---- -- --------- 17 | 18 | * 19 | INCLUDE GIO86U 20 | .SALL 21 | 22 | MELCO=0 23 | TETRA=0 24 | ZENITH=0 25 | CPM86=0 26 | INCLUDE MSDOSU 27 | 28 | ;OEM Switches 29 | ; 30 | 31 | PUBLIC LPTDSP,LPTINI,LPTTRM 32 | EXTRN DERBFM:NEAR,INIFDB:NEAR,UPDPOS:NEAR,$_LPT1:NEAR 33 | EXTRN DEVBOT:NEAR,DEVBIN:NEAR 34 | 35 | ;Line Printer Dispatch Table 36 | ; 37 | LPTDSP: 38 | DW (DERBFM) ;test EOF for file opened to this device 39 | DW (DERBFM) ;LOC 40 | DW (DERBFM) ;LOF 41 | DW (LPTCLS) ;perform special CLOSE functions for this device 42 | DW (LPTSWD) ;set device width 43 | DW (DERBFM) ;GET/PUT random record from/to this device 44 | DW (LPTOPN) ;perform special OPEN functions for this device 45 | DW (DERBFM) ;input 1 byte from file opened on this device 46 | DW (LPTSOT) ;output 1 byte to file opened on this device 47 | DW (LPTGPS) ;POS 48 | DW (LPTGWD) ;get device width 49 | DW (LPTSCW) ;set device comma width 50 | DW (LPTGCW) ;get device comma width 51 | DW (DEVBIN) ;block input from file opened on this device 52 | DW (DEVBOT) ;block output to file opened on this device 53 | 54 | LPTTRM: RET 55 | PAGE 56 | SUBTTL Line Printer Primitive I/O Routines 57 | 58 | DSEG SEGMENT PUBLIC 'DATASG' 59 | ASSUME DS:DSEG 60 | EXTRN LP1DCB:WORD 61 | DSEG ENDS 62 | 63 | ;LPT Device Control Block field definitions: 64 | ; 65 | _LPWID=0 ;device width (columns per line) 66 | _LPPOS=1 ;current column device is in 67 | _LPFLG=2 ;Boolean attributes mask for this device 68 | _LPCRF=1 ;non-zero=last char sent was Carriage Return 69 | 70 | ;LPTINI - called during BASIC initialization 71 | ; Entry - DI = -2*device id 72 | ; 73 | LPTINI: PUSH DI 74 | CALL GLPDCB ;DI points to device control block 75 | MOV BYTE PTR _LPWID[DI],LOW 80D ;default width = 80 chars / line 76 | MOV BYTE PTR _LPPOS[DI],LOW 0 ;initial position = 0 77 | MOV BYTE PTR _LPFLG[DI],LOW 0 ;reset device Flags 78 | POP DI 79 | RET 80 | 81 | ;LPTCLS - perform any device dependent close functions. 82 | ; Entry - SI points to File-Data-Block. 83 | ; DI = -2*device id 84 | ; Exit - All registers preserved. 85 | ; This routine is called before BASIC releases the 86 | ; file-data-block associated with this file. 87 | ; 88 | LPTCLS: RET 89 | 90 | ;LPTSWD - set device width 91 | ; Entry - [DX] = new device width 92 | ; DI = -2*device id 93 | ; 94 | LPTSWD: 95 | CALL GLPDCB ;DI points to device control block 96 | MOV BYTE PTR _LPWID[DI],DL 97 | RET 98 | 99 | EXTRN DERIFN:NEAR,SCDBIN:NEAR 100 | DSEG SEGMENT PUBLIC 'DATASG' 101 | EXTRN FILOPT:WORD 102 | DSEG ENDS 103 | 104 | ;LPTOPN - perform any device dependent open functions. 105 | ; Entry - [AL]= device id 106 | ; 0 if default device, 107 | ; 1..n for Disk A:, B:, ... 108 | ; -1..-n for non-disk devices 109 | ; [BX] = file number (0..n) 110 | ; [CX] = random record size if [FILMOD] = random 111 | ; (if [CX] = 0, use default record size) 112 | ; [DI] = device offset (2=LPTD, 4=SCRN, etc.) 113 | ; [FILMOD] = file mode (one of the following) 114 | ; MD.SQI ;sequential input 115 | ; MD.SQO ;sequential output 116 | ; MD.RND ;random 117 | ; MD.APP ;append 118 | ; [FILNAM] = filename 119 | ; [FILEXT] = 1..3 byte filename extension 120 | ; Exit - [SI] points to new FDB 121 | ; FDB is linked into FDB chain with all standard 122 | ; fields initialized. 123 | ; All other registers are preserved. 124 | ; 125 | LPTOPN: PUSH AX ;save device id for INIFDB 126 | CALL GLPDCB ;DI points to device control block 127 | MOV SI,OFFSET FILOPT ;SI points to options string 128 | MOV AH,LOW 337O ;0DFH - Mask for mapping lower to upper case 129 | CLD ;use Post-Increment addressing 130 | LODSB ;[AL]=1st byte of option string 131 | AND AL,AH ;Map Lower to Upper Case (turn off b6) 132 | PUSHF ;remember if BIN option was selected 133 | JE NOOPT ;branch if no option specified 134 | CMP AL,LOW "B" 135 | JNE IFNERR ;Bad File Name error if option not BIN 136 | LODSB ;[AL]=next byte of option string 137 | AND AL,AH ;Map Lower Case to Upper Case 138 | CMP AL,LOW "I" 139 | JNE IFNERR ;Bad File Name error if option not BIN 140 | LODSB ;[AL]=next byte of option string 141 | AND AL,AH ;Map Lower Case to Upper Case 142 | CMP AL,LOW "N" 143 | JNE IFNERR ;Bad File Name error if option not BIN 144 | LODSB ;[AL]=next byte of option string 145 | OR AL,AL 146 | JNE IFNERR ;Error if not end of options 147 | NOOPT: 148 | MOV DH,BYTE PTR _LPPOS[DI] ;initial file column position 149 | MOV DL,BYTE PTR _LPWID[DI] ;initial file width 150 | POPF 151 | POP AX ;[AL]=device id 152 | PUSHF ;remember if BIN option was selected 153 | MOV AH,LOW OFFSET MD_SQO OR MD_RND ;allow open for output/random 154 | CALL INIFDB 155 | POPF 156 | JE NOBIN ;branch if BIN option was not selected 157 | CALL SCDBIN ;set BINARY file mode 158 | NOBIN: 159 | RET 160 | 161 | IFNERR: JMP DERIFN ;"illegal filename" error 162 | 163 | ;LPTSOT - Sequential Output. 164 | ; Entry - SI points to File-Data-Block. 0 if Pseudo FDB (for LLIST/LPRINT) 165 | ; DI = -2*device id 166 | ; [AL] = byte to be output. 167 | ; Exit - SI, DI can be changed. 168 | ; All other registers preserved 169 | ; This routine keeps track of column position, 170 | ; expands tabs, and forces a carriage return when line width 171 | ; is exceeded. 172 | ; 173 | LPTSOT: PUSH BX ;save caller's BX 174 | PUSH AX ;save char to be output 175 | CALL GLPDCB ;DI points to line printer DCB 176 | MOV BL,AL ;[BL] = device id 177 | POP AX ;[AL] = byte to be output 178 | MOV AH,BL ;[AH] = device id 179 | POP BX ;restore caller's BX 180 | OR SI,SI 181 | JZ NOTBIN ;branch if not binary mode 182 | CMP BYTE PTR F_CODE[SI],LOW OFFSET FC_BIN 183 | JE LPROUT ;if binary, branch to Raw-Output routine 184 | NOTBIN: PUSH BX 185 | PUSH DX 186 | MOV DX,WORD PTR _LPWID[DI] ;[DL]=device width, [DH]=current column 187 | MOV BX,OFFSET LPOUT1 ;BX points to Raw Output Routine 188 | JZ PSDFDB ;branch if Pseudo FDB (LLIST/LPRINT) 189 | ;*** CAREFUL *** FLAGS must be preserved 190 | ; from OR SI,SI Above. 191 | MOV DL,BYTE PTR F_WID[SI] ;Get width from FDB 192 | PSDFDB: 193 | EXTRN CRIFEL:NEAR 194 | CALL CRIFEL ;force CR if End-Of-Line 195 | MOV BYTE PTR _LPPOS[DI],DH ;save new column position 196 | POP DX 197 | POP BX 198 | RET 199 | 200 | ;Low-Level Line Printer Output (updates column position) 201 | ;For IBM Compatibility, the following filter performs the following translations 202 | ; x x x CR x x x === x x x CR LF x x x 203 | ; x x x CR LF x x x === x x x CR LF x x x 204 | ;If LPT was opened for RANDOM mode, and WIDTH=255, then suppress LF which 205 | ; follow carriage returns for IBM compatibility. 206 | ; 207 | ; Eat all LineFeeds which follow CarriageReturns with following algorithm: 208 | ; if (Char <> LF) or (LastWasCR = 0) then output (Char) 209 | ; if (Char = CR) then 210 | ; Begin 211 | ; LastWasCR = 1 212 | ; if FDB.MODE<>RANDOM or FDB.WIDTH<>255 then 213 | ; output(LF) 214 | ; End 215 | ; else 216 | ; LastWasCR = 0 217 | ; 218 | ; The only case where this is not compatible with IBM is when the user executes: 219 | ; PRINT CHR$(13);CHR$(10);... 220 | ; 221 | ; The best way this could have been done was by setting CRONLY=1 in the 222 | ; switch files and letting the device drivers append Line-Feeds if necessary. 223 | ; It was considered too late to make a change this drastic 224 | ; 225 | LPOUT1: CALL UPDPOS ;[DH]=new column position(AL, DH) 226 | PUSH AX ;save character to be output 227 | CMP AL,LOW OFFSET ASCLF 228 | JNE LPOUT2 ;branch if not attempting to output LF 229 | TEST BYTE PTR _LPFLG[DI],LOW OFFSET _LPCRF 230 | JNE LPOUT3 ;brif last byte out was CR (eat LF) 231 | LPOUT2: 232 | CALL LPROUT ;output the character 233 | LPOUT3: 234 | POP AX ;restore [AL]=char which was output 235 | AND BYTE PTR _LPFLG[DI],LOW OFFSET 255D-_LPCRF ;reset last byte out was CR flag 236 | CMP AL,LOW OFFSET ASCCR 237 | JNE LPOUTX ;return if wasn't carriage return 238 | OR BYTE PTR _LPFLG[DI],LOW OFFSET _LPCRF ;set last byte out was CR flag 239 | OR SI,SI 240 | JZ OUTLF ;branch if Pseudo FDB (LLIST/LPRINT) 241 | CMP BYTE PTR F_WID[SI],LOW 255D 242 | JNE OUTLF ;output LF if width is not 255 243 | CMP BYTE PTR F_MODE[SI],LOW OFFSET MD_RND 244 | JE LPOUTX ;suppress LF following CRs 245 | OUTLF: 246 | PUSH AX 247 | MOV AL,LOW OFFSET ASCLF 248 | CALL LPROUT 249 | POP AX 250 | LPOUTX: 251 | RET 252 | 253 | ;Raw Line Printer Output routine 254 | ; Entry - [AL]=byte to be sent to current line printer 255 | ; [AH]=device id (0..n) 256 | ; Exit - Flags used, All other registers preserved. 257 | ; 258 | EXTRN SNDLPT:NEAR,ERROR:NEAR,ERRDNA:NEAR,ERRDTO:NEAR,ERROTP:NEAR 259 | EXTRN ERRDIO:NEAR 260 | LPROUT: 261 | PUSH AX 262 | CALL SNDLPT ;Call OEM routine to output to printer 263 | OR AH,AH 264 | JNE LPERR ;branch if OEM routine detected error 265 | POP AX 266 | RET 267 | LPERR: 268 | MOV AL,AH 269 | XOR AH,AH ;[AX]=error code 1..n 270 | DEC AX ;[AX]=error code 0..n 271 | MOV DI,OFFSET LPERRT 272 | ADD DI,AX ;[DI] points to BASIC Error code 273 | MOV DL,BYTE PTR CS:0[DI] 274 | CMP AL,LOW 3 275 | JB ERROR1 ;branch if legal error code 276 | MOV DL,LOW OFFSET ERRDIO ;map all other error codes to I/O error 277 | ERROR1: JMP ERROR 278 | 279 | LPERRT: DB OFFSET ERRDNA 280 | DB OFFSET ERRDTO 281 | DB OFFSET ERROTP 282 | 283 | ;LPOS(X) function 284 | ; 285 | PUBLIC LPOS 286 | EXTRN SNGFLT:NEAR,CONINT:NEAR 287 | LPOS: PUSH BX 288 | CALL CONINT ;Force FAC to byte integer in AL 289 | CBW 290 | OR AX,AX ;Test for LPT number 0 to map to 1 291 | JZ LPTN0 ;n = 0, so map to 1 292 | DEC AX 293 | SHR AX,1 ;Offset to correct DCB 294 | LPTN0: MOV BX,OFFSET LP1DCB+_LPPOS ;Get address of LPOS in first LPT DCB 295 | ADD BX,AX ;Get address of LPOS in current LPT DCB 296 | MOV AL,BYTE PTR 0[BX] ;[AL]=current 0 relative position 297 | INC AL ;return 1 relative number 298 | POP BX 299 | JMP SNGFLT ;return result to user 300 | 301 | ;LPTGPS - return current file position. 302 | ; Entry - SI points to File-Data-Block. 303 | ; Exit - [AH] = current file column. (0-relative) 304 | ; All other registers preserved 305 | ; 306 | LPTGPS: CALL GLPDCB ;DI points to device control block 307 | MOV AH,BYTE PTR _LPPOS[DI] 308 | RET 309 | 310 | ;LPTGWD - get device width 311 | ; Entry - DI = -2*device id 312 | ; Exit - [AH] = device width as set by xxxSWD 313 | ; All other registers preserved 314 | ; 315 | LPTGWD: CALL GLPDCB ;DI points to device control block 316 | MOV AH,BYTE PTR _LPWID[DI] 317 | RET 318 | 319 | ;LPTSCW - set device comma width 320 | ; Entry - [BX] = new device comma width 321 | ; DI = -2*device id 322 | ; Exit - SI, DI can be changed. 323 | ; All other registers preserved 324 | ; 325 | LPTSCW: RET 326 | 327 | ;LPTGCW - get device comma width 328 | ; Entry - DI = -2*device id 329 | ; Exit - [BX] = device comma width as set by xxxSCW 330 | ; All other registers preserved 331 | ; 332 | LPTGCW: RET 333 | 334 | ;GLPDCB - get pointer to line printer device control block 335 | ; Entry - [DI] = -2*device id (2,4,..n) 336 | ; Exit - DI points to the device control block for device DI. 337 | ; [AX] = 0..n for LPT1, LPT2, ... 338 | ; 339 | ;************************************************************************ 340 | ;* Note: IF LPT DCB size changes from 4, this routine should be changed * 341 | ;************************************************************************ 342 | ; 343 | GLPDCB: 344 | MOV AX,OFFSET ($_LPT1-400O) ;[AX]=-device id for LPT1 345 | SHL AX,1 ;[AX]=-2*device id for LPT1 346 | ADD AX,DI ;[AX]=0, 2, ... for LPT1, LPT2, ... 347 | MOV DI,AX ;[DI]=0, 2, ... for LPT1, LPT2, ... 348 | SHL DI,1 ;[DI]=0, 4, ... for LPT1, LPT2, ... 349 | SHR AX,1 ;[AX]=0, 1, ... for LPT1, LPT2, ... 350 | ADD DI,OFFSET LP1DCB ;[DI] points to LPTx device ctl block 351 | RET 352 | ; 353 | CSEG ENDS 354 | END 355 | -------------------------------------------------------------------------------- /GIOSCN.ASM: -------------------------------------------------------------------------------- 1 | ; [ This translation created 10-Feb-83 by Version 4.3 ] 2 | 3 | .RADIX 8 ; To be safe 4 | 5 | CSEG SEGMENT PUBLIC 'CODESG' 6 | ASSUME CS:CSEG 7 | 8 | INCLUDE OEM.H 9 | 10 | TITLE GIOSCN - Screen Machine Independent Device Driver Code 11 | 12 | COMMENT * 13 | 14 | --------- --- ---- -- --------- 15 | COPYRIGHT (C) 1982 BY MICROSOFT 16 | --------- --- ---- -- --------- 17 | 18 | * 19 | INCLUDE GIO86U 20 | .SALL 21 | 22 | CPM86=0 ;CPM86 Operating System 23 | IBMCSR=IBMLIK ;IBM compatibile cursor control interface 24 | 25 | ;Definition of scroll types 26 | ; Choice of scroll type is by switch SCROLT. 27 | ; Switches defined here are used to implement a specific SCROLT type. 28 | ; If other scroll types are needed then additional SCROLT types should be 29 | ; defined here. 30 | INVLIN=SCROLT ;Invisible (function key) Line 31 | FKFSRL=(SCROLT-1) AND 1 ;Clear fkeys/full scroll/rewrite fkeys 32 | 33 | INCLUDE MSDOSU ;Operating System Constants 34 | 35 | PUBLIC SCNDSP,SCNINI,SCNTRM 36 | EXTRN DERBFM:NEAR,INIFDB:NEAR 37 | EXTRN DEVBIN:NEAR,DEVBOT:NEAR 38 | DSEG SEGMENT PUBLIC 'DATASG' 39 | ASSUME DS:DSEG 40 | EXTRN TWOBYT:WORD 41 | DSEG ENDS 42 | 43 | ;Screen Dispatch Table 44 | ; 45 | SCNDSP: 46 | DW (DERBFM) ;test EOF for file opened to this device 47 | DW (DERBFM) ;LOC 48 | DW (DERBFM) ;LOF 49 | DW (SCNCLS) ;perform special CLOSE functions for this device 50 | DW (SCNSWD) ;set device width 51 | DW (DERBFM) ;GET/PUT random record from/to this device 52 | DW (SCNOPN) ;perform special OPEN functions for this device 53 | DW (DERBFM) ;input 1 byte from file opened on this device 54 | DW (SCNSOT) ;output 1 byte to file opened on this device 55 | DW (SCNGPS) ;POS 56 | DW (SCNGWD) ;get device width 57 | DW (SCNSCW) ;set device comma width 58 | DW (SCNGCW) ;get device comma width 59 | DW (DEVBIN) ;block input from file opened on this device 60 | DW (DEVBOT) ;block output to file opened on this device 61 | PUBLIC SCNSWD,SCNSOT,SCNGPS,SCNGWD,SCNSCW,SCNGCW 62 | PAGE 63 | SUBTTL CRT Primitive I/O Routines 64 | 65 | ;SCNINI is called to initialize Screen when BASIC comes up 66 | ; 67 | DSEG SEGMENT PUBLIC 'DATASG' 68 | EXTRN WDTFLG:WORD 69 | DSEG ENDS 70 | SCNINI: 71 | MOV AL,BYTE PTR LINLEN ; Get CRT logical line length 72 | MOV BYTE PTR WDTFLG,AL ; Default width of device SCRN: 73 | RET 74 | 75 | ;SCNTRM is called to Clean-up Screen when BASIC terminates 76 | ; 77 | EXTRN TKEYOF:NEAR 78 | SCNTRM: CALL TKEYOF ;Turn off KEY display 79 | EXTRN SCNPOS:NEAR 80 | CALL SCNPOS ;[DX]=current cursor location 81 | RET 82 | 83 | ;SCNCLS - perform any device dependent close functions. 84 | ; Entry - SI points to File-Data-Block. 85 | ; Exit - All registers preserved. 86 | ; This routine is called before BASIC releases the 87 | ; file-data-block associated with this file. 88 | ; 89 | SCNCLS: RET 90 | 91 | ;SCNSWD - set device width 92 | ; Entry - [DX] = new device width 93 | ; Exit - All registers preserved 94 | ; 95 | SCNSWD: 96 | EXTRN SWIDTH:NEAR 97 | DSEG SEGMENT PUBLIC 'DATASG' 98 | EXTRN LINCNT:WORD,WDTFLG:WORD 99 | DSEG ENDS 100 | MOV BYTE PTR WDTFLG,DL ;Set/Reset infinite length flag 101 | CMP DL,LOW 255D 102 | JNZ SCNWD1 ;BRIF not infinite length 103 | RET 104 | SCNWD1: PUSH CX 105 | PUSH AX 106 | MOV AL,DL ;pass Width in AL 107 | MOV CL,BYTE PTR LINCNT ;pass Height in CL 108 | CALL SWIDTH ;Let screen editor set width 109 | POP AX 110 | POP CX 111 | RET 112 | 113 | ;SCNOPN - perform any device dependent open functions. 114 | ; Entry - [AL]= device id 115 | ; 0 if default device, 116 | ; 1..n for Disk A:, B:, ... 117 | ; -1..-n for non-disk devices 118 | ; [BX] = file number (0..n) 119 | ; [CX] = random record size if [FILMOD] = random 120 | ; (if [CX] = 0, use default record size) 121 | ; [DI] = device offset (2=SCND, 4=SCRN, etc.) 122 | ; [FILMOD] = file mode 123 | ; MD.SQI = 1 ;sequential input 124 | ; MD.SQO = 2 ;sequential output 125 | ; MD.RND = 3 ;random 126 | ; MD.APP = 4 ;append 127 | ; [FILNAM] = filename 128 | ; [FILEXT] = 1..3 byte filename extension 129 | ; Exit - [SI] points to new FDB 130 | ; FDB is linked into FDB chain with all standard 131 | ; fields initialized. 132 | ; All other registers are preserved. 133 | ; 134 | SCNOPN: 135 | CALL SCNGPS ;[AH]=current column position 136 | MOV DH,AH ;[DH]=current column position 137 | MOV AH,LOW OFFSET MD_SQO ;allow open for output only 138 | MOV DL,BYTE PTR WDTFLG ;initial file logical width 139 | JMP INIFDB 140 | 141 | PUBLIC CALTTY,$CATTY 142 | 143 | ;CALTTY IS A SPECIAL ROUTINE TO OUTPUT ERROR MESSAGE TO TTY, REGARDLESS 144 | ; OF CURRENT FILE I/O. 145 | ; Entry - [AL] = byte to be output 146 | ; Exit - All registers preserved 147 | ; 148 | EXTRN OUTDO:NEAR 149 | DSEG SEGMENT PUBLIC 'DATASG' 150 | EXTRN PTRFIL:WORD 151 | DSEG ENDS 152 | $CATTY: 153 | CALTTY: PUSH WORD PTR PTRFIL 154 | MOV WORD PTR PTRFIL,0 ;Make sure we go to the "TTY" 155 | CALL OUTDO 156 | POP WORD PTR PTRFIL 157 | RET 158 | 159 | ;SCNSOT - Sequential Output. 160 | ; Entry - SI points to File-Data-Block. 161 | ; [AL] = byte to be output. 162 | ; Exit - SI, DI can be changed. 163 | ; All other registers preserved 164 | ; This routine expands tabs if appropriate. 165 | ; It need not force a carriage return when width 166 | ; exceeded as this is handled at a lower level. 167 | ; 168 | SCNSOT: 169 | EXTRN SCNOUT:NEAR 170 | PUSHF 171 | PUSH AX 172 | 173 | ;If last char SCNSOT was called with was the 1st byte of a 2-byte char, 174 | ; SCNSOT saved it in TWOBYT so they be both output as one 16-bit character. 175 | ; 176 | MOV AH,BYTE PTR TWOBYT ;If two byte, put first in [AH] 177 | OR AH,AH 178 | JZ SCNSO1 ;BRIF not second of two bytes 179 | MOV BYTE PTR TWOBYT,LOW 0 ;Clear TWOBYT flag 180 | JMP SHORT SCNSO3 ;Output both bytes at once 181 | SCNSO1: 182 | DSEG SEGMENT PUBLIC 'DATASG' 183 | EXTRN F_EDIT:WORD 184 | DSEG ENDS 185 | TEST BYTE PTR F_EDIT,LOW 377O 186 | JZ SCNS1A ;BRIF not in editor, don't collect FF codes 187 | CMP AL,LOW 255D 188 | JZ SCNS1B ;BRIF is first of two bytes 189 | SCNS1A: 190 | JMP SHORT SCNSO2 ;branch if not 1st of 2-bytes 191 | SCNS1B: 192 | MOV BYTE PTR TWOBYT,AL ;save char for next time 193 | JMP SHORT SCNSOX ;Set two byte flag and return 194 | SCNSO2: 195 | XOR AH,AH ;clear high-byte (not 2-byte char) 196 | SCNSO3: CALL SCNOL1 197 | SCNSOX: POP AX 198 | POPF 199 | RET 200 | 201 | ;SCNSOT level 1 202 | ; Outputs AX, destroys AX 203 | ; 204 | SCNOL1: 205 | DSEG SEGMENT PUBLIC 'DATASG' 206 | EXTRN LSTCHR:WORD 207 | DSEG ENDS 208 | ;For IBM Compatibility, the following filter performs the following translations 209 | ; x x x CR x x x === x x x CR LF x x x 210 | ; x x x CR LF x x x === x x x CR LF x x x 211 | ; 212 | ; If (Char = CR) then 213 | ; output CR : output LF 214 | ; else if (char <> LF) or (LSTCHR <> CR) then 215 | ; output char 216 | ; else 217 | ; {eat the LF which follows a CR} 218 | ; LSTCHR = CHR 219 | ; 220 | CMP BYTE PTR LSTCHR,LOW OFFSET ASCCR 221 | MOV BYTE PTR LSTCHR,AL ;save this char for comparison with next 222 | JNE NTCRLF ;branch if not LF after CR 223 | CMP AL,LOW OFFSET ASCLF 224 | JE RET22 ;eat LF if it follows CR 225 | NTCRLF: 226 | PUSH AX 227 | CALL SCNOL2 ;output this char 228 | POP AX 229 | CMP AL,LOW OFFSET ASCCR 230 | JNE RET22 ;if not CR, just output char 231 | MOV AX,OFFSET ASCLF ;else map CR to CR LF 232 | CALL SCNOL2 233 | RET22: RET 234 | 235 | ;SCNSOT level 2 236 | ; Output [AX], destroys AX 237 | ; 238 | SCNOL2: 239 | OR SI,SI 240 | JZ SCNSO8 ;BRIF is not file I/O 241 | CMP AL,LOW OFFSET ASCCR 242 | JZ SCNSO8 ;BRIF CR, don't do wrap 243 | PUSH AX ;save char to be output 244 | MOV AL,BYTE PTR CSRX 245 | OR AH,AH ;see if 2-byte char 246 | JZ SCNSO4 ;BRIF not DBLCHR 247 | INC AL ;Need two char posns for DBLCHR 248 | SCNSO4: 249 | CMP AL,BYTE PTR F_WID[SI] ;Compare posn with file width 250 | JA SCNSCR ;Beyond max, force CR 251 | CMP AL,BYTE PTR LINLEN 252 | JBE SCNSO7 ;Within line, go ahead and output 253 | DEC AL 254 | MOV BYTE PTR CSRX,AL ;Make sure there's room before end of line 255 | SCNSO7: POP AX ;restore char to be output 256 | SCNSO8: 257 | JMP SCNOUT ;Output the char in [AX] and return 258 | 259 | 260 | SCNSCR: CMP AL,BYTE PTR LINLEN 261 | JZ SCNSO7 ;BRIF file width .EQ. device width, use wrap code 262 | MOV AX,OFFSET ASCCR 263 | CALL SCNOUT ;Force new line 264 | MOV AX,OFFSET ASCLF 265 | CALL SCNOUT 266 | JMP SHORT SCNSO7 ;Output the character 267 | 268 | 269 | ;POS(X) function 270 | ; 271 | PUBLIC POS 272 | EXTRN SNGFLT:NEAR 273 | DSEG SEGMENT PUBLIC 'DATASG' 274 | EXTRN LINLEN:WORD 275 | DSEG ENDS 276 | POS: MOV AL,BYTE PTR CSRX ;[AL]=current 1 relative position 277 | CMP AL,BYTE PTR LINLEN 278 | JBE POS0 ;BRIF not beyond end of line 279 | MOV AL,LOW 1 ;Else next char will go in first column 280 | POS0: JMP SNGFLT ;return result to user 281 | 282 | ;SCNGPS - return current file position. 283 | ; Entry - SI points to File-Data-Block. 284 | ; Exit - [AH] = current file column. (0-relative) 285 | ; All other registers preserved 286 | ; 287 | DSEG SEGMENT PUBLIC 'DATASG' 288 | EXTRN CSRX:WORD 289 | DSEG ENDS 290 | SCNGPS: MOV AH,BYTE PTR CSRX 291 | PUSHF 292 | CMP AH,BYTE PTR LINLEN 293 | JBE SCNGP1 ;BRIF not beyond edge of screen 294 | MOV AH,BYTE PTR LINLEN ;Force posn within screen 295 | SCNGP1: POPF 296 | DEC AH ;Make it 0 relative 297 | RET 298 | 299 | ;SCNGWD - get device width 300 | ; Exit - [AH] = device width as set by xxxSWD 301 | ; All other registers preserved 302 | ; 303 | SCNGWD: 304 | DSEG SEGMENT PUBLIC 'DATASG' 305 | EXTRN LINLEN:WORD 306 | DSEG ENDS 307 | MOV AH,BYTE PTR LINLEN 308 | OR SI,SI 309 | JZ SCNGWX ;BRIF not file I/O, use device width 310 | MOV AH,BYTE PTR F_WID[SI] ;Is file I/O, use FDB width 311 | SCNGWX: RET 312 | 313 | ;SCNSCW - set device comma width 314 | ; Entry - [BX] = new device comma width 315 | ; Exit - SI, DI can be changed. 316 | ; All other registers preserved 317 | ; 318 | SCNSCW: RET 319 | 320 | ;SCNGCW - get device comma width 321 | ; Exit - [BX] = device comma width as set by xxxSCW 322 | ; All other registers preserved 323 | ; 324 | SCNGCW: RET 325 | 326 | CSEG ENDS 327 | END 328 | -------------------------------------------------------------------------------- /GIOTBL.ASM: -------------------------------------------------------------------------------- 1 | ; [ This translation created 10-Feb-83 by Version 4.3 ] 2 | 3 | .RADIX 8 ; To be safe 4 | 5 | CSEG SEGMENT PUBLIC 'CODESG' 6 | ASSUME CS:CSEG 7 | 8 | INCLUDE OEM.H 9 | 10 | TITLE GIOTBL - Device Name Table, Dispatch Table Address Tables 11 | ; Initialization and Termination Dispatch Tables 12 | 13 | COMMENT * 14 | 15 | --------- --- ---- -- --------- 16 | COPYRIGHT (C) 1982 BY MICROSOFT 17 | --------- --- ---- -- --------- 18 | 19 | * 20 | INCLUDE GIO86U 21 | .SALL 22 | 23 | INCLUDE MSDOSU ;MSDOS Constant Definitions 24 | IF CPM86 25 | INCLUDE CPM86U ;CPM86 Constant Definitions 26 | ENDIF 27 | 28 | .RADIX 10 29 | 30 | CPM86=0 ;CPM86 31 | 32 | ;Device Switches 33 | 34 | 35 | PUBLIC _DVTBL,_DVPTR,_DVINI,_DVTRM,$_NDEV 36 | 37 | EXTRN DSKDSP:NEAR 38 | EXTRN KYBDSP:NEAR,KYBINI:NEAR,KYBTRM:NEAR 39 | EXTRN SCNDSP:NEAR,SCNINI:NEAR,SCNTRM:NEAR 40 | EXTRN LPTDSP:NEAR,LPTINI:NEAR,LPTTRM:NEAR 41 | EXTRN COMDSP:NEAR,COMINI:NEAR,COMTRM:NEAR 42 | EXTRN CONDSP:NEAR,_RET:NEAR 43 | PAGE 44 | SUBTTL Device name table 45 | 46 | ;***************************************************************** 47 | ;*** *** 48 | ;*** Note: *** 49 | ;*** When adding additional devices, be sure to update *** 50 | ;*** OEMRAM to add device control blocks if necessary. *** 51 | ;*** Change $1STSD and $LSTSD if necessary. Change NMCOMT *** 52 | ;*** in switch file if adding COM device. *** 53 | ;*** *** 54 | ;****************************************************************** 55 | 56 | NDEV MACRO NAM,DSPADR,INIADR,TRMADR,N 57 | DEV NAM&N,DSPADR,INIADR,TRMADR 58 | ENDM 59 | 60 | NAMES MACRO 61 | DEV KYBD,KYBDSP,KYBINI,KYBTRM ;Keyboard 62 | DEV SCRN,SCNDSP,SCNINI,SCNTRM ;Crt 63 | DEV CONS,CONDSP,_RET,_RET ;Raw-I/O Crt (Esc Sequences) 64 | NLPT=0 65 | REPT NMLPT 66 | NLPT=NLPT+1 67 | NDEV LPT,LPTDSP,LPTINI,LPTTRM,%NLPT ;Line printer 68 | ENDM 69 | NCAS=0 70 | REPT GWCASS 71 | NCAS=NCAS+1 72 | NDEV CAS,CASDSP,CASINI,CASTRM,%NCAS ;Line printer 73 | ENDM 74 | NCOM=0 75 | REPT NMCOMT 76 | NCOM=NCOM+1 77 | NDEV COM,COMDSP,COMINI,COMTRM,%NCOM ;COM channel NCOM 78 | ENDM 79 | ENDM 80 | 81 | 82 | ;Generate DEVTBL ( text followed by device # ) 83 | ; 84 | NUM=377O 85 | DEV MACRO NAM,DSPADR,INIADR,TRMADR 86 | PUBLIC $_&NAM 87 | $_&NAM=NUM 88 | DB "&NAM&" 89 | DB OFFSET NUM 90 | NUM=NUM-1 91 | ENDM 92 | _DVTBL: 93 | NAMES 94 | DB 0 ;0 ends table 95 | 96 | $_NDEV=377O-NUM ;number of non-disk Devices 97 | 98 | ;Generate DEVPTR ( Addresses of dispatch tables ) 99 | ; 100 | DEV MACRO NAM,DSPADR,INIADR,TRMADR 101 | DW OFFSET DSPADR 102 | ENDM 103 | _DVPTR: 104 | DW (DSKDSP) ;1st entry in dispatch table is Disk Dispatch table 105 | NAMES ;then 1 entry for each device 106 | 107 | ;Generate Initialization Dispatch table 108 | ; 109 | DEV MACRO NAM,DSPADR,INIADR,TRMADR 110 | DW OFFSET INIADR 111 | ENDM 112 | _DVINI: 113 | NAMES ;address of initialization routine for each device 114 | 115 | ;Generate Termination Dispatch table 116 | ; 117 | DEV MACRO NAM,DSPADR,INIADR,TRMADR 118 | DW OFFSET TRMADR 119 | ENDM 120 | _DVTRM: 121 | NAMES ;address of termination routine for each device 122 | 123 | CSEG ENDS 124 | END 125 | 126 | -------------------------------------------------------------------------------- /GWBASIC.LNK: -------------------------------------------------------------------------------- 1 | GWDATA.OBJ+ 2 | ADVGRP.OBJ+ 3 | BIBOOT.OBJ+ 4 | BIMISC.OBJ+ 5 | BIPRTU.OBJ+ 6 | BIPTRG.OBJ+ 7 | BISTRS.OBJ+ 8 | CALL86.OBJ+ 9 | DSKCOM.OBJ+ 10 | FIVEO.OBJ+ 11 | GENGRP.OBJ+ 12 | GIO86.OBJ+ 13 | GIOCAS.OBJ+ 14 | GIOCOM.OBJ+ 15 | GIOCON.OBJ+ 16 | GIODSK.OBJ+ 17 | GIOKYB.OBJ+ 18 | GIOLPT.OBJ+ 19 | GIOSCN.OBJ+ 20 | GIOTBL.OBJ+ 21 | GWEVAL.OBJ+ 22 | GWINIT.OBJ+ 23 | GWLIST.OBJ+ 24 | GWMAIN.OBJ+ 25 | GWRAM.OBJ+ 26 | GWSTS.OBJ+ 27 | IBMRES.OBJ+ 28 | ITSA86.OBJ+ 29 | KANJ86.OBJ+ 30 | MACLNG.OBJ+ 31 | MATH.OBJ+ 32 | NEXT86.OBJ+ 33 | SCNDRV.OBJ+ 34 | SCNEDT.OBJ+ 35 | OEM.OBJ 36 | gwbasic /STACK:8192 37 | gwbasic.map; 38 | -------------------------------------------------------------------------------- /GWINIT.ASM: -------------------------------------------------------------------------------- 1 | ; [ This translation created 10-Feb-83 by Version 4.3 ] 2 | 3 | .RADIX 8 ; To be safe 4 | 5 | CSEG SEGMENT PUBLIC 'CODESG' 6 | ASSUME CS:CSEG 7 | 8 | INCLUDE OEM.H 9 | 10 | TITLE GWINIT GW-BASIC-86 Initialization 11 | 12 | ;Assumes LEN2, FIVMEM, FIVEO, I8086, PURE 13 | 14 | 15 | TRACEF=0 ;for Debugging when DEBUG can't be used 16 | CPM86=0 17 | DYNBUF=0 18 | BSEGSZ=0 ;Size of Buffer segment for Misc. Buffers 19 | 20 | .RADIX 10 21 | 22 | DSEG SEGMENT PUBLIC 'DATASG' 23 | ASSUME DS:DSEG 24 | EXTRN LSTVAR:WORD ;Last variable in RAM 25 | EXTRN FILTAB:WORD,STKLOW:WORD,MAXMEM:WORD 26 | EXTRN TSTACK:WORD,ERRFLG:WORD 27 | EXTRN MEMSIZ:WORD,TOPMEM:WORD,SAVSTK:WORD,FRETOP:WORD,TXTTAB:WORD 28 | EXTRN PROFLG:WORD,CHNFLG:WORD,MRGFLG:WORD,ERRFLG:WORD 29 | EXTRN CHNFLG:WORD,MRGFLG:WORD,ERRFLG:WORD 30 | EXTRN PRMSTK:WORD,PRMPRV:WORD 31 | DSEG ENDS 32 | 33 | EXTRN FCERR:NEAR,SNERR:NEAR 34 | 35 | ; 36 | SWTCHR=57O ;DEFAULT SWITCH CHARACTER IS SLASH 37 | EXTRN MAKUPL:NEAR 38 | EXTRN CNSGET:NEAR 39 | EXTRN CHRGTR:NEAR 40 | EXTRN OUTDO:NEAR,LINPRT:NEAR,CRDO:NEAR,OMERRR:NEAR 41 | EXTRN REASON:NEAR 42 | EXTRN READY:NEAR,STKINI:NEAR 43 | EXTRN DCOMPR:NEAR 44 | EXTRN SYNCHR:NEAR 45 | 46 | DSEG SEGMENT PUBLIC 'DATASG' 47 | EXTRN BUF:WORD 48 | DSEG ENDS 49 | EXTRN SNERR:NEAR,FCERR:NEAR,ATN:NEAR,COS:NEAR 50 | DSEG SEGMENT PUBLIC 'DATASG' 51 | EXTRN MSWFLG:WORD,MSWSIZ:WORD,CSWFLG:WORD,CSWSIZ:WORD,NEWDS:WORD 52 | DSEG ENDS 53 | EXTRN MAPCLC:NEAR,MAPINI:NEAR 54 | EXTRN INITSA:NEAR 55 | PAGE 56 | SUBTTL INIT - System Initialization Code 57 | 58 | PUBLIC INIT 59 | EXTRN STROUT:NEAR,HEDING:NEAR,WORDS:NEAR 60 | EXTRN GWINI:NEAR 61 | DSEG SEGMENT PUBLIC 'DATASG' 62 | EXTRN BUF:WORD,KBUF:WORD 63 | DSEG ENDS 64 | 65 | INIT: 66 | ; For safety, a label has been defined in BINTRP.MAC that contains the 67 | ; start of the data segment. That is where the O.S. control block will 68 | ; be copied to, so it MUST be first in the DSEG. 69 | ; BEGDSG is declared as a code segment external here even though it 70 | ; really is in the data segment. This makes it easier to get the offset 71 | ; of the beginning of the data segment from the beginning of the code 72 | ; segment. The beginning of DATASG MUST be within 64K of the beginning 73 | ; of CODESG for this to work. No error will be generated, so be careful. 74 | ; 75 | EXTRN BEGDSG:NEAR ;Beg. of the data segment, offset from CS 76 | INS86 272,,BEGDSG ;MOVI DX,BEGDSP 77 | INS86 261,4 ;MOVI CL,4 Divide by 16 to ... 78 | INS86 323,352 ;SHR DX,CL get paragraph address 79 | INS86 214,311 ;MOV CX,CS add in code segment 80 | INS86 3,321 ;ADD DX,CS 81 | INS86 264,46 ;MOVBI AH,38 SPECIAL FUNCTION TO CALC END 82 | ; OF CS AND RETURN START OF DS 83 | INS86 315,41 ;INT 33 CALL SCP DOS 84 | INS86 214,330 ;MOV AX,DS SAVE DS FOR EXIT VECTOR 85 | INS86 216,332 ;MOV DS,DX SET UP SEG REGS 86 | INS86 216,302 ;MOV ES,DX 87 | ;Initialize the jump vector for exit to MSDOS. MSDOS 2.0 requires that 88 | ; exit is made through the segment prefix table which is located at DS:0. 89 | ; For .EXE files, DS is not the same as CS at program initiation time (NOW). 90 | DSEG SEGMENT PUBLIC 'DATASG' 91 | EXTRN CPMEXT:WORD 92 | DSEG ENDS 93 | INS86 307,6,CPMEXT ;MOVI CPMEXT,^D0 94 | INS86 0,0 ; INS86 has 4 params 95 | ; & some may not be words 96 | INS86 220,243,CPMEXT+2 ;NOP NOP - pad to item 3 of INS86 97 | ;MOV CPMEXT+2,AX 98 | CLI ;Setting the stack segment and stack 99 | ;pointer must be an indivisable 100 | ;operation. 101 | INS86 216,322 ;MOV SS,DX 102 | MOV BX,OFFSET BUF+128D ;Use BUF for a temporary stack. 103 | MOV MEMSIZ,BX 104 | MOV SP,BX 105 | XOR AL,AL ;INITIALIZE PROTECT FLAG 106 | MOV BYTE PTR PROFLG,AL 107 | MOV BYTE PTR MSWFLG,AL ;Init /M: flag 108 | MOV BYTE PTR CSWFLG,AL ;Init /C: flag 109 | EXTRN CNSLEN:NEAR,CONSTR:NEAR 110 | DSEG SEGMENT PUBLIC 'DATASG' 111 | EXTRN ENDBUF:WORD,RAMLOW:WORD 112 | DSEG ENDS 113 | MOV CH,LOW OFFSET CNSLEN+3 ;Get number of bytes to move 114 | MOV BX,OFFSET RAMLOW ;WHERE THE CONSTANTS ARE STORE IN RAM 115 | MOV DX,OFFSET CONSTR ;WHERE THE CONSTANTS ARE HELD IN ROM 116 | MORMOV: ;MOVE ROM INITIALIZATION VALUES TO RAM 117 | INS86 213,362,56,254 ;CODE SEGMENT FETCH 118 | MOV BYTE PTR [BX],AL ;STORE IT AWAY IN RAM 119 | INC BX 120 | INC DX 121 | DEC CH 122 | JNZ SHORT MORMOV ;IF NOT, KEEP SHOVELING THEM DOWN 123 | STI 124 | EXTRN SCNIPL:NEAR 125 | CALL SCNIPL ;Screen editor initialization 126 | CALL GWINI ;OEM specific initialization 127 | EXTRN SNDRST:NEAR 128 | CALL SNDRST ;reset sound queue, disable speaker 129 | EXTRN GIOINI:NEAR 130 | CALL GIOINI 131 | MOV BX,MEMSIZ 132 | MOV TOPMEM,BX 133 | MOV BX,OFFSET KBUF-1 ;INITIALIZE KBUF-1 WITH A COLON 134 | MOV BYTE PTR [BX],LOW ":" ;DIRECT INPUTS RESTART OK. 135 | CALL STKINI ;REALLY SET UP INIT'S TEMPORARY STACK 136 | ; 137 | ; Check CP/M Version Number 138 | 139 | DSEG SEGMENT PUBLIC 'DATASG' 140 | EXTRN CPMREA:WORD 141 | DSEG ENDS 142 | 143 | MOV BX,OFFSET 34*256+33+0 ;2.x Read / Write 144 | CPMVR1: MOV CPMREA,BX ;Save Read/Write Codes 145 | DSEG SEGMENT PUBLIC 'DATASG' 146 | EXTRN CNTOFL:WORD 147 | DSEG ENDS 148 | XOR AL,AL 149 | MOV BYTE PTR CNTOFL,AL 150 | DSEG SEGMENT PUBLIC 'DATASG' 151 | EXTRN ENDBUF:WORD 152 | DSEG ENDS 153 | MOV BYTE PTR ENDBUF,AL ;MAKE SURE OVERRUNS STOP 154 | DSEG SEGMENT PUBLIC 'DATASG' 155 | EXTRN DSEGZ:WORD 156 | DSEG ENDS 157 | MOV BYTE PTR DSEGZ,AL ;(DS) LOCATED ZERO 158 | MOV BYTE PTR CHNFLG,AL ;MAKE SURE CHAINS AND MERGES 159 | MOV BYTE PTR MRGFLG,AL ;DONT TRY TO HAPPEN 160 | MOV BYTE PTR ERRFLG,AL ;DON'T ALLOW EDIT TO BE CALLED ON ERRORS 161 | DSEG SEGMENT PUBLIC 'DATASG' 162 | EXTRN TEMPST:WORD,TEMPPT:WORD 163 | DSEG ENDS 164 | MOV BX,OFFSET TEMPST 165 | MOV TEMPPT,BX 166 | MOV BX,OFFSET PRMSTK ;INITIALIZE PARAMETER BLOCK CHAIN 167 | MOV PRMPRV,BX 168 | 169 | 170 | SUBTTL Read Operating System Parameters (memsiz etc.) 171 | 172 | 173 | ; THE FOLLOWING CODE SCANS A CP/M COMMAND LINE FOR BASIC. 174 | 175 | ; THE FOLLOWING SWITCHES ARE RECOGNIZED: 176 | ; 177 | ; /M: 178 | ; /F: 179 | ; /S: 180 | ; /C: 181 | ; 182 | DSEG SEGMENT PUBLIC 'DATASG' 183 | EXTRN CPMMEM:WORD 184 | DSEG ENDS 185 | MOV BX,CPMMEM ;Load bytes free within segment 186 | ;For DYNCOM, CPMMEM holds the last segment addr of the system(i.e. CPMMEM=2) 187 | EXTRN SEGOFF:NEAR 188 | CALL SEGOFF ;Return byte offset of segment from current DS 189 | MOV MEMSIZ,BX ;USE AS DEFAULT 190 | MOV MAXMEM,BX ;set MAX DS size for CLEAR statement 191 | DSEG SEGMENT PUBLIC 'DATASG' 192 | EXTRN DSEGZ:WORD 193 | DSEG ENDS 194 | MOV BX,OFFSET DSEGZ ;IN THE DATA SEGMENT 195 | MOV TEMP8,BX ;SO IF RE-INITAILIZE OK 196 | EXTRN CPMWRM:NEAR 197 | TBUFF EQU CPMWRM+128D ;WHERE CP/M COMMAND BUFFER IS LOCATED 198 | 199 | MOV BX,OFFSET TBUFF ;POINT TO FIRST CHAR OF COMMAND BUFFER 200 | MOV AL,BYTE PTR [BX] ;WHICH CONTAINS # OF CHARS IN COMMAND 201 | OR AL,AL ;IS THERE A COMMAND? 202 | MOV TEMP8,BX ;SAVE POINTER TO THIS ZERO 203 | JNZ SHORT ??L000 204 | JMP DONCMD ;NOTHING IN COMMAND BUFFER 205 | ??L000: 206 | MOV CH,BYTE PTR [BX] ;AND [B] 207 | INC BX ;POINT TO FIRST CHAR IN BUFFER 208 | TBFLP: MOV AL,BYTE PTR [BX] ;GET CHAR FROM BUFFER 209 | DEC BX ;BACK UP POINTER 210 | MOV BYTE PTR [BX],AL ;STORE CHAR BACK 211 | INC BX ;NOW ADVANCE CHAR TO ONE PLACE 212 | INC BX ;AFTER PREVIOUS POSIT. 213 | DEC CH 214 | JNZ SHORT TBFLP ;KEEP MOVING CHARS 215 | DEC BX ;BACK UP POINTER 216 | ENDCMD: MOV BYTE PTR [BX],LOW 0 ;STORE TERMINATOR FOR CHRGET (0) 217 | MOV TEMP8,BX ;SAVE POINTER TO NEW ZERO (OLD DESTROYED) 218 | MOV BX,OFFSET TBUFF-1 ;POINT TO CHAR BEFORE BUFFER 219 | CALL CHRGTR ;IGNORE LEADING SPACES 220 | OR AL,AL 221 | JNZ SHORT ??L001 222 | JMP DONCMD ;END OF COMMAND 223 | ??L001: 224 | CMP AL,LOW OFFSET SWTCHR ;IS IT A SLASH 225 | JZ SHORT FNDSLH ;YES 226 | DEC BX ;BACK UP POINTER 227 | MOV BYTE PTR [BX],LOW 34 ;STORE DOUBLE QUOTE 228 | MOV TEMP8,BX ;SAVE POINTER TO START OF FILE NAME 229 | INC BX ;BUMP POINTER 230 | ISSLH: CMP AL,LOW OFFSET SWTCHR ;OPTION? 231 | JZ SHORT FNDSLH ;YES 232 | CALL CHRGTR ;SKIP OVER CHAR IN FILE NAME 233 | OR AL,AL ;SET CC'S 234 | JNZ SHORT ISSLH ;KEEP LOOKING FOR OPTION 235 | JMP DONCMD ;THATS IT 236 | FNDSLH: MOV BYTE PTR [BX],LOW 0 ;STORE TERMINATOR OVER "/" 237 | SCANSW: 238 | CALL CHRGTR ;GET CHAR AFTER SLASH 239 | SCANS1: 240 | CALL MAKUPL ;CONVERT SWITCH TO UPPER CASE 241 | CMP AL,LOW "S" ;IS IT /S: ? (SET MAX RECORD SIZE) 242 | JZ SHORT WASS 243 | CMP AL,LOW "C" ;COM buffer size option 244 | JZ SHORT WASC 245 | CMP AL,LOW "F" ;FILES OPTION 246 | JZ SHORT WASF 247 | CMP AL,LOW "M" ;MEMORY OPTION 248 | JZ SHORT ??L002 249 | JMP SNERR ;Branch if couldn't recognize option 250 | ??L002: 251 | CALL GETVAL ;[DX]=requested MEMSIZ 252 | MOV MSWSIZ,DX ;Record memory request 253 | MOV AL,LOW 377O 254 | MOV BYTE PTR MSWFLG,AL ;Set /M: option flag 255 | FOK: DEC BX ;RESCAN LAST CHAR 256 | CALL CHRGTR ;BY CALLING CHRGET 257 | JZ SHORT DONCMD ;END OF COMMAND 258 | CALL SYNCHR 259 | DB OFFSET SWTCHR ;SLASH SHOULD FOLLOW 260 | JMP SHORT SCANS1 ;SCAN NEXT SWITCH 261 | 262 | WASC: MOV AL,LOW 377O 263 | MOV BYTE PTR CSWFLG,AL ;Set /C: option flag 264 | CALL GETVAL ;Get COM request to D,E 265 | MOV CSWSIZ,DX ;Record for future memory map calc. 266 | JMP SHORT FOK 267 | WASS: ;GIO has dynamic record size 268 | WASF: ;GIO has dynamic number of files 269 | CALL GETVAL ;Get value 270 | JMP SHORT FOK ;Any value OK (and ignored) 271 | 272 | GETVAL: CALL CHRGTR ;skip M,F or S 273 | CALL SYNCHR 274 | DB OFFSET ":" ;MAKE SURE COLON FOLLOWS 275 | JMP CNSGET ;[DE]=VALUE FOLLOWING COLON 276 | DSEG SEGMENT PUBLIC 'DATASG' 277 | EXTRN TEMP8:WORD ;POINTER TO BASIC LOAD FILE 278 | DSEG ENDS 279 | ERRCMD: 280 | DONCMD: 281 | CALL MAPCLC ;Calc. (but don't set) the new mem. map 282 | 283 | ;Now copy the command line file name (if there is one) to BUF 284 | ;Move required since DS: segment header will be overwritten when the 285 | ;DS: is coppied to the new DS: location. 286 | 287 | MOV BX,TEMP8 ;Load address of command line file name 288 | MOV DX,OFFSET BUF ;Destination address 289 | MOV TEMP8,DX ;New command line buffer address 290 | NXTBYT: MOV AL,BYTE PTR [BX] ;File name character 291 | XCHG BX,DX 292 | MOV BYTE PTR [BX],AL ;Store at BUF 293 | INC BX 294 | XCHG BX,DX 295 | INC BX 296 | OR AL,AL ;Test for zero byte terminator 297 | JNZ SHORT NXTBYT ;Get next file name character 298 | 299 | SUBTTL Allocate Space for Disk Buffers 300 | 301 | ; Disk Initialization Routine 302 | 303 | ; setup file info blocks 304 | ; the number of each and information for 305 | ; getting to pointers to each is stored. no locations are 306 | ; initialized, this is done by nodsks, first closing all files. 307 | ; the number of files is the file pointer table 308 | ; 309 | MOV BX,MEMSIZ ;get size of memory 310 | DEC BX ;always leave top byte unused because 311 | ;val(string) makes byte in memory 312 | ;beyond last char of string=0 313 | MOV MEMSIZ,BX ;save in real memory size 314 | DEC BX ;one lower is stktop 315 | PUSH BX ;save it on stack 316 | 317 | 318 | SUBTTL INIT TXTAB, STKTOP, VARTAB, MEMSIZ, FRETOP, STREND 319 | 320 | ; Memory map for GW-BASIC: 321 | ; 322 | ; [MAXMEM]--} highest byte of physical memory in system 323 | ; user managed memory 324 | ; [TOPMEM]--} highest byte available to BASIC 325 | ; basic stack 326 | ; [STKLOW]--} lowest byte available for STACK 327 | ; +--}FDB---}[STKEND] {end of chain} 328 | ; +---FDB{--+ 329 | ; [FILTAB]-------}FDB---+ (FILTAB points to lowest byte of lowest FDB) 330 | ; 0 (1 byte string space terminator for VAL) 331 | ; [MEMSIZ]--} highest byte of IN-USE string space 332 | ; [FRETOP]--} highest byte of FREE string space 333 | ; [STREND]--} lowest byte of FREE string space 334 | ; [ARYTAB]--} lowest byte of Array Table 335 | ; [VARTAB]--} lowest byte of Variable Table 336 | ; [TXTTAB]--} lowest byte of BASIC Program Text 337 | ; 338 | ; note: when [FILTAB] = [STKLOW], no FDB's are allocated. 339 | ; when [FRETOP] = [MEMSIZ], IN-USE string space is empty. 340 | ; when [SP] = [STKLOW], STACK is full. 341 | 342 | ; At this point, MEMSIZ-1 is on stack, [HL]=TXTTAB-1 343 | ; 344 | MOV BX,OFFSET LSTVAR ;LSTVAR resides in last linked module with DS: 345 | MOV TXTTAB,BX ;save bottom of memory 346 | POP DX ;GET CURRENT MEMSIZ 347 | MOV AL,DL ;WANT AN EVEN STACK PTR. FOR 8086 348 | AND AL,LOW 254D ;SO WE'LL CLEAR LOW BIT 349 | MOV DL,AL ;OF THE STACK PTR. 350 | MOV AL,DL ;CALC TOTAL FREE/8 351 | SUB AL,BL 352 | MOV BL,AL 353 | MOV AL,DH 354 | SBB AL,BH 355 | MOV BH,AL 356 | JAE SHORT ??L003 357 | JMP OMERRR 358 | ??L003: 359 | MOV CL,LOW 3 ;SHIFT RIGHT THREE BITS (DIVIDE BY 8) 360 | INS86 323,353 ;SHR BX,CL 361 | MOV AL,BH ;SEE HOW MUCH 362 | CMP AL,LOW 2 ;IF LESS THAN 512 USE 1 EIGHTH 363 | JB SHORT SMLSTK 364 | MOV BX,512D 365 | SMLSTK: MOV AL,DL ;SUBTRACT STACK SIZE FROM TOP MEM 366 | SUB AL,BL 367 | MOV BL,AL 368 | MOV AL,DH 369 | SBB AL,BH 370 | MOV BH,AL 371 | JAE SHORT ??L004 372 | JMP OMERRR 373 | ??L004: 374 | 375 | MOV STKLOW,BX ;Save lowest legal value for [SP] 376 | MOV FILTAB,BX ;Initially there are no FDB's 377 | DEC BX 378 | MOV BYTE PTR [BX],LOW 0 ;String space should be terminated by 0 for VAL 379 | DEC BX 380 | MOV MEMSIZ,BX ;Save highest byte to be used by strings 381 | XCHG BX,DX 382 | MOV TOPMEM,BX 383 | MOV FRETOP,BX ;REASON USES THIS... 384 | MOV SP,BX ;SET UP NEW STACK 385 | MOV SAVSTK,BX 386 | MOV BX,TXTTAB 387 | XCHG BX,DX 388 | CALL REASON 389 | DSEG SEGMENT PUBLIC 'DATASG' 390 | EXTRN FREFLG:WORD ;Print free bytes flag 391 | DSEG ENDS 392 | XOR AL,AL 393 | MOV BYTE PTR FREFLG,AL ;Clear to print free bytes message 394 | EXTRN GETHED:NEAR ;OEM heading retrieval routine 395 | DSEG SEGMENT PUBLIC 'DATASG' 396 | EXTRN KEYSW:WORD ;Function key on flag 397 | DSEG ENDS 398 | MOV AL,LOW 255D ;if heading is printed, display Fn keys also 399 | MOV BYTE PTR KEYSW,AL 400 | CALL GETHED ;Get OEM specific portion of the heading 401 | JNZ SHORT PRNTIT ;Always print the heading option 402 | PUSH BX ;Print heading if no program option 403 | MOV BX,TEMP8 ;Get pointer to file or 0 404 | MOV AL,BYTE PTR [BX] ;Test for file on command line 405 | POP BX ;Retrieve OEM heading pointer 406 | OR AL,AL 407 | JZ SHORT PRNTIT ;No program - go print heading 408 | MOV BYTE PTR FREFLG,AL ;Set to inhibit free bytes message 409 | XOR AL,AL ;Turn keys off if there is a program 410 | MOV BYTE PTR KEYSW,AL ; otherwise allow OEM default 411 | JMP SHORT PRNTND ;Skip heading 412 | 413 | PRNTIT: CALL STROUT ;Print it 414 | MOV BX,OFFSET HEDING ;GET HEADING ("BASIC VERSION...") 415 | CALL STROUT ;PRINT IT 416 | PRNTND: 417 | EXTRN SKEYON:NEAR 418 | MOV AL,BYTE PTR KEYSW ;Get function key display switch 419 | OR AL,AL ;Keys need to be turned on? 420 | JNZ SHORT ??L005 421 | JMP KEYSOF ;Leave keys off 422 | ??L005: 423 | XOR AL,AL 424 | MOV BYTE PTR KEYSW,AL ;Show current status of keys 425 | CALL SKEYON ;Set function key display on 426 | KEYSOF: MOV AL,LOW 377O 427 | MOV BYTE PTR INITFG,AL ;Set the initialization complete flag 428 | ;indicating errors no longer result in an exit 429 | ;to the OS 430 | JMP INITSA 431 | PAGE 432 | ;CMDERR This routine is called when an error is detected before the 433 | ; completion of initialization (before INITFG is set to non-zero). 434 | ; CMDERR performs the following: 435 | ; 1. Write the heading 436 | ; 2. Write an error message implicating the command line. 437 | ; 3. Exit to the operating system through SYSTME 438 | 439 | DSEG SEGMENT PUBLIC 'DATASG' 440 | EXTRN INITFG:WORD 441 | DSEG ENDS 442 | EXTRN SYSTME:NEAR,CERMSG:NEAR 443 | PUBLIC CMDERR 444 | 445 | CMDERR: MOV BX,OFFSET HEDING ;Get heading ("BASIC VERSION...") 446 | CALL STROUT ;Print it 447 | MOV BX,OFFSET CERMSG ;Get command error message 448 | CALL STROUT ;Print it 449 | JMP SYSTME ;Exit to the OS 450 | 451 | PUBLIC $LAST 452 | $LAST=$ 453 | PUBLIC LASTWR 454 | LASTWR=$ 455 | CSEG ENDS 456 | END 457 | -------------------------------------------------------------------------------- /GWRAM.ASM: -------------------------------------------------------------------------------- 1 | ; [ This translation created 10-Feb-83 by Version 4.3 ] 2 | 3 | .RADIX 8 ; To be safe 4 | 5 | CSEG SEGMENT PUBLIC 'CODESG' 6 | ASSUME CS:CSEG 7 | 8 | INCLUDE OEM.H 9 | 10 | TITLE GWRAM - GW BASIC OEM Independent RAM Declarations 11 | 12 | COMMENT * 13 | --------- --- ---- -- --------- 14 | COPYRIGHT (C) 1981 BY MICROSOFT 15 | --------- --- ---- -- --------- 16 | * 17 | 18 | INCLUDE GIO86U 19 | .SALL 20 | 21 | .RADIX 10 22 | 23 | MUSIC=PLAYSW OR BEEPSW 24 | GRPMCL=1 25 | NMPAGE=1 26 | 27 | PUBLIC HEDING,$DATE,CERMSG 28 | 29 | QUOTE=42O 30 | CR=15O 31 | ; 32 | 33 | PAGE 34 | SUBTTL Sign on message and other data to be discarded after INIT 35 | 36 | HEDING: ACRLF 37 | DB "(C) Copyright Microsoft 1982" 38 | $DATE: DB " " ;$DATE 39 | ACRLF 40 | DB 00O ;Terminate previous string. 41 | 42 | CERMSG: ACRLF ;Command line error message 43 | DB "Error detected in command line" 44 | ACRLF 45 | DB 00O 46 | 47 | CSEG ENDS ; End of code segment constants 48 | PAGE 49 | DSEG SEGMENT PUBLIC 'DATASG' ; Start of data segment GW variables 50 | ASSUME DS:DSEG 51 | 52 | ; 53 | ; ASM86 version don't need to fool around with offsets into OEMBAS, 54 | ; as the linker can preload segments with data. Thus, the R macros 55 | ; need only define the label and a size if the variable is not intitalized. 56 | ; 57 | R1 MACRO NAME,SIZE 58 | Q=Q+SIZE 59 | QDS=QDS+SIZE 60 | PUBLIC NAME 61 | ORG $-1 62 | NAME LABEL WORD 63 | ORG $+1 64 | IF SIZE 65 | DB SIZE DUP(?) 66 | ENDIF 67 | ENDM 68 | 69 | R MACRO NAME,SIZE 70 | Q=Q+SIZE 71 | QDS=QDS+SIZE 72 | PUBLIC NAME 73 | NAME LABEL WORD 74 | IF SIZE 75 | DB SIZE DUP(?) 76 | ENDIF 77 | ENDM 78 | 79 | RINIT MACRO NAME,SIZE 80 | PUBLIC NAME 81 | NAME LABEL WORD 82 | QQ=NAME-MOVDAT-Q 83 | IF QQ 84 | %OUT *FATAL RINIT ERROR* 85 | ENDIF 86 | Q=Q+SIZE 87 | QDS=QDS+SIZE 88 | ENDM 89 | 90 | ACRLF MACRO 91 | DB 13D 92 | DB 10D 93 | ENDM 94 | 95 | 96 | Q=0 97 | QDS=0 98 | RINIT MOVDAT,0 99 | RINIT FREFLG,1 ;Flag to print BYTES FREE message 100 | DB 0D 101 | RINIT INITFG,1 ;Initialization complete flag 102 | DB 0D ;INITFG 103 | RINIT ESCFLG,1 ;Escape seq. in progress flag 104 | DB 0D 105 | RINIT TWOBYT,1 ;Save location for collecting two byte chars 106 | DB 0D 107 | 108 | ; 109 | ; Keyboard Support Variables 110 | ; 111 | RINIT STRTAB,16D*NMKEYF ;SOFTKEY table 112 | ; 113 | ;** The following line is used by a source maint. tool - do not remove 114 | ;** (OEM FUNCTION KEY DEFINITIONS) ************** 115 | ; 116 | DB "LIST" ;FUNCTION 1 117 | DB 0D 118 | DB 11D DUP(?) 119 | DB "RUN" ;FUNCTION 2 120 | DB OFFSET CR,0 121 | DB 11D DUP(?) 122 | DB "LOAD" ;FUNCTION 3 123 | DB OFFSET QUOTE,0 124 | DB 10D DUP(?) 125 | DB "SAVE" ;FUNCTION 4 126 | DB OFFSET QUOTE,0 127 | DB 10D DUP(?) 128 | DB "CONT" ;FUNCTION 5 129 | DB OFFSET CR,0 130 | DB 10D DUP(?) 131 | DB "," ;FUNCTION 6 132 | DB OFFSET QUOTE 133 | DB "LPT1:" 134 | DB OFFSET QUOTE,0 135 | DB 7D DUP(?) 136 | DB "TRON" ;FUNCTION 7 137 | DB OFFSET CR,0 138 | DB 10D DUP(?) 139 | DB "TROFF" ;FUNCTION 8 140 | DB OFFSET CR,0 141 | DB 9D DUP(?) 142 | DB "KEY" ;FUNCTION 9 143 | DB 0D 144 | DB 12D DUP(?) 145 | DB "SCREEN 0,0,0" ;FUNCTION : 146 | DB OFFSET CR,0 147 | DB 2D DUP(?) 148 | ;**(END OF DEFINITIONS) ************************* 149 | ;The preceding line is used by a source maint. tool - do not remove. 150 | ; 151 | RINIT ENDTAB,0 152 | DIST=ENDTAB-STRTAB-(16D*NMKEYF) 153 | IF DIST 154 | %OUT/++++BAD SOFTKEY PADDING+++++/ 155 | ENDIF 156 | 157 | 158 | RINIT CMDOFF,2 ;Index into ESCBUFF or STRTAB 159 | DW 0D 160 | RINIT FKCNUM,1 ;Number of chars. per fun. key to display 161 | DB 6D ; on the last line 162 | RINIT ACTPAG,1 ;Active page 163 | DB 1 DUP(?) 164 | RINIT F_EDPG,1 ; Flag - =^O377 indicates program statement edit 165 | DB 0 166 | RINIT SEMFLG,1 ; Flag - non-zero indicates INPUT; statement(no 167 | DB 0 ; CRLF at end of input) 168 | RINIT F_CRET,1 ;Zero indicates last character output was CR 169 | DB 377O 170 | RINIT F_INST,1 ; Flag - =^O377 indicates insert mode 171 | DB 0 172 | RINIT F_EDIT,1 ; Flag - non-zero indicates INLIN active 173 | DB 0 174 | ; 175 | ;MACLNG variables for DRAW 176 | ; 177 | RINIT DRWSCL,1 ;DRAW: SCALE 178 | DB 00O ;DRAW POS,2 ling factor 179 | RINIT DRWFLG,1 ;OPTION FLAGS 180 | DB 00O ;DRAW flag 181 | RINIT DRWANG,1 ;DRAW "ANGLE" (0..3) 182 | DB 00O ;DRAW translation angle 183 | RINIT MCLPTR,2 ;MAC LANG PTR 184 | DB 2 DUP(?) ;Other DRAW vars. not initialized 185 | RINIT MCLLEN,1 ;STRING LENGTH 186 | DB 1 DUP(?) 187 | RINIT MCLTAB,2 ;PTR TO COMMAND TABLE 188 | DB 2 DUP(?) 189 | ;OEM Independent Music Locations 190 | RINIT OCTAVE,1 ;PLAY: OCTAVE 191 | DB 4D ;OCTAVE 192 | RINIT BEATS,1 ;BEATS 193 | DB 120D ;BEATS (default = 120 L4 notes per minute) 194 | RINIT NOTELN,1 ;NOTE LENGTH 195 | DB 4D ;NOTELN 196 | RINIT NOTE1L,1 ;One (current) Note Length 197 | DB 4D ;NOTE1L 198 | RINIT MSCALE,1 ;Note Length Scale Factor (ML,MN,MS) 199 | DB 3D ;MSCALE (default = 7/8 time) 200 | RINIT MMODE,1 ;Music Mode (Foreground/Background) 201 | DB 0D ;MMODE (default = forground) 202 | RINIT SNDTIC,1 ;Sound/Clock tick modulo counter 203 | DB 1 DUP(?) 204 | RINIT SNDBAS,2 ;Base addr of Sound Queue Cells 205 | DB 2 DUP(?) 206 | RINIT SNDOUT,2 ;Base addr of Sound Queue Buffer 207 | DB 2 DUP(?) 208 | PAGE 209 | SUBTTL Page Dependent OEM Independent Variables 210 | 211 | ; Page Dependent variables arranged as follows: 212 | ; Variables which are initialized by block move are declared using the RINIT 213 | ; macro. These declarations are made within the definition of macro PDIRAM 214 | ; (page dependent initialized RAM). 215 | ; Variables which are not initialized by block move are declared using the R 216 | ; macro. These declarations are made within the definition of macro PDURAM 217 | ; (page dependent uninitialized RAM). 218 | ; The memory map for multi page page dependent variables is as follows: 219 | ;-------------------------------------------------------------------------- 220 | ; 221 | ; CS: resident initialization values are copied to DS: by the same copy 222 | ; as usual. 223 | ; 224 | ;-------------------------------------------------------------------------- 225 | ; 226 | ; DS:PDIDS1: ;Beginning of ini value block copied from CS: 227 | ; ; This block is used to initialize pages at 228 | ; ; various times during execution. 229 | ; 230 | ; (initialization values set by CS: to DS: block move) 231 | ; 232 | ; DS:FPDVAR: ;First page dependent variable 233 | ; 234 | ; (first come vars initializable by block move from PDIDS1. 235 | ; Then come all other vars. which are page dependent.) 236 | ; 237 | ; DS:LPDVAR: ;Address of end of variables for active page 238 | ; ; The variables between FPDVAR and LPDVAL are the 239 | ; ; ones that are labeled as per RINIT and R macros. 240 | ; 241 | ; (Lastly comes (LPDVAR-FPDVAR)*NMPAGE RAM locations used to store the state 242 | ; of each page while it is not active.) 243 | ; 244 | ;In systems where only one page is available label FPDVAL is made to 245 | ; coincide with label PDIDS1 and there are no locations reserved to store 246 | ; the state of the page while it is not active. 247 | ; 248 | 249 | PUBLIC PDIDS1 ;Start of DS: init block. 250 | PUBLIC FPDVAR,LPDVAR ;Addresses of first and last active page vars in DS: 251 | 252 | PDIRAM MACRO 253 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 254 | ; Start of declaration of page dependent variables 255 | ; which are initialized by block move either by 256 | ; GWINIT (for one page systems) or 257 | ; PDVINI (Page Dependent Var INI for multi-page systems 258 | ; 259 | ;CAUTION!!! 260 | ; 261 | ; The PDIRAM module is invoked several times. CS: space should be 262 | ; reserved only once. To solve this problem pseudos which declare 263 | ; CS: values must be accessed through a macro which can either be 264 | ; defined as calls to the appropriate pseudo or as NOPs. 265 | ; Currently, DB, DW, and DT are the only macros supported in this manner. 266 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 267 | 268 | ; 269 | ;Screen Editor Support Variables 270 | ; 271 | 272 | RINIT KEYSW,1 ;Flag for softkey display 273 | DB 0 ;Flag: 0=do not display softkeys. 274 | ENDM 275 | 276 | PDURAM MACRO 277 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 278 | ; Start of declaration of page dependent variables 279 | ; 280 | ; The PDRAM module is invoked several times. CS: space should 281 | ; not be reserved. DS: lables must be declared only once. 282 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 283 | 284 | ;The following is page dependent data unique to the SCNDRV module 285 | ; 286 | R LINLEN,1 ; Number of characters in a line 287 | R LINCNT,1 ; Number of lines 288 | R CRTWID,1 ; Characters per line 289 | R WDOTOP,1 ; Top line in window(1-[LINCNT]) 290 | R WDOBOT,1 ; Bottom line in window([WDOTOP]-[LINCNT]) 291 | R WDOLFT,1 ; Leftmost column in window(1-[CRTWID]) 292 | R WDORGT,1 ; Rightmost column plus one([WDOLFT]-[LINCNT]) 293 | R WDTFLG,1 ; Default width of SCRN: 294 | R LINTTB,2*(NMLINE+1) ; Line Terminator table 295 | R TRMCUR,2 ; Address of current terminator entry (2 bytes) 296 | R FSTLIN,1 ; Line number saved by SCNSTM call 297 | R FSTCOL,1 ; Column saved as above and decreases to WDOLFT 298 | R LSTLIN,1 ; Line number saved by SCNSTM and grows as the 299 | R LSTCOL,1 ; Column saved as above which grows as the 300 | ; col on LSTLIN). 301 | 302 | ;NOTE: Some Routines expect CSRX to immediately follow CSRY 303 | R CSRY,1 ; Current line(1-[LINCNT]) 304 | R CSRX,1 ; Current column(1-[CRTWID]) 305 | ENDM 306 | 307 | 308 | RINIT MACRO NAME,SIZE 309 | QDS=QDS+SIZE 310 | ENDM 311 | 312 | QDS=Q 313 | 314 | R PDIDS1,0 ;Page Dependent DS: init. value block start 315 | PDIRAM ;Insert Ini values 316 | FPDVAR=PDIDS1 ;INI area and First Page Dependent VARiable 317 | ; are overlaid in this case 318 | RINIT MACRO NAME,SIZE 319 | PUBLIC NAME 320 | NAME LABEL WORD 321 | QQ=NAME-MOVDAT-QDS 322 | IF QQ 323 | %OUT *FATAL RINIT ERROR* 324 | ENDIF 325 | Q=Q+SIZE 326 | QDS=QDS+SIZE 327 | ENDM 328 | 329 | ;Although RINIT is used subsequently there are no more CS: RAM locations 330 | ; to declare. The RINIT will be used for DS: declaration only 331 | ; 332 | ; 333 | ; Now declare the labeled DS: for 1 page systems. This area is the 334 | ; labeled active page for multi-page systmes 335 | ; 336 | PDIRAM ;Declare Active Page Inited RAM 337 | ; 338 | PDURAM ;Declare Active Page Uninit RAM 339 | R LPDVAR,0 ;End of active page vars in DS: 340 | 341 | RINIT MACRO NAME,SIZE 342 | IF SIZE 343 | DB SIZE DUP(?) 344 | QDS=QDS+SIZE 345 | ENDIF 346 | ENDM 347 | R MACRO NAME,SIZE 348 | IF SIZE 349 | DB SIZE DUP(?) 350 | QDS=QDS+SIZE 351 | ENDIF 352 | ENDM 353 | ; 354 | ;Now put back the R macro for use by Page Independent Uninitialized RAM 355 | ; declarations. 356 | ; 357 | ;P.I.U. RAM MUST be declared after all P.D.U. RAM, P.D.I. RAM, 358 | ; and P.I.I. RAM. 359 | ; 360 | 361 | R MACRO NAME,SIZE 362 | PUBLIC NAME 363 | NAME LABEL WORD 364 | IF SIZE 365 | DB SIZE DUP(?) 366 | ENDIF 367 | QQ=NAME-MOVDAT-QDS 368 | IF QQ 369 | %OUT *FATAL RINIT ERROR* 370 | ENDIF 371 | Q=Q+SIZE 372 | QDS=QDS+SIZE 373 | ENDM 374 | PAGE 375 | SUBTTL Page Independent Uninitialized RAM Location Definitions 376 | 377 | ;OEM Independent Graphics Locations 378 | ; 379 | R GRPACX,2 ; Previous X Coordinate 380 | R GRPACY,2 ; Previous Y Coordinate 381 | R ATRBYT,1 ;Attribute Byte to Store 382 | R GXPOS,2 ;X Position of Second Coordinate 383 | R GYPOS,2 ;Y Position of Second Coordinate 384 | R1 MAXUPD,2 ;Address of Major Axis Move Update 385 | R1 MINUPD,2 ;Address of Minor Axis Move Update 386 | R MAXDEL,2 ;Largest Delta for Line 387 | R MINDEL,2 ;Smaller of 2 Deltas for Line 388 | R ASPECT,2 ;ASPECT RATIO 389 | R CENCNT,2 ;END CIRCLE POINT COUNT 390 | R CLINEF,1 ;LINE-TO-CENTER FLAG 391 | R CNPNTS,2 ;1/8 NO. OF PTS IN CIRCLE 392 | R CPLOTF,1 ;PLOT FLAG 393 | R CPCNT,2 ;1/8 NO. OF PTS IN CIRCLE 394 | R CPCNT8,2 ;NO. OF PTS IN CIRCLE 395 | R CRCSUM,2 ;CIRCLE SUM 396 | R CSTCNT,2 ;START COUNT 397 | R CSCLXY,1 ;FLAG WHETHER ASPECT WAS .GT. 1 398 | R CSAVEA,2 ;ADVGRP C save area 399 | R CSAVEM,1 ;ADVGRP C save area 400 | R CXOFF,2 ;X OFFSET FROM CENTER SAVE LOC 401 | R CYOFF,2 ;Y OFFSET SAVE LOCATION 402 | R LOHMSK,1 ;RAM SAVE AREA FOR LEFT OVERHANG 403 | R LOHDIR,1 ;*** LOHMSK & LOHDIR MUST BE CONTIG ! 404 | R LOHADR,2 405 | R LOHCNT,2 406 | R LFPROG,1 ;PAINT: SCAN LINE ALREADY PAINTED FLAGS 407 | R RTPROG,1 408 | R SKPCNT,2 ;SKIP COUNT 409 | R MOVCNT,2 ;MOVE COUNT 410 | R PDIREC,1 ;PAINT DIRECTION 411 | R PUTFLG,1 ;WHETHER DOING PUT() OR GET() 412 | R QUEINP,2 413 | R QUEOUT,2 414 | R PSNLEN,2 ;Queue present length 415 | R QUELEN,2 ;Maximum queue length 416 | 417 | R SAVLEN,2 ;used by BLOAD, BSAVE 418 | 419 | ; 420 | ;Device Variables 421 | ; 422 | 423 | PUBLIC FOPTSZ 424 | FOPTSZ=64D ;size of file open options buffer 425 | 426 | R FILOPT,FOPTSZ ;buffer for Special-Device Open Options 427 | 428 | ; 429 | ;Line Printer variables 430 | ; 431 | ; note: If size of LPT Device Control Block changes, 432 | ; routine GLPDCB in GIOLPT must be changed. 433 | ; 434 | R LP1DCB,4*NMLPT ;LPT1 device control block 435 | ;2 bytes (width, position) 436 | ; 437 | ;Keyboard variables 438 | ; 439 | PUBLIC KYBQSZ 440 | KYBQSZ=32D 441 | R KYBQDS,8 ;queue descriptor (for format see GIO86) 442 | R KYBQUE,KYBQSZ ;buffer circular key queue 443 | 444 | ; 445 | ;RS232C variables 446 | ; 447 | R MSWSIZ,2D ;/M: value 448 | R MSWFLG,1D ;/M: exists flag 449 | R CSWSIZ,2D ;/C: value 450 | R CSWFLG,1D ;/C: exists flag 451 | R NEWDS,2D ;New DS: 452 | R COMDSC,18D ;buffer used to communicate RS232 requests to OS 453 | R CM1DCB,24D*NMCOMT ;COM1 device control block (24 bytes per device) 454 | R LSTIOB,1 ;Contains Last RS232 unit accessed (0..15) 455 | ;2 bytes (width, position) 456 | ;2 bytes (width, position) 457 | ; 458 | ; RAM USED FOR EVENT TRAPPING 459 | ; 460 | R TRPTBL,3*NUMTRP ;trap table - see GWSTS 461 | R ONGSBF,1 ;see NEWSTT 462 | R SOFTKY,1 ;used by key trapping in GWSTS 463 | R F_SUPR,1 ; Flag - non-zero = super shift expansion 464 | 465 | DSEG ENDS 466 | END 467 | -------------------------------------------------------------------------------- /IBMRES.ASM: -------------------------------------------------------------------------------- 1 | ; [ This translation created 10-Feb-83 by Version 4.3 ] 2 | 3 | .RADIX 8 ; To be safe 4 | 5 | CSEG SEGMENT PUBLIC 'CODESG' 6 | ASSUME CS:CSEG 7 | 8 | INCLUDE IBMRES.H 9 | 10 | SUBTTL Equates and External Declarations 11 | TITLE IBMRES - IBM compatible reserved words / MLC 12 | COMMENT * 13 | 14 | --------- --- ---- -- --------- 15 | COPYRIGHT (C) 1982 BY MICROSOFT 16 | --------- --- ---- -- --------- 17 | 18 | This module is used to create GW-BASICs with IBM PC compatible 19 | reserved word tokens. The reserved word tables were created by 20 | cleaning up a copy of the tables from BINTRP. The code and tables 21 | to handle the extended reserved words was taken from L2RESS.MAC and 22 | modified as necessary. 23 | * 24 | 25 | GWLEV2=0 ;GW BASIC version 2.0 features 26 | 27 | .SALL 28 | .RADIX 10 29 | 30 | 31 | PUBLIC $KEY2B,$COM2B,$PEN2B,$STR2B 32 | EXTRN CHRGTR:NEAR 33 | EXTRN DATEF:NEAR 34 | EXTRN LABBCK:NEAR 35 | EXTRN MAKUPL:NEAR 36 | EXTRN NOTRFN:NEAR 37 | EXTRN PARCHK:NEAR,PENS:NEAR,PLOOP2:NEAR,PPSWRT:NEAR 38 | EXTRN RENCRN:NEAR 39 | EXTRN STRIGS:NEAR 40 | EXTRN TIMEF:NEAR,TSTANM:NEAR 41 | 42 | DSEG SEGMENT PUBLIC 'DATASG' 43 | ASSUME DS:DSEG 44 | EXTRN FLGOVC:WORD,TEMPA:WORD 45 | DSEG ENDS 46 | 47 | 48 | 49 | ; 50 | ; THESE MACRO CALLS DEFINE THE RESWRD VALUES 51 | ; AND THE TABLE DISPATCH FOR STATEMENTS AND FUNCTIONS 52 | ; 53 | ; STATEMENTS: 54 | ; 55 | 56 | PUBLIC STMDSP 57 | STMDSP: ;MARKS START OF STATEMENT LIST 58 | QQ=128 59 | R2 END,ENDST 60 | R FOR 61 | R NEXT 62 | R2 DATA,DATAS 63 | R INPUT 64 | R DIM 65 | R READ 66 | R LET 67 | R GOTO 68 | R RUN 69 | R2 IF,IFS 70 | R RESTORE 71 | R GOSUB 72 | R RETURN 73 | R REM 74 | R STOP 75 | R PRINT 76 | R CLEAR 77 | R LIST 78 | R2 NEW,SCRATH 79 | R2 ON,ONGOTO 80 | R2 WAIT,FNWAIT 81 | R DEF 82 | R POKE 83 | R CONT 84 | R2 DUMMY,SNERR ;padding 85 | R2 DUMMY,SNERR ;padding 86 | R2 OUT,FNOUT 87 | R LPRINT 88 | R LLIST 89 | R2 DUMMY,SNERR ;padding 90 | R2 WIDTH,WIDTHS 91 | R2 ELSE,ELSES 92 | R2 TRON,TON 93 | R2 TROFF,TOFF 94 | R SWAP 95 | R ERASE 96 | R EDIT 97 | R2 ERROR,ERRORS 98 | R RESUME 99 | R DELETE 100 | R AUTO 101 | R2 RENUM,RESEQ 102 | R DEFSTR 103 | R DEFINT 104 | R2 DEFSNG,DEFREA 105 | R DEFDBL 106 | R LINE 107 | R WHILE 108 | R WEND 109 | R2 CALL,CALLS 110 | R2 DUMMY,SNERR ;padding 111 | R2 DUMMY,SNERR ;padding 112 | R2 DUMMY,SNERR ;padding 113 | R WRITE 114 | R OPTION 115 | R2 RANDOMIZE,RANDOM 116 | R OPEN 117 | R CLOSE 118 | R LOAD 119 | R MERGE 120 | R SAVE 121 | R COLOR 122 | R CLS 123 | R MOTOR 124 | R BSAVE 125 | R BLOAD 126 | R2 SOUND,SOUNDS 127 | R2 BEEP,BEEPS 128 | R PSET 129 | R PRESET 130 | R SCREEN 131 | R2 KEY,KEYS 132 | $KEY2B=0+QQ ;value of KEY 2-byte token 133 | R LOCATE 134 | 135 | PUBLIC NUMCMD 136 | NUMCMD=QQ-$END+1 137 | 138 | ; 139 | ; TOKENS 140 | ; 141 | 142 | ; 143 | ;QQ MUST BE SET SO TOKENS START AT RIGHT PLACE 144 | ; 145 | 146 | QQ=QQ+1 147 | 148 | T TO 149 | T THEN 150 | PUBLIC THENTK 151 | THENTK=QQ 152 | T TAB 153 | PUBLIC TABTK 154 | TABTK=QQ 155 | T STEP 156 | PUBLIC STEPTK 157 | STEPTK=QQ 158 | T USR 159 | PUBLIC USRTK 160 | USRTK=QQ 161 | T FN 162 | PUBLIC FNTK 163 | FNTK=QQ 164 | T SPC 165 | PUBLIC SPCTK 166 | SPCTK=QQ 167 | T NOT 168 | PUBLIC NOTTK 169 | NOTTK=QQ 170 | T ERL 171 | PUBLIC ERLTK 172 | ERLTK=QQ 173 | T ERR 174 | PUBLIC ERCTK 175 | ERCTK=QQ 176 | T STRING$ 177 | T USING 178 | PUBLIC USINTK 179 | USINTK=QQ 180 | T INSTRC 181 | PUBLIC INSRTK 182 | INSRTK=QQ 183 | T DUMMY 184 | PUBLIC SNGQTK 185 | SNGQTK=QQ 186 | T VARPTR 187 | T CSRLIN 188 | PUBLIC CLINTK 189 | CLINTK=QQ 190 | T POINT 191 | T OFF 192 | T INKEY$ 193 | 194 | ; 195 | ; OPERATORS 196 | ; 197 | 198 | QQ=QQ+7 199 | 200 | T DUMMY 201 | PUBLIC GREATK 202 | GREATK=QQ 203 | T DUMMY 204 | PUBLIC EQULTK 205 | EQULTK=QQ 206 | T DUMMY 207 | PUBLIC LESSTK 208 | LESSTK=QQ 209 | T DUMMY 210 | PUBLIC PLUSTK 211 | PLUSTK=QQ 212 | T DUMMY 213 | PUBLIC MINUTK 214 | MINUTK=QQ 215 | T DUMMY 216 | PUBLIC MULTK 217 | MULTK=QQ 218 | T DUMMY 219 | PUBLIC DIVTK 220 | DIVTK=QQ 221 | T DUMMY 222 | PUBLIC EXPTK 223 | EXPTK=QQ 224 | T AND 225 | T OR 226 | T XOR 227 | T EQV 228 | T IMP 229 | T MOD 230 | T DUMMY 231 | PUBLIC IDIVTK 232 | IDIVTK=QQ 233 | PUBLIC LSTOPK 234 | LSTOPK=QQ+1-PLUSTK 235 | 236 | ; 237 | ; FUNCTIONS - 2 byte tokens, the 1st byte is FF 238 | ; 239 | 240 | QQ=128 241 | PUBLIC FUNDSP 242 | FUNDSP: 243 | R LEFT$ 244 | PUBLIC ONEFUN 245 | ONEFUN=QQ 246 | R RIGHT$ 247 | R MID$ 248 | PUBLIC MIDTK 249 | MIDTK=QQ 250 | R SGN 251 | R2 INT,VINT 252 | R2 ABS,ABSFN 253 | R SQR 254 | PUBLIC SQRTK 255 | SQRTK=QQ 256 | R RND 257 | R SIN 258 | R LOG 259 | R EXP 260 | R COS 261 | R TAN 262 | R ATN 263 | PUBLIC ATNTK 264 | ATNTK=QQ 265 | R FRE 266 | R2 INP,FNINP 267 | R POS 268 | R LEN 269 | R STR$ 270 | R VAL 271 | R ASC 272 | R CHR$ 273 | R PEEK 274 | R SPACE$ 275 | R2 OCT$,STRO$ 276 | R2 HEX$,STRH$ 277 | R LPOS 278 | PUBLIC LASNUM 279 | LASNUM=QQ 280 | R2 CINT,FRCINT 281 | R2 CSNG,FRCSNG 282 | R2 CDBL,FRCDBL 283 | R2 DUMMY,FIXER 284 | PUBLIC $FIX 285 | $FIX=QQ 286 | R2 PEN,PENF 287 | $PEN2B=0+(400O*377O)+QQ ;value of PEN 2-byte token 288 | R2 STICK,STICKF 289 | R2 STRIG,STRIGF 290 | $STR2B=0+(400O*377O)+QQ ;value of STRIG 2-byte token 291 | R EOF 292 | R LOC 293 | R LOF 294 | 295 | ; 296 | ; THE FOLLOWING TABLES ARE THE ALPHABETIC DISPATCH TABLE 297 | ; FOLLOWED BY THE RESERVED WORD TABLE ITSELF 298 | ; 299 | PUBLIC ALPTAB 300 | ALPTAB: 301 | 302 | DW OFFSET ATAB 303 | DW OFFSET BTAB 304 | DW OFFSET CTAB 305 | DW OFFSET DTAB 306 | DW OFFSET ETAB 307 | DW OFFSET FTAB 308 | DW OFFSET GTAB 309 | DW OFFSET HTAB 310 | DW OFFSET ITAB 311 | DW OFFSET JTAB 312 | DW OFFSET KTAB 313 | DW OFFSET LTAB 314 | DW OFFSET MTAB 315 | DW OFFSET NTAB 316 | DW OFFSET OTAB 317 | DW OFFSET PTAB 318 | DW OFFSET QTAB 319 | DW OFFSET RTAB 320 | DW OFFSET STAB 321 | DW OFFSET TTAB 322 | DW OFFSET UTAB 323 | DW OFFSET VTAB 324 | DW OFFSET WTAB 325 | DW OFFSET XTAB 326 | DW OFFSET YTAB 327 | DW OFFSET ZTAB 328 | 329 | 330 | PUBLIC RESLST 331 | RESLST: 332 | 333 | ATAB: 334 | Q AUTO 335 | Q AND 336 | QF ABS 337 | QF ATN 338 | QF ASC 339 | DB 0 340 | BTAB: 341 | Q BSAVE 342 | Q BLOAD 343 | Q BEEP 344 | DB 0 345 | CTAB: 346 | Q COLOR 347 | Q CLOSE 348 | Q CONT 349 | Q CLEAR 350 | Q CSRLIN 351 | QF CINT 352 | QF CSNG 353 | QF CDBL 354 | QF COS 355 | QF CHR$ 356 | Q CALL 357 | Q CLS 358 | DB 0 359 | DTAB: 360 | Q DELETE 361 | Q DATA 362 | Q DIM 363 | Q DEFSTR 364 | Q DEFINT 365 | Q DEFSNG 366 | Q DEFDBL 367 | Q DEF 368 | DB 0 369 | ETAB: 370 | Q ELSE 371 | Q END 372 | Q ERASE 373 | Q EDIT 374 | Q ERROR 375 | Q ERL 376 | Q ERR 377 | QF EXP 378 | QF EOF 379 | Q EQV 380 | DB 0 381 | FTAB: 382 | Q FOR 383 | Q FN 384 | QF FRE 385 | QF FIX 386 | DB 0 387 | GTAB: 388 | Q GOTO 389 | DB "O" 390 | DB " " 391 | DB "T" 392 | DB "O"+128D 393 | DB OFFSET $GOTO 394 | Q GOSUB 395 | DB 0 396 | HTAB: 397 | QF HEX$ 398 | DB 0 399 | ITAB: 400 | Q INPUT 401 | Q IF 402 | Q INSTRC 403 | QF INT 404 | QF INP 405 | Q IMP 406 | Q INKEY$ 407 | DB 0 408 | JTAB: 409 | DB 0 410 | KTAB: 411 | Q KEY 412 | DB 0 413 | LTAB: 414 | Q LOCATE 415 | Q LPRINT 416 | Q LLIST 417 | QF LPOS 418 | Q LET 419 | Q LINE 420 | Q LOAD 421 | Q LIST 422 | QF LOG 423 | QF LOC 424 | QF LEN 425 | QF LEFT$ 426 | QF LOF 427 | DB 0 428 | MTAB: 429 | Q MOTOR 430 | Q MERGE 431 | Q MOD 432 | QF MID$ 433 | DB 0 434 | NTAB: 435 | Q NEXT 436 | Q NEW 437 | Q NOT 438 | DB 0 439 | OTAB: 440 | Q OPEN 441 | Q OUT 442 | Q ON 443 | Q OR 444 | QF OCT$ 445 | Q OPTION 446 | Q OFF 447 | DB 0 448 | PTAB: 449 | Q PRINT 450 | Q POKE 451 | QF POS 452 | QF PEEK 453 | Q PSET 454 | Q PRESET 455 | Q POINT 456 | QF PEN 457 | DB 0 458 | QTAB: 459 | DB 0 460 | RTAB: 461 | Q RUN 462 | Q RETURN 463 | Q READ 464 | Q RESTORE 465 | Q REM 466 | Q RESUME 467 | QF RIGHT$ 468 | QF RND 469 | Q RENUM 470 | Q RANDOMIZE 471 | DB 0 472 | STAB: 473 | Q SCREEN 474 | Q STOP 475 | Q SWAP 476 | Q SAVE 477 | DB "P" 478 | DB "C" 479 | DB "("+128D 480 | DB OFFSET SPCTK 481 | Q STEP 482 | QF SGN 483 | QF SQR 484 | QF SIN 485 | QF STR$ 486 | Q STRING$ 487 | QF SPACE$ 488 | Q SOUND 489 | QF STICK 490 | QF STRIG 491 | DB 0 492 | TTAB: 493 | Q THEN 494 | Q TRON 495 | Q TROFF 496 | DB "A" 497 | DB "B" 498 | DB "("+128D 499 | DB OFFSET TABTK 500 | Q TO 501 | QF TAN 502 | DB 0 503 | UTAB: 504 | Q USING 505 | Q USR 506 | DB 0 507 | VTAB: 508 | QF VAL 509 | Q VARPTR 510 | DB 0 511 | WTAB: 512 | Q WIDTH 513 | Q WAIT 514 | Q WHILE 515 | Q WEND 516 | Q WRITE 517 | DB 0 518 | XTAB: 519 | Q XOR 520 | DB 0 521 | YTAB: 522 | DB 0 523 | ZTAB: 524 | DB 0 525 | 526 | PUBLIC SPCTAB 527 | SPCTAB: 528 | DB "+"+128D 529 | DB OFFSET PLUSTK 530 | DB "-"+128D 531 | DB OFFSET MINUTK 532 | DB "*"+128D 533 | DB OFFSET MULTK 534 | DB "/"+128D 535 | DB OFFSET DIVTK 536 | DB "^"+128D 537 | DB OFFSET EXPTK 538 | DB "\"+128D 539 | DB OFFSET IDIVTK 540 | DB "'"+128D 541 | DB OFFSET SNGQTK 542 | DB 62+128D 543 | DB OFFSET GREATK 544 | DB "="+128D 545 | DB OFFSET EQULTK 546 | DB 60+128D 547 | DB OFFSET LESSTK 548 | DB 0 549 | 550 | SUBTTL Extended reserved words 551 | ;The following are 2 byte tokens, the 1st byte is FE 552 | 553 | QQ=128D 554 | STMDSX: 555 | R FILES 556 | R FIELD 557 | R SYSTEM 558 | R NAME 559 | R LSET 560 | R RSET 561 | R KILL 562 | R PUT 563 | R GET 564 | R RESET 565 | R COMMON 566 | R CHAIN 567 | R2 DATE$,DATES 568 | R2 TIME$,TIMES 569 | R PAINT 570 | R2 COM,COMS 571 | $COM2B=0+(400O*376O)+QQ ;value of COM 2-byte token 572 | R CIRCLE 573 | R DRAW 574 | R2 PLAY,PLAYS 575 | R TIMER 576 | R ERDEV 577 | R IOCTL 578 | R CHDIR 579 | R MKDIR 580 | R RMDIR 581 | R SHELL 582 | R ENVIRON 583 | R VIEW 584 | R WINDOW 585 | R PMAP 586 | R2 PALETTE,PALETE 587 | R2 LCOPY,LCOPYS 588 | R2 CALLS,CALLSL 589 | ;************************************************************************* 590 | ;*** The DEBUG entry should be the last entry in the FE Dispatch table *** 591 | ;************************************************************************* 592 | 593 | 594 | PAGE 595 | ;The following are 2 byte tokens, the 1st byte is FD 596 | 597 | QQ=128D 598 | FUNDSX: 599 | R CVI 600 | R CVS 601 | R CVD 602 | R MKI$ 603 | R MKS$ 604 | R MKD$ 605 | R2 KTN,KTNFN 606 | R2 JIS,JISFN 607 | R2 KPOS,KPOSFN 608 | R2 KLEN,KLENFN 609 | 610 | PAGE 611 | PUBLIC ALPTAX 612 | ALPTAX: 613 | ADR ATABX 614 | ADR BTABX 615 | ADR CTABX 616 | ADR DTABX 617 | ADR ETABX 618 | ADR FTABX 619 | ADR GTABX 620 | ADR HTABX 621 | ADR ITABX 622 | ADR JTABX 623 | ADR KTABX 624 | ADR LTABX 625 | ADR MTABX 626 | ADR NTABX 627 | ADR OTABX 628 | ADR PTABX 629 | ADR QTABX 630 | ADR RTABX 631 | ADR STABX 632 | ADR TTABX 633 | ADR UTABX 634 | ADR VTABX 635 | ADR WTABX 636 | ADR XTABX 637 | ADR YTABX 638 | ADR ZTABX 639 | 640 | PAGE 641 | RESLSX: 642 | 643 | ATABX: 644 | DB 0 645 | BTABX: 646 | DB 0 647 | CTABX: 648 | Q CHAIN 649 | QF CVI 650 | QF CVS 651 | QF CVD 652 | Q COMMON 653 | Q COM 654 | Q CIRCLE 655 | Q CALLS 656 | DB 0 657 | DTABX: 658 | Q DATE$ 659 | Q DRAW 660 | DB 0 661 | ETABX: 662 | DB 0 663 | FTABX: 664 | Q FIELD 665 | Q FILES 666 | DB 0 667 | GTABX: 668 | Q GET 669 | DB 0 670 | HTABX: 671 | DB 0 672 | ITABX: 673 | Q IOCTL 674 | DB 0 675 | JTABX: 676 | DB 0 677 | KTABX: 678 | Q KILL 679 | DB 0 680 | LTABX: 681 | Q LSET 682 | Q LCOPY 683 | DB 0 684 | MTABX: 685 | QF MKI$ 686 | QF MKS$ 687 | QF MKD$ 688 | DB 0 689 | NTABX: 690 | Q NAME 691 | DB 0 692 | OTABX: 693 | DB 0 694 | PTABX: 695 | Q PUT 696 | Q PAINT 697 | Q PLAY 698 | DB 0 699 | QTABX: 700 | DB 0 701 | RTABX: 702 | Q RSET 703 | Q RESET 704 | DB 0 705 | STABX: 706 | Q SYSTEM 707 | DB 0 708 | TTABX: 709 | Q TIME$ 710 | DB 0 711 | UTABX: 712 | DB 0 713 | VTABX: 714 | DB 0 715 | WTABX: 716 | DB 0 717 | XTABX: 718 | DB 0 719 | YTABX: 720 | DB 0 721 | ZTABX: 722 | DB 0 723 | 724 | PUBLIC NUMGFN,BOTCON,TOPCON,$RNDFN,$DATCO,$REMCO,NMREL 725 | PUBLIC $CHRFN,$CSNGF,$CDBLF 726 | NUMGFN=(2*MIDTK)-(2*ONEFUN)+1 727 | BOTCON=(SQRTK-ONEFUN)*2 728 | TOPCON=(ATNTK-ONEFUN)*2+1 729 | $RNDFN=$RND-ONEFUN 730 | $DATCO=$DATA-":" 731 | $REMCO=$REM-":" 732 | NMREL=LESSTK-GREATK+1 733 | $CHRFN=$CHR$-ONEFUN 734 | $CSNGF=$CSNG-ONEFUN 735 | $CDBLF=$CDBL-ONEFUN 736 | 737 | 738 | SUBTTL CRUNCH code to handle extended reserved words 739 | 740 | PUBLIC CRUNCX 741 | CRUNCX: POP BX ;GET BACK SOURCE POINTER 742 | PUSH BX ;TO TRY AGAIN 743 | DEC BX ;POINT AT CHARACTER 744 | CALL MAKUPL ;CONVERT TO UPPER CASE 745 | MOV BX,OFFSET ALPTAX ;GET POINTER TO ALPHA DISPATCH TABLE 746 | SUB AL,LOW "A" ;SUBTRACT ALPHA OFFSET 747 | ADD AL,AL ;MULTIPLY BY TWO 748 | MOV CL,AL ;SAVE OFFSET IN [C] FOR DAD. 749 | MOV CH,LOW 0 ;MAKE HIGH PART OF OFFSET ZERO 750 | ADD BX,CX ;ADD TO TABLE ADDRESS 751 | INS86 56 752 | MOV DX,[BX] ;GET POINTER IN [D,E] 753 | POP BX ;GET BACK SOURCE POINTER 754 | TRYAGA: PUSH BX ;SAVE TXTPTR TO START OF SEARCH AREA 755 | LOPPSI: 756 | CALL MAKUPL ;TRANSLATE THIS CHAR TO UPPER CASE 757 | MOV CL,AL ;SAVE CHAR IN [C] 758 | INS86 213,362,56,254 ;FETCH FROM CODE SEGMENT 759 | AND AL,LOW 127 ;GET RID OF HIGH BIT 760 | JNZ SHORT ??L000 761 | JMP NOTRFN ;IF=0 THEN END OF THIS CHARS RESLT 762 | ??L000: 763 | INC BX ;BUMP SOURCE POINTER 764 | CMP AL,CL ;COMPARE TO CHAR FROM SOURCE LINE 765 | JNZ SHORT LOPSKP ;IF NO MATCH, SEARCH FOR NEXT RESWRD 766 | INS86 213,362,56,254 ;FETCH FROM CODE SEGMENT 767 | INC DX ;BUMP RESLST POINTER 768 | OR AL,AL ;SET CC'S 769 | JS SHORT ??L001 770 | JMP LOPPSI ;SEE IF REST OF CHARS MATCH 771 | ??L001: 772 | INS86 213,362,56,254 ;FETCH FROM CODE SEGMENT 773 | CALL MAKUPL ;GET NEXT CHAR IN LINE (MC 6/22/80) 774 | CMP AL,LOW "." ;IS IT A DOT 775 | JZ SHORT ISVARS ;YES 776 | CALL TSTANM ;IS IT A LETTER IMMEDIATELY 777 | ;FOLLOWING RESWRD 778 | ISVARS: MOV AL,LOW 0 ;SET DONUM TO -1 779 | JNAE SHORT ??L002 780 | JMP NOTRFN ;IF ALPHA, CANT BE RESERVED WORD 781 | ??L002: 782 | POP AX ;GET RID OF SAVED [H,L] 783 | INS86 213,362,56,254 ;FETCH FROM CODE SEGMENT 784 | OR AL,AL ;SET CC'S 785 | POP CX ;GET CHAR COUNT OFF STACK 786 | POP DX ;GET DEPOSIT POINTER OFF STACK 787 | JNS SHORT ??L003 788 | JMP NOTFNT ;IF MINUS, WASNT FUNCTION TOKEN 789 | ??L003: 790 | OR AL,LOW 200O ;MAKE HIGH ORDER BIT ONE 791 | STC ;AND FORCE LEADER BYTE TO BE 375 792 | NOTFNT: PUSH AX ;SAVE FN CHAR 793 | MOV AL,LOW 376O ;GET BYTE WHICH PRECEEDS FNS 794 | SBB AL,LOW 0 ;MAKE FUNCTION LEADER 375 795 | JMP RENCRN ;REENTER CRUNCH WITH NEW RESERVED WORD 796 | 797 | LOPSKP: POP BX ;RESTORE UNDEFILED TEXT POINTER 798 | LOPSK2: 799 | INS86 213,362,56,254 ;FETCH FROM CODE SEGMENT 800 | INC DX ;BUMP RESLST POINTER 801 | OR AL,AL ;SET CC'S 802 | JS SHORT ??L004 803 | JMP LOPSK2 ;NOT END OF RESWRD, KEEP SKIPPING 804 | ??L004: 805 | INC DX ;POINT AFTER TOKEN 806 | JMP TRYAGA ;TRY ANOTHER RESWRD 807 | 808 | SUBTTL LIST code for extended reserved words 809 | 810 | BUFRET: RET 811 | 812 | NEWFUN: MOV AL,BYTE PTR [BX] ;GET FUNCTION NUMBER 813 | AND AL,LOW 177O ;TAKE OFF HIGH BIT 814 | JMP SHORT BUFCON 815 | 816 | PUBLIC LISTX 817 | LISTX: CMP AL,LOW 375O ;IS IT A NEW FUNCTION 818 | JZ SHORT NEWFUN 819 | CMP AL,LOW 376O ;IS IT A NEW STATEMENT 820 | JNZ SHORT BUFRET ;NO, JUST CONTINUE NORMAL PATH 821 | MOV AL,BYTE PTR [BX] ;GET NUMBER OF STATEMENT 822 | BUFCON: POP BX ;Get rid of the return address. 823 | MOV BX,OFFSET RESLSX-1 ;GET PTR TO START OF RESERVED WORD LIST 824 | MOV CH,AL ;SAVE THIS CHAR IN [B] 825 | MOV CL,LOW OFFSET "A"-1 ;INIT LEADING CHAR VALUE 826 | RESSR3: INC CL ;BUMP LEADING CHAR VALUE. 827 | RESSR1: INC BX ;BUMP POINTER INTO RESLST 828 | RESSRC: MOV DH,BH ;SAVE PTR TO START OF THIS RESWRD 829 | MOV DL,BL 830 | RESSR2: 831 | INS86 56 ;FETCH FROM CODE SEGMENT 832 | MOV AL,BYTE PTR [BX] ;GET CHAR FROM RESLST 833 | OR AL,AL ;SET CC'S 834 | JZ SHORT RESSR3 ;IF END OF THIS CHARS TABLE, 835 | ;GO BACK & BUMP C 836 | LAHF 837 | INC BX ;BUMP SOURCE PTR 838 | SAHF 839 | JS SHORT ??L005 840 | JMP RESSR2 ;IF NOT END OF THIS RESWRD, 841 | ??L005: 842 | ;THEN KEEP LOOKING 843 | INS86 56 ;FETCH FROM CODE SEGMENT 844 | MOV AL,BYTE PTR [BX] ;GET PTR TO RESERVED WORD VALUE 845 | CMP AL,CH ;SAME AS THE ONE WE SEARCH FOR? 846 | JNZ SHORT RESSR1 ;NO, KEEP LOOKING. 847 | XCHG BX,DX ;SAVE FOUND PTR IN [H,L] 848 | MOV AL,CL ;GET LEADING CHAR 849 | POP DX ;RESTORE LINE CHAR COUNT 850 | POP CX ;RESTORE DEPOSIT PTR 851 | MOV DL,AL ;SAVE LEADING CHAR IN [E] 852 | ; 853 | ; CODE BELOW NOT NEEDED SINCE NO SPECIAL REVERVED WORDS IN HOOK TABLE 854 | ; 855 | ; CPI "Z"+1 ;WAS IT A SPECIAL CHAR? 856 | ; JRNZ NTSPCH ;NON-SPECIAL CHAR 857 | ; XRA A ;SET NON-SPECIAL 858 | ; STA TEMPA 859 | ; JMPR MORPUR ;PRINT IT 860 | NTSPCH: MOV AL,BYTE PTR TEMPA ;WHAT DID WE DO LAST? 861 | OR AL,AL ;SPECIAL? 862 | MOV AL,LOW 255 ;FLAG IN RESERVED WORD 863 | MOV BYTE PTR TEMPA,AL ;CLEAR FLAG 864 | MORLNZ: JZ SHORT MORLN0 ;GET CHAR AND PROCEED 865 | MOV AL,LOW " " ;PUT SPACE IN BUFFER 866 | MOV DI,CX 867 | STOSB 868 | INC CX 869 | DEC DH ;ANY SPACE LEFT IN BUFFER 870 | JNZ SHORT ??L006 871 | JMP PPSWRT ;NO, RETURN 872 | ??L006: 873 | MORLN0: MOV AL,DL 874 | JMP SHORT MORLN1 ;CONTINUE 875 | MORPUR: 876 | INS86 56 ;FETCH FROM CODE SEGMENT 877 | MOV AL,BYTE PTR [BX] ;GET BYTE FROM RESWRD 878 | INC BX ;BUMP POINTER 879 | MORLNP: MOV DL,AL ;SAVE CHAR 880 | MORLN1: AND AL,LOW 177O ;AND OFF HIGH ORDER BIT FOR DISK & EDIT 881 | MOV DI,CX 882 | STOSB ;STORE THIS CHAR 883 | INC CX ;BUMP PTR 884 | DEC DH ;BUMP DOWN REMAINING CHAR COUNT 885 | JNZ SHORT ??L007 886 | JMP PPSWRT ;IF END OF LINE, JUST RETURN 887 | ??L007: 888 | OR AL,DL ;SET CC'S 889 | JS SHORT ??L008 890 | JMP MORPUR ;END OF RESWRD? 891 | ??L008: 892 | POP BX ;RESTORE SOURCE PTR. 893 | INC BX ;SKIP OVER RESERVED WORD 894 | JMP PLOOP2 ;GET NEXT CHAR FROM LINE 895 | 896 | SUBTTL Extended Statement Dispatching 897 | 898 | SNERRS: JMP SNERR 899 | 900 | PUBLIC NEWSTX 901 | NEWSTX: CMP AL,LOW OFFSET 376O-201O ;CHECK FOR NEW STATEMENT PREFIX 902 | JZ SHORT GONE4 ;IF SO, DISPATCH 903 | CMP AL,LOW OFFSET 377O-201O ;FUNCTION? 904 | JNZ SHORT GIIRET 905 | POP CX ;Put return address into B. 906 | INC BX 907 | MOV AL,BYTE PTR [BX] 908 | CMP AL,LOW OFFSET $PEN ; PEN as stmt? 909 | JNZ SHORT ??L009 910 | JMP PENV ; Brif so. 911 | ??L009: 912 | CMP AL,LOW OFFSET $STRIG ;STRIG as stmt? 913 | JNZ SHORT ??L010 914 | JMP STRIGV ; Brif so. 915 | ??L010: 916 | DEC BX 917 | MOV AL,LOW OFFSET 377O-201O 918 | PUSH CX ;Put the return address back on. 919 | GIIRET: RET ;MID$ OR SYNTAX ERROR 920 | 921 | PENV: CALL CHRGTR 922 | JMP PENS 923 | STRIGV: CALL CHRGTR 924 | JMP STRIGS 925 | 926 | 927 | GONE4: POP CX ;Get rid of the return address. 928 | INC BX ;LOOK AT NEXT CHAR 929 | MOV AL,BYTE PTR [BX] ;FETCH IT 930 | SUB AL,LOW 201O ;GET RELATIVE POSITION IN STMDSX 931 | JB SHORT SNERRS ;IF TOO SMALL, SYNTAX ERROR 932 | ADD AL,AL ;TURN BYTE INTO OFFSET 933 | INS86 62,344 ;XOR AH,AH 934 | INS86 213,360 ;MOV SI,AX - GET OFFSET INTO [SI] 935 | INS86 56 ;CODE SEGMENT OVERRIDE 936 | INS86 377,264,STMDSX ;PUSH STMDSP(SI) - PUSH ADDRESS 937 | JMP CHRGTR ;START STATEMENT 938 | 939 | SUBTTL EVAL code for extended functions 940 | 941 | PUBLIC EVALX 942 | EVALX: CMP AL,LOW 376O 943 | JZ SHORT EVALNS ;Brif possible stmt as function 944 | CMP AL,LOW 375O 945 | JZ SHORT EVALNF ;NEW FUNCTION IF 375 IN FRONT 946 | RET 947 | 948 | EVALNS: INC BX 949 | MOV AL,BYTE PTR [BX] 950 | CMP AL,LOW OFFSET $DATE$ 951 | JZ SHORT DATEV ;Brif DATE$ 952 | CMP AL,LOW OFFSET $TIME$ 953 | JZ SHORT TIMEV ;Brif TIME$ 954 | DEC BX 955 | MOV AL,BYTE PTR [BX] 956 | RET 957 | 958 | DATEV: POP CX ;Get rid of the hook return address. 959 | JMP DATEF ;Do DATE function. 960 | 961 | TIMEV: POP CX ;Get rid of the hook return address. 962 | JMP TIMEF ;Do TIME$ function. 963 | 964 | EVALNF: POP CX ;Get rid of the return address. 965 | INC BX 966 | MOV AL,BYTE PTR [BX] 967 | SUB AL,LOW 201O 968 | MOV CH,LOW 0 969 | ROL AL,1 970 | MOV CL,AL 971 | PUSH CX 972 | CALL CHRGTR 973 | CALL PARCHK 974 | POP SI ;XTHL 975 | XCHG SI,BX 976 | PUSH SI 977 | MOV DX,OFFSET LABBCK 978 | PUSH DX 979 | MOV AL,LOW 1 980 | MOV BYTE PTR FLGOVC,AL 981 | INS86 213,363 ;MOV SI,BX (GET FUNCTION OFFSET IN SI) 982 | INS86 56 983 | INS86 377,264,FUNDSX 984 | RET 985 | 986 | 987 | CSEG ENDS 988 | END 989 | -------------------------------------------------------------------------------- /IBMRES.H: -------------------------------------------------------------------------------- 1 | ; Include file for IBMRES.ASM 2 | ; 3 | INCLUDE OEM.H ; General definitions 4 | 5 | ; 6 | ; Reserve word table generating Macros 7 | ; 8 | un_def MACRO RESWRD 9 | %OUT +++ Undefined reserved word - &RESWRD 10 | ENDM 11 | 12 | T MACRO RESWRD 13 | QQ=QQ+1 14 | PUBLIC $&RESWRD 15 | $&RESWRD=QQ 16 | ENDM 17 | 18 | Q MACRO RESWRD 19 | IFDEF $&RESWRD 20 | $F=0 21 | IRPC XX, 22 | IF $F 23 | $Q="&XX&" 24 | DB "&XX&" 25 | ENDIF 26 | IFE $F-1 27 | .XLIST 28 | ENDIF 29 | $F=$F+1 30 | ENDM 31 | .LIST 32 | ORG $-1 33 | DB $Q+128D 34 | DB $&RESWRD 35 | ELSE 36 | un_def RESWRD 37 | ENDIF 38 | ENDM 39 | 40 | QF MACRO RESWRD 41 | IFDEF $&RESWRD 42 | $F=0 43 | IRPC XX, 44 | IF $F 45 | $Q="&XX&" 46 | DB "&XX&" 47 | ENDIF 48 | IFE $F-1 49 | .XLIST 50 | ENDIF 51 | $F=$F+1 52 | ENDM 53 | .LIST 54 | ORG $-1 55 | DB $Q+128D 56 | DB $&RESWRD-128D 57 | ELSE 58 | un_def RESWRD 59 | ENDIF 60 | ENDM 61 | 62 | ; 63 | R MACRO RESWRD 64 | extrn RESWRD:NEAR 65 | DW RESWRD 66 | QQ=QQ+1 67 | PUBLIC $&RESWRD 68 | $&RESWRD=QQ 69 | ENDM 70 | 71 | R2 MACRO RESWRD,RESDSP 72 | extrn RESDSP:NEAR 73 | DW RESDSP 74 | QQ=QQ+1 75 | PUBLIC $&RESWRD 76 | $&RESWRD=QQ 77 | ENDM 78 | ; 79 | PAGE 80 | -------------------------------------------------------------------------------- /ITSA86.ASM: -------------------------------------------------------------------------------- 1 | ; [ This translation created 10-Feb-83 by Version 4.3 ] 2 | 3 | .RADIX 8 ; To be safe 4 | 5 | CSEG SEGMENT PUBLIC 'CODESG' 6 | ASSUME CS:CSEG 7 | 8 | INCLUDE OEM.H 9 | 10 | TITLE ITSA86 - Resident Initialization for I8086 11 | 12 | COMMENT * 13 | 14 | --------- --- ---- -- --------- ----------- 15 | COPYRIGHT (C) 1982 BY MICROSOFT CORPORATION 16 | --------- --- ---- -- --------- ----------- 17 | 18 | by Len Oorthuys Microsoft Corp. 19 | * 20 | 21 | ;************************************************************************ 22 | ;* * 23 | ;* NOTE: Any code linked after this module is discarded after * 24 | ;* Initialization of BASIC. * 25 | ;* * 26 | ;************************************************************************ 27 | 28 | INCLUDE GIO86U 29 | .SALL 30 | 31 | CPM86=0 32 | TETRA=0 ;Save DS in DATSEG(defined in CS and 33 | ; used by interrupt routine). 34 | 35 | INCLUDE MSDOSU 36 | 37 | 38 | DSEG SEGMENT PUBLIC 'DATASG' 39 | ASSUME DS:DSEG 40 | EXTRN TEMP8:WORD,TXTTAB:WORD 41 | DSEG ENDS 42 | 43 | EXTRN NODSKS:NEAR,LRUN:NEAR,READY:NEAR 44 | 45 | PUBLIC WORDS 46 | WORDS: DB " Bytes free" ;WORDS 47 | DB 0 48 | 49 | PAGE 50 | SUBTTL INITSA 51 | PUBLIC INITSA 52 | INITSA: 53 | CALL NODSKS 54 | CALL MAPINI ;Init the new memory map 55 | MOV BX,WORD PTR TXTTAB 56 | DEC BX 57 | MOV WORD PTR 0[BX],0D 58 | MOV BX,WORD PTR TEMP8 ;POINT TO START OF COMMAND LINE 59 | MOV AL,BYTE PTR 0[BX] ;GET BYTE POINTED TO 60 | OR AL,AL ;IF ZERO, NO FILE SEEN 61 | JZ GREADY 62 | JMP LRUN ;TRY TO RUN FILE 63 | GREADY: JMP READY 64 | PAGE 65 | ;BASVAR - Retrieve or Modify BASIC Internal Data Locations 66 | ;This routine provides a method to retrieve or modify certain BASIC internal 67 | ;data locations. This routine is provided as support for PEEK and 68 | ;POKE filsters. These data items have been documented to IBM GW BASIC users 69 | ;in the IBM Technical Reference Manual. 70 | ; 71 | ;Entry - AX = Value to set (if PSW.C set) 72 | ; BX = 0 for current program line number 73 | ; 1 for last program line containing an error 74 | ; 2 for address of user program text 75 | ; 3 for address of user variable table 76 | ; PSW.C set indicates to write the variable 77 | ; PSW.C reset indicates to read the variable 78 | ;Exit - AX = value of appropriate variable 79 | ; BX modified 80 | ; 81 | DSEG SEGMENT PUBLIC 'DATASG' 82 | EXTRN CURLIN:WORD,ERRLIN:WORD,TXTTAB:WORD,VARTAB:WORD 83 | DSEG ENDS 84 | PUBLIC BASVAR 85 | BVTAB: DW OFFSET CURLIN 86 | DW OFFSET ERRLIN 87 | DW OFFSET TXTTAB 88 | DW OFFSET VARTAB 89 | 90 | BASVAR: 91 | PUSHF 92 | SHL BX,1 ;make word offset 93 | POPF ;preserve PSW.C (input parameter) 94 | MOV BX,WORD PTR BVTAB[BX] ;Get address of appropriate variable 95 | JNB BASVRD ;Performing read function 96 | MOV WORD PTR 0[BX],AX ;Perform write function 97 | BASVRD: MOV AX,WORD PTR 0[BX] ;Perform read function 98 | RET 99 | PAGE 100 | SUBTTL Initialization Support Routines 101 | DSEG SEGMENT PUBLIC 'DATASG' 102 | EXTRN CSWFLG:WORD,CSWSIZ:WORD,MSWFLG:WORD,MSWSIZ:WORD,NEWDS:WORD 103 | EXTRN STKLOW:WORD,MEMSIZ:WORD,TOPMEM:WORD,SAVSEG:WORD,MAXMEM:WORD 104 | EXTRN FILTAB:WORD 105 | EXTRN FREFLG:WORD ;BYTES FREE message flag 106 | DSEG ENDS 107 | 108 | EXTRN CLEARC:NEAR,OMERR:NEAR 109 | EXTRN SETCBF:NEAR ;OEM Set COM Buf (size & location) 110 | EXTRN LINPRT:NEAR,STROUT:NEAR,CRDO:NEAR ;COM 111 | EXTRN CPMMEM:NEAR 112 | 113 | 114 | PUBLIC MAPCLC,MAPINI 115 | 116 | ;MAPINI - Set up the final memory map. 117 | ;Entry - NEWDS = final DS: 118 | ; MSWSIZ = final MAXMEM 119 | ;Exit - DS: and stack moved. 120 | ; 121 | MAPINI: 122 | ;Move the stack to the end of the new memory map 123 | POP BX ;Return address 124 | CLI ;disable external interrupts 125 | ; while changing memory map 126 | MOV AX,WORD PTR NEWDS 127 | MOV SS,AX 128 | MOV SP,WORD PTR MSWSIZ ; 129 | PUSH BX ;Return address 130 | 131 | ;Move the data segment 132 | MOV ES,AX ;NEWDS 133 | XOR SI,SI 134 | MOV CX,WORD PTR TXTTAB ;Amount of memory to move 135 | SHR CX,1 ;In words 136 | CLD 137 | MOV BX,DS 138 | CMP AX,BX ;Test for direction of copy 139 | JB BLKCPY ;brif destination is below source 140 | STD ;Copy up 141 | MOV SI,WORD PTR TXTTAB ;starting from top 142 | BLKCPY: 143 | MOV DI,SI 144 | REP MOVSW 145 | 146 | ;Set new data segment 147 | MOV DS,AX ;NEWDS 148 | EXTRN SEGINI:NEAR 149 | CALL SEGINI 150 | MOV AX,DS 151 | MOV WORD PTR SAVSEG,AX ;For PEEK/POKE 152 | STI ;enable external interrupts 153 | 154 | ;Insure zeros at TXTTAB 155 | MOV BX,WORD PTR TXTTAB 156 | MOV WORD PTR 0[BX],0D 157 | MOV BYTE PTR 2[BX],LOW 0D ;Three zeros necessary 158 | 159 | ;Call CLEARC to set up stack and finalize the memory map 160 | MOV AX,WORD PTR MSWSIZ 161 | ;Make sure that [TXTTAB]++32 does not overflow memory 162 | MOV BX,WORD PTR TOPMEM 163 | SUB BX,WORD PTR STKLOW ;BX=stack size 164 | JBE GOMERR ;BRIF illegal stack(0 or less bytes) 165 | NEG BX 166 | ADD BX,AX ;BX=new stack bottom 167 | JNB GOMERR ;BRIF MSWSIZ is less than stack size 168 | SUB BX,32D ;Leave a little room for a program 169 | JB GOMERR ;BRIF no room left 170 | CMP BX,WORD PTR TXTTAB ;Is new MAXMEM big enough? 171 | JBE GOMERR ;BRIF new MAXMEM smaller than data area 172 | MAXRQ1: MOV BX,AX 173 | SUB BX,WORD PTR MAXMEM ;Calc. seg. size difference 174 | MOV WORD PTR MAXMEM,AX ;Memory request 175 | ADD WORD PTR TOPMEM,BX 176 | ADD WORD PTR STKLOW,BX 177 | ADD WORD PTR FILTAB,BX 178 | ADD WORD PTR MEMSIZ,BX 179 | POP BX ;Return address (BX saved by CLEARC) 180 | CALL CLEARC 181 | PUSH BX ;Return address (BX saved by CLEARC) 182 | 183 | ;Set up program segment prefix 184 | MOV DX,DS 185 | MOV AH,LOW 38D ;Function ^H26 186 | INT 33D ;MSDOS function request 187 | 188 | ;Print free bytes message 189 | TEST BYTE PTR FREFLG,LOW 255D ;BYTES FREE message flag 190 | JNZ MAPINX ;Exit - message not to be printed 191 | MOV BX,WORD PTR MEMSIZ 192 | SUB BX,WORD PTR TXTTAB 193 | DEC BX 194 | DEC BX 195 | CALL LINPRT ;PRINT # OF BYTES FREE 196 | MOV BX,OFFSET WORDS ;TYPE THE HEADING 197 | CALL STROUT ;"BYTES FREE" 198 | CALL CRDO ;PRINT CARRIAGE RETURN 199 | MAPINX: RET 200 | 201 | GOMERR: JMP OMERR 202 | PAGE 203 | SUBTTL End of the New CS: 204 | 205 | ;All code loaded after this label is resident only until routine MAPINI 206 | ;initializes the new memory map. 207 | 208 | CSEND: 209 | 210 | ;MAPCLC - Calculate the final memory map limits. 211 | ;Entry - CSWFLG = Flag nonzero when /C: option exists 212 | ; CSWSIZ = /C: option size 213 | ; MSWFLG = Flag nonzero when /M: option exists 214 | ; MSWSIZ = /C: option size 215 | ;Exit - NEWDS = Final DS: address 216 | ; MSWSIZ = Highest memory address (future MAXMEM) 217 | ; 218 | MAPCLC: 219 | ;Validate/get COM buffer size 220 | MOV DX,OFFSET CSEND ;Location of COM buffer (New end of CS:) 221 | ADD DX,15D ;Round to next higher paragraph 222 | MOV CL,LOW 4D 223 | SHR DX,CL 224 | MOV CX,CS 225 | ADD CX,DX ;Segment offset of COM buffer 226 | MOV DX,WORD PTR CSWSIZ ;Segment size request 227 | TEST BYTE PTR CSWFLG,LOW 255D ;Was there a /C: opt - PSW.Z for SETCBF 228 | CALL SETCBF ;Report buffer size/loc 229 | JB GOMERR ; & validate size 230 | MOV WORD PTR CSWSIZ,DX ;COM buffer size 231 | 232 | ;Calculate NEWDS (New DS:) 233 | ; DX - COM buffer size 234 | ; NEWDS = (D+15/16) + DS: 235 | ADD DX,15D ;Round off to paragraph 236 | SHR DX,1 237 | SHR DX,1 238 | SHR DX,1 239 | SHR DX,1 240 | ADD DX,CX ;Skip COM buffer 241 | JO GOMERR 242 | MOV WORD PTR NEWDS,DX 243 | 244 | ;Validate the /M option or calculate the maximum possible MAXMEM 245 | ;1. Calcualte maximum MAXMEM based on the NEWDS 246 | ;2. If there was no /M option then goto 4 247 | ;3. Compare /M to the maximum and declare an error if /M is larger 248 | ;4. Save the new memory size as MSWSIZ 249 | PUSH BX ;Save text pointer 250 | MOV BX,WORD PTR CPMMEM 251 | SUB BX,DX ;Avail paragraphs 252 | JB GOMERR 253 | MOV DX,OFFSET 65535D/16D ;Max usable paragraphs 254 | CMP BX,DX 255 | JB MAXREQ ;More than enough 256 | MOV BX,DX 257 | MAXREQ: MOV CL,LOW 4D 258 | SHL BX,CL ;DX has valid maximum bytes 259 | TEST BYTE PTR MSWFLG,LOW 255D 260 | JZ NOMOPT ;No memory option 261 | MOV DX,WORD PTR MSWSIZ ;Get /M: size 262 | CMP BX,DX 263 | JB GOMERR ;Not enough for request 264 | MOV BX,DX 265 | NOMOPT: MOV WORD PTR MSWSIZ,BX ;New MAXMEM 266 | ; ADDI BX,^D256 267 | ; JB MAXRQ1 ;BRIF very large MAXMEM, value OK 268 | ; CMP BX,TXTTAB ;Is new MAXMEM big enough? 269 | ; JBE GOMERR ;BRIF new MAXMEM smaller than data area 270 | POP BX 271 | RET 272 | 273 | ;SEGOFF Convert end of memory segment to offset from current DS 274 | ; 275 | ; On entry: BX=last segment in memory 276 | ; DS=current data segment 277 | ; 278 | ; On exit: BX=offset from current segment to paragraph specified by BX 279 | ; Other registers unchanged, flags modified 280 | ; 281 | PUBLIC SEGOFF 282 | EXTRN OMERR:NEAR 283 | 284 | SEGOFF: PUSH CX 285 | MOV CX,DS 286 | SUB BX,CX ;[BX]=number of paragraphs free for DSEG 287 | JBE SGOFER ;BRIF last segment is less than current 288 | MOV CX,7777O ;[CX]=max num of paragraphs BASIC could use 289 | CMP BX,CX 290 | JBE LESS64 ;Brif less than 64k bytes available 291 | MOV BX,CX ;don't need more than 64k bytes 292 | LESS64: 293 | MOV CL,LOW 4 294 | SHL BX,CL ;convert paragraphs to bytes 295 | POP CX ;restore caller's CX 296 | RET 297 | SGOFER: JMP OMERR 298 | 299 | CSEG ENDS 300 | END 301 | -------------------------------------------------------------------------------- /KANJ86.ASM: -------------------------------------------------------------------------------- 1 | ; [ This translation created 10-Feb-83 by Version 4.3 ] 2 | 3 | .RADIX 8 ; To be safe 4 | 5 | CSEG SEGMENT PUBLIC 'CODESG' 6 | ASSUME CS:CSEG 7 | 8 | INCLUDE OEM.H 9 | 10 | TITLE KANJ86 - KANJI String Function Support for Basic-86 11 | 12 | COMMENT * 13 | 14 | --------- --- ---- -- --------- 15 | COPYRIGHT (C) 1982 BY MICROSOFT 16 | --------- --- ---- -- --------- 17 | 18 | Author: Tom Corbett - Microsoft Inc. - April 28, 1982 19 | 20 | * 21 | INCLUDE GIO86U ;contains DB definition 22 | .SALL 23 | 24 | INCLUDE MSDOSU 25 | IF CPM86 26 | INCLUDE CPM86U 27 | ENDIF 28 | 29 | 30 | PUBLIC KTNFN 31 | KTNFN: 32 | PUBLIC JISFN 33 | JISFN: 34 | PUBLIC KLENFN 35 | KLENFN: 36 | PUBLIC KPOSFN 37 | KPOSFN: 38 | EXTRN SNERR:NEAR 39 | JMP SNERR 40 | 41 | 42 | CSEG ENDS 43 | END 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /MACLNG.ASM: -------------------------------------------------------------------------------- 1 | ; [ This translation created 10-Feb-83 by Version 4.3 ] 2 | 3 | .RADIX 8 ; To be safe 4 | 5 | CSEG SEGMENT PUBLIC 'CODESG' 6 | ASSUME CS:CSEG 7 | 8 | INCLUDE OEM.H 9 | 10 | TITLE MACLNG - MACRO LANGUAGE DRIVER 11 | ; 12 | ; MICROSOFT GRAPHICS AND SOUND MACRO LANGUAGES 13 | ; 14 | TSHIBA=0 15 | ALPCPM=0 16 | 17 | 18 | 19 | PUBLIC FETCHR,FETCHZ,DECFET 20 | PUBLIC VALSCN,VALSC2,VARGET,NEGD 21 | 22 | EXTRN FCERR:NEAR,FRESTR:NEAR,FRCINT:NEAR,FRMEVL:NEAR,ISVAR:NEAR 23 | 24 | DSEG SEGMENT PUBLIC 'DATASG' 25 | ASSUME DS:DSEG 26 | EXTRN MCLLEN:WORD,MCLPTR:WORD,BUF:WORD,MCLTAB:WORD 27 | DSEG ENDS 28 | 29 | PUBLIC MACLNG,MCLXEQ 30 | EXTRN GETBCD:NEAR 31 | 32 | MACLNG: MOV MCLTAB,DX ;SAVE POINTER TO COMMAND TABLE 33 | CALL FRMEVL ;EVALUATE STRING ARGUMENT 34 | PUSH BX ;SAVE TXTPTR TILL DONE 35 | MOV DX,0 ;PUSH DUMMY ENTRY TO MARK END OF STK 36 | PUSH DX ;DUMMY ADDR 37 | PUSH AX ;DUMMY LENGTH 38 | 39 | MCLNEW: CALL FRESTR 40 | CALL GETBCD ;GET LENGTH & POINTER 41 | MOV AL,CH 42 | OR AL,CL 43 | JZ SHORT MCLOOP ;Don't Push if addr is 0 44 | MOV AL,DH 45 | OR AL,AL 46 | JZ SHORT MCLOOP ; or if Len is 0... 47 | PUSH CX ;PUSH ADDR OF STRING 48 | MOV AL,DH ;PUT IN [AL] 49 | PUSH AX 50 | 51 | MCLOOP: POP AX ;GET LENGTH OFF STACK 52 | MOV BYTE PTR MCLLEN,AL 53 | POP BX ;GET ADDR 54 | OR BX,BX ;SEE IF LAST ENTRY 55 | JNZ SHORT ??L000 56 | JMP POPTRT 57 | ??L000: ;ALL FINISHED IF ZERO 58 | MOV MCLPTR,BX ;SET UP POINTER 59 | 60 | MCLSCN: CALL FETCHR ;GET A CHAR FROM STRING 61 | JZ SHORT MCLOOP ;END OF STRING - SEE IF MORE ON STK 62 | ADD AL,AL ;PUT CHAR * 2 INTO [C] 63 | MOV CL,AL 64 | MOV BX,MCLTAB ;POINT TO COMMAND TABLE 65 | MSCNLP: 66 | INS86 56 ;CS OVERRIDE 67 | MOV AL,BYTE PTR [BX] ;GET CHAR FROM COMMAND TABLE 68 | ADD AL,AL ;CHAR = CHAR * 2 (CLR HI BIT FOR CMP) 69 | GOFCER: JNZ SHORT ??L001 70 | CALL FCERR ;END OF TABLE. 71 | ??L001: 72 | CMP AL,CL ;HAVE WE GOT IT? 73 | JZ SHORT MISCMD ;YES. 74 | INC BX ;MOVE TO NEXT ENTRY 75 | INC BX 76 | INC BX 77 | JMP SHORT MSCNLP 78 | 79 | MISCMD: 80 | MOV CX,OFFSET MCLSCN ;RETURN TO TOP OF LOOP WHEN DONE 81 | PUSH CX 82 | INS86 56 ;CS OVERRIDE 83 | MOV AL,BYTE PTR [BX] ;SEE IF A VALUE NEEDED 84 | MOV CL,AL ;PASS GOTTEN CHAR IN [C] 85 | ADD AL,AL 86 | JAE SHORT MNOARG ;COMMAND DOESN'T REQUIRE ARGUMENT 87 | OR AL,AL ;CLEAR CARRY 88 | RCR AL,1 ;MAKE IT A CHAR AGAIN 89 | MOV CL,AL ;PUT IN [C] 90 | PUSH CX 91 | PUSH BX ;SAVE PTR INTO CMD TABLE 92 | CALL FETCHR ;GET A CHAR 93 | MOV DX,1 ;DEFAULT ARG=1 94 | JNZ SHORT ??L002 95 | JMP VSNAR0 ;NO ARG IF END OF STRING 96 | ??L002: 97 | CALL ISLET2 ;SEE IF POSSIBLE LETTER 98 | JNAE SHORT ??L003 99 | JMP VSNARG 100 | ??L003: 101 | CALL VALSC3 ;GET THE VALUE 102 | STC ;SET CARRY TO FLAG USING NON-DEFAULT 103 | JMP SHORT ISCMD3 104 | VSNARG: CALL DECFET ;PUT CHAR BACK INTO STRING 105 | VSNAR0: OR AL,AL ;CLEAR CARRY 106 | ISCMD3: POP BX 107 | POP CX ;GET BACK COMMAND CHAR 108 | MNOARG: INC BX ;POINT TO DISPATCH ADDR 109 | INS86 56 ;CS OVERRIDE 110 | MOV BX,[BX] ;GET ADDRESS INTO HL 111 | JMP BX ;DISPATCH 112 | 113 | FETCHZ: CALL FETCHR ;GET A CHAR FROM STRING 114 | JZ SHORT GOFCER ;GIVE ERROR IF END OF LINE 115 | RET 116 | 117 | FETCHR: PUSH BX 118 | FETCH2: MOV BX,OFFSET MCLLEN ;POINT TO STRING LENGTH 119 | MOV AL,BYTE PTR [BX] 120 | OR AL,AL 121 | JZ SHORT POPTRT ;RETURN Z=0 IF END OF STRING 122 | DEC BYTE PTR [BX] ;UPDATE COUNT FOR NEXT TIME 123 | MOV BX,MCLPTR ;GET PTR TO STRING 124 | MOV AL,BYTE PTR [BX] ;GET CHARACTER FROM STRING 125 | INC BX ;UPDATE PTR FOR NEXT TIME 126 | MOV MCLPTR,BX 127 | CMP AL,LOW " " ;SKIP SPACES 128 | JZ SHORT FETCH2 129 | CMP AL,LOW 96D ;CONVERT LOWER CASE TO UPPER 130 | JB SHORT POPTRT 131 | SUB AL,LOW 32D ;DO CONVERSION 132 | POPTRT: POP BX 133 | RET 134 | 135 | DECFET: PUSH BX 136 | MOV BX,OFFSET MCLLEN ;INCREMENT LENGTH 137 | INC BYTE PTR [BX] 138 | MOV BX,MCLPTR ;BACK UP POINTER 139 | DEC BX 140 | MOV MCLPTR,BX 141 | POP BX 142 | RET 143 | 144 | VALSCN: CALL FETCHZ ;GET FIRST CHAR OF ARGUMENT 145 | VALSC3: CMP AL,LOW "=" ;NUMERIC? 146 | JNZ SHORT ??L004 147 | JMP VARGET 148 | ??L004: 149 | CMP AL,LOW "+" ;PLUS SIGN? 150 | JZ SHORT VALSCN ;THEN SKIP IT 151 | CMP AL,LOW "-" ;NEGATIVE VALUE? 152 | JNZ SHORT VALSC2 153 | MOV DX,OFFSET NEGD ;IF SO, NEGATE BEFORE RETURNING 154 | PUSH DX 155 | JMP SHORT VALSCN ;EAT THE "-" 156 | VALSC2: 157 | MOV DX,0 ;INITIAL VALUE OF ZERO 158 | NUMLOP: 159 | CMP AL,LOW 54O ;COMMA 160 | JZ SHORT DECFET ;YES, BACK UP AND RETURN 161 | CMP AL,LOW 73O ;SEMICOLON? 162 | JNZ SHORT $+3 163 | RET ;YES, JUST RETURN 164 | CMP AL,LOW OFFSET "9"+1 ;NOW SEE IF ITS A DIGIT 165 | JAE SHORT DECFET ;IF NOT, BACK UP AND RETURN 166 | CMP AL,LOW "0" 167 | JB SHORT DECFET 168 | MOV BX,0 ;[HL] is accumulator 169 | MOV CH,LOW 10D ;[HL]=[DE]*10 170 | NUML01: ADD BX,DX 171 | JB SHORT SCNFC ;overflow - JMP Function Call Error 172 | DEC CH 173 | JNZ SHORT NUML01 174 | SUB AL,LOW "0" ;ADD IN THE DIGIT 175 | MOV DL,AL 176 | MOV DH,LOW 0 177 | ADD BX,DX 178 | JB SHORT SCNFC ;overflow - JMP Function Call Error 179 | XCHG BX,DX ;VALUE SHOULD BE IN [DE] 180 | CALL FETCHR ;GET NEXT CHAR 181 | JNZ SHORT NUMLOP ;branch if not end of string 182 | RET 183 | 184 | 185 | SCNVAR: 186 | DSEG SEGMENT PUBLIC 'DATASG' 187 | EXTRN VALTYP:WORD 188 | DSEG ENDS 189 | EXTRN RETVAR:NEAR 190 | ;Allow VARPTR$(variable) for BASCOM compatibility 191 | ; 192 | MOV BX,MCLPTR ;Get string pntr 193 | MOV AL,BYTE PTR [BX] ;possible VALTYP if string created by VARPTR$ 194 | CMP AL,LOW 9D ;If .gt. 8 then not VARPTR$ string 195 | JAE SHORT SCNVR2 ;Brif not VARPTR$ candidate 196 | MOV AL,BYTE PTR MCLLEN ;Get str len 197 | SUB AL,LOW 3D ;at least 3 bytes if it was created by VARPTR$ 198 | JB SHORT SCNVR2 ;else let SCNVAR generate FCERR for bad var name 199 | MOV BYTE PTR MCLLEN,AL ;len -3 200 | MOV AL,BYTE PTR [BX] ;assume Byte 1 is Type 201 | MOV BYTE PTR VALTYP,AL ;so store in FAC 202 | INC BX 203 | MOV DL,BYTE PTR [BX] 204 | INC BX 205 | MOV DH,BYTE PTR [BX] ;[DE] = Var address. 206 | INC BX 207 | MOV MCLPTR,BX ;New pntr 208 | JMP RETVAR ;Go return value in FAC 209 | SCNVR2: 210 | CALL FETCHZ ;MAKE SURE FIRST CHAR IS LETTER 211 | MOV DX,OFFSET BUF ;PLACE TO COPY NAME FOR PTRGET 212 | PUSH DX ;SAVE ADDR OF BUF FOR "ISVAR" 213 | MOV CH,LOW 40D ;COPY MAX OF 40 CHARACTERS 214 | CALL ISLET2 ;MAKE SURE IT'S A LETTER 215 | JB SHORT SCNFC ;FC ERROR IF NOT LETTER 216 | 217 | SCNVLP: MOV DI,DX 218 | STOSB ;STORE CHAR IN BUF 219 | INC DX 220 | CMP AL,LOW 73O ;A SEMICOLON? 221 | JZ SHORT SCNV2 ;YES - END OF VARIABLE NAME 222 | CALL FETCHZ ;GET NEXT CHAR 223 | DEC CH 224 | JNZ SHORT SCNVLP 225 | 226 | SCNFC: CALL FCERR ;ERROR - VARIABLE TOO LONG 227 | SCNV2: POP BX ;GET PTR TO BUF 228 | JMP ISVAR ;GO GET ITS VALUE 229 | 230 | VARGET: CALL SCNVAR ;SCAN & EVALUATE VARIABLE 231 | CALL FRCINT ;MAKE IT AN INTEGER 232 | XCHG BX,DX ;IN [DE] 233 | RET 234 | 235 | EXTRN GETSTK:NEAR 236 | MCLXEQ: CALL SCNVAR ;SCAN VARIABLE NAME 237 | MOV AL,BYTE PTR MCLLEN ;SAVE CURRENT STRING POS & LENGTH 238 | MOV BX,MCLPTR 239 | POP SI ;XTHL 240 | XCHG SI,BX 241 | PUSH SI ;POP OFF RET ADDR, PUSH MCLPTR 242 | PUSH AX 243 | MOV CL,LOW 2 ;MAKE SURE OF ROOM ON STACK 244 | CALL GETSTK 245 | JMP MCLNEW 246 | 247 | NEGD: 248 | INS86 367,332 ;NEG DX,DX 249 | RET 250 | 251 | ISLET2: CMP AL,LOW "A" 252 | JB SHORT ISLETX ;TOO SMALL FOR LETTER 253 | CMP AL,LOW OFFSET "Z"+1 254 | CMC ;SET CARRY IF NOT LETTER 255 | ISLETX: RET 256 | 257 | CSEG ENDS 258 | END 259 | -------------------------------------------------------------------------------- /MAKEFILE: -------------------------------------------------------------------------------- 1 | ASM=MASM 2 | 3 | 4 | ADVGRP.OBJ: ADVGRP.ASM 5 | $(ASM) ADVGRP.asm; 6 | 7 | BIBOOT.OBJ: BIBOOT.ASM 8 | $(ASM) BIBOOT.asm; 9 | 10 | BIMISC.OBJ: BIMISC.ASM 11 | $(ASM) BIMISC.asm; 12 | 13 | BIPRTU.OBJ: BIPRTU.ASM 14 | $(ASM) BIPRTU.asm; 15 | 16 | BIPTRG.OBJ: BIPTRG.ASM 17 | $(ASM) BIPTRG.asm; 18 | 19 | BISTRS.OBJ: BISTRS.ASM 20 | $(ASM) BISTRS.asm; 21 | 22 | CALL86.OBJ: CALL86.ASM 23 | $(ASM) CALL86.asm; 24 | 25 | DSKCOM.OBJ: DSKCOM.ASM 26 | $(ASM) DSKCOM.asm; 27 | 28 | FIVEO.OBJ: FIVEO.ASM 29 | $(ASM) FIVEO.asm; 30 | 31 | GENGRP.OBJ: GENGRP.ASM 32 | $(ASM) GENGRP.asm; 33 | 34 | GIO86.OBJ: GIO86.ASM 35 | $(ASM) GIO86.asm; 36 | 37 | GIOCAS.OBJ: GIOCAS.ASM 38 | $(ASM) GIOCAS.asm; 39 | 40 | GIOCOM.OBJ: GIOCOM.ASM 41 | $(ASM) GIOCOM.asm; 42 | 43 | GIOCON.OBJ: GIOCON.ASM 44 | $(ASM) GIOCON.asm; 45 | 46 | GIODSK.OBJ: GIODSK.ASM 47 | $(ASM) GIODSK.asm; 48 | 49 | GIOKYB.OBJ: GIOKYB.ASM 50 | $(ASM) GIOKYB.asm; 51 | 52 | GIOLPT.OBJ: GIOLPT.ASM 53 | $(ASM) GIOLPT.asm; 54 | 55 | GIOSCN.OBJ: GIOSCN.ASM 56 | $(ASM) GIOSCN.asm; 57 | 58 | GIOTBL.OBJ: GIOTBL.ASM 59 | $(ASM) GIOTBL.asm; 60 | 61 | GWDATA.OBJ: GWDATA.ASM 62 | $(ASM) GWDATA.asm; 63 | 64 | GWEVAL.OBJ: GWEVAL.ASM 65 | $(ASM) GWEVAL.asm; 66 | 67 | GWINIT.OBJ: GWINIT.ASM 68 | $(ASM) GWINIT.asm; 69 | 70 | GWLIST.OBJ: GWLIST.ASM 71 | $(ASM) GWLIST.asm; 72 | 73 | GWMAIN.OBJ: GWMAIN.ASM 74 | $(ASM) GWMAIN.asm; 75 | 76 | GWRAM.OBJ: GWRAM.ASM 77 | $(ASM) GWRAM.asm; 78 | 79 | GWSTS.OBJ: GWSTS.ASM 80 | $(ASM) GWSTS.asm; 81 | 82 | IBMRES.OBJ: IBMRES.ASM 83 | $(ASM) IBMRES.asm; 84 | 85 | ITSA86.OBJ: ITSA86.ASM 86 | $(ASM) ITSA86.asm; 87 | 88 | KANJ86.OBJ: KANJ86.ASM 89 | $(ASM) KANJ86.asm; 90 | 91 | MACLNG.OBJ: MACLNG.ASM 92 | $(ASM) MACLNG.asm; 93 | 94 | MATH.OBJ: MATH.ASM 95 | $(ASM) MATH.asm; 96 | 97 | MATH.ASM: MATH1.ASM MATH2.ASM 98 | copy MATH1.ASM+MATH2.ASM MATH.ASM 99 | 100 | MATH.OBJ: MATH.ASM 101 | $(ASM) MATH.ASM; 102 | 103 | NEXT86.OBJ: NEXT86.ASM 104 | $(ASM) NEXT86.asm; 105 | 106 | SCNDRV.OBJ: SCNDRV.ASM 107 | $(ASM) SCNDRV.asm; 108 | 109 | SCNEDT.OBJ: SCNEDT.ASM 110 | $(ASM) SCNEDT.asm; 111 | 112 | OEM.OBJ: OEM.ASM 113 | $(ASM) OEM.ASM; 114 | 115 | gwbasic.exe: ADVGRP.OBJ BIBOOT.OBJ BIMISC.OBJ BIPRTU.OBJ BIPTRG.OBJ \ 116 | BISTRS.OBJ CALL86.OBJ DSKCOM.OBJ FIVEO.OBJ GENGRP.OBJ GIO86.OBJ \ 117 | GIOCAS.OBJ GIOCOM.OBJ GIOCON.OBJ GIODSK.OBJ GIOKYB.OBJ GIOLPT.OBJ \ 118 | GIOSCN.OBJ GIOTBL.OBJ GWDATA.OBJ GWEVAL.OBJ GWINIT.OBJ GWLIST.OBJ \ 119 | GWMAIN.OBJ GWRAM.OBJ GWSTS.OBJ IBMRES.OBJ ITSA86.OBJ KANJ86.OBJ \ 120 | MACLNG.OBJ MATH.OBJ MATH.OBJ NEXT86.OBJ SCNDRV.OBJ \ 121 | SCNEDT.OBJ OEM.OBJ 122 | link @gwbasic.lnk 123 | 124 | -------------------------------------------------------------------------------- /MSDOSU: -------------------------------------------------------------------------------- 1 | ; [ This translation created 12-Jan-83 by Version 4.3 ] 2 | 3 | SUBTTL MSDOSU - MS-DOS Constants and Data-Structure Definitions 4 | 5 | COMMENT * 6 | 7 | --------- --- ---- -- --------- 8 | COPYRIGHT (C) 1982 BY MICROSOFT 9 | --------- --- ---- -- --------- 10 | 11 | Programmer: Tom Corbett, Microsoft Inc. 12 | 13 | * 14 | 15 | CALLOS MACRO FUNC 16 | IFNB 17 | MOV AH,LOW OFFSET FUNC 18 | ENDIF 19 | INT 33D ;MSDOS system call 20 | ENDM 21 | 22 | ROFFST MACRO NAME,SIZE ;define record macro 23 | NAME=_OFFST 24 | _OFFST=_OFFST+SIZE 25 | ENDM 26 | 27 | 28 | ; MSDOS System Call codes 29 | ; 30 | C_PRTO=5D ;Printer output 31 | C_DCIO=6D ;Direct console I/O 32 | C_REST=13D ;INITIALIZE BDOS 33 | C_SDRV=14D ;SET CURRENTLY SELECTED DRIVE 34 | C_OPEN=15D 35 | C_CLOS=16D 36 | C_SEAR=17D ;SEARCH FOR FILE 37 | C_DELE=19D 38 | C_READ=20D 39 | C_MAKE=22D 40 | C_RENA=23D 41 | C_GDRV=25D ;GET CURRENTLY SELECTED DRIVE 42 | C_BUFF=26D ;SET DMA ADDRESS 43 | C_RNDR=33D ;Random read 44 | C_RNDW=34D ;Random write 45 | C_RBR=39D ;Random Block Read 46 | C_PARS=41D ;Parse Filename 47 | 48 | FNAML=11D ;number of bytes in Filename with extension 49 | DATPSC=128D ;bytes per sector 50 | FCBSIZ=38D ;File Control Block size 51 | 52 | ;MS-DOS FILE-DATA-BLOCK Record Definition 53 | ; 54 | _OFFST=0 ;initialize count 55 | ROFFST F_NUL1,1 ;not used by basic interpreter 56 | ROFFST F_NUM,1 ;file number 0..255 57 | ROFFST F_NUL2,2 ;not used by basic interpreter 58 | ROFFST F_NEXT,2 ;thread for linked list, [MEMSIZ]=end 59 | ROFFST F_MODE,1 ;file mode: 60 | MD_SQI=1D ;sequential input 61 | MD_SQO=2D ;sequential output 62 | MD_RND=4D ;random 63 | MD_APP=8D ;append 64 | ROFFST F_FCB,FCBSIZ ;File Control Block: used to communicate with OS 65 | ROFFST F_CLOC,2 ;for seq files: num sectors read/written (LOCOFS) 66 | ;for rnd files: last record number + 1 67 | ROFFST F_ORCT,1 ;"Original Byte Count" (ORNOFS) 68 | ;for seq input: #bytes in sector when read 69 | ;for seq output: #bytes in output sector 70 | ;for random files: bytes per sector 71 | ROFFST F_BREM,1 ;number of bytes till end-of-buffer (NMLOFS) 72 | ROFFST F_CODE,1 ;file encoding: 73 | FC_ASC=0 ;Ascii SAVE, Data files 74 | FC_BIN=1 ;binary file (BSAVE, binary SAVE) 75 | ROFFST F_BAKC,1 ;holds next sequential input when F.FLBS.FL.BKC is true 76 | ROFFST F_NUL3,1 ;not used by basic interpreter 77 | ROFFST F_DEV,1 ;Device number (FL.DSK) 78 | ROFFST F_WID,1 ;File width 79 | ROFFST F_NUL4,1 ;not used by basic interpreter 80 | ROFFST F_FLGS,1 ;flags 81 | FL_BKC=200O ;when true, F.BAKC contains next sequential input 82 | ROFFST F_POS,1 ;Current column position (FL.OPS) 83 | ROFFST FDBSIZ,0 ;size of device independent part of FDB 84 | ;device dependant FDB entries start here 85 | 86 | ROFFST DATOFS,DATPSC ;Operating System interface buffer 87 | ROFFST FD_SIZ,2 ;variable record length for random files 88 | ROFFST FD_PHY,2 ;current physical record number 89 | ROFFST FD_LOG,2 ;current logical record number 90 | ROFFST F_NUL5,1 ;Future use 91 | ROFFST FD_OPS,2 ;current output position for sequential I/O 92 | ROFFST FD_DAT,0 ;field buffer of random file 93 | 94 | ; OFFSETS INTO MSDOS FCB 95 | ; 96 | FCB_DV=F_FCB+0D ;DRIVE (0=default, 1=A:, 2=B:, ...) 97 | FCB_FN=F_FCB+1D ;FILE NAME 98 | FCB_FT=F_FCB+9D ;EXTENSION 99 | FCB_EX=F_FCB+12D ;FILE EXTENT (identifies block of 128 logical records) 100 | FCB_RC=F_FCB+14D ;RECORD SIZE 101 | FCB_FS=F_FCB+16D ;FILE SIZE IN BYTES 102 | FCB_DT=F_FCB+20D ;Date of last write to file 103 | FCB_DT=F_FCB+22D ;Time of last write to file 104 | FCB_NR=F_FCB+32D ;NEXT RECORD NUMBER 105 | FCB_RN=F_FCB+33D ;CP/M 2.x Random Record Number 106 | 107 | PAGE 108 | -------------------------------------------------------------------------------- /NEXT86.ASM: -------------------------------------------------------------------------------- 1 | ; [ This translation created 10-Feb-83 by Version 4.3 ] 2 | 3 | .RADIX 8 ; To be safe 4 | 5 | CSEG SEGMENT PUBLIC 'CODESG' 6 | ASSUME CS:CSEG 7 | 8 | INCLUDE OEM.H 9 | 10 | TITLE NEXT86 CODE 11 | .SALL 12 | .RADIX 8 13 | ;**************************************************************** 14 | ; 15 | ; A "FOR" ENTRY ON THE STACK HAS THE FOLLOWING FORMAT: 16 | ; 17 | ; LOW ADDRESS 18 | ; TOKEN ($FOR IN HIGH BYTE) 1 BYTES 19 | ; A POINTER TO THE LOOP VARIABLE 2 BYTES 20 | ; UNDER ANSI & LENGTH=2, TWO BYTES GIVING TEXT POINTER OF 21 | ; MATCHING "NEXT" 22 | ; A BYTE REFLECTING THE SIGN OF THE INCREMENT 1 BYTE 23 | ; UNDER LENGTH=2, A BYTE MINUS FOR INTEGER AND 24 | ; POSITIVE FOR FLOATING "FOR'S" 25 | ; THE STEP 4 BYTES 26 | ; THE UPPER VALUE 4 BYTES 27 | ; THE LINE # OF THE "FOR" STATEMENT 2 BYTES 28 | ; A TEXT POINTER INTO THE "FOR" STATEMENT 2 BYTES 29 | ; HIGH ADDRESS 30 | ; 31 | ; TOTAL 16-19 BYTES 32 | ; 33 | ;***************************************************************** 34 | 35 | EXTRN CHRGTR:NEAR,DCOMPR:NEAR,FADDS:NEAR,FCOMP:NEAR,FNDFOR:NEAR 36 | EXTRN IADD:NEAR 37 | EXTRN ICMPA:NEAR,MOVFM:NEAR,MOVMF:NEAR,MOVRM:NEAR,NEWSTT:NEAR 38 | EXTRN NFERR:NEAR,NXTCON:NEAR,OVERR:NEAR 39 | EXTRN PTRGET:NEAR 40 | PUBLIC NEXT 41 | PUBLIC NEXTS 42 | DSEG SEGMENT PUBLIC 'DATASG' 43 | ASSUME DS:DSEG 44 | EXTRN NXTFLG:WORD,FVALSV:WORD,NXTTXT:WORD 45 | DSEG ENDS 46 | DSEG SEGMENT PUBLIC 'DATASG' 47 | EXTRN FACLO:WORD,SAVSTK:WORD,TEMP:WORD,VALTYP:WORD,CURLIN:WORD 48 | DSEG ENDS 49 | 50 | NF1: JMP NFERR 51 | NEXT: 52 | LAHF ;FLAGS TO AH 53 | XCHG AH,AL 54 | PUSH AX 55 | MOV AL,LOW 1 56 | JMP SHORT NEXTS1 57 | NEXTS: XOR AL,AL ;FLAG THAT "FOR IS USING "NEXT 58 | NEXTS1: MOV BYTE PTR NXTFLG,AL 59 | POP AX 60 | XCHG AL,AH 61 | SAHF 62 | MOV DX,0 63 | NEXTC: 64 | MOV WORD PTR NXTTXT,BX ;SAVE STARTING TEXT POINTER 65 | JZ NEXTC1 66 | CALL PTRGET 67 | NEXTC1: MOV WORD PTR TEMP,BX ;SAVE PTR TO LOOP VARIABLE 68 | CALL FNDFOR ;TRY TO FING A "FOR ENTRY 69 | JNZ NF1 ;NEXT W/O FOR ERROR 70 | MOV SP,BX ;SETUP STACK BY CHOPPING HERE 71 | MOV SI,WORD PTR NXTTXT 72 | CMP WORD PTR 0[BX],SI ;COMPARE TEXT POINTERS AT THE START 73 | JNZ NF1 ;OF THIS "NEXT WITH THIS NEXT 74 | PUSH DX ;PUSH STEP ONTO THE STACK 75 | MOV AH,BYTE PTR 2[BX] ; 76 | PUSH AX 77 | PUSH DX ;PTR. TO LOOP VAR. ON STACK 78 | ADD BX,4 79 | TEST BYTE PTR -1[BX],LOW 200O ;SEE IF INTEGER FOR 80 | JS INTNXT ;IF INTEGER HANDLE SEPARATELY 81 | MOV CX,2 ; 82 | CLD ;DF=0 SO MOVW WILL INCREMENT 83 | MOV SI,BX 84 | MOV DI,OFFSET FACLO 85 | REP MOVSW ;GET LOOP VARIABLE 86 | POP BX ;PTR TO FOR ENTRY 87 | PUSH SI ; 88 | PUSH BX 89 | TEST BYTE PTR NXTFLG,LOW 377O 90 | JNZ NXTDO 91 | MOV SI,OFFSET FVALSV ;FETCH INITIAL VALUE 92 | SUB DI,4 ;POINT DI BACK TO FACLO 93 | MOV CX,2 ;TWO WORD MOVE 94 | REP MOVSW 95 | XOR AL,AL ;CONTINUE "NEXT" WITH INITIAL VALUE 96 | JZ NXTDOA ; 97 | NXTDO: CALL FADDS 98 | NXTDOA: POP DI ;POP PTR TO LOOP VARIABLE 99 | MOV SI,OFFSET FACLO ;WILL MOVE FAC TO THERE 100 | MOV CX,2 101 | CLD 102 | REP MOVSW 103 | POP SI ;GET ENTRY PTR. 104 | MOV DX,WORD PTR 0[SI] 105 | MOV CX,WORD PTR 2[SI] 106 | ADD SI,4 107 | PUSH SI ;SAVE ENTRY PTR. 108 | CALL FCOMP ;COMPARE THE NOS. RETURNING 109 | ;377 IF FAC LESS THAN REGS,0 IF = 110 | ;AND 1 IF GREATER 111 | JMP SHORT FINNXT ;SKIP INTEGER CODE 112 | INTNXT: ADD BX,4 ;SKIP 4 DUMMY BYTES 113 | MOV CX,WORD PTR 0[BX] ;FETCH STEP TO CX 114 | INC BX 115 | INC BX 116 | POP SI ;PTR TO LOOP VARIABLE 117 | MOV DX,WORD PTR 0[SI] 118 | TEST BYTE PTR NXTFLG,LOW 377O ;SEE IF "FOR IS USING "NEXT CODE 119 | JNZ INXTDO ;NO , JUST CONTINUE 120 | MOV DX,WORD PTR FVALSV ;GET THE INITIAL VALUE 121 | JMP SHORT IFORIN ;CONTINUE FIRST ITERATION CHECK 122 | INXTDO: ADD DX,CX 123 | JO OV1 124 | IFORIN: 125 | MOV WORD PTR 0[SI],DX 126 | PUSH DX ;SAVE THE VALUE OF THE LOOP VAR. 127 | MOV DX,WORD PTR 0[BX] ; 128 | INC BX 129 | INC BX 130 | POP AX 131 | PUSH BX 132 | CALL ICMPA ;COMPARE (AX) WITH (DX) 133 | FINNXT: 134 | POP BX ;POP "FOR ENTRY PTR 135 | POP CX ;GET SGN OF INCREMENT 136 | SUB AL,CH ;SUBTRACT THE INCREMENTS SIGN FROM 137 | ;THAT OF (CURRENT VAL-FINAL VAL) 138 | CALL MOVRM ;GET LINE # OF "FOR INTO DX AND 139 | ;TEXT PTR OF "FOR INTO CX 140 | JZ LOOPDN ;JUMP IF DONE 141 | MOV WORD PTR CURLIN,DX ;STORE LINE NO. 142 | MOV DX,CX ;SETUP THE TEXT PTR 143 | XCHG DX,BX 144 | JMP NXTCON 145 | LOOPDN: MOV SP,BX ;ELIMINATE FOR ENTRY & SAVE UPDATED 146 | MOV WORD PTR SAVSTK,BX ;STACK 147 | MOV BX,WORD PTR TEMP ;RESTORE TEXT PTR 148 | CMP BYTE PTR 0[BX],LOW 54O ;COMMA? 149 | JNZ NS1 ;"NEXT 150 | LOOPD1: MOV BYTE PTR NXTFLG,LOW 377O ;Set NXTFLG non-zero since NEXT couldn't 151 | ;have been called by FOR in this case 152 | CALL CHRGTR ;Skip comma 153 | MOV DX,SP ;[DX]=[SP] which will never match 154 | ;any VARPTR (see FNDFOR) 155 | CALL NEXTC ;Process Next NEXT 156 | OV1: JMP OVERR 157 | NS1: JMP NEWSTT 158 | CSEG ENDS 159 | END 160 | -------------------------------------------------------------------------------- /OEM.ASM: -------------------------------------------------------------------------------- 1 | .RADIX 8 ; To be safe 2 | 3 | CSEG SEGMENT PUBLIC 'CODESG' 4 | ASSUME CS:CSEG 5 | 6 | INCLUDE OEM.H 7 | 8 | TITLE OEM - Vendor provided code 9 | 10 | COMMENT * 11 | Written by: Stjepan Gros 12 | 13 | A lot of screen related rutines use INT 10H services, so much of 14 | data can be inferred by reading documentation for INT 10H. 15 | * 16 | .SALL 17 | 18 | ;; Text screen group of subroutines 19 | 20 | ; OEM supplied Clear-Screen Routine 21 | PUBLIC CLRSCN 22 | CLRSCN: 23 | RET 24 | 25 | ; OEM supplied screen clear to end of line 26 | ; Clear from (DH,DL) to EOL (from GWSTS.ASM) 27 | PUBLIC CLREOL 28 | CLREOL: 29 | RET 30 | 31 | ; OEM supplied SCROLL routine 32 | ; 33 | ; INPUT 34 | ; AX 35 | ; OUTPUT 36 | ; 37 | ; REGISTERS AFFECTED 38 | ; 39 | PUBLIC SCROLL 40 | SCROLL: ;Dummy function 41 | RET 42 | 43 | ; OEM supplied screen input(read character) 44 | ; 45 | ; INPUT 46 | ; DH,DL Coordinates, DH->Row, DL->Column 47 | ; CF=0 Indicates call is from Screen Editor 48 | ; OUTPUT 49 | ; X=Character at (DH,DL) 50 | ; REGISTERS AFFECTED 51 | 52 | PUBLIC SCRINP 53 | SCRINP: ;Dummy function 54 | RET 55 | 56 | 57 | ; OEM supplied character output 58 | ; 59 | ; INPUT 60 | ; AL Character to output 61 | ; DH, DL Position 62 | ; OUTPUT 63 | ; 64 | ; REGISTERS AFFECTED 65 | ; 66 | PUBLIC SCROUT 67 | SCROUT: 68 | push ax 69 | push bx 70 | push cx 71 | xor bx,bx 72 | mov ah,2 73 | push ax 74 | int 20 ; 0x10 75 | pop ax 76 | mov cx,1 77 | mov bx,7 78 | mov ah,12 ; 0xa 79 | int 20 ; 0x10 80 | pop cx 81 | pop bx 82 | pop ax 83 | RET 84 | 85 | ; MSX: Record current cursor addresses mask pattern 86 | ; Input : BX - Cursor address 87 | ; AL - Mask pattern 88 | PUBLIC STOREC 89 | STOREC: ;Dummy function 90 | RET 91 | 92 | ;Let screen editor set width 93 | ;pass Width in AL 94 | ;pass Height in CL 95 | 96 | PUBLIC SWIDTH 97 | SWIDTH: ;Dummy function 98 | RET 99 | 100 | PUBLIC NREAD 101 | NREAD: ;Dummy function 102 | RET 103 | 104 | PUBLIC RDTRIG 105 | RDTRIG: ;Dummy function 106 | RET 107 | 108 | ; MSX: Set horizontal screen pixels 109 | PUBLIC NSETCX 110 | NSETCX: ;Dummy function 111 | RET 112 | 113 | PUBLIC EDTMAP 114 | EDTMAP: ;Dummy function 115 | RET 116 | 117 | PUBLIC DONOTE 118 | DONOTE: ;Dummy function 119 | RET 120 | 121 | PUBLIC SNDLPT 122 | SNDLPT: ;Dummy function 123 | RET 124 | 125 | PUBLIC PEKFLT 126 | PEKFLT: ;Dummy function 127 | RET 128 | 129 | PUBLIC SETCBF 130 | SETCBF: ;Dummy function 131 | RET 132 | 133 | ; MSX: Shifts screen pixel to the left 134 | PUBLIC LEFTC 135 | LEFTC: ;Dummy function 136 | RET 137 | 138 | PUBLIC PGINIT 139 | PGINIT: ;Dummy function 140 | RET 141 | 142 | PUBLIC MAPXYC 143 | MAPXYC: ;Dummy function 144 | RET 145 | 146 | PUBLIC INKMAP 147 | INKMAP: ;Dummy function 148 | RET 149 | 150 | PUBLIC SETFBC 151 | SETFBC: ;Dummy function 152 | RET 153 | 154 | ; MSX: Tests whether DOWNC is possible, if possible, execute DOWNC 155 | ; Set carry flag set if operation would end outside the screen 156 | PUBLIC TDOWNC 157 | TDOWNC: ;Dummy function 158 | RET 159 | 160 | ; MSX: Scans screen pixels to the right 161 | PUBLIC SCANR 162 | SCANR: ;Dummy function 163 | RET 164 | 165 | PUBLIC INICOM 166 | INICOM: ;Dummy function 167 | RET 168 | 169 | PUBLIC GETHED 170 | GETHED: ;Dummy function 171 | RET 172 | 173 | ; MSX: Shifts screen pixel up 174 | PUBLIC UPC 175 | UPC: ;Dummy function 176 | RET 177 | 178 | ; MSX: Scans screen pixels to the left 179 | PUBLIC SCANL 180 | SCANL: ;Dummy function 181 | RET 182 | 183 | ; MSX: Gets current cursor addresses mask pattern 184 | ; Output : BX - Cursor address 185 | ; AL - Mask pattern 186 | PUBLIC FETCHC 187 | FETCHC: ;Dummy function 188 | RET 189 | 190 | ; MSX: Scales X and Y coordinates 191 | PUBLIC SCALXY 192 | SCALXY: ;Dummy function 193 | RET 194 | 195 | PUBLIC GETFBC 196 | GETFBC: ;Dummy function 197 | RET 198 | 199 | PUBLIC SNDCOM 200 | SNDCOM: ;Dummy function 201 | RET 202 | 203 | PUBLIC STACOM 204 | STACOM: ;Dummy function 205 | RET 206 | 207 | ; MSX: Reads attribute byte of current screen pixel 208 | PUBLIC READC 209 | READC: ;Dummy function 210 | RET 211 | 212 | PUBLIC INFMAP 213 | INFMAP: ;Dummy function 214 | RET 215 | 216 | ; MSX: Tests whether UPC is possible, if possible, execute UPC 217 | ; Set carry flag set if operation would end outside the screen 218 | PUBLIC TUPC 219 | TUPC: ;Dummy function 220 | RET 221 | 222 | ; MSX: Shifts screen pixel to the right 223 | PUBLIC RIGHTC 224 | RIGHTC: ;Dummy function 225 | RET 226 | 227 | PUBLIC SEGINI 228 | SEGINI: ;Dummy function 229 | RET 230 | 231 | ; MSX: Gets screen relations 232 | ; Output : DX, BX 233 | PUBLIC GTASPC 234 | GTASPC: ;Dummy function 235 | RET 236 | 237 | PUBLIC RECCOM 238 | RECCOM: ;Dummy function 239 | RET 240 | 241 | ; MSX: Returns current screen pixel of specified attribute byte 242 | PUBLIC SETC 243 | SETC: ;Dummy function 244 | RET 245 | 246 | PUBLIC PIXSIZ 247 | PIXSIZ: ;Dummy function 248 | RET 249 | 250 | ; MSX: Shifts screen pixel down 251 | PUBLIC DOWNC 252 | DOWNC: ;Dummy function 253 | RET 254 | 255 | PUBLIC LCPY 256 | LCPY: ;Dummy function 257 | RET 258 | 259 | PUBLIC FKYFMT 260 | FKYFMT: ;Dummy function 261 | RET 262 | 263 | ;Do OEM specific termination processing (from GIODSK.ASM) 264 | PUBLIC GWTERM 265 | GWTERM: ;Dummy function 266 | RET 267 | 268 | PUBLIC GRPSIZ 269 | GRPSIZ: ;Dummy function 270 | RET 271 | 272 | PUBLIC FKYADV 273 | FKYADV: ;Dummy function 274 | RET 275 | 276 | ; 277 | ; RETURN 278 | ; ZF=0 no key available 279 | ; [AX]=next key from keyboard if one exists 280 | PUBLIC KEYINP 281 | KEYINP: ;Dummy function 282 | RET 283 | 284 | PUBLIC PRTMAP 285 | PRTMAP: ;Dummy function 286 | RET 287 | 288 | PUBLIC RDPEN 289 | RDPEN: ;Dummy function 290 | RET 291 | 292 | PUBLIC CSRATR 293 | CSRATR: ;Dummy function 294 | RET 295 | 296 | PUBLIC GWINI 297 | GWINI: ;Dummy function 298 | RET 299 | 300 | PUBLIC NWRITE 301 | NWRITE: ;Dummy function 302 | RET 303 | 304 | PUBLIC SCRSTT 305 | SCRSTT: ;Dummy function 306 | RET 307 | 308 | PUBLIC CSRDSP 309 | CSRDSP: 310 | RET 311 | 312 | ; MSX: Set attribute byte 313 | PUBLIC SETATR 314 | SETATR: ;Dummy function 315 | RET 316 | 317 | ; MSX: Initalises the PAINT instruction 318 | PUBLIC PNTINI 319 | PNTINI: ;Dummy function 320 | RET 321 | 322 | PUBLIC SETCLR 323 | SETCLR: ;Dummy function 324 | RET 325 | 326 | PUBLIC SCRATR 327 | SCRATR: ;Dummy function 328 | RET 329 | 330 | PUBLIC TRMCOM 331 | TRMCOM: ;Dummy function 332 | RET 333 | 334 | PUBLIC POLLEV 335 | POLLEV: ;Dummy function 336 | RET 337 | 338 | PUBLIC POKFLT 339 | POKFLT: ;Dummy function 340 | RET 341 | 342 | PUBLIC RDSTIK 343 | RDSTIK: ;Dummy function 344 | RET 345 | 346 | PUBLIC MAPSUP 347 | MAPSUP: ;Dummy function 348 | RET 349 | 350 | 351 | CSEG ENDS 352 | END 353 | -------------------------------------------------------------------------------- /OEM.H: -------------------------------------------------------------------------------- 1 | ; [ This translation created 10-Feb-83 by Version 4.3 ] 2 | 3 | SUBTTL Common file to produce 2-segment 8086 GW-CPM BASIC 4 | 5 | .SALL 6 | 7 | .RADIX 10 8 | OEMRAM=0D 9 | ;Pascal program HFILE searches for the following line - DO NOT MODIFY 10 | ;** (VERSION SPECIFIC VALUES) ************************************************ 11 | NMLINE=25 ;Max screen display text lines 12 | NBANKS=1 ;Number of graphic planes 13 | PALSIZ=0 ;Size of OEM color palette 14 | DBLCHR=0 ;Editor support for KANJI chars 15 | KANABS=0 ;Kana BASIC (Japanese JIS codes) 16 | KANJFN=0 ;KANJI String Functions KPOS, KLEN .. 17 | JISKTN=0 ;&K, &J constants (KANJI) 18 | SUPRSH=1 ;1=super shift key feature 19 | NMKEYF=10 ;number of function keys 20 | NMKEYT=14 ;number of function key traps 21 | FKEYON=1 ;yes=display function keys 22 | SCROLT=1 ;Line 25 allocated for status only 23 | PLAYSW=1 ;for PLAY statement 24 | BEEPSW=1 ;for SOUND, BEEP statements 25 | NMLPT=3 ;number of line printers 26 | CONSSW=1 ;Device CONS: 27 | NMCOMT=2 ;number of COMmunications ports 28 | NMPENT=1 ;number of light pens 29 | NMSTRT=4 ;number of joysticks 30 | GWCASS=0 ;Cassette switch (CSAVE,CLOAD,MOTOR) 31 | IBMLIK=1 ;IBM compatibility package 32 | IBMTOK=1 ;IBM token compatibility 33 | DYNCOM=1 ;Dynamic communication buffers 34 | ;** (END OF VERSION SPECIFIC VALUES) ***************************************** 35 | ;Pascal program HFILE searches for the previous line - DO NOT MODIFY 36 | ; 37 | NUMTRP=NMKEYT+NMCOMT+NMPENT+NMSTRT 38 | GW=1 ;GW BASIC 39 | ESCCTL=0 ;Escape Sequence processing in SCROUT 40 | GWDBUG=0 ;DEBUG statement (TEST VERSIONS ONLY) 41 | ; Support is in BINTRP.MAC and GWSTS.MAC 42 | SNOUT=0 ; (Added; TODO: Find and fix name) 43 | ;single precision numbers for output. 44 | ; 0 := 7 digits 45 | ; 1 := 6 digits 46 | CASSW=0 ;CASSETTE SWITCH 47 | LABKEY=1 ;^T (LABEL) key capability 48 | HGHBIT=1 ;8-bit characters (ASCII & Graphics) 49 | QUEUE=1 ;Queued painting algorithm (vs. stack) 50 | GIO86=1 ;BASIC-86 Generalized I/O 51 | SCRNIO=1 ;Screen editor 52 | SCRN86=1 ;8086 Screen editor 53 | I8086=1 ;CROSS ASSEMBLING FOR 8086 54 | MULSEG=1 ;MULTI-SEGMENT 8086 BASIC 55 | SHORTV=0 ;"SMALL" VERSION OF 8086 BASIC IF SET (UNUSED) 56 | TRUROM=1 57 | SBC86=0 ;SBC 86/02 BOARD? 58 | SHORTJ=1 ;USE INTRA-SEGMENT SHORT JUMPS 59 | ;IN 8086 CODE 60 | LNGVAR=1 ;LONG VARIABLE NAME SUPPORT (EXTENDED ONLY) 61 | SHTERR=0 ;SHORT (2 CHAR) ERROR MESSAGES 62 | SHTINS=0 ;INSTRC IN NON-FAST LEN2 VERSIONS 63 | SHTLHM=0 ;LEFT HAND SIDE MID IN NON FAST LEN2 VERSIONS 64 | SHTCHN=0 ;ALLOW CHAIN IN NON-5.0 65 | SHTPRO=0 ;ALLOW PROTECTED FILES IN NON-FIVDSK 66 | SHTLIN=0 ;ALLOW LINE INPUT IN NON-EXTENDED NON-FAST 67 | SHTREN=0 ;ALLOW RENUM IN NON-FST VERSIONS 68 | INKEYF=1 ;ADDS INKEY$ FUNCTION 69 | NOIOS=0 ;NO I/O STATMENTS (INP,OUT, WAIT) 70 | NOPEKS=0 ;NO PEEK, POKE 71 | NOUSR=0 ;NO USR 72 | NOCTLA=0 ;NO CONTROL-A IN EXTENDED 73 | NORUBT=0 ;NO RUBOUT 74 | NOROMP=0 ;NO ROM PROGRAM FEATURE 75 | NOATDL=0 ;NO AUTO DELETE IN NON-FAST EXTENDED 76 | NODOT=0 ;NO DOT IN LEN2 77 | NOEDIT=0 ;NO EDIT COMMAND 78 | CRONLY=0 ;ONLY PUT OUT CR, NOT CRLF TO TERMINAL 79 | ;AND FILES 80 | NONULL=0 ;NO NULL COMMAND, PUT OUT NULLS IN CRDO & OUTCH1 81 | NOVARP=0 ;NO VARPTR FUNCTION 82 | FIVEO=1 ;GENERATE VERSION WITH RELEASE 5.0 FEATURES 83 | FIVMEM=1 84 | ANSI=1 85 | FIVDSK=1 ;5.0 NEW DSK CODE 86 | FIVLPT=1 ;WIDTH LPRINT AND 255 FEATURE 87 | HEXOCT=1 ;&H..., HEX$, &O..., OCT$ 88 | BINCSW=0 ;&B..., BIN$ 89 | BLODSW=1 ;BLOAD, BSAVE COMMANDS 90 | MEMIMG=1 ;MEMORY IMAGE FILES 91 | GENBIN=1 92 | 93 | TRUANS=0 ;TRUE ANSI VERSION (STATIC SCAN, ON ERROR) 94 | COMMNT=0 ;DONT WANT BIG COMMENT 95 | INTEL=0 ;INTEL PROPRIETARY 96 | INTFSW=0 ;INTEL FLOATING POINT 97 | INTFHW=0 98 | RMX=0 ;INTEL RMX VERSION 99 | EDIT80=0 ;FOR EDIT80 I/O ROUTINES 100 | RSHACK=0 101 | INTLEC=0 102 | XLENGTH=2 ; 1 MEANS 8K, 2 MEANS 12K (UNUSED) 103 | BASDEB=0 ;WHETHER DBG WILL BE LOADED WITH BASIC 104 | RSTLES=1 ;WHETHER BASIC WILL USE RST LOCATIONS 105 | ;TO MAKE ITSELF SMALLER & QUICKER 106 | REALIO=1 ;WHETHER SIMULATE (=0) OR ON MACHINE (=1) 107 | GENIO=1 ;USE G/P ROUTINES 108 | CHSEAT=1 ;CHSNS eats chars 109 | GENDSK=0 ;USE G/P DSK CODE 110 | LONGI=0 ;WHETHER WE ASK "TERMINAL WIDTH?" 111 | ;AND WANT SIN-TAN-COS-ATN? 112 | INSTSW=0 ;FOR INSTRC INSTRUCTION 113 | SWAPSW=1 ;FOR SWAP STATEMENT 114 | MDS=0 ;FOR INTEL MDS SYSTEMS 115 | SBC=0 ;FOR INTEL SINGLE BOARD COMPUTER 116 | ;1=SBC 80/10, 2=SBC 80/20 117 | PURE=1 ;ON FOR PURE CODE 118 | KILLER=0 ;FOR ROM VERSION THAT WONT RUN IN RAM 119 | INTROM=0 120 | LPTSW=1 121 | NCRLPT=1 122 | NCRCAS=0 123 | ISC=0 ;FOR ISC VERSION 124 | LPT3=0 ;THREE LPT DRIVER VERSION(QUME,OKIA,CENT) 125 | TSLPT=0 126 | 127 | DOS=0 ;ON TO GEN ROUTINES FOR DOS 128 | DISK=1 ;FILE I/O FEATURES 129 | TIMSHR=0 ;NO TIME-SHARING DISK 130 | TSDISK=0 ;NO TIME-SHARING DISK FOR US 131 | SPCDSK=0 ;MAY HAVE MM'S DISK CODE 132 | SPCNDS=0 133 | FAST=1 ;CONSTANT COMPRESSION, RENUM & FRIENDS 134 | KEYSTA=0 135 | ISIS=0 ;FOR VERSION TO RUN UNDER INTEL'S ISIS II DOS 136 | MDSISS=0 ;FOR MDS VERSION THAT RUNS UNDER ISIS-II 137 | CPM=1 ;FOR CPM compatible operating systems 138 | CPM2=1 ;VERSION 2. CPM 139 | CPM86=0 ;FOR CP/M-86 operating system 140 | SCP=1 ;MS-DOS operating system 141 | CPMCON=0 142 | CPMSER=0 ;CHECK CPM SERIAL #'S 143 | CPMADD=0 ;FOR VERSION TO RUN ON ADDS CPM 144 | CPMA75=0 ;FOR VERSION TO RUN ON ADDS SYSTEM 75 145 | ;CP/M 146 | CPMRSH=0 ;FOR RADIO SHACK CPM/M 147 | CPM110=0 ;FOR CP/M @1100 HEX (INTERALIA) 148 | CPMSBC=0 ;FOR VERSION TO RUN ON SBC CP/M AT 4100H 149 | CPMPER=0 ;FOR PERTEC VERSION OF CPM 150 | CPMLIF=0 ;LIFEBOAT CP/M AT 4200H 151 | CPMMDS=0 ;MOHAWK DATA SYSTEMS CP/M 152 | CPMCON=0 153 | Z80=0 154 | DISK=1 155 | NCRLPT=1 156 | RSTLES=1 157 | DRVPOS=CPMADD 158 | TRNCHR=CPMADD 159 | INLADD=CPMADD 160 | LISTEN=1 ;ON MEANS LISTEN FOR ^C 161 | LISTEN=1 162 | LEN2=0 163 | LEN2=1 164 | HEXOCT=1 165 | LENGTH=2 166 | RSTLES=1 167 | FIVLPT=1 168 | I8251=0 ;THIS SWITCH IS USED FOR ROSEMOUNT VERSION 169 | CONTRO=1 ;ALLOW ^O 170 | LEN3=LEN2 OR CASSW 171 | 172 | 173 | 174 | STRING=1 175 | NCRLPT=1 176 | 177 | ; *** OEM Switches which need to be defaulted to 0 178 | ; 179 | CMPUTN=0 180 | DUPONT=0 181 | EXIDY=0 182 | GESBC=0 183 | HEATH=0 184 | LOKHED=0 185 | MOSTEK=0 186 | TEK=0 187 | TRSER2=0 188 | NASCOM=0 189 | NATROM=0 190 | NCRBAS=0 191 | NCRDEB=0 192 | NCRDEB=0 193 | NCRELS=0 194 | ONTEL=0 195 | PCS=0 196 | SGSATS=0 197 | ALTAIR=0 198 | DMC=0 199 | PANBAS=0 200 | XTNSYS=0 201 | NECBAS=0 202 | ;******************************************************************* 203 | ; Z80 related macros 204 | ;******************************************************************* 205 | Z80=1 ;FOR VERSION THAT RUNS ON BOTH 206 | ;8080'S AND ZILOG Z-80'S 207 | Z80MAC=1 ;USE 8080 MACROS INSTEAD OF Z80 INSTRUCTIONS 208 | Z80=0 209 | Z80=1 210 | LDIR MACRO 211 | MOV WORD PTR A,WORD PTR M 212 | STAX D 213 | INXF H 214 | INXF D 215 | DCXF B 216 | MOV WORD PTR A,WORD PTR B 217 | ORA C 218 | JNZ _-8D 219 | ENDM 220 | LDDR MACRO 221 | MOV WORD PTR A,WORD PTR M 222 | STAX D 223 | DCXF H 224 | DCXF D 225 | DCXF B 226 | MOV WORD PTR A,WORD PTR B 227 | ORA C 228 | JNZ _-8D 229 | ENDM 230 | DJNZ MACRO DEST 231 | DCR B 232 | JNZ DEST 233 | ENDM 234 | ;******************************************************************* 235 | ; Define reset routines. 236 | ;******************************************************************* 237 | FSIGN MACRO 238 | CALL SIGN 239 | ENDM 240 | PUSHM MACRO 241 | MOV WORD PTR C,WORD PTR M 242 | INX H 243 | MOV WORD PTR B,WORD PTR M 244 | INX H 245 | PUSH WORD PTR B 246 | ENDM 247 | SYNCHK MACRO X 248 | CALL SYNCHR 249 | DB OFFSET X 250 | ENDM 251 | OUTCHR MACRO 252 | CALL OUTDO 253 | ENDM 254 | CHRGET MACRO 255 | CALL CHRGTR 256 | ENDM 257 | COMPAR MACRO 258 | CALL DCOMPR 259 | ENDM 260 | GETYPE MACRO 261 | CALL GETYPR 262 | ENDM 263 | COMPAR MACRO 264 | DB 73O 265 | DB 332O 266 | ENDM 267 | ACRLF MACRO 268 | DB 13D 269 | DB 10D 270 | ENDM 271 | PUSHR MACRO 272 | PUSH WORD PTR D 273 | PUSH WORD PTR B 274 | ENDM 275 | POPR MACRO 276 | POP WORD PTR B 277 | POP WORD PTR D 278 | ENDM 279 | MOVRI MACRO B,C,D,E 280 | DB 1O ; "LXI B" 281 | DB OFFSET C 282 | DB OFFSET B 283 | DB 21O ; "LXI D" 284 | DB OFFSET E 285 | DB OFFSET D 286 | ENDM 287 | INST MACRO X 288 | DB OX 289 | ENDM 290 | 291 | 292 | CONTO=15 ;CHARACTER TO SUPRESS OUTPUT (USUALLY CONTROL-O) 293 | DBLTRN=0 ;FOR DOUBLE PRECISION TRANSCENDENTALS 294 | 295 | CLMWID=14D ;MAKE COMMA COLUMNS FOURTEEN CHARACTERS 296 | DATPSC=128D ;NUMBER OF DATA BYTES IN DISK SECTOR 297 | LINLN=80D ;TERMINAL LINE LENGTH 298 | LPTLEN=132D 299 | BUFLEN=255 ;LONG LINES 300 | NAMLEN=40D ;MAXIMUM LENGTH NAME -- 3 TO 127 301 | 302 | NUMLEV=110D ;NUMBER OF STACK LEVELS RESERVED 303 | ;BY AN EXPLICIT CALL TO GETSTK 304 | STRSIZ=4 305 | STRSIZ=3 306 | NUMTMP=3 ;NUMBER OF STRING TEMPORARIES 307 | NUMTMP=10 308 | 309 | .RADIX 8 310 | ; 311 | ; Useful macros 312 | ; 313 | 314 | ACRLF MACRO 315 | DB 13D 316 | DB 10D 317 | ENDM 318 | 319 | INS86 MACRO A,B,C,D 320 | DB A&O 321 | IFNB 322 | DB B&O 323 | ENDIF 324 | IFNB 325 | DB C&O 326 | DB D&O 327 | ENDIF 328 | IFB 329 | IFNB 330 | DW C 331 | ENDIF 332 | ENDIF 333 | ENDM 334 | 335 | CALLOS MACRO 336 | CALL CPMENT 337 | ENDM 338 | 339 | POPR MACRO 340 | POP CX 341 | POP DX 342 | ENDM 343 | 344 | ADR MACRO X 345 | DW X 346 | ENDM 347 | 348 | DC MACRO ARG 349 | IRPC ZZ, 350 | IFDIF ,<"> 351 | DB "&ZZ&" 352 | _A="&ZZ&" 353 | ENDIF 354 | ENDM 355 | ENDM 356 | ; 357 | PAGE 358 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Microsoft GW-BASIC Interpreter Source Code 2 | 3 | This repo contains the original source-code for Microsoft's GW-BASIC interpreter, as of 1983, 4 | adjusted for assembling with available versions of the Microsoft Macro Assembler. 5 | 6 | ## Announcement blog 7 | https://devblogs.microsoft.com/commandline/microsoft-open-sources-gw-basic/ 8 | 9 | ## Progress 10 | 11 | All files can now be assembled with Microsoft MASM 5.1A. 12 | This is the version that currently seems to match the code most closely. 13 | 14 | The following identifiers cannot be resolved. 15 | `CLREOL`, 16 | `CLRSCN`, 17 | `CSRATR`, 18 | `CSRDSP`, 19 | `DONOTE`, 20 | `DOWNC`, 21 | `EDTMAP`, 22 | `FETCHC`, 23 | `FKYADV`, 24 | `FKYFMT`, 25 | `GETFBC`, 26 | `GETHED`, 27 | `GRPSIZ`, 28 | `GTASPC`, 29 | `GWINI`, 30 | `GWTERM`, 31 | `INFMAP`, 32 | `INICOM`, 33 | `INKMAP`, 34 | `KEYINP`, 35 | `LCPY`, 36 | `LEFTC`, 37 | `MAPSUP`, 38 | `MAPXYC`, 39 | `NREAD`, 40 | `NSETCX`, 41 | `NWRITE`, 42 | `PEKFLT`, 43 | `PGINIT`, 44 | `PIXSIZ`, 45 | `PNTINI`, 46 | `POKFLT`, 47 | `POLLEV`, 48 | `PRTMAP`, 49 | `RDPEN`, 50 | `RDSTIK`, 51 | `RDTRIG`, 52 | `READC`, 53 | `RECCOM`, 54 | `RIGHTC`, 55 | `SCALXY`, 56 | `SCANL`, 57 | `SCANR`, 58 | `SCRATR`, 59 | `SCRINP`, 60 | `SCROLL`, 61 | `SCROUT`, 62 | `SCRSTT`, 63 | `SEGINI`, 64 | `SETATR`, 65 | `SETC`, 66 | `SETCBF`, 67 | `SETCLR`, 68 | `SETFBC`, 69 | `SNDCOM`, 70 | `SNDLPT`, 71 | `STACOM`, 72 | `STOREC`, 73 | `SWIDTH`, 74 | `TDOWNC`, 75 | `TRMCOM`, 76 | `TUPC`, 77 | `UPC`. 78 | Most identifiers appear to be missing from the source code. 79 | 80 | 81 | Pull requests for fixing the remaining compilation programs are welcomed. 82 | 83 | ## Building instructions 84 | Using [DOSBox](https://www.dosbox.com/) mount a directory containing: 85 | * This code 86 | * The Microsoft Macro Assembler (MASM) version 5.1A (`masm.exe`). 87 | * The Microsoft make program that comes with MASM (`make.exe`). 88 | 89 | Run `make makefile` to assemble the files. 90 | Note the tools may leave behind party-built executables or object files. 91 | If you want to rebuild them without changing the source code, you need 92 | to delete these files by hand. 93 | 94 | You can fetch MASM 5.1A from 95 | [this site](https://www.pcjs.org/software/pcx86/lang/microsoft/masm/5.10x/) as follows. 96 | * From the pull-down menu select `MS MAcro Assembler 5.10A (Update)` 97 | * Press the `Load` button to load the disk image into the emulator 98 | * Press the `Save` button to save the disk image to your computer 99 | * Copy the saved disk image to a Linux computer 100 | * Mount the image using the command `sudo mount MASM51A-UPDATE.img /mnt` 101 | * Copy the files from `/mnt` to your development directory 102 | 103 | ## License 104 | 105 | All files within this repo are released under the [MIT (OSI) License]( https://en.wikipedia.org/wiki/MIT_License) as per the [LICENSE file](https://github.com/Microsoft/GW-BASIC/blob/master/LICENSE) stored in the root of this repo. 106 | 107 | ## Contributing 108 | 109 | Pull requests addressing problems in getting GW-BASIC to build and run 110 | are welcomed. 111 | 112 | ## Code of Conduct 113 | 114 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 115 | -------------------------------------------------------------------------------- /SCNEDT.ASM: -------------------------------------------------------------------------------- 1 | ; [ This translation created 10-Feb-83 by Version 4.3 ] 2 | 3 | .RADIX 8 ; To be safe 4 | 5 | CSEG SEGMENT PUBLIC 'CODESG' 6 | ASSUME CS:CSEG 7 | 8 | INCLUDE OEM.H 9 | 10 | TITLE SCNEDT Screen Oriented Editor for GW-BASIC 11 | SUBTTL DATA DEFINITIONS 12 | 13 | 14 | COMMENT * 15 | --------- --- ---- -- --------- 16 | COPYRIGHT (C) 1982 BY MICROSOFT 17 | --------- --- ---- -- --------- 18 | * 19 | 20 | INCLUDE GIO86U 21 | .RADIX 8 22 | .SALL 23 | 24 | ;OEM IFNDEF'S: 25 | MELCO=0 26 | HAL=0 27 | 28 | ;GENERIC IFNDEF'S: 29 | TERMSW=0 30 | HLPTRP=0 31 | STPTRP=0 32 | HLPEDT=0 33 | SCRKEY=0 34 | NMPAGE=0 35 | IBMCSR=IBMLIK 36 | 37 | 38 | 39 | ;INTERNAL ROUTINES: 40 | 41 | PUBLIC PINLIN ; Program line input 42 | ;on exit: BX=addr of input -1 43 | 44 | PUBLIC INLIN ; BASIC INPUT Statements line input 45 | ;on exit: BX=addr of input -1 46 | 47 | PUBLIC SINLIN ; BASIC INPUT Statements redo line input 48 | ;on exit: BX=addr of input -1 49 | 50 | PUBLIC QINLIN ; BASIC INPUT Statements with output of "?" first 51 | ;on exit: BX=addr of input -1 52 | 53 | PUBLIC SCNSEM ; BASIC INPUT statement scan for semicolon 54 | ;on exit: SEMFLG flag set 55 | PUBLIC EDTBRK ; BASIC received break, reinitialize routine 56 | 57 | PUBLIC ERREDT ; BASIC Syntax error auto-edit on ERRLIN 58 | ;on exit: Removes return and jumps to MAIN after 59 | ; listing ERRLIN and positioning cursor at 60 | ; start of line. 61 | 62 | PUBLIC EDIT ; EDIT Statement 63 | ;on exit: Same as ERREDT, except takes line number 64 | ; to list as argument. 65 | 66 | ; INTERN EDITRT ; AUTO Program line input processing 67 | ;on exit: BX=addr of input(BUF) 68 | ; it also puts PSW on stack with carry 69 | ; set and jumps to EDENT for exit 70 | 71 | 72 | ;EXTERNAL ROUTINES: 73 | 74 | EXTRN OUTDO:NEAR ; Character output(GIO86) 75 | EXTRN KEYIN:NEAR ; Key input(expands any string keys-GIOKYB) 76 | EXTRN SCNMRK:NEAR ; Mark current posn as start of line(SCNDRV) 77 | EXTRN SCNRDL:NEAR ; Read current logical line(SCNDRV) 78 | EXTRN CRDO:NEAR ; BASIC new line routine 79 | EXTRN CHRGTR:NEAR ; BASIC character scan routine 80 | 81 | ;DATA (DEFINED IN RAM MODULE) 82 | DSEG SEGMENT PUBLIC 'DATASG' 83 | ASSUME DS:DSEG 84 | EXTRN F_EDPG:WORD ; Flag - =^O377 indicates program statement edit 85 | EXTRN SEMFLG:WORD ; Flag - zero indicates INPUT; statement(no crlf 86 | ; at end of input line) 87 | EXTRN F_INST:WORD ; Flag - =^O377 indicates insert mode 88 | EXTRN BUF:WORD ; Buffer where line of data is returned 89 | ; NOTE: assumes non-blank at BUF-1 90 | EXTRN F_EDIT:WORD ; Flag - non-zero indicates INLIN active 91 | EXTRN AUTFLG:WORD ; AUTO mode flag 92 | EXTRN CSRX:WORD ; Cursor column (1..n) 93 | EXTRN CSRY:WORD ; Cursor line (1..n) 94 | DSEG ENDS 95 | ;LITERALS NEEDED ELSEWHERE 96 | PUBLIC CHRLNF ; Line feed character 97 | PUBLIC CHRRET ; Carriage return character 98 | 99 | 100 | ;CHARACTER DEFINITIONS 101 | ; 102 | ; 103 | CHREDT=1 ; EDiT 104 | CHRBKW=2 ; BacK Word 105 | CHRCAN=3 ; CANcel 106 | CHRHCN=4 ; Hard CaNcel 107 | CHRCLE=5 ; CLear to End of line 108 | CHRFDW=6 ; ForwarD Word 109 | CHRBEL=7 ; BELl 110 | CHRBAK=8D ; BAcKspace 111 | CHRTAB=9D ; TAB 112 | CHRLNF=10D ; LiNeFeed 113 | CHRHOM=11D ; HOMe 114 | CHRERA=12D ; ERAse 115 | CHRRET=13D ; RETurn 116 | CHRAPP=14D ; APPend 117 | CHRINS=18D ; INSert 118 | CHRLDL=21D ; Line DeLete 119 | CHRADV=28D ; cursor RiGhT 120 | CHRREG=29D ; cursor LeFT 121 | CHRUP=30D ; cursor UP 122 | CHRDWN=31D ; cursor DoWN 123 | CHRDEL=127D ; DELete 124 | SUBTTL Entry points for editing 125 | 126 | 127 | 128 | ;ENTRY: PINLIN, QINLIN, INLIN, SINLIN 129 | ; 130 | ;PROGRAM STATEMENT INPUT 131 | PUBLIC PINLIN 132 | PINLIN: CALL DSKCHI ; Don't return if Loading ASCII File 133 | STC ; Indicate program statement input 134 | JMP SHORT INLIN0 135 | 136 | ;PRINT "?" BEFORE GETTING INPUT 137 | PUBLIC QINLIN 138 | QINLIN: MOV AL,LOW "?" 139 | CALL OUTDO ; Output a "?" 140 | MOV AL,LOW " " 141 | CALL OUTDO ; Followed by a space 142 | 143 | ;INPUT STATEMENT 144 | PUBLIC INLIN 145 | INLIN: 146 | 147 | ;INPUT STATEMENT REDO 148 | PUBLIC SINLIN 149 | SINLIN: OR AL,AL ; Indicate INPUT statement line input 150 | 151 | INLIN0: 152 | SBB AL,AL ; If INPUT statement AL=0, else AL=-1 153 | MOV BYTE PTR F_EDPG,AL ; Save flag 154 | MOV AL,BYTE PTR F_EDIT ; Get old value of F.EDIT(in case of EDIT statement) 155 | MOV BYTE PTR F_EDIT,LOW 377O ; Indicate executing INLIN 156 | CALL SCNMRK ; Set up for edit 157 | ; If AL=1 then move cursor to start of logical 158 | ; line which preceeds current. 159 | ; Else if ZF=1 then set up FSTPOS, LSTPOS 160 | ; if ZF=0 then FSTPOS=0,0; LSTPOS=max,max 161 | SUBTTL MAIN loop of editor 162 | 163 | 164 | 165 | ;WHILE EOL.NE.TRUE BEGIN 166 | ;** GET A KEY 167 | INLLOP: 168 | EXTRN STCTYP:NEAR 169 | CLC ; Signal for insert or overwrite cursor 170 | CALL STCTYP ; Set new cursor type 171 | CALL KEYIN ; AX=key value 172 | ;At this point we can have three classes of characters: 173 | ; CF=1 indicates 2 byte char with 2 sub classes: 174 | ; AH=FF indicates editor control function 175 | ; AH<>FF indicates 2 byte character to echo 176 | ; CF=0 indicates 1 or 3 byte key 177 | ; AL=FF indicates a 3 byte key with scan code in DX - these are ignored 178 | ; AL<>FF indicates a 1 byte key to echo, except if char is CR. 179 | JB INL2BY ; BRIF 2-byte character, check for editor controls 180 | CMP AL,LOW OFFSET CHRRET 181 | JZ INLRET ; BRIF CR, terminate line input 182 | ;** IF CURRENT_CHAR IS SPECIAL THREE BYTE CHAR 183 | CMP AL,LOW 254D ; Test for 3-byte character 184 | ;** *** IGNORE THIS CHAR 185 | JZ INLLOP ; BRIF to ignore 3-byte character 186 | JMP SHORT INLOP0 ; Not 3-bytes, just echo single byte 187 | INL2BY: 188 | ;** IF CURRENT_CHAR IS CONTROL_CHAR 189 | CMP AH,LOW 255D 190 | JNZ INLOP0 ; BRIF not editor control character, echo char 191 | CMP AL,LOW 177O 192 | JZ INLP0 ; BRIF is a control character 193 | CMP AL,LOW " " 194 | JNB INLOP0 ; BRIF is not a control character 195 | INLP0: 196 | ;** IF CURRENT_CHAR IS RETURN CURRENT LOGICAL LINE 197 | CMP AL,LOW OFFSET CHRRET 198 | JZ INLRET ; BRIF is carriage return(EOL) 199 | ;** IF (CURRENT_CHAR= AND INPUT_MODE=PROGRAM) DO EDIT ON KBUF 200 | CMP AL,LOW OFFSET CHREDT 201 | JNZ INLOP0 202 | JMP INLHLP ; BRIF help char, do edit on KBUF 203 | ;Echo character in AX 204 | INLOP0: 205 | OR AH,AH 206 | JZ INLOP3 ; Single byte character 207 | XCHG AL,AH ; Output AH first 208 | CALL OUTDO ; Output a char 209 | XCHG AL,AH ; Restore AL 210 | INLOP3: CALL OUTDO ; Output a char 211 | JMP SHORT INLLOP 212 | ;** END 213 | 214 | ;SCAN FOR SEMICOLON 215 | ; 216 | SCNSEM: CMP AL,LOW ";" 217 | JNZ SCNSMR ; BRIF not semicolon, return 218 | MOV BYTE PTR SEMFLG,AL 219 | JMP CHRGTR ; Skip semicolon and return 220 | SCNSMR: RET 221 | SUBTTL Exit, return current logical line 222 | 223 | 224 | 225 | ;READ LOGICAL LINE INTO BUF 226 | INLRET: MOV BX,OFFSET BUF ; Put data into BUF 227 | MOV CX,255D ; CX=Max number of bytes to move 228 | TEST BYTE PTR F_EDPG,LOW 377O ; Set zero flag if program statement input 229 | PUSHF 230 | MOV DL,BYTE PTR CSRY ; (DH,DL) = (CSRX,CSRY) 231 | MOV DH,BYTE PTR CSRX 232 | CALL SCNRDL ; Read the logical line into BUF 233 | ; BX=address of last char in BUF plus one 234 | ;IF PROGRAM_STATEMENT_INPUT BEGIN 235 | POPF 236 | JZ INCRTX ; BRIF not statement input 237 | ;** WHILE POSN.NE.BEGIN_OF_LINE AND [POSN].NE.BLANK AND [POSN].NE.LF BEGIN 238 | MOV CX,BX 239 | SUB CX,OFFSET BUF ; CX=count of chars in BUF 240 | JZ INCRTX ; BUF is empty 241 | PUSH DI 242 | MOV DI,BX 243 | DEC DI ; Start scan at last valid data 244 | INLOT0: MOV AL,LOW " " 245 | ;** *** POSN=POSN-1 246 | INLOT1: STD ; Scan backwards 247 | REPE SCASB ; This works for blank line("," at BUF-1) 248 | INC DI ; [DI] = last valid data 249 | MOV AL,LOW " " 250 | CMP BYTE PTR 0[DI],AL 251 | JZ INLOT2 ; BRIF more trailing blanks 252 | MOV AL,LOW OFFSET CHRLNF 253 | CMP AL,BYTE PTR 0[DI] 254 | JNZ INLOT3 ; BRIF not more trailing linefeeds 255 | INLOT2: OR CL,CL 256 | JNZ INLOT1 ; BRIF not at beginning of buffer 257 | ;** *** END 258 | ;** END 259 | INLOT3: MOV BX,DI 260 | POP DI 261 | INC BX 262 | INCRTX: MOV BYTE PTR 0[BX],LOW 0 ; Terminate BUF 263 | ;** UPDATE CURSOR POSN, RETURN 264 | TEST BYTE PTR SEMFLG,LOW 377O 265 | JNZ INCRTF ; BRIF if INPUT statement 266 | MOV AX,OFFSET CHRAPP 267 | CALL OUTDO ; Move to end of logical 268 | MOV BYTE PTR F_EDIT,LOW 0 269 | CALL CRDO ; Move to first posn beyond this logical 270 | INCRTF: MOV BX,OFFSET BUF-1 ; Return BUF - 1 271 | PUSHF 272 | CALL CLRFLG ; Clear miscellaneous status flags 273 | POPF 274 | RET 275 | 276 | 277 | ;SUBROUTINE EDTBRK ; Routine which initializes when break detected 278 | ;** ; This is called by the STOP code 279 | ;** 280 | EDTBRK: 281 | EXTRN SETCSR:NEAR 282 | DSEG SEGMENT PUBLIC 'DATASG' 283 | EXTRN CSRTYP:WORD 284 | DSEG ENDS 285 | MOV BYTE PTR CSRTYP,LOW 0D ; Indicate cursor off 286 | CALL SETCSR 287 | CALL CLRFLG ; Clear editor flags 288 | PUSH AX 289 | MOV AL,LOW OFFSET CHRAPP 290 | MOV BYTE PTR F_EDIT,AL 291 | CALL OUTDO ; Move cursor to end of logical line 292 | MOV BYTE PTR F_EDIT,LOW 0 ; Reset edit mode 293 | CALL CRDO ; Move cursor to next physical line 294 | POP AX 295 | MOV BYTE PTR AUTFLG,LOW 0 ; Reset AUTO mode 296 | RET 297 | ;** END SUBROUTINE EDTBRK 298 | 299 | ;SUBROUTINE CLRFLG ; Routine which clears flags 300 | ;** 301 | CLRFLG: MOV BYTE PTR F_EDIT,LOW 0 ; No longer in INLIN 302 | MOV BYTE PTR F_EDPG,LOW 0 ; Not program edit 303 | MOV BYTE PTR F_INST,LOW 0 ; Not insert mode 304 | MOV BYTE PTR SEMFLG,LOW 0 ; Not INPUT; statement 305 | RET 306 | ;** END SUBROUTINE CLRFLG 307 | 308 | SUBTTL EDIT code 309 | 310 | 311 | 312 | EXTRN MAIN:NEAR,LINSPC:NEAR,FNDLIN:NEAR,DEPTR:NEAR,LISPRT:NEAR 313 | EXTRN LINPRT:NEAR,FCERR:NEAR,USERR:NEAR,BUFLIN:NEAR 314 | DSEG SEGMENT PUBLIC 'DATASG' 315 | EXTRN DOT:WORD,ERRFLG:WORD,ERRLIN:WORD 316 | DSEG ENDS 317 | 318 | ;EDIT COMMAND 319 | ; 320 | PUBLIC EDIT 321 | EDIT: CALL LINSPC ; LINE NUMBER IN DE 322 | JNZ EFCERR ; STATEMENT MUST HAVE ENDED 323 | EREDIT: POP BX ; REMOVE NEWSTT(OR CALL FROM MAIN)RETURN 324 | MOV WORD PTR DOT,DX 325 | CALL FNDLIN ; FIND LINE 326 | JNB EUSERR ; LINE DOES NOT EXIST 327 | MOV BX,CX ; CX=LINE PTR 328 | ERED2: INC BX 329 | INC BX 330 | MOV DX,WORD PTR 0[BX] ; DE=LINE NUMBER 331 | INC BX 332 | INC BX 333 | ERED3: PUSH BX 334 | MOV BYTE PTR F_EDIT,LOW 1 ; SET FLAG INDICATING IN EDIT MODE 335 | ; (FORCES OPEN LINES DURING LIST) 336 | ; (AND TELLS INLIN TO START AT BEGIN OF LOGICAL) 337 | XCHG BX,DX 338 | ERED4: CALL LINPRT ; PRINT THE LINE NUMBER 339 | POP BX 340 | CMP BYTE PTR 0[BX],LOW 9D ; LINE START WITH TAB? 341 | JZ ERED5 342 | MOV AL,LOW " " 343 | CALL OUTDO ; NO, PUT SPACE OUT 344 | ;ENTRY FOR EDIT ON KBUF IS HERE 345 | ERED5: 346 | MOV BYTE PTR F_EDIT,LOW 1 ; SET FLAG INDICATING IN EDIT MODE 347 | ; (FORCES OPEN LINES DURING LIST) 348 | ; (AND TELLS INLIN TO START AT BEGIN OF LOGICAL) 349 | CALL BUFLIN ; PUT LINE IN BUF AND SET UP HLPBFA 350 | MOV BX,OFFSET BUF 351 | CALL LISPRT ; PRINT THE LINE AND SET UP HLPCSR 352 | MOV BL,BYTE PTR CSRY 353 | MOV BH,BYTE PTR CSRX 354 | JMP MAIN 355 | EFCERR: JMP FCERR ; Indirect jump to FCERR 356 | EUSERR: JMP USERR ; Indirect jump to USERR 357 | 358 | ;Help key edit 359 | ; 360 | INLHLP: TEST BYTE PTR F_EDPG,LOW 377O 361 | JNZ INLHL0 ; BRIF do help edit on program statement 362 | ;Help during input statement 363 | JMP INLOP3 ; Just output char 364 | 365 | 366 | ;DO EDIT ON DOT 367 | INLHL0: POP AX ; Remove call to this routine 368 | 369 | ;See if edit on error line number 370 | MOV DX,WORD PTR ERRLIN 371 | CALL ERRED2 ; If exists,do edit on error line number 372 | 373 | ;See if edit on current line number 374 | MOV DX,WORD PTR CURLIN 375 | CALL ERRED2 ; If exists,do edit on current line number 376 | ;ERRLIN AND CURLIN ARE DIRECT, DO EDIT ON KBUF 377 | DSEG SEGMENT PUBLIC 'DATASG' 378 | EXTRN KBUF:WORD,CURLIN:WORD 379 | DSEG ENDS 380 | EXTRN SCNEXT:NEAR,DEPTR:NEAR 381 | CALL DEPTR ; Remove line pointers from program 382 | MOV BX,OFFSET KBUF 383 | PUSH BX 384 | DEC BX 385 | CALL SCNEXT ; Remove any line pointers from KBUF 386 | POP BX 387 | JMP SHORT ERED5 388 | 389 | ;AUTOMATIC EDIT FOR ERRORS 390 | ; 391 | PUBLIC ERREDT 392 | ERREDT: MOV BYTE PTR ERRFLG,AL ; Reset the flag to call edit 393 | MOV DX,WORD PTR ERRLIN ; Get the line number 394 | ERRED2: CMP DX,177777O ; See if it was direct 395 | JZ ERRED3 ; Go back if direct 396 | OR DX,DX 397 | JZ ERRED3 ; Go back if zero 398 | JMP EREDIT 399 | ERRED3: RET 400 | SUBTTL ASCII LOAD and SAVE line handler 401 | 402 | 403 | 404 | ;LOAD ASCII: 405 | ; PROGRAM LINE INPUT FROM DISK 406 | ; 407 | EXTRN ISFLIO:NEAR,OUTDO:NEAR,INCHR:NEAR,LBOERR:NEAR 408 | DSKCHI: 409 | CALL ISFLIO ; Set FLAGS.NZ if PTRFIL points to active file 410 | JNZ ISLOAD ; BRIF LOAD statement 411 | RET ; If so use special screen io 412 | ISLOAD: POP AX ; Discard Return Address 413 | MOV CL,LOW OFFSET BUFLEN ; Setup the maximum character count 414 | MOV BX,OFFSET BUF ; Place we are going to stoer the line 415 | LOPBUF: CALL INCHR ; Get a character from the file 416 | ; (will call indskc and handle eof) 417 | MOV BYTE PTR 0[BX],AL ; Store the character 418 | CMP AL,LOW 13D ; Is it the end (a CR) 419 | JNZ INOTCR ; Not a [CR] 420 | CMP BYTE PTR -1[BX],LOW 10D ; Preceeded by a line feed? 421 | JZ LOPBUF ; Yes, ignore the [CR] 422 | JMP SHORT FINLIN ; No, this is the end of a line 423 | INOTCR: 424 | OR CL,CL 425 | JE LTLONG ; Branch if line is too long to fit in BUF 426 | CMP AL,LOW 10D ; LEADING LINE FEEDS MUST BE IGNORED 427 | JNZ INOTLF 428 | CMP CL,LOW OFFSET BUFLEN ; CL=BUFLEN if this is the 1st char on the line 429 | JZ LOPBUF ; Branch if this was a leading line-feed 430 | INOTLF: INC BX ; ADVANCE THE POINTER 431 | DEC CL 432 | JMP SHORT LOPBUF ; DO NEXT CHAR 433 | DEC CL 434 | FINLIN: 435 | MOV BYTE PTR 0[BX],LOW 0 436 | MOV BX,OFFSET BUF-1 ; POINT AT BUFMIN 437 | RET 438 | 439 | LTLONG: JMP LBOERR ; Report LINE BUFFER OVERFLOW error 440 | ; (This program wasn't created by BASIC) 441 | 442 | ;SAVE ASCII: 443 | ; PROGRAM LISTING CHAR OUTPUT TO DISK(CONVERT TO ) 444 | ; 445 | PUBLIC OUTCH1 446 | OUTCH1: CMP AL,LOW OFFSET CHRLNF 447 | JZ OUTCH0 ; IS LF 448 | JMP OUTDO 449 | OUTCH0: 450 | EXTRN ISFLIO:NEAR 451 | CALL ISFLIO 452 | JNZ OUTCH2 ; branch if outputting to file 453 | CALL OUTDO 454 | RET 455 | 456 | OUTCH2: CALL OUTDO 457 | MOV AL,LOW OFFSET CHRRET 458 | CALL OUTDO 459 | MOV AL,LOW OFFSET CHRLNF 460 | RET 461 | CSEG ENDS 462 | END 463 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets Microsoft's [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)) of a security vulnerability, please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). 40 | 41 | 42 | --------------------------------------------------------------------------------