]> git.sur5r.net Git - cc65/commitdiff
support for loading modules in GEOS, VDC memory driver for GEOS
authorizydorst <izydorst@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Wed, 25 Dec 2002 18:42:42 +0000 (18:42 +0000)
committerizydorst <izydorst@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Wed, 25 Dec 2002 18:42:42 +0000 (18:42 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@1845 b7a2c559-68d2-44c3-8de9-860c34a00d81

libsrc/Makefile
libsrc/geos/devel/Makefile
libsrc/geos/devel/fio_module.s [new file with mode: 0644]
libsrc/geos/devel/geos-vdc.s [new file with mode: 0644]

index 17f0383dc9c01734c4f9b354fb92d65f02b74cfb..39a209db09af62a0632e90477a22221bac005ea9 100644 (file)
@@ -190,7 +190,7 @@ geoslib:
        AFLAGS="-t geos -I../../../asminc" \
        CFLAGS="-Osir -g -T -t geos -I../../../include" \
        $(MAKE) -C geos || exit 1
-       for i in common runtime; do \
+       for i in em common runtime; do \
            CC=$(CC) \
            AS=$(AS) \
            LD=$(LD) \
@@ -206,6 +206,7 @@ geoslib:
                fi; \
            done \
        done
+       cp geos/devel/*.emd .
 
 #-----------------------------------------------------------------------------
 # CBM PET machines
index b4675cca27c5e7dcb39a3a095e0fbaca4bbcdb46..51d21eaa93f1ba86ad514a96570ea8e4c610adfb 100644 (file)
@@ -7,10 +7,27 @@
 %.o:   %.s
        @$(AS) -o $@ $(AFLAGS) $<
 
+%.emd: %.o ../../runtime/zeropage.o
+       @$(LD) -t module -o $@ $^
 
-S_OBJS = crt0.o oserrlist.o oserror.o randomize.o
+%.joy: %.o ../../runtime/zeropage.o
+       @$(LD) -t module -o $@ $^
 
-all: $(S_OBJS)
+%.tgi: %.o ../../runtime/zeropage.o
+       @$(LD) -t module -o $@ $^
+
+S_OBJS = crt0.o oserror.o oserrlist.o randomize.o fio_module.o
+
+#--------------------------------------------------------------------------
+# Drivers
+
+EMDS = geos-vdc.emd
+
+JOYS =
+
+TGIS =
+
+all: $(S_OBJS) $(EMDS) $(JOYS) $(TGIS)
 
 clean:
-       @rm -f *.~ $(S_OBJS) core
+       @rm -f *.~ core $(S_OBJS) $(EMDS:.emd=.o) $(JOYS:.joy=.o) $(TGIS:.tgi=.o)
diff --git a/libsrc/geos/devel/fio_module.s b/libsrc/geos/devel/fio_module.s
new file mode 100644 (file)
index 0000000..dca3497
--- /dev/null
@@ -0,0 +1,184 @@
+;
+; Low level file I/O routines, ONLY for module loading OR sth similar
+;
+; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
+; 25.12.2002
+;
+; only ONE opened file at a time, only O_RDONLY flag
+
+; int open (const char* name, int flags, ...); /* May take a mode argument */
+; int __fastcall__ close (int fd);
+; int __fastcall__ read (int fd, void* buf, unsigned count);
+
+FILEDES        = 3     ; first free to use file descriptor
+
+       .include        "../inc/geossym.inc"
+       .include        "../inc/const.inc"
+       .include        "fcntl.inc"
+
+        .importzp       ptr1, ptr2, ptr3, tmp1
+        .import         addysp, popax
+        .import         __oserror
+       .import         _FindFile, _ReadByte
+
+       .export         _open, _close, _read
+
+
+;--------------------------------------------------------------------------
+; _open
+
+_open:
+
+       cpy     #4              ; correct # of arguments (bytes)?
+       beq     @parmok         ; parameter count ok
+       tya                     ; parm count < 4 shouldn't be needed to be...
+               sec                     ; ...checked (it generates a c compiler warning)
+       sbc     #4
+       tay
+       jsr     addysp          ; fix stack, throw away unused parameters
+
+; Parameters ok. Pop the flags and save them into tmp3
+
+@parmok:
+       jsr     popax           ; Get flags
+       sta     tmp1
+        jsr     popax           ; Get name
+       sta     ptr1
+       stx     ptr1+1
+
+       lda     filedesc        ; is there a file already open?
+       bne     @alreadyopen
+
+       lda     tmp1            ; check open mode
+       and     #(O_RDWR | O_CREAT)
+       cmp     #O_RDONLY       ; only O_RDONLY is valid
+       bne     @badmode
+
+       lda     ptr1
+       ldx     ptr1+1
+       jsr     _FindFile       ; try to find the file
+       bne     @error
+
+       lda     dirEntryBuf + OFF_DE_TR_SC              ; tr&se for ReadByte (r1)
+       sta     f_track
+       lda     dirEntryBuf + OFF_DE_TR_SC + 1
+       sta     f_sector
+       lda     #<diskBlkBuf                            ; buffer for ReadByte (r4)
+       sta     f_buffer
+       lda     #>diskBlkBuf
+       sta     f_buffer+1
+       ldx     #0                                      ; offset for ReadByte (r5)
+       stx     f_offset
+       stx     f_offset+1
+       lda     #FILEDES        ; return fd
+       sta     filedesc
+       rts
+@badmode:
+@alreadyopen:
+       lda     #70             ; no channel
+       sta     __oserror
+@error:
+       lda     #$ff
+       tax
+       rts
+
+_close:
+       lda #0                  ; clear fd
+       sta filedesc
+       tax
+       rts
+
+_read:
+    ; a/x - number of bytes
+    ; popax - buffer ptr
+    ; popax - fd, must be == to the above one
+    ; return -1+__oserror or number of bytes read
+
+       eor     #$ff
+       sta     ptr1
+       txa
+       eor     #$ff
+       sta     ptr1+1          ; -(# of bytes to read)-1
+       jsr     popax
+       sta     ptr2
+       stx     ptr2+1          ; buffer ptr
+       jsr     popax
+       cmp     #FILEDES
+       bne     @notopen
+       txa
+       bne     @notopen        ; fd must be == FILEDES
+
+       lda     #0
+       sta     ptr3
+       sta     ptr3+1          ; put 0 into ptr3 (number of bytes read)
+
+       lda     f_track         ; restore stuff for ReadByte
+       ldx     f_sector
+       sta     r1L
+       stx     r1H
+       lda     f_buffer
+       ldx     f_buffer+1
+       sta     r4L
+       stx     r4H
+       lda     f_offset
+       ldx     f_offset+1
+       sta     r5L
+       stx     r5H
+
+       clc
+       bcc     @L3             ; branch always
+
+@L0:   jsr     _ReadByte
+       ldy     #0              ; store the byte
+       sta     (ptr2),y
+       inc     ptr2            ; increment target address
+       bne     @L1
+       inc     ptr2+1
+
+@L1:   inc     ptr3            ; increment byte count
+       bne     @L2
+       inc     ptr3+1
+
+@L2:   txa                     ; was there error ?
+       beq     @L3
+       cmp     #BFR_OVERFLOW   ; EOF?
+       bne     @error
+       beq     @done
+
+@L3:   inc     ptr1            ; decrement the count
+       bne     @L0
+       inc     ptr1+1
+       bne     @L0
+
+@done:
+       lda     r1L             ; preserve data for ReadByte
+       ldx     r1H
+       sta     f_track
+       stx     f_sector
+       lda     r4L
+       ldx     r4H
+       sta     f_buffer
+       stx     f_buffer+1
+       lda     r5L
+       ldx     r5H
+       sta     f_offset
+       stx     f_offset+1
+       
+       lda     ptr3            ; return byte count
+       ldx     ptr3+1
+       rts
+
+@notopen:
+       lda     #61             ; File not open
+@error:
+       sta     __oserror
+       lda     #$ff
+       tax
+       rts
+
+.bss
+filedesc:      .res 1          ; file open flag - 0 (no file opened) or 1
+f_track:       .res 1          ; values preserved for ReadByte
+f_sector:      .res 1
+f_offset:      .res 2
+f_buffer:      .res 2
diff --git a/libsrc/geos/devel/geos-vdc.s b/libsrc/geos/devel/geos-vdc.s
new file mode 100644 (file)
index 0000000..1265fc4
--- /dev/null
@@ -0,0 +1,426 @@
+;
+; Extended memory driver for the VDC RAM available on all C128 machines
+; version for GEOS enters safe I/O config on C64 (transparent on C128)
+; 
+; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
+; 06,20,25.12.2002
+
+       .include        "zeropage.inc"
+
+       .include        "em-kernel.inc"
+        .include       "em-error.inc"
+
+
+        .macpack        generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment        "JUMPTABLE"
+
+; Driver signature
+
+        .byte   $65, $6d, $64           ; "emd"
+        .byte   $00                     ; EM API version number
+
+; Jump table.
+
+        .word   INSTALL
+        .word   DEINSTALL
+        .word   PAGECOUNT
+        .word   MAP
+       .word   USE
+        .word   COMMIT
+       .word   COPYFROM
+        .word   COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+VDC_ADDR_REG     = $D600                 ; VDC address
+VDC_DATA_REG     = $D601                 ; VDC data
+
+VDC_DATA_HI      = 18                    ; used registers
+VDC_DATA_LO      = 19
+VDC_CSET         = 28
+VDC_DATA         = 31
+
+; ------------------------------------------------------------------------
+; Data.
+
+.data
+
+pagecount:      .word  64                 ; $0000-$3fff as 16k default
+curpage:       .word  $ffff               ; currently mapped-in page (invalid)
+
+.bss
+
+window:                .res    256                ; memory window
+
+.code
+
+; ------------------------------------------------------------------------
+; INSTALL routine. Is called after the driver is loaded into memory. If
+; possible, check if the hardware is present and determine the amount of
+; memory available.
+; Must return an EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+       ; do test for VDC presence here???
+
+       php
+       sei
+       lda     $01
+       pha
+       lda     #$35
+       sta     $01
+
+       ldx     #VDC_CSET       ; determine size of RAM...
+       jsr     vdcgetreg
+       sta     tmp1
+       ora     #%00010000
+       jsr     vdcputreg       ; turn on 64k
+
+       jsr     settestadr1     ; save original value of test byte
+       jsr     vdcgetbyte
+       sta     tmp2
+
+       lda     #$55            ; write $55 here
+       ldy     #ptr1
+       jsr     test64k         ; read it here and there
+       lda     #$aa            ; write $aa here
+       ldy     #ptr2
+       jsr     test64k         ; read it here and there
+
+       jsr     settestadr1
+       lda     tmp2
+       jsr     vdcputbyte      ; restore original value of test byte
+
+       lda     ptr1            ; do bytes match?
+       cmp     ptr1+1
+       bne     @have64k
+       lda     ptr2
+       cmp     ptr2+1
+       bne     @have64k
+
+       ldx     #VDC_CSET
+       lda     tmp1
+       jsr     vdcputreg       ; restore 16/64k flag
+       jmp     @endok          ; and leave default values for 16k
+
+@have64k:
+       lda     #<256
+       ldx     #>256
+       sta     pagecount
+       stx     pagecount+1
+@endok:
+       pla
+       sta     $01
+       plp
+       lda     #<EM_ERR_OK
+        ldx     #>EM_ERR_OK
+        rts
+
+test64k:
+       sta     tmp1
+       sty     ptr3
+       lda     #0
+       sta     ptr3+1
+       jsr     settestadr1
+       lda     tmp1
+       jsr     vdcputbyte              ; write $55
+       jsr     settestadr1
+       jsr     vdcgetbyte              ; read here
+       pha
+       jsr     settestadr2
+       jsr     vdcgetbyte              ; and there
+       ldy     #1
+       sta     (ptr3),y
+       pla
+       dey
+       sta     (ptr3),y
+       rts
+
+settestadr1:
+       ldy     #$02                    ; test page 2 (here)
+       .byte   $2c
+settestadr2:
+       ldy     #$42                    ; or page 64+2 (there)
+       lda     #0
+       jmp     vdcsetsrcaddr
+
+; ------------------------------------------------------------------------
+; DEINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+DEINSTALL:
+       ;on C128 restore font and clear the screen?
+        rts
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+        lda     pagecount
+        ldx     pagecount+1
+        rts
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP:   sta     curpage
+       stx     curpage+1
+       sta     ptr1+1
+       ldy     #0
+       sty     ptr1
+
+       lda     #<window
+       sta     ptr2
+       lda     #>window
+       sta     ptr2+1
+
+       jsr     transferin
+
+        lda     #<window
+        ldx     #>window
+       rts
+
+; copy a single page from (ptr1):VDCRAM to (ptr2):RAM
+
+transferin:
+       php
+       sei
+       lda     $01
+       pha
+       lda     #$35
+       sta     $01
+       lda     ptr1
+       ldy     ptr1+1
+       jsr     vdcsetsrcaddr           ; set source address in VDC
+       ldy     #0
+       ldx     #VDC_DATA
+       stx     VDC_ADDR_REG
+@L0:   bit     VDC_ADDR_REG
+       bpl     @L0
+       lda     VDC_DATA_REG            ; get 2 bytes at a time to speed-up
+       sta     (ptr2),y                ; (in fact up to 8 bytes could be fetched with special VDC config)
+       iny
+       lda     VDC_DATA_REG
+       sta     (ptr2),y
+       iny
+       bne     @L0
+       pla
+       sta     $01
+       plp
+       rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+
+USE:    sta     curpage
+        stx     curpage+1               ; Remember the page
+        lda     #<window
+        ldx     #>window                ; Return the window
+done:   rts
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT:
+       lda     curpage                 ; jump if no page mapped
+       ldx     curpage+1
+       bmi     done
+       sta     ptr1+1
+       ldy     #0
+       sty     ptr1
+
+       lda     #<window
+       sta     ptr2
+       lda     #>window
+       sta     ptr2+1
+
+; fall through to transferout
+
+; copy a single page from (ptr2):RAM to (ptr1):VDCRAM
+
+transferout:
+       php
+       sei
+       lda     $01
+       pha
+       lda     #$35
+       sta     $01
+       lda     ptr1
+       ldy     ptr1+1
+       jsr     vdcsetsrcaddr           ; set source address in VDC
+       ldy     #0
+       ldx     #VDC_DATA
+       stx     VDC_ADDR_REG
+@L0:   bit     VDC_ADDR_REG
+       bpl     @L0
+       lda     (ptr2),y                ; speedup does not work for writing
+       sta     VDC_DATA_REG
+       iny
+       bne     @L0
+       pla
+       sta     $01
+       plp
+       rts
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYFROM:
+       jsr     setup
+       beq     @L2                     ; Skip if no full pages
+
+; Copy full pages 
+
+@L1:    jsr     transferin
+        inc     ptr1+1
+        inc     ptr2+1
+        dec     tmp1
+        bne     @L1
+
+; Copy the remainder of the page
+
+@L2:    ldy     #EM_COPY_COUNT
+        lda     (ptr3),y                ; Get bytes in last page
+        beq     @L4
+        sta    tmp1
+
+; Transfer the bytes in the last page
+       php
+       sei
+       lda     $01
+       pha
+       lda     #$35
+       sta     $01
+       ldy     #0
+@L3:   jsr     vdcgetbyte
+       sta     (ptr2),y
+       iny
+       dec     tmp1
+       lda     tmp1
+       bne     @L3
+       pla
+       sta     $01
+       plp
+@L4:   rts
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO:
+       jsr     setup
+       beq     @L2                     ; Skip if no full pages
+
+; Copy full pages 
+
+@L1:    jsr     transferout
+        inc     ptr1+1
+        inc     ptr2+1
+        dec     tmp1
+        bne     @L1
+
+; Copy the remainder of the page
+
+@L2:    ldy     #EM_COPY_COUNT
+        lda     (ptr3),y                ; Get bytes in last page
+        beq     @L4
+        sta    tmp1
+
+; Transfer the bytes in the last page
+       php
+       sei
+       lda     $01
+       pha
+       lda     #$35
+       sta     $01
+       ldy     #0
+@L3:   lda     (ptr2),y
+       jsr     vdcputbyte
+       iny
+       dec     tmp1
+       lda     tmp1
+       bne     @L3
+       pla
+       sta     $01
+       plp
+@L4:   rts
+
+;-------------------------------------------------------------------------
+; Helper functions to handle VDC ram
+;
+
+vdcsetsrcaddr:
+       ldx     #VDC_DATA_LO
+       stx     VDC_ADDR_REG
+@L0:   bit     VDC_ADDR_REG
+       bpl     @L0
+       sta     VDC_DATA_REG
+       dex
+       tya
+       stx     VDC_ADDR_REG
+       sta     VDC_DATA_REG
+       rts
+
+vdcgetbyte:
+       ldx     #VDC_DATA
+vdcgetreg:
+       stx     VDC_ADDR_REG
+@L0:   bit     VDC_ADDR_REG
+       bpl     @L0
+       lda     VDC_DATA_REG
+       rts
+
+vdcputbyte:
+       ldx     #VDC_DATA
+vdcputreg:
+       stx     VDC_ADDR_REG
+@L0:   bit     VDC_ADDR_REG
+       bpl     @L0
+       sta     VDC_DATA_REG
+       rts
+
+; ------------------------------------------------------------------------
+; Helper function for COPYFROM and COPYTO: Store the pointer to the request
+; structure and prepare data for the copy
+;
+
+setup:
+       sta     ptr3
+        stx     ptr3+1                  ; Save the passed em_copy pointer
+
+        ldy     #EM_COPY_OFFS
+        lda     (ptr3),y
+        sta     ptr1
+        ldy     #EM_COPY_PAGE
+        lda     (ptr3),y
+        sta     ptr1+1                  ; From
+
+        ldy     #EM_COPY_BUF
+        lda     (ptr3),y
+        sta     ptr2
+        iny
+        lda     (ptr3),y
+        sta     ptr2+1                  ; To
+
+       ldy     #EM_COPY_COUNT+1
+        lda     (ptr3),y                ; Get number of pages
+        sta     tmp1
+       rts
+