You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1055 line
22KB

  1. ; output.s - generated PRG and MAP writer (E04-S01).
  2. ;
  3. ; Container (D128):
  4. ; PRG starts with the load address PRG_LOAD_ADDR, then ordered sections.
  5. ; A gap before a section is filled with zero bytes. The MAP is PETSCII text:
  6. ;
  7. ; NOVA128 MAP 1
  8. ; ENTRY hhhh
  9. ; SECTION name start size
  10. ; CLASS name size destroy interface-count interface-directory
  11. ;
  12. ; API (all calls in the bank-0 compiler state):
  13. ; out_begin A/X = source name (bank 0), Y = length. Sets out_load and
  14. ; out_entry first. Refuses an existing NAME.PRG or NAME.MAP
  15. ; with OUT_ERR_EXISTS; no existing output is overwritten.
  16. ; out_startup Emits the BASIC 7 stub at $1C01 and the startup code at
  17. ; $1C0D from src/runtime/startup.s.
  18. ; out_section A/X = section name, Y = length; out_start = start address.
  19. ; out_byte A = byte; requires an open section.
  20. ; out_bytes A/X = data, Y = count (0-255).
  21. ; out_end_section
  22. ; out_finish Writes the MAP, closes both files, and returns C=0 on success.
  23. ; out_class A/X = class name, Y = length. Adds a deterministic CLASS
  24. ; record from out_class_size/destroy/ifaces/ifdir. Class
  25. ; records follow the SECTION lines in call order.
  26. ; out_abort Closes and scratches only files created by this run.
  27. ;
  28. ; Every failure sets out_err and returns C=1; the caller must call out_abort.
  29. ; DOS/KERNAL errors are OUT_ERR_DISK; the detailed DOS code is not retained.
  30. .setcpu "6502"
  31. .include "../common/c128.inc"
  32. .include "../common/diskio.inc"
  33. .include "../common/formats.inc"
  34. .import dio_open_cmd, dio_open_in, dio_open_out, dio_read_status
  35. .import dio_chkout, dio_putc, dio_clrchn, dio_close, dio_command, dio_dos_code
  36. .import gen_stub, gen_startup, gen_startup_size
  37. .export out_begin, out_startup, out_section, out_end_section
  38. .export out_byte, out_bytes, out_finish, out_abort
  39. .export out_class
  40. .export out_class_size, out_class_destroy, out_class_ifaces, out_class_ifdir
  41. .export out_load, out_entry, out_start, out_err
  42. .segment "ZEROPAGE"
  43. out_dst: .res 2
  44. out_srcp: .res 2
  45. out_rec_ptr: .res 2
  46. .segment "CODE"
  47. ; Build one name from out_base plus the suffix at out_srcp (out_suffix_len).
  48. ; out_dst is advanced to the end; out_name_len is the total length.
  49. build_name:
  50. ldy #$00
  51. @base: cpy out_base_len
  52. beq @suffix
  53. lda out_base,y
  54. sta (out_dst),y
  55. iny
  56. bne @base
  57. @suffix:
  58. sty out_tmp
  59. clc
  60. lda out_dst
  61. adc out_tmp
  62. sta out_dst
  63. bcc :+
  64. inc out_dst+1
  65. : ldy #$00
  66. @sl: cpy out_suffix_len
  67. beq @done
  68. lda (out_srcp),y
  69. sta (out_dst),y
  70. iny
  71. bne @sl
  72. @done: lda out_base_len
  73. clc
  74. adc out_suffix_len
  75. sta out_name_len
  76. rts
  77. .macro MAKE_NAME dst, suffix, slen, lenvar
  78. lda #<dst
  79. sta out_dst
  80. lda #>dst
  81. sta out_dst+1
  82. lda #<suffix
  83. sta out_srcp
  84. lda #>suffix
  85. sta out_srcp+1
  86. lda #slen
  87. sta out_suffix_len
  88. jsr build_name
  89. lda out_name_len
  90. sta lenvar
  91. .endmacro
  92. ; Append out_append_len bytes from out_srcp to out_dst.
  93. append_bytes:
  94. ldy #$00
  95. @loop: cpy out_append_len
  96. beq @done
  97. lda (out_srcp),y
  98. sta (out_dst),y
  99. iny
  100. bne @loop
  101. @done: tya
  102. clc
  103. adc out_dst
  104. sta out_dst
  105. bcc :+
  106. inc out_dst+1
  107. : rts
  108. ; out_rec_ptr = out_sections + out_index * OUT_RECORD_SIZE.
  109. set_rec_ptr:
  110. lda #<out_sections
  111. sta out_rec_ptr
  112. lda #>out_sections
  113. sta out_rec_ptr+1
  114. ldx out_index
  115. beq @done
  116. @add: clc
  117. lda out_rec_ptr
  118. adc #OUT_RECORD_SIZE
  119. sta out_rec_ptr
  120. bcc :+
  121. inc out_rec_ptr+1
  122. : dex
  123. bne @add
  124. @done: rts
  125. ; out_rec_ptr = out_classes + out_index * OUT_CLASS_RECORD_SIZE.
  126. set_class_ptr:
  127. lda #<out_classes
  128. sta out_rec_ptr
  129. lda #>out_classes
  130. sta out_rec_ptr+1
  131. ldx out_index
  132. beq @done
  133. @add: clc
  134. lda out_rec_ptr
  135. adc #OUT_CLASS_RECORD_SIZE
  136. sta out_rec_ptr
  137. bcc :+
  138. inc out_rec_ptr+1
  139. : dex
  140. bne @add
  141. @done: rts
  142. ; Build and send "S0:name" on the command channel.
  143. out_scratch:
  144. sta out_scratch_ptr
  145. stx out_scratch_ptr+1
  146. sty out_scratch_len
  147. lda #<out_cmd
  148. sta out_dst
  149. lda #>out_cmd
  150. sta out_dst+1
  151. lda #<scratch_prefix
  152. sta out_srcp
  153. lda #>scratch_prefix
  154. sta out_srcp+1
  155. lda #3
  156. sta out_append_len
  157. jsr append_bytes
  158. lda out_scratch_ptr
  159. sta out_srcp
  160. lda out_scratch_ptr+1
  161. sta out_srcp+1
  162. lda out_scratch_len
  163. sta out_append_len
  164. jsr append_bytes
  165. lda out_scratch_len
  166. clc
  167. adc #3
  168. sta out_cmd_len
  169. lda #<out_cmd
  170. ldx #>out_cmd
  171. ldy out_cmd_len
  172. jsr dio_command
  173. bcs @disk
  174. lda dio_dos_code
  175. cmp #20
  176. bcc @ok
  177. cmp #62 ; already absent is harmless
  178. beq @ok
  179. @disk: lda #OUT_ERR_DISK
  180. sta out_err
  181. sec
  182. rts
  183. @ok: clc
  184. rts
  185. ; Test A/X name, length Y. C=1 if it exists (out_err=0) or the drive failed
  186. ; (out_err=OUT_ERR_DISK); C=0 if it does not exist.
  187. out_exists:
  188. jsr dio_open_in
  189. bcs @disk
  190. jsr dio_read_status
  191. bcs @disk
  192. lda dio_dos_code
  193. cmp #62
  194. beq @absent
  195. cmp #20
  196. bcs @disk
  197. lda #DIO_LFN_IN
  198. jsr dio_close
  199. lda #OUT_OK
  200. sta out_err
  201. sec
  202. rts
  203. @absent:
  204. lda #DIO_LFN_IN
  205. jsr dio_close
  206. lda #OUT_OK
  207. sta out_err
  208. clc
  209. rts
  210. @disk:
  211. lda #DIO_LFN_IN
  212. jsr dio_close
  213. lda #OUT_ERR_DISK
  214. sta out_err
  215. sec
  216. rts
  217. out_begin:
  218. sta out_srcp
  219. stx out_srcp+1
  220. sty out_name_len
  221. lda #$00
  222. sta out_count
  223. sta out_class_count
  224. sta out_in_section
  225. sta out_prg_created
  226. sta out_map_created
  227. sta out_cmd_open
  228. sta out_prg_is_open
  229. sta out_map_is_open
  230. sta out_err
  231. lda out_load
  232. sta out_current
  233. lda out_load+1
  234. sta out_current+1
  235. lda out_name_len
  236. sta out_base_len
  237. cmp #4
  238. bcc @base_ready
  239. ldy out_name_len
  240. dey
  241. lda (out_srcp),y
  242. cmp #'8'
  243. bne @base_ready
  244. dey
  245. lda (out_srcp),y
  246. and #$7F
  247. cmp #'N'
  248. bne @base_ready
  249. dey
  250. lda (out_srcp),y
  251. cmp #'.'
  252. bne @base_ready
  253. lda out_name_len
  254. sec
  255. sbc #3
  256. sta out_base_len
  257. @base_ready:
  258. lda out_base_len
  259. bne @have_base
  260. jmp @bad_name
  261. @have_base:
  262. cmp #13
  263. bcc @base_ok
  264. jmp @bad_name
  265. @base_ok:
  266. ldy #$00
  267. @copy: cpy out_base_len
  268. beq @copied
  269. lda (out_srcp),y
  270. sta out_base,y
  271. iny
  272. bne @copy
  273. @copied:
  274. MAKE_NAME out_prg_name, sfx_prg, 4, out_prg_len
  275. MAKE_NAME out_map_name, sfx_map, 4, out_map_len
  276. MAKE_NAME out_prg_open, sfx_prg_open, 8, out_prg_open_len
  277. MAKE_NAME out_map_open, sfx_map_open, 8, out_map_open_len
  278. MAKE_NAME out_prg_read, sfx_prg_read, 8, out_prg_read_len
  279. MAKE_NAME out_map_read, sfx_map_read, 8, out_map_read_len
  280. jsr dio_open_cmd
  281. bcc :+
  282. jmp @disk_fail
  283. :
  284. lda #1
  285. sta out_cmd_open
  286. lda #<out_prg_read
  287. ldx #>out_prg_read
  288. ldy out_prg_read_len
  289. jsr out_exists
  290. bcc @check_map
  291. lda out_err
  292. bne @close_fail
  293. jmp @exists
  294. @check_map:
  295. lda #<out_map_read
  296. ldx #>out_map_read
  297. ldy out_map_read_len
  298. jsr out_exists
  299. bcc @open_prg
  300. lda out_err
  301. bne @close_fail
  302. jmp @exists
  303. @exists:
  304. lda #OUT_ERR_EXISTS
  305. sta out_err
  306. jmp @close_fail
  307. @open_prg:
  308. lda #1
  309. sta out_prg_is_open
  310. sta out_prg_created
  311. lda #<out_prg_open
  312. ldx #>out_prg_open
  313. ldy out_prg_open_len
  314. jsr dio_open_out
  315. bcs @fail_created
  316. jsr dio_read_status
  317. bcs @fail_created
  318. lda dio_dos_code
  319. cmp #20
  320. bcs @fail_created
  321. ldx #DIO_LFN_ERR
  322. jsr dio_chkout
  323. bcs @fail_created
  324. lda out_load
  325. jsr out_put
  326. bcs @fail_created
  327. lda out_load+1
  328. jsr out_put
  329. bcs @fail_created
  330. lda out_load ; the header is not part of section 0
  331. sta out_current
  332. lda out_load+1
  333. sta out_current+1
  334. clc
  335. rts
  336. @bad_name:
  337. lda #OUT_ERR_NAME
  338. sta out_err
  339. sec
  340. rts
  341. @disk_fail:
  342. lda #OUT_ERR_DISK
  343. sta out_err
  344. sec
  345. rts
  346. @close_fail:
  347. jsr out_close_cmd
  348. sec
  349. rts
  350. @fail_created:
  351. lda #OUT_ERR_DISK
  352. sta out_err
  353. jsr out_cleanup
  354. sec
  355. rts
  356. out_startup:
  357. lda #<PRG_LOAD_ADDR
  358. sta out_start
  359. lda #>PRG_LOAD_ADDR
  360. sta out_start+1
  361. lda #<stub_name
  362. ldx #>stub_name
  363. ldy #4
  364. jsr out_section
  365. bcs @out
  366. lda #<gen_stub
  367. ldx #>gen_stub
  368. ldy #PRG_STUB_SIZE
  369. jsr out_bytes
  370. bcs @out
  371. jsr out_end_section
  372. lda #<PRG_ENTRY_ADDR
  373. sta out_start
  374. lda #>PRG_ENTRY_ADDR
  375. sta out_start+1
  376. lda #<start_name
  377. ldx #>start_name
  378. ldy #5
  379. jsr out_section
  380. bcs @out
  381. lda #<gen_startup
  382. ldx #>gen_startup
  383. ldy #<gen_startup_size
  384. jsr out_bytes
  385. bcs @out
  386. jmp out_end_section
  387. @out: rts
  388. out_section:
  389. sta out_tmp
  390. stx out_tmp+1
  391. sty out_tmp_len
  392. lda out_in_section
  393. beq @no_prev
  394. jsr out_end_section
  395. @no_prev:
  396. lda out_count
  397. cmp #OUT_MAX_SECTIONS
  398. bcs @too_many
  399. lda out_tmp_len
  400. cmp #OUT_SECTION_NAME_MAX + 1
  401. bcs @bad_name
  402. lda out_count
  403. sta out_index
  404. jsr set_rec_ptr
  405. ldy #0
  406. lda out_tmp
  407. sta (out_rec_ptr),y
  408. iny
  409. lda out_tmp+1
  410. sta (out_rec_ptr),y
  411. iny
  412. lda out_tmp_len
  413. sta (out_rec_ptr),y
  414. iny
  415. lda out_start
  416. sta (out_rec_ptr),y
  417. iny
  418. lda out_start+1
  419. sta (out_rec_ptr),y
  420. iny
  421. lda #$00
  422. sta (out_rec_ptr),y
  423. iny
  424. sta (out_rec_ptr),y
  425. lda out_current+1
  426. cmp out_start+1
  427. bcc @pad
  428. bne @order
  429. lda out_current
  430. cmp out_start
  431. bcc @pad
  432. bne @order
  433. beq @at_start
  434. @pad: lda out_current+1
  435. cmp out_start+1
  436. bcc @pad_byte
  437. bne @at_start
  438. lda out_current
  439. cmp out_start
  440. bcs @at_start
  441. @pad_byte:
  442. lda #$00
  443. jsr out_put
  444. bcs @out
  445. jmp @pad
  446. @at_start:
  447. lda #1
  448. sta out_in_section
  449. inc out_count
  450. clc
  451. rts
  452. @order:
  453. lda #OUT_ERR_ORDER
  454. sta out_err
  455. sec
  456. rts
  457. @too_many:
  458. lda #OUT_ERR_SECTIONS
  459. sta out_err
  460. sec
  461. rts
  462. @bad_name:
  463. lda #OUT_ERR_NAME
  464. sta out_err
  465. sec
  466. @out: rts
  467. out_end_section:
  468. lda out_in_section
  469. beq @ok
  470. ldy #5
  471. lda out_current
  472. sec
  473. sbc out_start
  474. sta (out_rec_ptr),y
  475. iny
  476. lda out_current+1
  477. sbc out_start+1
  478. sta (out_rec_ptr),y
  479. lda #$00
  480. sta out_in_section
  481. @ok: clc
  482. rts
  483. out_byte:
  484. sta out_byte_value
  485. lda out_in_section
  486. bne @write
  487. lda #OUT_ERR_STATE
  488. sta out_err
  489. sec
  490. rts
  491. @write: lda out_byte_value
  492. jmp out_put
  493. ; A = byte, no section check. Preserves Y; C=1 on write failure.
  494. out_put:
  495. sty out_y
  496. jsr dio_putc
  497. bcs @fail
  498. inc out_current
  499. bne @ok
  500. inc out_current+1
  501. @ok: ldy out_y
  502. clc
  503. rts
  504. @fail:
  505. lda #OUT_ERR_DISK
  506. sta out_err
  507. ldy out_y
  508. sec
  509. rts
  510. out_bytes:
  511. sta out_srcp
  512. stx out_srcp+1
  513. sty out_append_len
  514. ldy #$00
  515. @loop: cpy out_append_len
  516. beq @done
  517. lda (out_srcp),y
  518. sty out_y
  519. jsr out_byte
  520. bcs @out
  521. ldy out_y
  522. iny
  523. bne @loop
  524. @done: clc
  525. @out: rts
  526. ; A/X = class name, Y = length. The descriptor values are supplied in the
  527. ; exported out_class_* variables. C=1 sets out_err and adds no record.
  528. out_class:
  529. sta out_tmp
  530. stx out_tmp+1
  531. sty out_tmp_len
  532. lda out_class_count
  533. cmp #OUT_MAX_CLASSES
  534. bcs @too_many
  535. lda out_tmp_len
  536. cmp #OUT_SECTION_NAME_MAX + 1
  537. bcs @bad_name
  538. lda out_class_count
  539. sta out_index
  540. jsr set_class_ptr
  541. ldy #0
  542. lda out_tmp
  543. sta (out_rec_ptr),y
  544. iny
  545. lda out_tmp+1
  546. sta (out_rec_ptr),y
  547. iny
  548. lda out_tmp_len
  549. sta (out_rec_ptr),y
  550. iny
  551. lda out_class_size
  552. sta (out_rec_ptr),y
  553. iny
  554. lda out_class_size+1
  555. sta (out_rec_ptr),y
  556. iny
  557. lda out_class_destroy
  558. sta (out_rec_ptr),y
  559. iny
  560. lda out_class_destroy+1
  561. sta (out_rec_ptr),y
  562. iny
  563. lda out_class_ifaces
  564. sta (out_rec_ptr),y
  565. iny
  566. lda out_class_ifdir
  567. sta (out_rec_ptr),y
  568. iny
  569. lda out_class_ifdir+1
  570. sta (out_rec_ptr),y
  571. inc out_class_count
  572. clc
  573. rts
  574. @too_many:
  575. lda #OUT_ERR_CLASSES
  576. sta out_err
  577. sec
  578. rts
  579. @bad_name:
  580. lda #OUT_ERR_NAME
  581. sta out_err
  582. sec
  583. rts
  584. out_finish:
  585. jsr out_end_section
  586. jsr out_close_prg
  587. lda #1
  588. sta out_map_is_open
  589. sta out_map_created
  590. lda #<out_map_open
  591. ldx #>out_map_open
  592. ldy out_map_open_len
  593. jsr dio_open_out
  594. bcs @fail
  595. jsr dio_read_status
  596. bcs @fail
  597. lda dio_dos_code
  598. cmp #20
  599. bcs @fail
  600. ldx #DIO_LFN_ERR
  601. jsr dio_chkout
  602. bcs @fail
  603. jsr out_write_map
  604. bcs @fail
  605. jsr out_close_map
  606. jsr out_close_cmd
  607. lda #OUT_OK
  608. sta out_err
  609. lda #$00
  610. sta out_prg_created
  611. sta out_map_created
  612. clc
  613. rts
  614. @fail:
  615. lda out_err
  616. bne :+
  617. lda #OUT_ERR_DISK
  618. sta out_err
  619. : jsr out_cleanup
  620. sec
  621. rts
  622. out_abort:
  623. lda #OUT_OK
  624. sta out_err
  625. jsr out_cleanup
  626. lda out_err
  627. beq @ok
  628. sec
  629. rts
  630. @ok: clc
  631. rts
  632. ; Close created outputs and scratch only files this run created.
  633. out_cleanup:
  634. jsr out_close_prg
  635. jsr out_close_map
  636. lda out_cmd_open
  637. bne @have_cmd
  638. jsr dio_open_cmd
  639. bcs @done
  640. lda #1
  641. sta out_cmd_open
  642. @have_cmd:
  643. lda out_prg_created
  644. beq @map
  645. lda #<out_prg_name
  646. ldx #>out_prg_name
  647. ldy out_prg_len
  648. jsr out_scratch
  649. @map: lda out_map_created
  650. beq @close
  651. lda #<out_map_name
  652. ldx #>out_map_name
  653. ldy out_map_len
  654. jsr out_scratch
  655. @close:
  656. jsr out_close_cmd
  657. @done:
  658. lda #$00
  659. sta out_prg_created
  660. sta out_map_created
  661. rts
  662. out_close_prg:
  663. lda out_prg_is_open
  664. beq @ok
  665. jsr dio_clrchn
  666. lda #DIO_LFN_ERR
  667. jsr dio_close
  668. lda #$00
  669. sta out_prg_is_open
  670. @ok: clc
  671. rts
  672. out_close_map:
  673. lda out_map_is_open
  674. beq @ok
  675. jsr dio_clrchn
  676. lda #DIO_LFN_ERR
  677. jsr dio_close
  678. lda #$00
  679. sta out_map_is_open
  680. @ok: clc
  681. rts
  682. out_close_cmd:
  683. lda out_cmd_open
  684. beq @ok
  685. lda #DIO_LFN_CMD
  686. jsr dio_close
  687. lda #$00
  688. sta out_cmd_open
  689. @ok: clc
  690. rts
  691. ; ---------------------------------------------------------------- MAP text
  692. out_write_map:
  693. lda #<map_header
  694. ldx #>map_header
  695. ldy #map_header_len
  696. jsr out_text
  697. bcc :+
  698. jmp @out
  699. :
  700. lda #<map_entry
  701. ldx #>map_entry
  702. ldy #map_entry_len
  703. jsr out_text
  704. bcc :+
  705. jmp @out
  706. :
  707. lda out_entry
  708. sta out_num
  709. lda out_entry+1
  710. sta out_num+1
  711. jsr out_hex4
  712. bcc :+
  713. jmp @out
  714. :
  715. jsr out_cr
  716. bcc :+
  717. jmp @out
  718. :
  719. lda #$00
  720. sta out_index
  721. @section:
  722. lda out_index
  723. cmp out_count
  724. beq @done
  725. jsr set_rec_ptr
  726. lda #<section_prefix
  727. ldx #>section_prefix
  728. ldy #section_prefix_len
  729. jsr out_text
  730. bcs @out
  731. ldy #0
  732. lda (out_rec_ptr),y
  733. sta out_srcp
  734. iny
  735. lda (out_rec_ptr),y
  736. sta out_srcp+1
  737. iny
  738. lda (out_rec_ptr),y
  739. sta out_text_len
  740. ldy #0
  741. @name: cpy out_text_len
  742. beq @named
  743. lda (out_srcp),y
  744. sty out_y
  745. jsr out_char
  746. bcs @out
  747. ldy out_y
  748. iny
  749. bne @name
  750. @named:
  751. lda #' '
  752. jsr out_char
  753. bcs @out
  754. ldy #3
  755. lda (out_rec_ptr),y
  756. sta out_num
  757. iny
  758. lda (out_rec_ptr),y
  759. sta out_num+1
  760. jsr out_hex4
  761. bcs @out
  762. lda #' '
  763. jsr out_char
  764. bcs @out
  765. ldy #5
  766. lda (out_rec_ptr),y
  767. sta out_num
  768. iny
  769. lda (out_rec_ptr),y
  770. sta out_num+1
  771. jsr out_hex4
  772. bcs @out
  773. jsr out_cr
  774. bcs @out
  775. inc out_index
  776. jmp @section
  777. @done: jsr out_write_classes
  778. bcs @out
  779. clc
  780. @out: rts
  781. ; Write CLASS records after the SECTION records, in out_class call order.
  782. out_write_classes:
  783. lda #$00
  784. sta out_index
  785. @class:
  786. lda out_index
  787. cmp out_class_count
  788. bne @body
  789. jmp @done
  790. @body:
  791. jsr set_class_ptr
  792. lda #<class_prefix
  793. ldx #>class_prefix
  794. ldy #class_prefix_len
  795. jsr out_text
  796. bcc @prefix_ok
  797. jmp @out
  798. @prefix_ok:
  799. ldy #0
  800. lda (out_rec_ptr),y
  801. sta out_srcp
  802. iny
  803. lda (out_rec_ptr),y
  804. sta out_srcp+1
  805. iny
  806. lda (out_rec_ptr),y
  807. sta out_text_len
  808. ldy #0
  809. @name: cpy out_text_len
  810. beq @named
  811. lda (out_srcp),y
  812. sty out_y
  813. jsr out_char
  814. bcc @name_ok
  815. jmp @out
  816. @name_ok:
  817. ldy out_y
  818. iny
  819. bne @name
  820. @named:
  821. lda #' '
  822. jsr out_char
  823. bcc @space1
  824. jmp @out
  825. @space1:
  826. ldy #3
  827. lda (out_rec_ptr),y
  828. sta out_num
  829. iny
  830. lda (out_rec_ptr),y
  831. sta out_num+1
  832. jsr out_hex4
  833. bcc @size_ok
  834. jmp @out
  835. @size_ok:
  836. lda #' '
  837. jsr out_char
  838. bcc @space2
  839. jmp @out
  840. @space2:
  841. ldy #5
  842. lda (out_rec_ptr),y
  843. sta out_num
  844. iny
  845. lda (out_rec_ptr),y
  846. sta out_num+1
  847. jsr out_hex4
  848. bcc @destroy_ok
  849. jmp @out
  850. @destroy_ok:
  851. lda #' '
  852. jsr out_char
  853. bcc @space3
  854. jmp @out
  855. @space3:
  856. ldy #7
  857. lda (out_rec_ptr),y
  858. jsr out_hex_byte
  859. bcc @count_ok
  860. jmp @out
  861. @count_ok:
  862. lda #' '
  863. jsr out_char
  864. bcc @space4
  865. jmp @out
  866. @space4:
  867. ldy #8
  868. lda (out_rec_ptr),y
  869. sta out_num
  870. iny
  871. lda (out_rec_ptr),y
  872. sta out_num+1
  873. jsr out_hex4
  874. bcc @dir_ok
  875. jmp @out
  876. @dir_ok:
  877. jsr out_cr
  878. bcc @line_ok
  879. jmp @out
  880. @line_ok:
  881. inc out_index
  882. jmp @class
  883. @done: clc
  884. @out: rts
  885. ; A/X = text, Y = length.
  886. out_text:
  887. sta out_srcp
  888. stx out_srcp+1
  889. sty out_text_len
  890. ldy #$00
  891. @loop: cpy out_text_len
  892. beq @done
  893. lda (out_srcp),y
  894. sty out_y
  895. jsr out_char
  896. bcs @out
  897. ldy out_y
  898. iny
  899. bne @loop
  900. @done: clc
  901. @out: rts
  902. out_cr:
  903. lda #$0D
  904. jmp out_char
  905. out_char:
  906. sty out_y
  907. jsr dio_putc
  908. bcs @fail
  909. ldy out_y
  910. clc
  911. rts
  912. @fail:
  913. lda #OUT_ERR_DISK
  914. sta out_err
  915. ldy out_y
  916. sec
  917. rts
  918. out_hex4:
  919. lda out_num+1
  920. jsr out_hex_byte
  921. bcs @out
  922. lda out_num
  923. jmp out_hex_byte
  924. @out: rts
  925. out_hex_byte:
  926. pha
  927. lsr a
  928. lsr a
  929. lsr a
  930. lsr a
  931. tax
  932. lda hex_digits,x
  933. jsr out_char
  934. bcs @fail
  935. pla
  936. and #$0F
  937. tax
  938. lda hex_digits,x
  939. jmp out_char
  940. @fail: pla
  941. sec
  942. rts
  943. .segment "RODATA"
  944. sfx_prg: .byte ".PRG"
  945. sfx_map: .byte ".MAP"
  946. sfx_prg_open: .byte ".PRG,P,W"
  947. sfx_map_open: .byte ".MAP,S,W"
  948. sfx_prg_read: .byte ".PRG,P,R"
  949. sfx_map_read: .byte ".MAP,S,R"
  950. stub_name: .byte "STUB"
  951. start_name: .byte "START"
  952. scratch_prefix: .byte "S0:"
  953. map_header: .byte "NOVA128 MAP 1", $0D
  954. map_header_len = * - map_header
  955. map_entry: .byte "ENTRY "
  956. map_entry_len = * - map_entry
  957. section_prefix: .byte "SECTION "
  958. section_prefix_len = * - section_prefix
  959. class_prefix: .byte "CLASS "
  960. class_prefix_len = * - class_prefix
  961. hex_digits: .byte "0123456789ABCDEF"
  962. .segment "BSS"
  963. out_base: .res 12
  964. out_base_len: .res 1
  965. out_name_len: .res 1
  966. out_suffix_len: .res 1
  967. out_prg_name: .res 16
  968. out_prg_len: .res 1
  969. out_map_name: .res 16
  970. out_map_len: .res 1
  971. out_prg_open: .res 20
  972. out_prg_open_len: .res 1
  973. out_map_open: .res 20
  974. out_map_open_len: .res 1
  975. out_prg_read: .res 20
  976. out_prg_read_len: .res 1
  977. out_map_read: .res 20
  978. out_map_read_len: .res 1
  979. out_cmd: .res 48
  980. out_cmd_len: .res 1
  981. out_load: .res 2
  982. out_entry: .res 2
  983. out_start: .res 2
  984. out_current: .res 2
  985. out_count: .res 1
  986. out_class_count: .res 1
  987. out_index: .res 1
  988. out_in_section: .res 1
  989. out_prg_created: .res 1
  990. out_map_created: .res 1
  991. out_cmd_open: .res 1
  992. out_prg_is_open: .res 1
  993. out_map_is_open: .res 1
  994. out_err: .res 1
  995. out_sections: .res OUT_MAX_SECTIONS * OUT_RECORD_SIZE
  996. out_classes: .res OUT_MAX_CLASSES * OUT_CLASS_RECORD_SIZE
  997. out_class_size: .res 2
  998. out_class_destroy: .res 2
  999. out_class_ifaces: .res 1
  1000. out_class_ifdir: .res 2
  1001. out_tmp: .res 2
  1002. out_tmp_len: .res 1
  1003. out_scratch_ptr: .res 2
  1004. out_scratch_len: .res 1
  1005. out_append_len: .res 1
  1006. out_byte_value: .res 1
  1007. out_text_len: .res 1
  1008. out_y: .res 1
  1009. out_num: .res 2

Powered by TurnKey Linux.