home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / chasm.arc / CHASM.BAS (.txt) next >
Encoding:
GW-BASIC  |  1983-08-01  |  32.4 KB  |  1,146 lines

  1. 10000  '==============================
  2. 10010  'PROGRAM CHASM    Version 2.10
  3. 10020  'Begun 6/15/82 by Dave Whitman
  4. 10030  '==============================
  5. 10040  DEFINT A-Z
  6. 10050  MAXOBJ = 50: DIM OBJ(50)
  7. 10060  MAXSTK = 10: DIM PROCTYPE(10): STKTOP = 0
  8. 10070  NUMOP = 213
  9. 10080  DIM OPCODE$(213),OPVAL(213),SRCTYPE(213),DSTTYPE(213),OFLAG(213)
  10. 10090  PREDEF = 29: MAXSYM = 200
  11. 10100  DIM SYM$(200),VAL1(200),VAL2(29),SYMTYPE(200)
  12. 10110  '
  13. 10120  'main program
  14. 10130    GOSUB 50000  'initialize
  15. 10140    CHAIN MERGE "chasm.ovl",10150,ALL,DELETE 50000-51660 'kill init section
  16. 10150    GOSUB 19500  'finish init
  17. 10160    GOSUB 10200  'pass 1: build sym table
  18. 10170    GOSUB 10420  'pass 2: obj code & listing
  19. 10180    GOSUB 19000  'clean up
  20. 10190  SYSTEM
  21. 10200  '===================
  22. 10210  'SUBROUTINE PASSONE
  23. 10220  'Builds symbol table
  24. 10230  '===================
  25. 10240  PASS = 1
  26. 10250  OPEN O$ AS #3 LEN=1: FIELD #3,1 AS BYTE$
  27. 10260  LOCTR = 256  'room for PSP
  28. 10270  LINENUM = 0
  29. 10280  BASCODE = FALSE
  30. 10290  WHILE NOT EOF(1)
  31. 10300   'get line, init
  32. 10310    GOSUB 10630
  33. 10320   'parse
  34. 10330    GOSUB 10810
  35. 10340   'label? add to table
  36. 10350    IF LABEL$ <> "" THEN GOSUB 11580
  37. 10360   'op? decode, update loctr
  38. 10370    IF OP$ <> "" THEN GOSUB 12320
  39. 10380   'report
  40. 10390    GOSUB 19370
  41. 10400   WEND
  42. 10410  RETURN
  43. 10420  '============================
  44. 10430  'SUBROUTINE PASSTWO
  45. 10440  'Generates obj code & listing
  46. 10450  '============================
  47. 10460  GOSUB 18730  'pass2_init
  48. 10470  '
  49. 10480  WHILE NOT EOF(1)
  50. 10490   'get line, init
  51. 10500    GOSUB 10630
  52. 10510   'parse
  53. 10520    GOSUB 10810
  54. 10530   'phase?
  55. 10540    IF LABEL$ <> "" THEN GOSUB 11780
  56. 10550   'update loctr, gen. obj. code
  57. 10560    IF OP$ <> "" THEN GOSUB 12320
  58. 10570   'output
  59. 10580    GOSUB 18140
  60. 10590   'report
  61. 10600    GOSUB 19370
  62. 10610   WEND
  63. 10620  RETURN
  64. 10630  '===========================
  65. 10640  'SUBROUTINE GETLINE
  66. 10650  'Gets src line, expands tabs
  67. 10660  '& sets up for new iteration
  68. 10670  '===========================
  69. 10680  LINE INPUT#1, INPLINE$
  70. 10690  GOSUB 10750  'tabs
  71. 10700  LINENUM = LINENUM + 1
  72. 10710  NEEDOFFSET = NONE: DSFLAG = FALSE
  73. 10720  OBJLEN = 0
  74. 10730  RETURN
  75. 10740  'subroutine tabs
  76. 10750  I = INSTR(INPLINE$,CHR$(9))
  77. 10760  WHILE I <> 0
  78. 10770   INPLINE$ = LEFT$(INPLINE$,I-1)+SPACE$(8-((I-1)MOD 8))+MID$(INPLINE$,I+1)
  79. 10780   I = INSTR(INPLINE$,CHR$(9))
  80. 10790   WEND
  81. 10800  RETURN
  82. 10810  '=================
  83. 10820  'SUBROUTINE PARSE
  84. 10830  'Parses input line
  85. 10840  '=================
  86. 10850  LINEPTR = 1: LINEPTR2 = 1
  87. 10860  LABEL$ = "": OP$ = "": SOURCE$ = "": DEST$ = ""
  88. 10870  'mark end of code
  89. 10880   ENDPTR = INSTR(INPLINE$,";") - 1
  90. 10890   IF ENDPTR = -1 THEN ENDPTR = LEN(INPLINE$)
  91. 10900  'no code? (exit)
  92. 10910   IF ENDPTR = 0 THEN 11120
  93. 10920  'capitalize
  94. 10930   GOSUB 11140
  95. 10940  'label?
  96. 10950   IF INSTR(DELIM$,LEFT$(INPLINE$,1))  THEN 10980
  97. 10960     GOSUB 11270  'getfield
  98. 10970     LABEL$ = FLD$
  99. 10980  'op-code
  100. 10990   GOSUB 11270  'getfield
  101. 11000   IF NOT FOUND THEN 11120
  102. 11010   OP$ = FLD$
  103. 11020  'save ptr to start of operands
  104. 11030   OPDPTR = LINEPTR
  105. 11040  'dest operand?
  106. 11050   GOSUB 11270  'getfield
  107. 11060   IF NOT FOUND THEN 11120
  108. 11070   DEST$ = FLD$
  109. 11080  'src operand?
  110. 11090   GOSUB 11270  'getfield
  111. 11100   IF NOT FOUND THEN 11120
  112. 11110   SOURCE$ = FLD$
  113. 11120  RETURN
  114. 11130  '
  115. 11140  'subroutine caps
  116. 11150  'Scans inpline$ up to ";" capitalizing.  Skips strings
  117. 11160  FOR I = 1 TO ENDPTR
  118. 11170    C$ = MID$(INPLINE$,I,1)
  119. 11180    'skip strings
  120. 11190     IF C$ <> "'" THEN 11230
  121. 11200       STRGEND = INSTR(I+1,INPLINE$,C$)
  122. 11210       IF STRGEND > 0 THEN I = STRGEND: GOTO 11240
  123. 11220    'convert
  124. 11230     IF ASC(C$) => 97 AND ASC(C$) <= 122 THEN C$ = CHR$(ASC(C$) - 32):                  MID$(INPLINE$,I,1) = C$
  125. 11240    NEXT I
  126. 11250  RETURN
  127. 11260  '===================================================
  128. 11270  'SUBROUTINE GETFIELD
  129. 11280  'Starting at lineptr, trys to get next field in FLD$
  130. 11290  'Sets found if sucessful. Moves lineptr past field
  131. 11300  '====================================================
  132. 11310  'find next non-delim or run off end
  133. 11320   WHILE LINEPTR <= ENDPTR
  134. 11330     IF INSTR(DELIM$,MID$(INPLINE$,LINEPTR,1)) = 0 THEN 11360
  135. 11340     LINEPTR = LINEPTR + 1
  136. 11350     WEND
  137. 11360  'past end?
  138. 11370   IF LINEPTR <= ENDPTR  THEN 11400
  139. 11380     FOUND = FALSE
  140. 11390     RETURN
  141. 11400  'strings end with '
  142. 11410   IF MID$(INPLINE$,LINEPTR,1) <> "'" THEN 11460
  143. 11420     STRGEND = INSTR(LINEPTR+1,INPLINE$,"'")
  144. 11430     IF STRGEND = 0 THEN 11460
  145. 11440       LINEPTR2 = STRGEND + 1
  146. 11450       GOTO 11520
  147. 11460  'else, find delim or go 1 past end
  148. 11470   LINEPTR2 = LINEPTR
  149. 11480   WHILE LINEPTR2 <= ENDPTR
  150. 11490     IF INSTR(DELIM$,MID$(INPLINE$,LINEPTR2,1)) > 0 THEN 11520
  151. 11500     LINEPTR2 = LINEPTR2 + 1
  152. 11510     WEND
  153. 11520  'copy field
  154. 11530   FLD$ = MID$(INPLINE$,LINEPTR,LINEPTR2-LINEPTR)
  155. 11540  'lineptr past field, set found
  156. 11550   LINEPTR = LINEPTR2
  157. 11560   FOUND = TRUE
  158. 11570   RETURN
  159. 11580  '============================
  160. 11590  'SUBROUTINE NEWENTRY
  161. 11600  'Adds new symbol to sym table
  162. 11610  '============================
  163. 11620  'already there?
  164. 11630   TARGET$ = LABEL$
  165. 11640   GOSUB 11890     'operand_lookup
  166. 11650   IF NOT FOUND THEN 11680
  167. 11660     MSG$ = "Duplicate definition of "+LABEL$+" ": GOSUB 18920
  168. 11670     RETURN
  169. 11680  'table full?
  170. 11690   IF NUMSYM < MAXSYM THEN 11720
  171. 11700     MSG$ = "Too many user symbols": GOSUB 18920
  172. 11710     RETURN
  173. 11720  'else make new entry
  174. 11730   NUMSYM = NUMSYM + 1
  175. 11740   SYM$(NUMSYM) = LABEL$
  176. 11750   VAL1(NUMSYM) = LOCTR
  177. 11760   SYMTYPE(NUMSYM) = NEAR
  178. 11770  RETURN
  179. 11780  '=============================
  180. 11790  'SUBROUTINE CHECK_PHASE
  181. 11800  'Label value same both passes?
  182. 11810  '=============================
  183. 11820  IF OP$ = "EQU" THEN 11880
  184. 11830  TARGET$ = LABEL$
  185. 11840  GOSUB 11890  'operand_lookup
  186. 11850  IF (SYMTYPE(TABLEPTR) AND (NEAR OR MEM)) = FALSE THEN 11880
  187. 11860    IF VAL1(TABLEPTR) = LOCTR THEN 11880
  188. 11870      MSG$ = "Phase Error": GOSUB 18920
  189. 11880  RETURN
  190. 11890  '===========================================
  191. 11900  'SUBROUTINE OPERAND_LOOKUP
  192. 11910  'Trys to find TARGET$ in sym table. If there
  193. 11920  'sets FOUND true, & TABLEPTR to its position
  194. 11930  '===========================================
  195. 11940  'scan table
  196. 11950   FOR TABLEPTR = 1 TO NUMSYM
  197. 11960     IF SYM$(TABLEPTR) = TARGET$ THEN 12010
  198. 11970     NEXT TABLEPTR
  199. 11980  'failure
  200. 11990   FOUND = FALSE
  201. 12000   RETURN
  202. 12010  'sucess
  203. 12020   FOUND = TRUE
  204. 12030   RETURN
  205. 12040  '================================================
  206. 12050  'SUBROUTINE LOOKUP_OP
  207. 12060  'Given op-code in op$, & operand types in dtype &
  208. 12070  'stype, trys to find op in opcode table. If there
  209. 12080  'sets found true, & opptr to its position.
  210. 12090  '================================================
  211. 12100  'binary search for good starting pt.
  212. 12110   MOVE = NUMOP: ST = MOVE/2
  213. 12120   WHILE MOVE >= 2
  214. 12130     MOVE = MOVE/2
  215. 12140     IF OP$ > OPCODE$(ST) THEN ST = ST + MOVE ELSE ST = ST - MOVE
  216. 12150     IF ST < 1 THEN ST = 1
  217. 12160     IF ST > NUMOP THEN ST = NUMOP
  218. 12170     WEND
  219. 12180  'scan to match all 3 fields
  220. 12190   FOR OPPTR = ST TO NUMOP
  221. 12200     IF OPCODE$(OPPTR) > OP$ THEN 12260   'failed
  222. 12210     IF OPCODE$(OPPTR) <> OP$ THEN 12250
  223. 12220     IF (SRCTYPE(OPPTR) AND STYPE) = FALSE THEN 12250
  224. 12230     IF (DSTTYPE(OPPTR) AND DTYPE) = FALSE THEN 12250
  225. 12240     GOTO 12290 'found!
  226. 12250     NEXT OPPTR
  227. 12260  'failure
  228. 12270   FOUND = FALSE
  229. 12280   RETURN
  230. 12290  'success
  231. 12300   FOUND = TRUE
  232. 12310   RETURN
  233. 12320  '==============================
  234. 12330  'SUBROUTINE UPDATE_LOCTR
  235. 12340  'Decodes op & advances loctr
  236. 12350  '2nd pass, generate obj code
  237. 12360  '==============================
  238. 12370  'set operand types & vals
  239. 12380    'dest
  240. 12390     TARGET$ = DEST$: GOSUB 12660  'type_operand
  241. 12400     DTYPE = TARGTYPE: DVAL1 = TARGVAL1: DVAL2 = TARGVAL2
  242. 12410    'src
  243. 12420    'special case: RET op
  244. 12430     IF OP$ = "RET" THEN STYPE = PROCTYPE(STKTOP): GOTO 12480
  245. 12440    'normal
  246. 12450     TARGET$ = SOURCE$: GOSUB 12660   'type_operand
  247. 12460     STYPE = TARGTYPE: SVAL1 = TARGVAL1: SVAL2 = TARGVAL2
  248. 12470  '
  249. 12480  'find op in op table (not there: error)
  250. 12490   TARGET$ = OP$
  251. 12500   GOSUB 12040   'lookup_op
  252. 12510   IF FOUND THEN 12610
  253. 12520     IF PASS = 1 THEN RETURN
  254. 12530     MSG$ = "Syntax Error: "+ OP$ + " " + STR$(DTYPE) + " " + STR$(STYPE)
  255. 12540     GOSUB 18920
  256. 12550     IF ((ACUM8 OR ACUM16 OR REG8 OR REG16 OR SEGR OR CS)                                AND (DTYPE OR STYPE)) THEN 12600
  257. 12560     IF (STYPE AND (NONE OR IMMED8 OR IMMED16)) = FALSE THEN 12600
  258. 12570     IF INSTR("BW",RIGHT$(OP$,1)) <> 0 THEN 12600
  259. 12580        DIAGFLAG = TRUE
  260. 12590        MSG$ = "Specify word or byte operation": GOSUB 18920
  261. 12600     RETURN
  262. 12610   FLAG = OFLAG(OPPTR)
  263. 12620  '
  264. 12630  'branch to update loctr
  265. 12640   IF FLAG AND MACHOP THEN GOSUB 14830 ELSE GOSUB 15580
  266. 12650  RETURN
  267. 12660  '======================================
  268. 12670  'SUBROUTINE TYPE_OPERAND
  269. 12680  'Sets TARGTYPE to TARGET$'s type.  Sets
  270. 12690  'TARGVAL1 to its value. If a reg, sets
  271. 12700  'TARVAL2 to its val2. If offset appears
  272. 12710  'NEEDOFFSET & OFFSET are set.
  273. 12720  '======================================
  274. 12730  'any operand?
  275. 12740   IF LEN(TARGET$) > 0 THEN 12770
  276. 12750     TARGTYPE = NONE
  277. 12760     RETURN
  278. 12770  'in sym table?
  279. 12780   GOSUB 11890
  280. 12790   IF NOT FOUND THEN 12830
  281. 12800     TARGTYPE = SYMTYPE(TABLEPTR): TARGVAL1 = VAL1(TABLEPTR)
  282. 12810     IF TABLEPTR <= PREDEF THEN TARGVAL2 = VAL2(TABLEPTR)
  283. 12820     RETURN
  284. 12830  'number?
  285. 12840   GOSUB 13230
  286. 12850   IF NOT FOUND THEN 12880
  287. 12860     TARGTYPE = NUMTYPE: TARGVAL1 = NUMVAL
  288. 12870     RETURN
  289. 12880  'mem ref?
  290. 12890   GOSUB 13630
  291. 12900   IF NOT FOUND THEN 12930
  292. 12910     TARGTYPE = MEM: TARVAL1 = MEMADDR
  293. 12920     RETURN
  294. 12930  'offset off register?
  295. 12940   GOSUB 13930
  296. 12950   IF NOT FOUND THEN 12990
  297. 12960     TARGTYPE = MEMREG: TARGVAL1 = REGVAL
  298. 12970     RETURN
  299. 12980  'offset?
  300. 12990   GOSUB 14490
  301. 13000   IF NOT FOUND THEN 13030
  302. 13010     TARGTYPE = OFFSETYPE: TARGVAL1 = OFFSETVAL
  303. 13020     RETURN
  304. 13030  'char?
  305. 13040   GOSUB 14720
  306. 13050   IF NOT FOUND THEN 13080
  307. 13060      TARGTYPE = IMMED8 OR IMMED16: TARGVAL1 = CHARVAL
  308. 13070      RETURN
  309. 13080  'string?
  310. 13090   IF LEFT$(TARGET$,1) <> "'" THEN 13120
  311. 13100     TARGTYPE = STRING
  312. 13110     RETURN
  313. 13120  'not found? assume label or mem (pass 2 error)
  314. 13130   IF PASS = 1 THEN 13210
  315. 13140     MSG$ = "Undefined Symbol "+TARGET$: GOSUB 18920
  316. 13150    'look like hex?
  317. 13160     IF RIGHT$(TARGET$,1) <> "H" OR LEN(TARGET$) > 5 THEN 13210
  318. 13170     FOR I = 1 TO LEN(TARGET$)-1
  319. 13180       IF INSTR("1234567890ABCDEF", MID$(TARGET$,I,1)) = 0 THEN 13210
  320. 13190       NEXT I
  321. 13200     MSG$ = "Add leading zero to hex constant":DIAGFLAG = TRUE: GOSUB 18920
  322. 13210   TARGTYPE = NEAR OR MEM
  323. 13220  RETURN
  324. 13230  '=====================================
  325. 13240  'SUBROUTINE TEST_NUMBER
  326. 13250  'Trys to interpret TARGET$ as a num
  327. 13260  'If sucessful, sets FOUND true, NUMVAL
  328. 13270  'to its value and NUMTYPE to its type
  329. 13280  '=====================================
  330. 13290  FOUND = FALSE
  331. 13300  IF INSTR("1234567890",LEFT$(TARGET$,1)) = 0 THEN RETURN
  332. 13310  TN$ = TARGET$  'make copy
  333. 13320  IF LEFT$(TN$,1) = "0" THEN TN$ = RIGHT$(TN$,LEN(TN$)-1)
  334. 13330  '
  335. 13340  'hex?
  336. 13350   IF (RIGHT$(TN$,1) <> "H") OR (LEN(TN$) > 5) THEN 13490
  337. 13360    'lop off H
  338. 13370     TN$ = LEFT$(TN$,LEN(TN$)-1)
  339. 13380    'non-hex digits?
  340. 13390     I = 1
  341. 13400     FOR I = 1 TO LEN(TN$)
  342. 13410       C$ = MID$(TN$,I,1)
  343. 13420       IF INSTR("0123456789ABCDEF",C$) = 0 THEN RETURN
  344. 13430       NEXT I
  345. 13440    'get value
  346. 13450     NUMVAL = VAL("&H"+TN$)
  347. 13460    'set type, return
  348. 13470     GOTO 13590
  349. 13480  '
  350. 13490  'dec number?
  351. 13500    'non-dec digits?
  352. 13510     FOR I = 1 TO LEN(TN$)
  353. 13520       C$ = MID$(TN$,I,1)
  354. 13530       IF INSTR("0123456789-+",C$) = 0 THEN RETURN
  355. 13540       NEXT I
  356. 13550    'get value (overflow?)
  357. 13560     NVAL# = VAL(TN$)
  358. 13570  IF NVAL# < 32768 AND NVAL# > -32769 THEN NUMVAL = NVAL# ELSE RETURN
  359. 13580  '
  360. 13590  'sucess exit
  361. 13600   FOUND = TRUE
  362. 13610   IF LEN(HEX$(NUMVAL)) < 3  THEN NUMTYPE = IMMED16 OR IMMED8                        ELSE NUMTYPE = IMMED16
  363. 13620  RETURN
  364. 13630  '==================================
  365. 13640  'SUBROUTINE MEMREF
  366. 13650  'Trys to interpret target$ as a mem
  367. 13660  'ref.  If so, sets FOUND true, &
  368. 13670  'MEMADDR to the address referenced.
  369. 13680  '==================================
  370. 13690  MR$ = TARGET$  'save copy
  371. 13700  '[]?
  372. 13710   IF LEFT$(MR$,1) <> "[" OR RIGHT$(MR$,1) <> "]" THEN RETURN
  373. 13720  'strip []
  374. 13730   TARGET$ = MID$(MR$,2,LEN(MR$)-2)
  375. 13740  'try to parse as addr
  376. 13750   'number?
  377. 13760    GOSUB 13230
  378. 13770    IF NOT FOUND THEN 13800
  379. 13780      MEMADDR = NUMVAL
  380. 13790      GOTO 13900 'exit
  381. 13800   'symbol?
  382. 13810    GOSUB 11890
  383. 13820    IF NOT FOUND THEN 13860
  384. 13830      IF (SYMTYPE(TABLEPTR) AND IMMED16) = FALSE THEN 13860
  385. 13840        MEMADDR = VAL1(TABLEPTR)
  386. 13850        GOTO 13900 'exit
  387. 13860  'failure
  388. 13870   FOUND = FALSE
  389. 13880   TARGET$ = MR$
  390. 13890   RETURN
  391. 13900  'sucess
  392. 13910   TARGET$ = MR$
  393. 13920   RETURN
  394. 13930  '=======================================
  395. 13940  'SUBROUTINE PARSE_DISP_OFF_REG
  396. 13950  'Trys to parse TARGET$ as offset off reg
  397. 13960  'If so, sets FOUND true, sets NEEDOFFSET
  398. 13970  'to offset's type, and OFFSET its value
  399. 13980  '=======================================
  400. 13990  PDOR$ = TARGET$  'save copy
  401. 14000  '
  402. 14010  'special case
  403. 14020   IF TARGET$ = "[BP]" THEN REGVAL = 6: NEEDOFFSET = IMMED8: OFFSET = 0:              GOTO 14410
  404. 14030  '
  405. 14040  'parse reg
  406. 14050   'set ptr to candidate
  407. 14060    PTR = INSTR(TARGET$,"[")
  408. 14070    IF PTR <= 1 THEN 14450  'no disp, exit
  409. 14080   'isolate candidate
  410. 14090    REG$ = RIGHT$(PDOR$,LEN(PDOR$)-PTR+1)
  411. 14100   'valid reg?
  412. 14110    IF REG$ = "[BP]" THEN REGVAL = 6: GOTO 14180
  413. 14120    TARGET$ = REG$
  414. 14130    GOSUB 11890  'operand_lookup
  415. 14140    IF NOT FOUND OR SYMTYPE(TABLEPTR) <> MEMREG THEN 14450
  416. 14150     'save reg value
  417. 14160      REGVAL = VAL1(TABLEPTR)
  418. 14170  '
  419. 14180  'now parse disp.
  420. 14190   'isolate candidate
  421. 14200    DISP$ = LEFT$(PDOR$,PTR-1)
  422. 14210   'valid disp?
  423. 14220    TARGET$ = DISP$
  424. 14230     'might be symbol
  425. 14240      GOSUB 11890
  426. 14250      IF NOT FOUND THEN 14300   'not sym
  427. 14260      IF (SYMTYPE(TABLEPTR) AND (IMMED16 OR IMMED8)) = FALSE THEN 14300
  428. 14270        OFFSET = VAL1(TABLEPTR)
  429. 14280        NEEDOFFSET  = SYMTYPE(TABLEPTR)
  430. 14290        GOTO 14410
  431. 14300     'or number
  432. 14310      GOSUB 13230
  433. 14320      IF NOT FOUND THEN 14360
  434. 14330        OFFSET = NUMVAL
  435. 14340        IF OFFSET > 127 OR OFFSET < -128                                                   THEN NEEDOFFSET  = IMMED16 ELSE NEEDOFFSET = IMMED8
  436. 14350        GOTO 14410
  437. 14360     'or offset
  438. 14370      GOSUB 14490 'offset
  439. 14380      IF NOT FOUND THEN 14450
  440. 14390        OFFSET = OFFSETVAL
  441. 14400        NEEDOFFSET = IMMED16
  442. 14410  'sucess
  443. 14420   TARGET$ = PDOR$
  444. 14430   FOUND = TRUE
  445. 14440   RETURN
  446. 14450  'failure
  447. 14460   TARGET$ = PDOR$
  448. 14470   FOUND = FALSE
  449. 14480   RETURN
  450. 14490  '======================================
  451. 14500  'SUBROUTINE OFFSET
  452. 14510  'Trys to interpret TARGET$ as an offset
  453. 14520  'If sucessful, set FOUND, set OFFSETYPE
  454. 14530  'to immed16, TARGVAL1 to label's offset
  455. 14540  '======================================
  456. 14550  OS$ = TARGET$
  457. 14560  IF LEFT$(OS$,7) <> "OFFSET(" THEN FOUND = FALSE: RETURN
  458. 14570  IF PASS = 1 THEN 14680
  459. 14580  'isolate label
  460. 14590   TARGET$ = MID$(TARGET$,8,LEN(TARGET$)-8)
  461. 14600  'look it up
  462. 14610   GOSUB 11890
  463. 14620  IF FOUND AND (SYMTYPE(TABLEPTR) AND (MEM OR NEAR)) THEN 14660
  464. 14630    MSG$ = "Illegal or undefined argument for Offset": GOSUB 18920
  465. 14640    OFFSETVAL = 0
  466. 14650    GOTO 14680
  467. 14660  OFFSETVAL = VAL1(TABLEPTR)
  468. 14670  '
  469. 14680  FOUND = TRUE
  470. 14690  OFFSETYPE = IMMED16
  471. 14700  TARGET$ = OS$
  472. 14710  RETURN
  473. 14720  '=============================
  474. 14730  'SUBROUTINE CHAR
  475. 14740  'Trys to parse TARGET$ as char
  476. 14750  '=============================
  477. 14760  FOUND = FALSE
  478. 14770  IF LEN(TARGET$) <> 3 THEN RETURN
  479. 14780  IF LEFT$(TARGET$,1) <> "'" THEN RETURN
  480. 14790  IF RIGHT$(TARGET$,1) <> "'" THEN RETURN
  481. 14800    FOUND = TRUE
  482. 14810    CHARVAL = ASC(MID$(TARGET$,2,1))
  483. 14820  RETURN
  484. 14830  '=============================
  485. 14840  'SUBROUTINE MACHOP
  486. 14850  'Updates loctr based on op len
  487. 14860  'On pass 2, generates obj. code
  488. 14870  '==============================
  489. 14880  GOSUB 15450  'op_type
  490. 14890  '
  491. 14900  'opcode
  492. 14910   LOCTR = LOCTR + 1
  493. 14920   IF PASS = 2 THEN GOSUB 15640  'build_opcode
  494. 14930  '
  495. 14940  '2nd op byte?
  496. 14950   IF (OPVAL(OPPTR) <> &HD5) AND (OPVAL(OPPTR) <> &HD4) THEN 14990
  497. 14960     LOCTR = LOCTR + 1
  498. 14970     IF PASS = 2 THEN OBJLEN = OBJLEN + 1: OBJ(OBJLEN) = &HA
  499. 14980  '
  500. 14990  'room for m. byte disp. (must go here)
  501. 15000   IF NEEDOFFSET = NONE THEN 15030
  502. 15010     IF NEEDOFFSET AND IMMED8 THEN LOCTR = LOCTR+1: ELSE LOCTR = LOCTR+2
  503. 15020  '
  504. 15030  'direct addr. mode byte? leave room for addr
  505. 15040   IF (FLAG AND (NEEDMODEBYTE OR NEEDEXT)) = FALSE THEN 15070
  506. 15050     IF (DTYPE OR STYPE) AND MEM THEN LOCTR = LOCTR + 2
  507. 15060  '
  508. 15070  'ext. byte?
  509. 15080   IF (FLAG AND NEEDEXT) = FALSE THEN 15120
  510. 15090     LOCTR = LOCTR + 1
  511. 15100     IF PASS = 2 THEN GOSUB 15850   'build_ext
  512. 15110  '
  513. 15120  'mode byte?
  514. 15130   IF (FLAG AND NEEDMODEBYTE) = FALSE THEN 15170
  515. 15140     LOCTR = LOCTR + 1
  516. 15150     IF PASS = 2 THEN GOSUB 15970  'build_modebyte
  517. 15160  '
  518. 15170  '8 bit disp?
  519. 15180   IF (FLAG AND NEEDISP8) = FALSE THEN 15220
  520. 15190     LOCTR = LOCTR + 1
  521. 15200     IF PASS = 2 THEN GOSUB 16420  'build_disp8
  522. 15210  '
  523. 15220  '16 bit disp?
  524. 15230   IF (FLAG AND NEEDISP16) = FALSE THEN 15270
  525. 15240     LOCTR = LOCTR + 2
  526. 15250     IF PASS = 2 THEN GOSUB 16590 'build_disp16
  527. 15260  '
  528. 15270  'immed byte?
  529. 15280   IF (FLAG AND NEEDIMMED8) = FALSE THEN 15310
  530. 15290     LOCTR = LOCTR + 1
  531. 15300     IF PASS = 2 THEN GOSUB 16850
  532. 15310   IF WORD OR ((FLAG AND NEEDIMMED) = FALSE) THEN 15350
  533. 15320     LOCTR = LOCTR + 1
  534. 15330     IF PASS = 2 THEN GOSUB 16850   'build_immed8
  535. 15340  '
  536. 15350  'immed word(s)?
  537. 15360   IF NOT(WORD) OR ((FLAG AND NEEDIMMED) = FALSE) THEN 15400
  538. 15370     IF DTYPE = IMMED16 THEN LOCTR = LOCTR + 4 ELSE LOCTR = LOCTR + 2
  539. 15380     IF PASS = 2 THEN GOSUB 16720  'build_immed16
  540. 15390  '
  541. 15400  'mem addr?
  542. 15410   IF (FLAG AND NEEDMEM) = FALSE THEN 15440
  543. 15420     LOCTR = LOCTR + 2
  544. 15430     IF PASS = 2 THEN GOSUB 16960  'mem_addr
  545. 15440  RETURN
  546. 15450  '===============================
  547. 15460  'SUBROUTINE OP_TYPE
  548. 15470  'Decides between word & byte ops
  549. 15480  '===============================
  550. 15490  IF (DTYPE OR STYPE) AND (REG16 OR ACUM16 OR SEGR OR CS) THEN 15520
  551. 15500  IF (DTYPE OR STYPE) AND (REG8 OR ACUM8) THEN 15550
  552. 15510  IF RIGHT$(OP$,1) = "B" THEN 15550
  553. 15520  'word
  554. 15530   WORD = TRUE
  555. 15540   RETURN
  556. 15550  'byte
  557. 15560   WORD = FALSE
  558. 15570   RETURN
  559. 15580  '====================
  560. 15590  'SUBROUTINE PSEUDO-OP
  561. 15600  '====================
  562. 15610  ON OPVAL(OPPTR) GOSUB 17080,17210,17270,17670,17830,17930,18010,18060
  563. 15620  '                      EQU   ORG   DB    DS   PROC  ENDP  BSAVE EJECT
  564. 15630  RETURN
  565. 15640  '=======================
  566. 15650  'SUBROUTINE BUILD_OPCODE
  567. 15660  'Builds opcode in OBJ
  568. 15670  '=======================
  569. 15680  OBJLEN = OBJLEN + 1
  570. 15690  OBJ(OBJLEN) = OPVAL(OPPTR)
  571. 15700  '
  572. 15710  'reg field?
  573. 15720   IF (FLAG AND ADDREG) = FALSE THEN 15780
  574. 15730     'seg reg
  575. 15740     IF DTYPE AND (SEGR OR CS) THEN R = DVAL2: GOTO 15770
  576. 15750     'normal reg
  577. 15760     IF (FLAG AND DIRECTION) THEN R = SVAL2/8 ELSE R = DVAL2/8
  578. 15770     OBJ(OBJLEN) = OBJ(OBJLEN) + R
  579. 15780  'word bit?
  580. 15790   IF (FLAG AND AUTOW) = FALSE THEN 15810
  581. 15800     IF WORD THEN OBJ(OBJLEN) = OBJ(OBJLEN) + 1
  582. 15810  'count bit?
  583. 15820   IF (FLAG AND AUTOC) = FALSE THEN 15840
  584. 15830     IF STYPE AND CL THEN OBJ(OBJLEN) = OBJ(OBJLEN) + 2
  585. 15840  RETURN
  586. 15850  '===================================
  587. 15860  'SUBROUTINE BUILD_EXTENSION_BYTE
  588. 15870  'Builds opcode ext byte.  Ext val is
  589. 15880  'extracted from bits 3-5 of flag word
  590. 15890  '====================================
  591. 15900  'get ext
  592. 15910   MASK = &H38
  593. 15920   EXT = FLAG AND MASK
  594. 15930  'define proper opd as ext & build
  595. 15940   IF FLAG AND DIRECTION THEN DVAL2 = EXT ELSE SVAL2 = EXT
  596. 15950   GOSUB 15970  'build_modebyte
  597. 15960  RETURN
  598. 15970  '======================================================
  599. 15980  'SUBROUTINE BUILD_MODE_BYTE
  600. 15990  'Given direction flag, memreg values in dval1 & sval1 &
  601. 16000  'reg values in dval2 & sval2, builds an addressing mode
  602. 16010  'byte.  If necessary, also builds displacement byte(s).
  603. 16020  '=======================================================
  604. 16030  OBJLEN = OBJLEN + 1
  605. 16040  'special case: direct mem. addressing?
  606. 16050   IF ((DTYPE OR STYPE) AND MEM) = FALSE THEN 16110
  607. 16060     IF DTYPE = MEM THEN  M = SVAL2 ELSE M = DVAL2
  608. 16070       OBJ(OBJLEN) = 6 + M
  609. 16080       GOSUB 16960  'build_mem_addr
  610. 16090       RETURN
  611. 16100  'normal mode byte
  612. 16110  'opds in normal or reverse order?
  613. 16120   IF FLAG AND DIRECTION THEN M = SVAL1 + DVAL2 ELSE M = DVAL1 + SVAL2
  614. 16130   OBJ(OBJLEN) = M
  615. 16140  'offset byte(s)?
  616. 16150  IF NEEDOFFSET = NONE THEN 16310
  617. 16160  '8 bit disp.
  618. 16170  IF OFFSET > 127 OR OFFSET < -128 THEN 16240
  619. 16180    OBJ(OBJLEN) = OBJ(OBJLEN) + 64  'set mod field
  620. 16190    'crunch neg. offset to 8 bits
  621. 16200      IF OFFSET < 0 THEN OFFSET = OFFSET AND &HFF
  622. 16210    OBJLEN = OBJLEN + 1
  623. 16220    OBJ(OBJLEN) = OFFSET
  624. 16230    RETURN
  625. 16240  '16 bit disp.
  626. 16250   OBJ(OBJLEN) = OBJ(OBJLEN) + 128  'set mod field
  627. 16260   OBJLEN = OBJLEN + 2
  628. 16270   'convert to hi/low form
  629. 16280      NUMLOW = OFFSET: GOSUB 16320  'hi/low
  630. 16290   OBJ(OBJLEN-1) = NUMLOW
  631. 16300   OBJ(OBJLEN) = NUMHIGH
  632. 16310  RETURN
  633. 16320  '=====================================
  634. 16330  'SUBROUTINE HI/LOW
  635. 16340  'Splits 16 bit number in numlow into 2
  636. 16350  'byte-sized chunks in numhigh & numlow
  637. 16360  '=====================================
  638. 16370  H$ = HEX$(NUMLOW)
  639. 16380  H$ = STRING$(4-LEN(H$),"0") + H$
  640. 16390  NUMLOW =  VAL("&H" + RIGHT$(H$,2))
  641. 16400  NUMHIGH = VAL("&H" + LEFT$(H$,2))
  642. 16410  RETURN
  643. 16420  '=================================
  644. 16430  'SUBROUTINE BUILD_DISP8
  645. 16440  'Builds displacement byte.  Prints
  646. 16450  'error msg if disp. exceeds 127
  647. 16460  '=================================
  648. 16470  'calc disp.
  649. 16480   D = DVAL1 - LOCTR
  650. 16490  'check size
  651. 16500   IF ABS(D) < 128 THEN 16530
  652. 16510     D = 0
  653. 16520     IF PASS = 2 THEN MSG$ = "Too far for short jump": GOSUB 18920
  654. 16530  'if neg. crunch to 8 bits
  655. 16540   IF D < 0 THEN D = D AND &HFF
  656. 16550  'build obj. code
  657. 16560   OBJLEN = OBJLEN + 1
  658. 16570   OBJ(OBJLEN) = D
  659. 16580  RETURN
  660. 16590  '========================
  661. 16600  'SUBROUTINE BUILD_DISP16
  662. 16610  'Builds displacement word
  663. 16620  '========================
  664. 16630  'calc disp.
  665. 16640   D = DVAL1 - LOCTR
  666. 16650  IF OP$ = "JMP" AND (D < 128 AND D > -129) THEN DIAGFLAG = TRUE:                   MSG$ = "Could use JMPS": GOSUB 18920
  667. 16660  'build obj. code
  668. 16670   NUMLOW = D: GOSUB 16320  'hi/low
  669. 16680   OBJLEN = OBJLEN + 2
  670. 16690   OBJ(OBJLEN-1) = NUMLOW
  671. 16700   OBJ(OBJLEN) = NUMHIGH
  672. 16710  RETURN
  673. 16720  '============================
  674. 16730  'SUBROUTINE BUILD_IMMED16
  675. 16740  'Builds word(s) of immed data
  676. 16750  '============================
  677. 16760  IF DTYPE AND IMMED16 THEN IVAL = DVAL1: GOSUB 16790
  678. 16770  IF STYPE AND IMMED16 THEN IVAL = SVAL1: GOSUB 16790
  679. 16780  RETURN
  680. 16790  'subroutine immed16
  681. 16800  NUMLOW = IVAL: GOSUB 16320   'hi/low
  682. 16810  OBJLEN = OBJLEN + 2
  683. 16820  OBJ(OBJLEN-1) = NUMLOW
  684. 16830  OBJ(OBJLEN) = NUMHIGH
  685. 16840  RETURN
  686. 16850  '=========================
  687. 16860  'SUBROUTINE BUILD_IMMED8
  688. 16870  'Builds byte of immed data
  689. 16880  '=========================
  690. 16890  IF DTYPE AND IMMED8 THEN IVAL = DVAL1: GOSUB 16920
  691. 16900  IF STYPE AND IMMED8 THEN IVAL = SVAL1: GOSUB 16920
  692. 16910  RETURN
  693. 16920  'sub. immed8
  694. 16930  OBJLEN = OBJLEN + 1
  695. 16940  OBJ(OBJLEN) = IVAL
  696. 16950  RETURN
  697. 16960  '======================
  698. 16970  'SUBROUTINE MEMREF
  699. 16980  'Builds a mem addr word
  700. 16990  '======================
  701. 17000  'get addr in hi/low form
  702. 17010   IF DTYPE = MEM THEN NUMLOW = DVAL1 ELSE NUMLOW = SVAL1
  703. 17020   GOSUB 16320
  704. 17030  'build word
  705. 17040   OBJLEN = OBJLEN + 2
  706. 17050   OBJ(OBJLEN-1) = NUMLOW
  707. 17060   OBJ(OBJLEN) = NUMHIGH
  708. 17070  RETURN
  709. 17080  '==============
  710. 17090  'SUBROUTINE EQU
  711. 17100  '==============
  712. 17110  IF (LABEL$ <> "")  THEN 17140
  713. 17120    IF PASS = 2 THEN MSG$ = "EQU without symbol": GOSUB 18920
  714. 17130    RETURN
  715. 17140  IF PASS = 2 THEN 17200
  716. 17150  IF DTYPE <> (NEAR OR MEM) THEN 17180   'pass 1 default
  717. 17160    MSG$ = "EQU with forward reference": GOSUB 18920
  718. 17170    RETURN
  719. 17180  VAL1(NUMSYM) = DVAL1
  720. 17190  SYMTYPE(NUMSYM) = DTYPE
  721. 17200  RETURN
  722. 17210  '==============
  723. 17220  'SUBROUTINE ORG
  724. 17230  '==============
  725. 17240  'reset loctr
  726. 17250  LOCTR = DVAL1
  727. 17260  RETURN
  728. 17270  '=============
  729. 17280  'SUBROUTINE DB
  730. 17290  '=============
  731. 17300  IF PASS = 2 THEN 17330
  732. 17310  'label? set type to mem
  733. 17320   IF LABEL$ <> "" THEN SYMTYPE(NUMSYM) = MEM
  734. 17330  'scan, building obj. code
  735. 17340   LINEPTR = OPDPTR: LINEPTR2 = OPDPTR
  736. 17350   WHILE LINEPTR < ENDPTR
  737. 17360    'get operand
  738. 17370     GOSUB 11260  'get_field
  739. 17380     IF NOT FOUND THEN 17540  'exit
  740. 17390    'branch for byte or string
  741. 17400     TARGET$ = FLD$: GOSUB 13230 'test_number
  742. 17410     IF NOT FOUND OR (NUMTYPE AND IMMED8) = FALSE THEN 17440
  743. 17420       GOSUB 17560  'build_byte
  744. 17430       GOTO 17530
  745. 17440     GOSUB 11890 'operand lookup
  746. 17450     IF (NOT FOUND) OR ((SYMTYPE(TABLEPTR) AND IMMED8) = FALSE) THEN 17480
  747. 17460        NUMVAL = VAL1(TABLEPTR): GOSUB 17560
  748. 17470        GOTO 17530
  749. 17480     IF LEFT$(FLD$,1) <> "'" THEN 17510
  750. 17490       GOSUB 17600  'build_stg
  751. 17500       GOTO 17530
  752. 17510    'not byte or string? pass 2 error
  753. 17520     IF PASS = 2 THEN MSG$ = "Unrecognized operand "+FLD$: GOSUB 18920
  754. 17530    WEND
  755. 17540  LOCTR = LOCTR + OBJLEN
  756. 17550  RETURN
  757. 17560  'subroutine build_byte
  758. 17570  OBJLEN = OBJLEN + 1
  759. 17580  OBJ(OBJLEN) = NUMVAL
  760. 17590  RETURN
  761. 17600  'subroutine build_stg
  762. 17610  FLD$ = MID$(FLD$,2,LEN(FLD$)-2) 'strip off 's
  763. 17620  FOR I = 1 TO LEN(FLD$)
  764. 17630    OBJLEN = OBJLEN + 1
  765. 17640    OBJ(OBJLEN) = ASC(MID$(FLD$,I,1))
  766. 17650    NEXT I
  767. 17660  RETURN
  768. 17670  '=============
  769. 17680  'SUBROUTINE DS
  770. 17690  '=============
  771. 17700  DSFLAG = TRUE  'signal a ds
  772. 17710  IF PASS = 2 THEN 17740 'skip type setting?
  773. 17720  'label?
  774. 17730   IF LABEL$ <> "" THEN SYMTYPE(NUMSYM) = MEM
  775. 17740  'output code
  776. 17750   IF STYPE AND IMMED8 THEN DSVAL = SVAL1 ELSE DSVAL = 0
  777. 17760  'pass 2, generate obj. code directly
  778. 17770   IF PASS = 1 THEN 17810
  779. 17780     FOR I = 1 TO DVAL1
  780. 17790       LSET BYTE$ = CHR$(DSVAL): PUT #3
  781. 17800       NEXT I
  782. 17810   LOCTR = LOCTR + DVAL1: BYTESGEN = BYTESGEN + DVAL1
  783. 17820  RETURN
  784. 17830  '===============
  785. 17840  'SUBROUTINE PROC
  786. 17850  '===============
  787. 17860  IF STKTOP < MAXSTK THEN 17890
  788. 17870    IF PASS = 2 THEN MSG$ = "Procedures nested too deeply": GOSUB 18920
  789. 17880    RETURN
  790. 17890  'push new proc type
  791. 17900   STKTOP = STKTOP + 1
  792. 17910   PROCTYPE(STKTOP) = DTYPE
  793. 17920  RETURN
  794. 17930  '===============
  795. 17940  'SUBROUTINE ENDP
  796. 17950  '===============
  797. 17960  IF STKTOP > 0 THEN 17990
  798. 17970    IF PASS = 2 THEN MSG$ = "ENDP without PROC": GOSUB 18920
  799. 17980    RETURN
  800. 17990  STKTOP = STKTOP - 1
  801. 18000  RETURN
  802. 18010  '================
  803. 18020  'SUBROUTINE BSAVE
  804. 18030  '================
  805. 18040  BASCODE = TRUE
  806. 18050  RETURN
  807. 18060  '================
  808. 18070  'SUBROUTINE EJECT
  809. 18080  '================
  810. 18090  IF PASS = 1 THEN RETURN
  811. 18100  LINESUSED = LINENUM + DIAG + ERRS + XTRA
  812. 18110  PAGEPOS = LINESUSED MOD PAGELEN
  813. 18120  GOSUB 18620
  814. 18130  RETURN
  815. 18140  '================================
  816. 18150  'SUBROUTINE OUTPUT
  817. 18160  'Outputs obj code & listing line,
  818. 18170  'given code in obj(objlength)
  819. 18180  '================================
  820. 18190  'update # of bytes generated
  821. 18200   BYTESGEN = BYTESGEN + OBJLEN
  822. 18210  IF DSFLAG THEN H$ = HEX$(LOCTR-DVAL1) ELSE H$ = HEX$(LOCTR-OBJLEN)
  823. 18220  H$ = STRING$(4-LEN(H$),"0") + H$
  824. 18230  PRINT#2, TAB(1) H$;
  825. 18240  'first 6 bytes
  826. 18250   I = 1
  827. 18260   PRINT#2, TAB(6)
  828. 18270   WHILE I <= 6
  829. 18280     IF I > OBJLEN THEN 18350
  830. 18290     LSET BYTE$ = CHR$(OBJ(I)): PUT #3
  831. 18300     H$ = HEX$(OBJ(I)): IF LEN(H$) = 1 THEN H$ = "0" + H$
  832. 18310     PRINT#2, H$;
  833. 18320     I = I + 1
  834. 18330     WEND
  835. 18340  '
  836. 18350  'source (truncate?)
  837. 18360   PRINT#2, TAB(19)
  838. 18370   PRINT#2, USING "####"; LINENUM;
  839. 18380   PRINT#2, SPACE$(2) LEFT$(INPLINE$, LWIDTH-26)
  840. 18390  '
  841. 18400  'formfeed?
  842. 18410   GOSUB 18530
  843. 18420  '
  844. 18430  'rest of obj. code
  845. 18440   WHILE I <= OBJLEN
  846. 18450     IF I MOD 6 = 1 THEN PRINT#2, TAB(6): XTRA = XTRA + 1: GOSUB 18530
  847. 18460     LSET BYTE$ = CHR$(OBJ(I)): PUT #3
  848. 18470     H$ = HEX$(OBJ(I)): IF LEN(H$) = 1 THEN H$ = "0" + H$
  849. 18480     PRINT#2, H$;
  850. 18490     I = I + 1
  851. 18500     WEND
  852. 18510   IF OBJLEN > 6 THEN PRINT#2,: XTRA = XTRA + 1: GOSUB 18530
  853. 18520  RETURN
  854. 18530  '=====================
  855. 18540  'SUBROUTINE NEEDEJECT?
  856. 18550  '=====================
  857. 18560  IF L$ <> "lpt1:" THEN RETURN
  858. 18570  '
  859. 18580  LINESUSED = LINENUM + DIAG + ERRS + XTRA
  860. 18590  PAGEPOS = LINESUSED MOD PAGELEN
  861. 18600  IF PAGEPOS > MAXLINES THEN GOSUB 18620
  862. 18610  RETURN
  863. 18620  '================================
  864. 18630  'SUBROUTINE FORMFEED
  865. 18640  'Advances to new print page given
  866. 18650  'current position in PAGEPOS
  867. 18660  '================================
  868. 18670  IF L$ <> "lpt1:" THEN RETURN
  869. 18680  FOR I = 1 TO (PAGELEN - PAGEPOS)
  870. 18690    PRINT#2,
  871. 18700    NEXT I
  872. 18710  XTRA = XTRA + PAGELEN - PAGEPOS
  873. 18720  RETURN
  874. 18730  '=======================
  875. 18740  'SUBROUTINE PASSTWO_INIT
  876. 18750  '=======================
  877. 18760   CLOSE 1: OPEN SC$ FOR INPUT AS 1
  878. 18770  '
  879. 18780   IF NOT BASCODE THEN 18870
  880. 18790    'build bsave header
  881. 18800     LSET BYTE$ = CHR$(253): PUT 3
  882. 18810     FOR I = 1 TO 4
  883. 18820       LSET BYTE$ = CHR$(0): PUT 3
  884. 18830       NEXT I
  885. 18840     NUMLOW = LOCTR: GOSUB 16320 'hi/low
  886. 18850     LSET BYTE$ = CHR$(NUMLOW): PUT 3
  887. 18860     LSET BYTE$ = CHR$(NUMHIGH): PUT 3
  888. 18870  PASS = 2
  889. 18880  LOCTR = 256
  890. 18890  TOTALINES = LINENUM: LINENUM = 0
  891. 18900  BYTESGEN = 0
  892. 18910  RETURN
  893. 18920  '=====================
  894. 18930  'SUBROUTINE ERRMSG
  895. 18940  'Prints error & diag messages
  896. 18950  '=====================
  897. 18960  IF AUDIO THEN BEEP
  898. 18970  IF DIAGFLAG = TRUE THEN DIAG = DIAG + 1: PRINT#2, "****Diagnostic: ";              ELSE ERRS = ERRS + 1: PRINT#2, "****";
  899. 18980  PRINT #2, MSG$;: IF PASS = 1 THEN PRINT#2, " in"; LINENUM ELSE PRINT#2,
  900. 18990  DIAGFLAG = FALSE: RETURN
  901. 19000  '====================
  902. 19010  'SUBROUTINE FINALPROC
  903. 19020  '====================
  904. 19030  IF STKTOP > 0 THEN MSG$ = "Error: missing ENDP": GOSUB 18920
  905. 19040  PRINT#2,: PRINT#2,: PRINT#2, ERRS; "Error(s) detected"
  906. 19050  XTRA = XTRA + 3: GOSUB 18530 'page eject?
  907. 19060  PRINT#2, DIAG; "Diagnostic(s) offered": XTRA = XTRA + 1: GOSUB 18530
  908. 19070  PRINT#2,: PRINT#2, BYTESGEN; "Bytes of object code generated"
  909. 19080  XTRA = XTRA + 2: GOSUB 18530
  910. 19090  'dump sym table
  911. 19100   GOSUB 19200
  912. 19110  'reset printer
  913. 19120   IF L$ = "lpt1:" THEN PRINT#2, PMODEOFF$
  914. 19130  'hang onto scrn listing
  915. 19140   IF L$ <> "scrn:" THEN 19190
  916. 19150     LOCATE 25,1: BEEP: COLOR BG,FG
  917. 19160     PRINT TAB(30) "Hit any key to exit" TAB(79);
  918. 19170     C$ = INKEY$: IF C$ = "" THEN 19170
  919. 19180     COLOR FG,BG
  920. 19190  RETURN
  921. 19200  '=========================
  922. 19210  'SUBROUTINE DUMP_SYM_TABLE
  923. 19220  '=========================
  924. 19230  IF NUMSYM = PREDEF THEN RETURN
  925. 19240  PRINT#2,: PRINT#2, "SYMBOL TABLE DUMP:": XTRA = XTRA + 2: GOSUB 18530
  926. 19250  I = PREDEF + 1
  927. 19260  F$ =  "\        \!\  \\  \"  'format
  928. 19270  PERLINE = LWIDTH \ LEN(F$)
  929. 19280  WHILE I <= NUMSYM
  930. 19290    H$ = HEX$(VAL1(I)): H$ = STRING$(4-LEN(H$),"0") + H$
  931. 19300    PRINT#2, USING F$; SYM$(I); " ";  H$; "    ";
  932. 19310    I = I + 1
  933. 19320    IF (I - PREDEF) MOD PERLINE <> 1 THEN 19340
  934. 19330      PRINT#2,: XTRA = XTRA + 1: GOSUB 18530
  935. 19340    WEND
  936. 19350  PRINT#2,: XTRA = XTRA + 1: GOSUB 18530
  937. 19360  RETURN
  938. 19370  '=========================
  939. 19380  'SUBROUTINE PROGESS REPORT
  940. 19390  '=========================
  941. 19400  X = POS(0): Y = CSRLIN: LOCATE 25,1: COLOR BG,FG
  942. 19410  PRINT "Errors: "; ERRS TAB(25) "Pass ";
  943. 19420  IF PASS = 1 THEN PRINT "ONE"; ELSE PRINT "TWO";
  944. 19430  PRINT " in progress.";
  945. 19440  IF PASS = 1 THEN PRINT TAB(59) "Lines processed:"; LINENUM;                        ELSE PRINT TAB(51) "Lines processed:"; LINENUM; "of"; TOTALINES;
  946. 19450  PRINT TAB(80);: COLOR FG,BG: LOCATE Y,X
  947. 19460  RETURN
  948. 19470  '======================
  949. 19480  'SUBROUTINE FINISH_INIT
  950. 19490  '======================
  951. 19500  GOSUB 19530 'sym table
  952. 19510  GOSUB 19630 'header
  953. 19520  RETURN
  954. 19530  '=======================
  955. 19540  'SUBROUTINE SYMBOL_TABLE
  956. 19550  'Sets up sym table
  957. 19560  '=======================
  958. 19570  FOR I = 1 TO PREDEF  'pre-defined
  959. 19580    INPUT#3, SYM$(I), VAL1(I), VAL2(I), SYMTYPE(I)
  960. 19590    NEXT I
  961. 19600  NUMSYM = PREDEF
  962. 19610  CLOSE 3
  963. 19620  RETURN
  964. 19630  '=================
  965. 19640  'SUBROUTINE HEADER
  966. 19650  '=================
  967. 19660  'printer set up?
  968. 19670   IF L$ <> "lpt1:" OR PMODEON$ = "" THEN 19700
  969. 19680     PRINT#2, PMODEON$;
  970. 19690     WIDTH#2, 132: LWIDTH = 131
  971. 19700  'title & date
  972. 19710   D$ = LEFT$(DATE$,2) + "/" + MID$(DATE$,4,2) + "/" +  RIGHT$(DATE$,2)
  973. 19720   PRINT#2, SC$ TAB(LWIDTH-LEN(D$)) D$:PRINT#2,:PRINT#2,
  974. 19730  'column headings
  975. 19740   PRINT#2,"LOC"TAB(6)"OBJ"TAB(19)"LINE"TAB(25)"SOURCE":PRINT#2,
  976. 19750  'used 4 lines
  977. 19760  XTRA = XTRA + 4
  978. 19770  RETURN
  979. 50000  '=============================
  980. 50010  'SUBROUTINE INIT
  981. 50020  'Initializes all but sym table
  982. 50030  '=============================
  983. 50040  ERRS = 0: DIAG = 0
  984. 50050  'configure
  985. 50060   GOSUB 50160
  986. 50070  'title page
  987. 50080   GOSUB 50660
  988. 50090  'constants
  989. 50100   GOSUB 50900
  990. 50110  'files
  991. 50120   GOSUB 51050
  992. 50130  'op table
  993. 50140   GOSUB 51560
  994. 50150  RETURN
  995. 50160  '=================
  996. 50170  'SUBROUTINE CONFIG
  997. 50180  'Reads CHASM.CFG
  998. 50190  '=================
  999. 50200  'defaults:
  1000. 50210  PMODEON$ = "": PMODEOFF$ = "": LWIDTH = 79: AUDIO = 1
  1001. 50220  FG = 7: BG = 0: MAXLINES = 58: PAGELEN = 66
  1002. 50230  ON ERROR GOTO 50490
  1003. 50240  OPEN "chasm.cfg" FOR INPUT AS 3
  1004. 50250  '
  1005. 50260  WHILE NOT EOF(3)
  1006. 50270    INPUT#3, C$
  1007. 50280    IF C$ <> "/80" THEN 50300
  1008. 50290      GOSUB 50590: PMODEOFF$ = CTL$ 'get ctl$
  1009. 50300    IF C$ <> "/132" THEN 50320
  1010. 50310      GOSUB 50590: PMODEON$ = CTL$ 'get ctl$
  1011. 50320    IF C$ <> "/LINES" AND C$ <> "/lines" THEN 50340
  1012. 50330      INPUT#3, MAXLINES
  1013. 50340    IF C$ <> "/PAGELEN" AND C$ <> "/pagelen" THEN 50360
  1014. 50350      INPUT#3, PAGELEN
  1015. 50360    IF C$ <> "/FG" AND C$ <> "/fg" THEN 50380
  1016. 50370      INPUT#3, FG
  1017. 50380    IF C$ <> "/BG" AND C$ <> "/bg" THEN 50400
  1018. 50390      INPUT#3, BG
  1019. 50400    IF C$ <> "/BEEP" AND C$ <> "/beep" THEN 50430
  1020. 50410      INPUT#3, AUDIO
  1021. 50420    IF OVERRAN THEN OVERRAN = FALSE: GOTO 50280
  1022. 50430    WEND
  1023. 50440  CLOSE #3
  1024. 50450  'config screen
  1025. 50460   SCREEN 0,0,0: WIDTH 80: COLOR FG,BG: KEY OFF: CLS
  1026. 50470  ON ERROR GOTO 0
  1027. 50480  RETURN
  1028. 50490  IF ERL = 50240 THEN 50570
  1029. 50500    BEEP: COLOR FG,BG: CLS: COLOR BG,FG: LOCATE 12,25
  1030. 50510    PRINT "Problem with CHASM.CFG"
  1031. 50520    COLOR FG,BG: LOCATE 24,15
  1032. 50530    PRINT "Hit Esc to exit, anything else to continue...";
  1033. 50540    I$ = INKEY$: IF I$ = "" THEN 50540
  1034. 50550    IF I$ = CHR$(27) THEN SYSTEM
  1035. 50560    CLS
  1036. 50570  RESUME 50460
  1037. 50580  '
  1038. 50590  OVERRAN = FALSE: CTL$ = "": INPUT#3, C$
  1039. 50600  WHILE (NOT EOF(3)) AND (LEFT$(C$,1) <> "/")
  1040. 50610    CTL$ = CTL$ + CHR$(VAL(C$))
  1041. 50620    INPUT#3, C$
  1042. 50630    WEND
  1043. 50640  IF EOF(3) THEN CTL$ = CTL$ + CHR$(VAL(C$)) ELSE OVERRAN = TRUE
  1044. 50650  RETURN
  1045. 50660  '================
  1046. 50670  'SUBROUTINE TITLE
  1047. 50680  '================
  1048. 50690  CLS: LOCATE 24,1,0
  1049. 50700  PRINT TAB(12)"KEY";STRING$(56,"THEN");"CLOSE
  1050. 50710  PRINT TAB(12)"OPEN"TAB(69)"OPEN
  1051. 50720  PRINT TAB(12)"OPEN"TAB(32)"CHASM  version 2.10"TAB(69)"OPEN
  1052. 50730  PRINT TAB(12)"OPEN"TAB(69)"OPEN
  1053. 50740  PRINT TAB(12)"OPEN"TAB(25)"Cheap Assembler for the IBM PC"TAB(69)"OPEN
  1054. 50750  PRINT TAB(12)"OPEN"TAB(69)"OPEN
  1055. 50760  PRINT TAB(12)"OPEN      If you have used this program and found it of     OPEN
  1056. 50770  PRINT TAB(12)"OPEN   value, your $20 contribution will be appreciated.    OPEN
  1057. 50780  PRINT TAB(12)"OPEN"TAB(69)"OPEN
  1058. 50790  PRINT TAB(12)"OPEN"TAB(29)"David Whitman"TAB(69)"OPEN
  1059. 50800  PRINT TAB(12)"OPEN"TAB(29)"2 N Park St."TAB(69)"OPEN
  1060. 50810  PRINT TAB(12)"OPEN"TAB(29)"Apartment L"TAB(69)"OPEN
  1061. 50820  PRINT TAB(12)"OPEN"TAB(29)"Hanover, NH  03755"TAB(69)"OPEN
  1062. 50830  PRINT TAB(12)"OPEN"TAB(69)"OPEN
  1063. 50840  PRINT TAB(12)"OPEN   You are encouraged to copy and share this program.   OPEN
  1064. 50850  PRINT TAB(12)"OPEN"TAB(69)"OPEN
  1065. 50860  PRINT TAB(12)"SCREEN";STRING$(56,"THEN");"LOAD":PRINT
  1066. 50870  PRINT TAB(27) "Hit any key to continue...":PRINT:PRINT
  1067. 50880  I$ = INKEY$: IF I$ = "" THEN 50880
  1068. 50890  CLS: RETURN
  1069. 50900  '====================
  1070. 50910  'SUBROUTINE CONSTANTS
  1071. 50920  '====================
  1072. 50930  'general
  1073. 50940   TRUE = -1: FALSE = 0: DELIM$ = " ,"
  1074. 50950  'flag values
  1075. 50960  'bits 3-5 reserved for ext. values
  1076. 50970   MACHOP = 1: AUTOW = 4: ADDREG = 64: NEEDEXT = 128
  1077. 50980   NEEDISP8 = 256: NEEDISP16 = 512: NEEDMODEBYTE = 1024: NEEDIMMED8 = 2048
  1078. 50990   NEEDIMMED = 4096: DIRECTION = 8192: NEEDMEM = 16384: AUTOC = &H8000
  1079. 51000  'operand types
  1080. 51010   ACUM8 = 1: ACUM16 = 2: REG8 = 4: REG16 = 8: MEMREG = 16: CS = 32
  1081. 51020   SEGR = 64: MEM = 128: IMMED8 = 256: IMMED16 = 512: NONE = 1024
  1082. 51030   STRING = 2048: NEAR = 4096: FAR = 8192: CL = 16384
  1083. 51040  RETURN
  1084. 51050  '======================
  1085. 51060  'SUBROUTINE OPEN_FILES
  1086. 51070  'Gets & opens i/o files
  1087. 51080  '======================
  1088. 51090  ON ERROR GOTO 51370
  1089. 51100  'input file
  1090. 51110   LOCATE 1,1: INPUT"Source code file name? [.asm] ", S$
  1091. 51120   IF S$ = "" THEN BEEP: GOTO 51110
  1092. 51130   'no ext, add default
  1093. 51140    IF INSTR(S$,".") = 0 THEN SC$ = S$ + ".asm"                                       ELSE SC$ = S$: S$ = LEFT$(S$,INSTR(S$,".")-1)
  1094. 51150   OPEN SC$ FOR INPUT AS #1
  1095. 51160   LOCATE 3,1
  1096. 51170   INPUT"Direct listing to Printer (P), Screen (S), or Disk (D)?",L$
  1097. 51180   IF L$ = "" THEN BEEP: GOTO 51160
  1098. 51190     IF INSTR("PpSsDd",L$) = 0 THEN BEEP: GOTO 51160  'invalid response
  1099. 51200     IF L$ = "P" OR L$ = "p" THEN L$ = "lpt1:" : GOTO 51260
  1100. 51210     IF L$ = "S" OR L$ = "s" THEN L$ = "scrn:" : GOTO 51260
  1101. 51220       LOCATE 3,1: PRINT SPACE$(79);: LOCATE 3,1
  1102. 51230       PRINT"Name for listing file? [";S$;".lst] ";
  1103. 51240       INPUT "",L$
  1104. 51250       IF L$ = "" THEN L$ = S$ + ".lst"
  1105. 51260     OPEN L$ FOR OUTPUT AS 2
  1106. 51270  PRINT#2, 'test printer
  1107. 51280  'obj file
  1108. 51290   LOCATE 5,1: PRINT "Name for object file?  [";S$;".com] ";
  1109. 51300   INPUT "",O$
  1110. 51310   'default:
  1111. 51320    IF O$ = "" THEN O$ = S$ + ".com"
  1112. 51330   'open later
  1113. 51340  ON ERROR GOTO 0
  1114. 51350  PRINT: PRINT: PRINT
  1115. 51360  RETURN
  1116. 51370  '=============
  1117. 51380  'Error Handler
  1118. 51390  '=============
  1119. 51400  IF ERR = 53 THEN 51420
  1120. 51410  IF NOT((ERR = 52) AND (ERL = 51150)) THEN 51490
  1121. 51420    COLOR BG,FG: BEEP
  1122. 51430    PRINT SC$;" not found.  Press Esc to exit, anything else to continue.";
  1123. 51440    SC$ = INKEY$: IF SC$ = "" THEN 51440
  1124. 51450    IF SC$ = CHR$(27) THEN SYSTEM
  1125. 51460    LOCATE ,1: COLOR FG,BG: PRINT TAB(80);
  1126. 51470    LOCATE 1,31: PRINT TAB(80); : LOCATE ,1: RESUME 51110
  1127. 51480  '
  1128. 51490  IF ERL <> 51270 THEN 51550
  1129. 51500    CLOSE #2: COLOR BG,FG: BEEP
  1130. 51510    PRINT"Printer not available.  Press any key to continue.";
  1131. 51520    L$ = INKEY$ : IF L$ = "" THEN 51520
  1132. 51530    LOCATE ,1: COLOR FG,BG: PRINT TAB(80);
  1133. 51540    LOCATE 3,56: PRINT TAB(80);: LOCATE ,1: RESUME 51170
  1134. 51550  ON ERROR GOTO 0
  1135. 51560  '===================
  1136. 51570  'SUBROUTINE OP_TABLE
  1137. 51580  '===================
  1138. 51590  X = POS(0): Y = CSRLIN: LOCATE 25,1: COLOR BG+16,FG
  1139. 51600  PRINT TAB(30) "*Set-up in progress*" TAB(80);
  1140. 51610  COLOR FG,BG: LOCATE Y,X
  1141. 51620  OPEN "chasm.dat" FOR INPUT AS 3
  1142. 51630  FOR I = 1 TO NUMOP
  1143. 51640    INPUT#3, OPCODE$(I),OPVAL(I),DSTTYPE(I),SRCTYPE(I),OFLAG(I)
  1144. 51650    NEXT I
  1145. 51660  RETURN
  1146.