|
- ; E04-S05: compile hello.n8 and emit a runnable PRG (x128).
- ;
- ; The fixture runs in the compiler mapping, loads HELLO.N8, parses and
- ; type-checks it normally, and reads the single string print captured during
- ; pass 2. It then writes HELLO.PRG with output.s: the standard BASIC stub at
- ; $1C01 and a body at $1C0D that saves CR, selects the D129 mapping ($0E),
- ; prints the captured bytes through CHROUT, restores CR, and returns to BASIC.
- ;
- ; This is a bounded source-to-code proof, not the general statement emitter:
- ; one string print is required and gen_bad rejects anything else.
- ;
- ; Mailbox data: +0 diagnostics, +1 print count, +2 gen_bad, +3 text length,
- ; +4 out_err. FAIL code is the stage: 1 load, 2 diagnostics, 3 unsupported
- ; print, 4 output.
-
- .setcpu "6502"
- .include "../../src/common/c128.inc"
- .include "../../src/common/mailbox.inc"
- .include "../../src/common/formats.inc"
-
- .import mmu_init, mmu_bank0, mmu_shutdown
- .import src_load, src_dos_code, src_kernal_err
- .import names_init
- .import diag_init, diag_finish, diag_screen
- .import parse_file, gen_text, gen_text_len, gen_print_count, gen_bad
- .import out_begin, out_section, out_end_section
- .import out_byte, out_bytes, out_finish, out_abort
- .import out_load, out_entry, out_start, out_err
- .import gen_stub
-
- ; A conditional branch to a far error path: near branch over an absolute JMP.
- .macro ON_CARRY target
- bcc :+
- jmp target
- :
- .endmacro
-
- .segment "LOADADDR"
- .word $1C01
-
- .segment "EXEHDR"
- .word basic_end
- .word 10
- .byte $9E
- .byte "7181"
- .byte $00
- basic_end:
- .word $0000
-
- .segment "MAILBOX"
- .res MB_SIZE
-
- .segment "STARTUP"
- .export test_entry
- test_entry:
- php
- sei
- ldx #MB_SIZE - 1
- lda #$00
- @clr: sta MB_BASE,x
- dex
- bpl @clr
- lda #MB_MAGIC0_VALUE
- sta MB_MAGIC0
- lda #MB_MAGIC1_VALUE
- sta MB_MAGIC1
- lda #MB_PROD_COMPILER
- sta MB_PRODUCER
- lda #MB_ST_RUNNING
- sta MB_STATUS
- lda #$00
- sta MB_DATA
- sta MB_DATA+1
- sta MB_DATA+2
- sta MB_DATA+3
- sta MB_DATA+4
- sta MB_DATA+5
- sta MB_DATA+6
- sta MB_DATA+7
-
- jsr mmu_init
- jsr mmu_bank0
-
- lda #<PRG_LOAD_ADDR
- sta out_load
- lda #>PRG_LOAD_ADDR
- sta out_load+1
- lda #<PRG_ENTRY_ADDR
- sta out_entry
- lda #>PRG_ENTRY_ADDR
- sta out_entry+1
-
- lda #<name_src
- ldx #>name_src
- ldy #name_src_len
- jsr src_load
- cmp #$00
- bne @fail_load
-
- jsr names_init
- lda #<name_src
- ldx #>name_src
- ldy #name_src_len
- jsr diag_init
- lda #$00 ; ERR files only; keep the screen quiet
- sta diag_screen
- jsr parse_file
- jsr diag_finish
- sta diag_count
-
- lda diag_count
- sta MB_DATA+0
- lda gen_print_count
- sta MB_DATA+1
- lda gen_bad
- sta MB_DATA+2
- lda gen_text_len
- sta MB_DATA+3
-
- lda diag_count
- bne @fail_diag
- lda gen_bad
- bne @fail_gen
- lda gen_print_count
- cmp #1
- bne @fail_gen
- lda gen_text_len
- beq @fail_gen
-
- jsr emit_hello
- bcc @ok
- lda emit_err
- sta MB_DATA+4
- lda #4
- jmp @fail
- @ok: lda out_err
- sta MB_DATA+4
- lda #MB_ST_PASS
- sta MB_STATUS
- jmp @done
- @fail_load:
- sta MB_DATA+5 ; src_load result
- lda src_dos_code
- sta MB_DATA+6
- lda src_kernal_err
- sta MB_DATA+7
- lda #1
- jmp @fail
- @fail_diag:
- lda #2
- jmp @fail
- @fail_gen:
- lda #3
- @fail: sta MB_CODE
- lda #$00
- sta MB_CODE+1
- lda #MB_ST_FAIL
- sta MB_STATUS
- @done: jsr mmu_shutdown
- plp
- rts
-
- ; Write HELLO.PRG through output.s. C=1 on any output error.
- emit_hello:
- lda #<name_hello
- ldx #>name_hello
- ldy #name_hello_len
- jsr out_begin
- ON_CARRY @abort
-
- lda #<PRG_LOAD_ADDR ; BASIC stub section
- sta out_start
- lda #>PRG_LOAD_ADDR
- sta out_start+1
- lda #<sec_stub
- ldx #>sec_stub
- ldy #4
- jsr out_section
- ON_CARRY @abort
- lda #<gen_stub
- ldx #>gen_stub
- ldy #PRG_STUB_SIZE
- jsr out_bytes
- ON_CARRY @abort
- jsr out_end_section
- ON_CARRY @abort
-
- lda #<PRG_ENTRY_ADDR ; generated body
- sta out_start
- lda #>PRG_ENTRY_ADDR
- sta out_start+1
- lda #<sec_code
- ldx #>sec_code
- ldy #4
- jsr out_section
- ON_CARRY @abort
- lda #<prologue
- ldx #>prologue
- ldy #prologue_len
- jsr out_bytes
- ON_CARRY @abort
-
- ldy #$00
- @chars: cpy gen_text_len
- beq @epilogue
- sty temp_y
- lda #$A9 ; LDA #char
- jsr out_byte
- ON_CARRY @abort
- ldy temp_y
- lda gen_text,y
- jsr out_byte
- ON_CARRY @abort
- lda #$20 ; JSR $FFD2 (CHROUT)
- jsr out_byte
- ON_CARRY @abort
- lda #$D2
- jsr out_byte
- ON_CARRY @abort
- lda #$FF
- jsr out_byte
- ON_CARRY @abort
- ldy temp_y
- iny
- bne @chars
-
- @epilogue:
- lda #<epilogue
- ldx #>epilogue
- ldy #epilogue_len
- jsr out_bytes
- ON_CARRY @abort
- jsr out_end_section
- ON_CARRY @abort
- jsr out_finish
- ON_CARRY @abort
- clc
- rts
- @abort: lda out_err
- sta emit_err
- jsr out_abort
- sec
- rts
-
- .segment "RODATA"
- name_src: .byte "HELLO.N8"
- name_src_len = * - name_src
- name_hello: .byte "HELLO"
- name_hello_len = * - name_hello
- sec_stub: .byte "STUB"
- sec_code: .byte "CODE"
-
- ; LDA MMU_CR / PHA / LDA #$0E / STA MMU_CR
- prologue:
- .byte $AD, $00, $FF, $48, $A9, $0E, $8D, $00, $FF
- prologue_len = * - prologue
- ; PLA / STA MMU_CR / RTS
- epilogue:
- .byte $68, $8D, $00, $FF, $60
- epilogue_len = * - epilogue
-
- .segment "BSS"
- diag_count: .res 1
- temp_y: .res 1
- emit_err: .res 1
|