From: izydorst Date: Wed, 25 Dec 2002 18:42:42 +0000 (+0000) Subject: support for loading modules in GEOS, VDC memory driver for GEOS X-Git-Tag: V2.12.0~1826 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=62907d1cc6e89e1774367cfb43aaebb2c7fb5060;p=cc65 support for loading modules in GEOS, VDC memory driver for GEOS git-svn-id: svn://svn.cc65.org/cc65/trunk@1845 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/libsrc/Makefile b/libsrc/Makefile index 17f0383dc..39a209db0 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -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 diff --git a/libsrc/geos/devel/Makefile b/libsrc/geos/devel/Makefile index b4675cca2..51d21eaa9 100644 --- a/libsrc/geos/devel/Makefile +++ b/libsrc/geos/devel/Makefile @@ -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 index 000000000..dca349712 --- /dev/null +++ b/libsrc/geos/devel/fio_module.s @@ -0,0 +1,184 @@ +; +; Low level file I/O routines, ONLY for module loading OR sth similar +; +; Maciej 'YTM/Elysium' Witkowiak +; 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 + 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 index 000000000..1265fc457 --- /dev/null +++ b/libsrc/geos/devel/geos-vdc.s @@ -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 +; 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 + 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+1 + + jsr transferin + + lda #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 ; 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+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 +