; The header of the o65 file. Since we don't need the first 8 bytes any
; longer, once we've checked them, we will overlay them with other data to
; save a few bytes.
-Header: .res O65_HDR_SIZE ; The o65 header
+Header: .tag O65_HDR ; The o65 header
; Input
InputByte = Header ; Byte read from input
.rodata
ExpectedHdr:
- .byte $01, $00 ; non C64 marker
- .byte $6F, $36, $35 ; Magic ("o65")
- .byte $00 ; Version
- .word O65_CPU_6502|O65_RELOC_BYTE|O65_SIZE_16BIT|O65_FTYPE_EXE|O65_ADDR_SIMPLE|O65_ALIGN_1
+ .byte O65_MARKER_0, O65_MARKER_1 ; non C64 marker
+ .byte O65_MAGIC_0, O65_MAGIC_1, O65_MAGIC_2 ; Magic ("o65")
+ .byte O65_VERSION ; Version
+ .word O65_MODE_CC65 ; Mode word
ExpectedHdrSize = * - ExpectedHdr
;------------------------------------------------------------------------------
-; PushCtrl: Push the address of the control structure onto the C stack.
+; PushCallerData: Push the callerdata member from control structure onto the
+; C stack.
.code
-PushCtrl:
- lda Ctrl
- ldx Ctrl+1
+PushCallerData:
+ ldy #MOD_CTRL::CALLERDATA+1
+ lda (Ctrl),y
+ tax
+ dey
+ lda (Ctrl),y
jmp pushax
;------------------------------------------------------------------------------
ldx #>__ZP_START__
rts
+;------------------------------------------------------------------------------
+; ReadByte: Read one byte with error checking into InputByte and A.
+; ReadAndCheckError: Call read with the current C stack and check for errors.
+
+.bss
+ReadSize: .res 2
+
+.code
+ReadByte:
+
+; C->read (C->callerdata, &B, 1)
+
+ jsr PushCallerData
+ lda #<InputByte
+ ldx #>InputByte
+ jsr pushax
+ ldx #0
+ lda #1
+
+; This is a second entry point used by the other calls to Read
+
+ReadAndCheckError:
+ sta ReadSize
+ stx ReadSize+1
+ jsr Read
+
+; Check the return code and bail out in case of problems
+
+ cmp ReadSize
+ bne @L1
+ cpx ReadSize+1
+ beq @L2 ; Jump if ok
+@L1: lda #MLOAD_ERR_READ
+ bne CleanupAndExit
+
+; Done
+
+@L2: lda InputByte ; If called ReadByte, load the byte read
+Done: rts
+
;------------------------------------------------------------------------------
; FormatError: Bail out with an o65 format error
; Check if we have to free the allocated block
- lda Module
- ora Module+1
- beq @L1 ; Jump if no memory allocated
-
lda Module
ldx Module+1
- jsr _free ; Free the allocated block
+ bne @L1
+ tay ; Test high byte
+ beq @L2
+@L1: jsr _free ; Free the allocated block
; Restore the register bank
-@L1: jsr RestoreRegBank
+@L2: jsr RestoreRegBank
; Restore the error code and return to the caller
pla
rts
-;------------------------------------------------------------------------------
-; ReadByte: Read one byte with error checking into InputByte and A.
-; ReadAndCheckError: Call read with the current C stack and check for errors.
-
-.code
-ReadByte:
-
-; C->read (C, &B, 1)
-
- jsr PushCtrl
- lda #<InputByte
- ldx #>InputByte
- jsr pushax
- jsr push1
-
-; This is a second entry point used by the other calls to Read
-
-ReadAndCheckError:
- jsr Read
-
-; Check the return code and bail out in case of problems
-
- tax
- beq @L1 ; Jump if ok
- lda #MLOAD_ERR_READ
- bne CleanupAndExit
-
-; Done
-
-@L1: lda InputByte ; If called ReadByte, load the byte read
-Done: rts
-
;------------------------------------------------------------------------------
; RelocSeg: Relocate the segment pointed to by a/x
; Get the read function pointer from the control structure and place it into
; our call vector
- ldy #MODCTRL_READ
+ ldy #MOD_CTRL::READ
lda (Ctrl),y
sta Read+1
iny
lda (Ctrl),y
sta Read+2
-; Read the o65 header: C->read (C, &H, sizeof (H))
+; Read the o65 header: C->read (C->callerdata, &H, sizeof (H))
- jsr PushCtrl
+ jsr PushCallerData
lda #<Header
ldx #>Header
jsr pushax
- lda #O65_HDR_SIZE
- jsr pusha0 ; Always less than 256
+ lda #.sizeof(O65_HDR)
+ ldx #0 ; Always less than 256
jsr ReadAndCheckError ; Bails out in case of errors
; We read the o65 header successfully. Validate it.
bne OSError
jsr ReadByte ; Get the operating system
- cmp #O65_OS_CC65_MODULE
+ cmp #O65_OS_CC65
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
+ ldy #MOD_CTRL::MODULE_ID
sta (Ctrl),y
jsr ReadByte
- ldy #MODCTRL_MODULE_ID+1
+ ldy #MOD_CTRL::MODULE_ID+1
sta (Ctrl),y
inc TPtr+1 ; Remember that we got the OS
; caller
CalcSizes:
- lda Header + O65_HDR_TLEN
- add Header + O65_HDR_DLEN
+ lda Header + O65_HDR::TLEN
+ add Header + O65_HDR::DLEN
sta TPtr
- lda Header + O65_HDR_TLEN + 1
- adc Header + O65_HDR_DLEN + 1
+ lda Header + O65_HDR::TLEN + 1
+ adc Header + O65_HDR::DLEN + 1
sta TPtr+1
lda TPtr
- add Header + O65_HDR_BLEN
+ add Header + O65_HDR::BLEN
pha ; Save low byte of total size
- ldy #MODCTRL_MODULE_SIZE
+ ldy #MOD_CTRL::MODULE_SIZE
sta (Ctrl),y
lda TPtr+1
- adc Header + O65_HDR_BLEN + 1
+ adc Header + O65_HDR::BLEN + 1
iny
sta (Ctrl),y
tax
sta Module
stx Module+1
- ldy #MODCTRL_MODULE
+ ldy #MOD_CTRL::MODULE
sta (Ctrl),y
txa
iny
tax
pla
jsr pushax
- lda Header + O65_HDR_BLEN
- ldx Header + O65_HDR_BLEN+1
+ lda Header + O65_HDR::BLEN
+ ldx Header + O65_HDR::BLEN+1
jsr _bzero ; bzero (bss, bss_size);
; Load code and data segment into memory. The sum of the sizes of
; code+data segment is still in TPtr.
-; C->read (C, C->module, H.tlen + H.dlen)
+; C->read (C->callerdata, C->module, H.tlen + H.dlen)
- jsr PushCtrl
+ jsr PushCallerData
lda Module
ldx Module+1
jsr pushax
lda TPtr
ldx TPtr+1
- jsr pushax
jsr ReadAndCheckError ; Bails out in case of errors
; We've got the code and data segments in memory. Next section contains
; Relocate the data segment
lda Module
- add Header + O65_HDR_TLEN
+ add Header + O65_HDR::TLEN
pha
lda Module + 1
- adc Header + O65_HDR_TLEN + 1
+ adc Header + O65_HDR::TLEN + 1
tax
pla ; Data segment address in a/x
jsr RelocSeg