From 83890e56eb61933ee45985de368d5f80d56eab77 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt Date: Thu, 22 Feb 2018 13:30:50 +0100 Subject: [PATCH 1/5] Update dio.sgml --- doc/dio.sgml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/dio.sgml b/doc/dio.sgml index c85992a4a..39aac251c 100644 --- a/doc/dio.sgml +++ b/doc/dio.sgml @@ -25,8 +25,7 @@ released with the dio_close function. dhandle_t __fastcall__ dio_open (unsigned char device); -The device specifies the device to access, with 0 being the first -device, 1 the second, and so on. +The device specifies the device to access. unsigned char __fastcall__ dio_close (dhandle_t handle); From 3a0506ccb3582ea4677c000d9a4a581c46e3914f Mon Sep 17 00:00:00 2001 From: Greg King Date: Fri, 23 Feb 2018 16:06:49 -0500 Subject: [PATCH 2/5] Changed the PC-Engine's configuration file, so that the command line can build 8K, 16K, and 32K carts. Adjusted the PCE's document, the start-up code, and the PCE library test makefile. That makefile shows how to post-process the linker's output file. --- cfg/pce.cfg | 43 +++++++++++-------------- doc/pce.sgml | 61 +++++++++++++++++++++++++---------- libsrc/pce/crt0.s | 68 +++++++++++++++++---------------------- testcode/lib/pce/Makefile | 25 +++++++++++--- testcode/lib/pce/conio.c | 2 +- 5 files changed, 115 insertions(+), 84 deletions(-) diff --git a/cfg/pce.cfg b/cfg/pce.cfg index 6332f8eff..77f8c5c97 100644 --- a/cfg/pce.cfg +++ b/cfg/pce.cfg @@ -1,34 +1,29 @@ -# linker config to produce simple NEC PC-Engine cartridge (.pce) - +# linker config. to produce a NEC PC-Engine 8K, 16K, or 32K image (.bin) SYMBOLS { + __CARTSIZE__: type = weak, value = $2000; # $2000, $4000, or $8000 __STACKSIZE__: type = weak, value = $0300; # 3 pages stack } - MEMORY { - # FIXME: is this correct? the first 3? bytes cant be used? - ZP: file = "", start = $0003, size = $00FD, type = rw, define = yes; - - # reset-bank and hardware vectors - ROM0: file = %O, start = $E000, size = $1FF6, fill = yes, define = yes; - ROMV: file = %O, start = $FFF6, size = $000A, fill = yes; - - # first RAM page (also contains stack and zeropage) - RAM: file = "", start = $2200, size = $1e00, define = yes; + ZP: file = "", start = $0000, size = $0100, define = yes; + # RAM bank + MAIN: file = "", start = $2200, size = $1E00 - __STACKSIZE__, define = yes; + # ROM banks, before swapping, and after mapping + ROM: file = %O, start = $10000 - __CARTSIZE__, size = __CARTSIZE__, fill = yes, fillval = $FF; } - SEGMENTS { - ZEROPAGE: load = ZP, type = zp, define = yes; - EXTZP: load = ZP, type = zp, define = yes, optional = yes; - APPZP: load = ZP, type = zp, define = yes, optional = yes; - STARTUP: load = ROM0, type = ro, define = yes; - ONCE: load = ROM0, type = ro, optional = yes; - CODE: load = ROM0, type = ro, define = yes; - RODATA: load = ROM0, type = ro, define = yes; - DATA: load = ROM0, run = RAM, type = rw, define = yes; - BSS: load = RAM, type = bss, define = yes; - VECTORS: load = ROMV, type = rw, define = yes; + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, optional = yes; + APPZP: load = ZP, type = zp, optional = yes; + DATA: load = ROM, run = MAIN, type = rw, define = yes; + INIT: load = MAIN, type = bss, optional = yes; + BSS: load = MAIN, type = bss, define = yes; + RODATA: load = ROM, type = ro; + CODE: load = ROM, type = ro; + LOWCODE: load = ROM, type = ro, optional = yes; + ONCE: load = ROM, type = ro, optional = yes; + STARTUP: load = ROM, type = ro, start = $FFF6 - $0066; + VECTORS: load = ROM, type = ro, start = $FFF6; } - FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, diff --git a/doc/pce.sgml b/doc/pce.sgml index 927df8f5c..bc7dcf5c8 100644 --- a/doc/pce.sgml +++ b/doc/pce.sgml @@ -3,9 +3,9 @@
PC-Engine (TurboGrafx) System specific information for cc65 -<author> -<url url="mailto:groepaz@gmx.net" name="Groepaz/Hitmen"> -<date>2016-09-29 +<author><url url="mailto:groepaz@gmx.net" name="Groepaz/Hitmen">,<newline> +<url url="mailto:greg.king5@verizon.net" name="Greg King"> +<date>2018-02-12 <abstract> An overview over the PCE runtime system as it is implemented for the @@ -30,11 +30,36 @@ more than one platform. Please see the function reference for more information. + <sect>Binary format<p> -The standard binary output format generated by the linker for the PCE target -is a cartridge image with no header. It is of course possible to change this -behaviour by using a modified startup file and linker config. +The binary output file generated by the linker, for the PCE target, is an +image, with no header, that has 8K bytes in the wrong place. That file must be +post-processed; the 8K at the end must be moved to the front of the image. + +On POSIX systems, the <tt/dd/ command and the shell give a convenient way to do +it. Here is an example of their use: +<tscreen><verb> +dd if=conio.bin bs=8K skip=3 > conio.pce +dd if=conio.bin bs=8K count=3 >> conio.pce +</verb></tscreen> +The first command grabs the last 8K of a 32K file, and writes it as the first +part of a new file. The second command reads all but the last part of the old +file, and appends it to the new file. +<tscreen><verb> ++--------+--------+--------+--------+ +| Bank 1 | Bank 2 | Bank 3 | Bank 0 | <-- "conio.bin" ++--------+--------+--------+--------+ + ++--------+--------+--------+--------+ +| Bank 0 | Bank 1 | Bank 2 | Bank 3 | <-- "conio.pce" ++--------+--------+--------+--------+ +</verb></tscreen> +<em/Note/: That <tt/.pce/ file shows the format of the ROM cartridge that is +plugged into a PC-Engine. But, that <tt/.bin/ file shows what programs +actually see when they execute the code in that cartridge. + + <sect>Memory layout<p> @@ -52,19 +77,23 @@ Special locations: <tag/Stack/ The C runtime stack is located in system RAM at $3FFF and growing downwards. - <tag/BSS and Data/ - - The BSS (uninitialized variables) and Data (initialized variables) sections are - placed one after the other into system RAM at $2000. + <tag/Data and BSS/ + The Data (initialized variables) and BSS (uninitialized variables) sections are + placed one after the other into system RAM at $2200. <tag/Heap/ - The C heap is located after the end of the Data section and grows towards the C + The C heap is located after the end of the BSS section; and, grows towards the C runtime stack. <tag/Code/ - The startup code is located at $E000 in the System/Hardware bank. Further - code can be placed in other ROM banks, this must be done manually however. + In an 8K ROM cartridge, code and read-only data are located between + $E000 and $FFF5 in the System bank. + In a 16K cartridge, code and read-only data are located between $C000 + and $FFF5. + + In a 32K cartridge, code and read-only data are located between $8000 + and $FFF5. </descrip><p> @@ -171,7 +200,8 @@ following functions (and a few others): <sect>Other hints<p> <itemize> -<item>a good emulator to use for PC-Engine is "mednafen" (<url url="http://mednafen.fobby.net/">) +<item><url url="https://mednafen.github.io/" name= "Mednafen"> is a good +emulator to use for the PC-Engine. </itemize> some useful resources on PCE coding: @@ -210,6 +240,3 @@ freely, subject to the following restrictions: </enum> </article> - - - diff --git a/libsrc/pce/crt0.s b/libsrc/pce/crt0.s index 80b32c089..75ffb7f05 100644 --- a/libsrc/pce/crt0.s +++ b/libsrc/pce/crt0.s @@ -4,33 +4,26 @@ ; by Groepaz/Hitmen <groepaz@gmx.net> ; based on code by Ullrich von Bassewitz <uz@cc65.org> ; -; This must be the *first* file on the linker command line +; 2018-02-11, Greg King ; .export _exit .export __STARTUP__ : absolute = 1 ; Mark as startup .import initlib, donelib - .import push0, _main, zerobss - .import initheap + .import push0, _main .import IRQStub - ; Linker generated - .import __RAM_START__, __RAM_SIZE__ - .import __ROM0_START__, __ROM0_SIZE__ - .import __ROM_START__, __ROM_SIZE__ - .import __STARTUP_LOAD__,__STARTUP_RUN__, __STARTUP_SIZE__ - .import __CODE_LOAD__,__CODE_RUN__, __CODE_SIZE__ - .import __RODATA_LOAD__,__RODATA_RUN__, __RODATA_SIZE__ - .import __DATA_LOAD__,__DATA_RUN__, __DATA_SIZE__ - .import __BSS_SIZE__ + ; Linker-generated + .import __CARTSIZE__ + .import __DATA_LOAD__, __DATA_RUN__, __DATA_SIZE__ + .import __BSS_RUN__, __BSS_SIZE__ + .import __MAIN_START__, __MAIN_SIZE__, __STACKSIZE__ .include "pce.inc" .include "extzp.inc" .importzp sp - .importzp ptr1,ptr2 - .importzp tmp1,tmp2,tmp3 ; ------------------------------------------------------------------------ ; Place the startup code in a special segment. @@ -53,29 +46,27 @@ start: ldx #$FF ; Stack top ($21FF) txs - ; At startup all MPRs are set to 0, so init them - lda #$ff - tam #%00000001 ; 0000-1FFF = Hardware page + ; At power-on, most MPRs have random values; so, initiate them. + lda #$FF + tam #%00000001 ; $0000-$1FFF = Hardware bank lda #$F8 - tam #%00000010 ; 2000-3FFF = Work RAM - - ; FIXME: setup a larger block of memory to use with C-code + tam #%00000010 ; $2000-$3FFF = Work RAM ;lda #$F7 - ;tam #%00000100 ; 4000-5FFF = Save RAM - ;lda #1 - ;tam #%00001000 ; 6000-7FFF Page 2 - ;lda #2 - ;tam #%00010000 ; 8000-9FFF Page 3 - ;lda #3 - ;tam #%00100000 ; A000-BFFF Page 4 + ;tam #%00000100 ; $4000-$47FF = 2K Battery-backed RAM ;lda #4 - ;tam #%01000000 ; C000-DFFF Page 5 - ;lda #0 - ;tam #%10000000 ; e000-fFFF hucard/syscard bank 0 + ;tam #%00001000 ; $6000-$7FFF - ; Clear work RAM (2000-3FFF) - stz <$00 - tii $2000, $2001, $1FFF + lda #$01 + ldx #>$8000 + cpx #>__CARTSIZE__ + bcc @L1 ;(blt) + tam #%00010000 ; $8000-$9FFF = ROM bank 1 (32K block of ROM) + inc a + tam #%00100000 ; $A000-$BFFF = ROM bank 2 + inc a +@L1: tam #%01000000 ; $C000-$DFFF = ROM bank 3 (32K) or 1 (16K) + ;lda #$00 ; (The reset default) + ;tam #%10000000 ; $E000-$FFFF hucard/syscard bank 0 ; Initialize hardware stz TIMER_CTRL ; Timer off @@ -91,15 +82,16 @@ start: lda #$05 sta IRQ_MASK ; IRQ1=on - ; Clear the BSS data - jsr zerobss - ; Copy the .data segment to RAM tii __DATA_LOAD__, __DATA_RUN__, __DATA_SIZE__ + ; Clear the .bss segment + stz __BSS_RUN__ + tii __BSS_RUN__, __BSS_RUN__ + 1, __BSS_SIZE__ - 1 + ; Set up the stack - lda #<(__RAM_START__+__RAM_SIZE__) - ldx #>(__RAM_START__+__RAM_SIZE__) + lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) + ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) sta sp stx sp + 1 diff --git a/testcode/lib/pce/Makefile b/testcode/lib/pce/Makefile index 9a4dd7506..a4a495c9a 100644 --- a/testcode/lib/pce/Makefile +++ b/testcode/lib/pce/Makefile @@ -1,12 +1,29 @@ .PHONY: all clean test +# Size of cartridge to generate. +# Possible values: +# 8K = 0x2000 +# 16K = 0x4000 +# 32K = 0x8000 +CARTSIZE := 0x2000 + +ifeq (${CARTSIZE},0x8000) +COUNT := 3 +else +COUNT := 1 +endif + all: conio.pce -conio.pce: conio.c - ../../../bin/cl65 -t pce conio.c --mapfile conio.map -o conio.pce +%.pce: %.bin + dd if=$< bs=8K skip=${COUNT} > $@ + dd if=$< bs=8K count=${COUNT} >> $@ + +%.bin: %.c ../../../lib/pce.lib + ../../../bin/cl65 -t pce $< -Wl -D__CARTSIZE__=${CARTSIZE} -m $*.map -o $@ clean: - $(RM) conio.o conio.pce conio.map + $(RM) conio.o conio.??? test: conio.pce - mednafen -force_module pce conio.pce + mednafen -force_module pce $< diff --git a/testcode/lib/pce/conio.c b/testcode/lib/pce/conio.c index ed3f86240..858f01918 100644 --- a/testcode/lib/pce/conio.c +++ b/testcode/lib/pce/conio.c @@ -45,7 +45,7 @@ void main(void) p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15] ); } - memcpy(p, main, 0); /* test that a zero length doesn't copy 64K */ + memcpy(p, main, i = 0); /* test that a zero length doesn't copy 64K */ gotoxy(0,ysize - 1); for (i = 0; i < xsize; ++i) { From 8476360e9f5f3737eb740e8faffdeece2e4847aa Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 24 Aug 2015 02:53:47 -0400 Subject: [PATCH 3/5] Fixed bugs in geos-cbm's dio_open(). * Trying to open an unused drive would leave a byte on the hardware stack. * Too high device numbers weren't caught. --- libsrc/geos-cbm/disk/dio_openclose.s | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libsrc/geos-cbm/disk/dio_openclose.s b/libsrc/geos-cbm/disk/dio_openclose.s index ec5aa8795..72e3e32e9 100644 --- a/libsrc/geos-cbm/disk/dio_openclose.s +++ b/libsrc/geos-cbm/disk/dio_openclose.s @@ -1,8 +1,8 @@ ; -; Maciej 'YTM/Elysium' Witkowiak +; 2001-07-02, Maciej 'YTM/Elysium' Witkowiak +; 2015-08-24, Greg King ; ; based on Atari version by Christian Groessler -; 2.7.2001 ; ; dhandle_t __fastcall__ dio_open (unsigned char device); ; unsigned char __fastcall__ dio_close (dhandle_t handle); @@ -27,11 +27,13 @@ sectsizetab: .code _dio_open: - pha + cmp #4 + bcs _inv_drive tax lda driveType,x ; check if there's a device beq _inv_drive txa + pha clc adc #8 ; normalize devnum sta curDevice From 6fd56bf9b6b594a722bc508b6dfc7c1f21fdc3b4 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 27 Aug 2015 04:02:26 -0400 Subject: [PATCH 4/5] Fixed bugs in the geos-cbm DIO sector-number converter functions. * The 16-bit comparison code actually didn't compare the high byte. * This implementation supports only the 1541, 1571, and 1581; but, it didn't exclude the other drive types that GEOS supports. * Two error code numbers were swapped. * A 1571 converter didn't catch sector numbers that are too high. * A 1581 converter didn't catch sector numbers that are too high. --- libsrc/geos-cbm/disk/dio_cts.s | 10 +++++----- libsrc/geos-cbm/disk/dio_stc.s | 23 ++++++++++++----------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/libsrc/geos-cbm/disk/dio_cts.s b/libsrc/geos-cbm/disk/dio_cts.s index 8be343641..043e1f8d8 100644 --- a/libsrc/geos-cbm/disk/dio_cts.s +++ b/libsrc/geos-cbm/disk/dio_cts.s @@ -1,6 +1,6 @@ ; -; Maciej 'YTM/Elysium' Witkowiak -; 2.7.2001 +; 2001-07-02, Maciej 'YTM/Elysium' Witkowiak +; 2015-08-26, Greg King ; ; ; unsigned char __fastcall__ dio_phys_to_log (dhandle_t handle, @@ -59,7 +59,7 @@ _dio_phys_to_log: lda (ptr3),y tay lda driveType,y - and #%00000011 ; this is for RamDrive compatibility + and #%00001111 ; remove ramDisk flags cmp #DRV_1541 beq dio_cts1541 cmp #DRV_1571 @@ -67,7 +67,7 @@ _dio_phys_to_log: cmp #DRV_1581 beq dio_cts1581 - lda #DEV_NOT_FOUND ; unknown device + lda #INCOMPATIBLE ; unsupported device ldx #0 beq ret @@ -91,7 +91,7 @@ _inv_data: lda #INV_TRACK .byte $2c _inv_hand: - lda #INCOMPATIBLE + lda #DEV_NOT_FOUND ldx #0 beq ret diff --git a/libsrc/geos-cbm/disk/dio_stc.s b/libsrc/geos-cbm/disk/dio_stc.s index 586e3f3db..7398edb63 100644 --- a/libsrc/geos-cbm/disk/dio_stc.s +++ b/libsrc/geos-cbm/disk/dio_stc.s @@ -1,6 +1,6 @@ ; -; Maciej 'YTM/Elysium' Witkowiak -; 2.7.2001 +; 2001-07-02, Maciej 'YTM/Elysium' Witkowiak +; 2015-08-27, Greg King ; ; unsigned char __fastcall__ dio_log_to_phys (dhandle_t handle, ; unsigned *sectnum, /* input */ @@ -55,7 +55,7 @@ _dio_log_to_phys: lda (ptr3),y tay lda driveType,y - and #%00000011 ; this is for RamDrive compatibility + and #%00001111 ; remove ramDisk flags cmp #DRV_1541 beq dio_stc1541 cmp #DRV_1571 @@ -63,7 +63,7 @@ _dio_log_to_phys: cmp #DRV_1581 beq dio_stc1581 - lda #DEV_NOT_FOUND ; unknown device + lda #INCOMPATIBLE ; unsupported device ldx #0 beq _ret @@ -86,7 +86,7 @@ _inv_data: lda #INV_TRACK .byte $2c _inv_hand: - lda #INCOMPATIBLE + lda #DEV_NOT_FOUND ldx #0 beq _ret @@ -102,8 +102,8 @@ _loop41: bne _nxt lda tmp1 cmp sectab_1541_l+1,x - bcc _found -_nxt: inx +_nxt: bcc _found + inx cpx #35 bne _loop41 beq _inv_data @@ -124,12 +124,11 @@ dio_stc1571: ; - fall down to 1541 lda tmp2 cmp #>683 - bne _cnt71 + bne _if71 lda tmp1 cmp #<683 - bcc dio_stc1541 +_if71: bcc dio_stc1541 -_cnt71: lda tmp1 sec sbc #<683 @@ -138,6 +137,8 @@ _cnt71: sbc #>683 sta tmp2 jsr dio_stc1541 ; will fall through here + tay + bne _ret ; result beyond track 70 ldy #diopp_track lda (ptr1),y @@ -166,7 +167,7 @@ _sub81: lda tmp1 sbc #0 sta tmp2 inx - cpx #81 + cpx #80 bne _loop81 beq _inv_data From 39b4b6838ff3a72432ae2b0d9af4de360c344672 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 27 Aug 2015 05:10:01 -0400 Subject: [PATCH 5/5] Made dio_read(), dio_write(), and dio_write_verify() catch sector number conversion errors. --- libsrc/geos-cbm/disk/dio_read.s | 8 +++++--- libsrc/geos-cbm/disk/dio_write.s | 8 ++++++-- libsrc/geos-cbm/disk/dio_writev.s | 8 +++++--- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/libsrc/geos-cbm/disk/dio_read.s b/libsrc/geos-cbm/disk/dio_read.s index db46c9b69..ac19f9afa 100644 --- a/libsrc/geos-cbm/disk/dio_read.s +++ b/libsrc/geos-cbm/disk/dio_read.s @@ -1,6 +1,6 @@ ; -; Maciej 'YTM/Elysium' Witkowiak -; 2.7.2001 +; 2001-07-02, Maciej 'YTM/Elysium' Witkowiak +; 2015-08-27, Greg King ; ; this file provides the _dio_read function ; @@ -15,7 +15,9 @@ _dio_read: jsr dio_params + tay + bne err jsr ReadBlock stx __oserror txa - rts +err: rts diff --git a/libsrc/geos-cbm/disk/dio_write.s b/libsrc/geos-cbm/disk/dio_write.s index 14267803a..a5f747519 100644 --- a/libsrc/geos-cbm/disk/dio_write.s +++ b/libsrc/geos-cbm/disk/dio_write.s @@ -1,6 +1,6 @@ ; -; Maciej 'YTM/Elysium' Witkowiak -; 2.7.2001 +; 2001-07-02, Maciej 'YTM/Elysium' Witkowiak +; 2015-08-27, Greg King ; ; this file provides the _dio_write function ; @@ -15,5 +15,9 @@ _dio_write: jsr dio_params + tay + bne err jsr WriteBlock jmp setoserror + +err: rts diff --git a/libsrc/geos-cbm/disk/dio_writev.s b/libsrc/geos-cbm/disk/dio_writev.s index 7cb9b029f..9b36ed096 100644 --- a/libsrc/geos-cbm/disk/dio_writev.s +++ b/libsrc/geos-cbm/disk/dio_writev.s @@ -1,6 +1,6 @@ ; -; Maciej 'YTM/Elysium' Witkowiak -; 2.7.2001 +; 2001-07-02, Maciej 'YTM/Elysium' Witkowiak +; 2015-08-27, Greg King ; ; this file provides the _dio_write function ; @@ -15,7 +15,9 @@ _dio_write_verify: jsr dio_params + tay + bne err jsr VerWriteBlock stx __oserror txa - rts +err: rts