1
0
mirror of https://github.com/cc65/cc65.git synced 2024-10-01 00:57:11 +00:00

Added check/support for simple addressing format.

Check the operating system option and return the module id to the caller.
Use bzero instead of memset.


git-svn-id: svn://svn.cc65.org/cc65/trunk@1278 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2002-05-18 21:38:01 +00:00
parent 009df2d6b5
commit 9364b206ab

View File

@ -37,7 +37,7 @@
.include "modload.inc" .include "modload.inc"
.import pushax, pusha0, push0, push1, decax1 .import pushax, pusha0, push0, push1, decax1
.import _malloc, _free, _memset .import _malloc, _free, _bzero
.import __ZP_START__ ; Linker generated .import __ZP_START__ ; Linker generated
.importzp sp, ptr1, tmp1, regbank .importzp sp, ptr1, tmp1, regbank
@ -68,21 +68,16 @@ Header: .res O65_HDR_SIZE ; The o65 header
; Input ; Input
InputByte = Header ; Byte read from input InputByte = Header ; Byte read from input
; Segment addresses. Since the ld65 linker uses a relocation base address
; of zero for all segments, the addresses of the segments are also the
; relocation values.
CodeAddr = Module ; Address of code seg
DataAddr = Header + 1 ; Address of data seg
BssAddr = Header + 3 ; Address of bss seg
.data .data
Read: jmp $FFFF ; Jump to read routine Read: jmp $FFFF ; Jump to read routine
.rodata .rodata
ExpectedHdr: .byte $01, $00 ; non C64 marker ExpectedHdr:
.byte $01, $00 ; non C64 marker
.byte $6F, $36, $35 ; Magic ("o65") .byte $6F, $36, $35 ; Magic ("o65")
.byte $00 ; Version .byte $00 ; Version
.word $0000 ; Mode word .word O65_CPU_6502|O65_RELOC_BYTE|O65_SIZE_16BIT|O65_FTYPE_EXE|O65_ADDR_SIMPLE|O65_ALIGN_1
ExpectedHdrSize = * - ExpectedHdr ExpectedHdrSize = * - ExpectedHdr
@ -109,37 +104,33 @@ RestoreRegBank:
rts rts
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; GetReloc: Return a relocation value based on the segment in A ; GetReloc: Return a relocation value based on the segment in A.
; The routine uses some knowledge about the values to make the code shorter.
.code .code
GetReloc: GetReloc:
cmp #O65_SEGID_TEXT cmp #O65_SEGID_TEXT
bne @L1 bcc FormatError
lda CodeAddr cmp #O65_SEGID_ZP
ldx CodeAddr+1 beq @L1
bcs FormatError
; Text, data and bss segment
lda Module
ldx Module+1 ; Return start address of buffer
rts rts
@L1: cmp #O65_SEGID_DATA ; Zero page relocation
bne @L2
lda DataAddr
ldx DataAddr+1
rts
@L2: cmp #O65_SEGID_BSS @L1: lda #<__ZP_START__
bne @L3
lda BssAddr
ldx BssAddr+1
rts
@L3: cmp #O65_SEGID_ZP
bne FormatError
lda #<__ZP_START__
ldx #>__ZP_START__ ldx #>__ZP_START__
rts rts
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; FormatError: Bail out with an o65 format error ; FormatError: Bail out with an o65 format error
.code
FormatError: FormatError:
lda #MLOAD_ERR_FMT lda #MLOAD_ERR_FMT
; bne CleanupAndExit ; Branch always ; bne CleanupAndExit ; Branch always
@ -271,10 +262,8 @@ Loop: jsr ReadByte ; Read byte from relocation table
RelocLow: RelocLow:
ldy #0 ldy #0
clc clc
lda (TPtr),y lda ptr1
adc ptr1 bcc AddCommon
sta (TPtr),y
jmp Loop
; Relocate a high byte ; Relocate a high byte
@ -283,8 +272,10 @@ RelocHigh:
ldy #0 ldy #0
clc clc
adc ptr1 ; We just need the carry adc ptr1 ; We just need the carry
AddHigh:lda (TPtr),y AddHigh:
adc ptr1+1 lda ptr1+1
AddCommon:
adc (TPtr),y
sta (TPtr),y sta (TPtr),y
jmp Loop ; Done, next entry jmp Loop ; Done, next entry
@ -293,8 +284,8 @@ AddHigh:lda (TPtr),y
RelocWord: RelocWord:
ldy #0 ldy #0
clc clc
lda (TPtr),y lda ptr1
adc ptr1 adc (TPtr),y
sta (TPtr),y sta (TPtr),y
iny iny
bne AddHigh ; Branch always (add high byte) bne AddHigh ; Branch always (add high byte)
@ -350,31 +341,89 @@ _mod_load:
; We read the o65 header successfully. Validate it. ; We read the o65 header successfully. Validate it.
ldy #ExpectedHdrSize-1 ldy #ExpectedHdrSize-1
@L3: lda Header,y ValidateHeader:
lda Header,y
cmp ExpectedHdr,y cmp ExpectedHdr,y
beq @L4 bne HeaderError
lda #MLOAD_ERR_HDR dey
jmp CleanupAndExit bpl ValidateHeader
@L4: dey
bpl @L3
; Header is ok as far as we can say now. Read and skip all options. We may ; Header is ok as far as we can say now. Read all options, check for the
; add a check here for the OS option later. ; OS option and ignore all others. The OS option contains a version number
; and the module id as additional data.
Opt: jsr ReadByte iny ; Y = $00
sty TPtr+1 ; Flag for OS option read
Opt: jsr ReadByte ; Read the length byte
beq OptDone ; Jump if done beq OptDone ; Jump if done
sta TPtr ; Use TPtr as a counter sta TPtr ; Use TPtr as a counter
OneOpt: dec TPtr
; An option has a length of at least 2 bytes
cmp #2
bcc HeaderError ; Must be 2 bytes total at least
; Check for the OS option
dec TPtr
jsr ReadByte ; Get the option type
cmp #O65_OPT_OS ; OS option?
bne SkipOpt ; No: Skip
lda TPtr ; Get remaining length+1
cmp #5 ; CC65 has 6 bytes total
bne OSError
jsr ReadByte ; Get the operating system
cmp #O65_OS_CC65_MODULE
bne OSError ; Wrong operating system
jsr ReadByte ; Get the version number, expect zero
bne OSError ; Wrong version
jsr ReadByte ; Get low byte of id
ldy #MODCTRL_MODULE_ID
sta (Ctrl),y
jsr ReadByte
ldy #MODCTRL_MODULE_ID+1
sta (Ctrl),y
inc TPtr+1 ; Remember that we got the OS
jmp Opt
; Skip one option
SkipOpt:
dec TPtr
beq Opt ; Next option beq Opt ; Next option
jsr ReadByte ; Skip one byte jsr ReadByte ; Skip one byte
jmp OneOpt jmp SkipOpt
; Operating system error
OSError:
lda #MLOAD_ERR_OS
jmp CleanupAndExit
; Options done, check that we got the OS option
OptDone: OptDone:
lda TPtr+1
bne CalcSizes
; Entry point for header errors
HeaderError:
lda #MLOAD_ERR_HDR
jmp CleanupAndExit
; Skipped all options. Calculate the size of text+data and of text+data+bss ; Skipped all options. Calculate the size of text+data and of text+data+bss
; (the latter is the size of the memory block we need). We will store the ; (the latter is the size of the memory block we need). We will store the
; total module size also into the control structure for evaluation by the ; total module size also into the control structure for evaluation by the
; caller ; caller
CalcSizes:
lda Header + O65_HDR_TLEN lda Header + O65_HDR_TLEN
add Header + O65_HDR_DLEN add Header + O65_HDR_DLEN
sta TPtr sta TPtr
@ -393,12 +442,20 @@ OptDone:
tax tax
pla ; Restore low byte of total size pla ; Restore low byte of total size
; Total memory size is now in a/x. Allocate memory, check if we got it. ; Total memory size is now in a/x. Allocate memory and remember the result,
; both, locally and in the control structure so it the caller can access
; the memory block. After that, check if we got the requested memory.
jsr _malloc jsr _malloc
sta Module sta Module
stx Module+1 stx Module+1
ora Module+1
ldy #MODCTRL_MODULE
sta (Ctrl),y
txa
iny
sta (Ctrl),y
ora Module
bne GotMem bne GotMem
; Could not allocate memory ; Could not allocate memory
@ -406,39 +463,26 @@ OptDone:
lda #MLOAD_ERR_MEM lda #MLOAD_ERR_MEM
jmp CleanupAndExit jmp CleanupAndExit
; We got the memory block. Place a pointer to the memory block also in the ; Control structure is complete now. Clear the bss segment.
; module control structure. ; bzero (bss_addr, bss_size)
GotMem: lda Module ; Ctrl->module = Module;
ldy #MODCTRL_MODULE
sta (Ctrl),y
txa
iny
sta (Ctrl),y
; Calculate the start addresses of the segments. Since the linker uses a
; base address of zero for all segments, the load addresses are also the
; relocation values for the segments.
lda Module
add Header + O65_HDR_TLEN
sta DataAddr
lda Module + 1
adc Header + O65_HDR_TLEN + 1
sta DataAddr + 1
lda Module lda Module
add TPtr add TPtr
sta BssAddr pha
lda Module+1 lda Module+1
add TPtr+1 adc TPtr+1 ; Module + tlen + dlen
sta BssAddr + 1 tax
pla
jsr pushax
lda Header + O65_HDR_BLEN
ldx Header + O65_HDR_BLEN+1
jsr _bzero ; bzero (bss, bss_size);
; Control structure is complete now. Load code and data segment into memory. ; Load code and data segment into memory. The sum of the sizes of
; The sum of the sizes of code+data segment is still in TPtr. ; code+data segment is still in TPtr.
; C->read (C, C->module, H.tlen + H.dlen) ; C->read (C, C->module, H.tlen + H.dlen)
jsr PushCtrl GotMem: jsr PushCtrl
lda Module lda Module
ldx Module+1 ldx Module+1
jsr pushax jsr pushax
@ -472,19 +516,9 @@ Reloc: lda Module
lda Module + 1 lda Module + 1
adc Header + O65_HDR_TLEN + 1 adc Header + O65_HDR_TLEN + 1
tax tax
pla ; Date segment address in a/x pla ; Data segment address in a/x
jsr RelocSeg jsr RelocSeg
; Clear the bss segment: memset (bss_addr, 0, bss_size)
lda BssAddr
ldx BssAddr + 1
jsr pushax
jsr push0
lda Header + O65_HDR_BLEN
ldx Header + O65_HDR_BLEN+1
jsr _memset ; memset (bss, 0, bss_size);
; We're done. Restore the register bank and return a success code ; We're done. Restore the register bank and return a success code
jsr RestoreRegBank ; X will be zero on return jsr RestoreRegBank ; X will be zero on return