Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.sys.apple2.programmer > #838 > unrolled thread
| Started by | "Bill Buckels" <bbuckels@mts.net> |
|---|---|
| First post | 2013-08-30 12:14 -0500 |
| Last post | 2013-08-30 22:16 -0500 |
| Articles | 7 — 2 participants |
Back to article view | Back to comp.sys.apple2.programmer
DOS 3.3 RWTS - C65 library function - please help "Bill Buckels" <bbuckels@mts.net> - 2013-08-30 12:14 -0500
Re: DOS 3.3 RWTS - C65 library function - please help "Bill Buckels" <bbuckels@mts.net> - 2013-08-30 12:19 -0500
Re: DOS 3.3 RWTS - C65 library function - please help "Bill Buckels" <bbuckels@mts.net> - 2013-08-30 12:28 -0500
Re: DOS 3.3 RWTS - C65 library function - please help "Bill Buckels" <bbuckels@mts.net> - 2013-08-30 13:19 -0500
Re: DOS 3.3 RWTS - C65 library function - please help Antoine Vignau <antoine.vignau@laposte.net> - 2013-08-30 12:35 -0700
Re: DOS 3.3 RWTS - C65 library function - please help "Bill Buckels" <bbuckels@mts.net> - 2013-08-30 17:07 -0500
Re: DOS 3.3 RWTS - C65 library function - please help "Bill Buckels" <bbuckels@mts.net> - 2013-08-30 22:16 -0500
| From | "Bill Buckels" <bbuckels@mts.net> |
|---|---|
| Date | 2013-08-30 12:14 -0500 |
| Subject | DOS 3.3 RWTS - C65 library function - please help |
| Message-ID | <kvqju7$lph$1@speranza.aioe.org> |
The following Code will not work in the Aztec C65 3.2b compiler but works in
the previous version. I have commented the heck out of it. Any thoughts,
tips, or solutions?
I will follow this listing with an uncommented original source.
VAL EQU 0
SP EQU 2
FRAME EQU 4
PC EQU 6
R0 EQU 8
R1 EQU 12
R2 EQU 16
* Removed old equates from CII (old version)
* ACC EQU 20
* SEC EQU 22
* Added Zero Page offsets for this version (3.2b)
ACC EQU 28
SEC EQU 30
*
*
* call sequence (stack offsets below):
*
* rwts(tr, se, buf, cmd, sl, dr, vol);
* 01 23 45 67 89 ab cd
*
*
* Accumulator (A)
* Stack pointer (S)
* Processor status (P)
* Index registers (X and Y)
*
* # - immediate mode of addressing is signified by a
* # (pound sign) followed by a constant (i.e. a decimal value)
*
* () - indexed indirect - parentheses around a zero page address
*JSR $3D9 ;call RWTS (with IOB address in Y/A)
*
*The IOB (Input/Output Block)
*============================
*
*$00 table type (always $01)
*$01 slot *16
*$02 drive (1 or 2)
*$03 volume expected ($00 for any)
*$04 track ($0-$22)
*$05 sector ($0-$0f)
*$06-07 address (lo/hi) of the Device Characteristics Table
*$08-09 address (lo/hi) of the 256 byte buffer for read/write
*$0A not used
*$0B byte count for partial sector ($00 for 256 bytes)
*$0C command code (0= seek, 1=read, 2=write, 4=format)
*$0D return code (carry set on error):
* $00 = no errors
* $08 = error during initialization
* $10 = write protect error
* $20 = volume mismatch error
* $40 = drive error
* $80 = read error (obsolete)
*$0E volume number of last access (must be initialized)
*$0F slot number of last access *16 (must be initialized)
*$10 drive number of last access (must be initialized)
*
*Device characteristics table:
*============================
*
*$00 device type (should be $00 for DiskII)
*$01 phases per track (should be $01 for DiskII)
*$02-03 motor on time count (should be $EFD8 for DiskII)
*
* NOTE: RWTS uses zero-page location $48, which is also used by the Apple
* monitor to hold the P-register value.
*
* Location $48 should be set to zero after each call to RWTS.
* (Not Done Below - No need for monitor I guess.)
IOB EQU $48
*
cseg
public rwts_
rwts_ clc ; clear carry flag
jsr $3e3 ; get address of RWTS IOB
sta IOB+1 ; IOB address in Y/A)
sty IOB
* This provides the following:
* - address of the device characteristics table
* - volume number of last access
* - slot number of last access * 16
* - drive number of last access
*
* Track
ldy #0 ; track offset on stack
lda (SP),y ; put track in accumulator
ldy #4 ; track offset in IOB
sta (IOB),y ; put track into IOB
* Sector
ldy #2 ; sector offset on stack
lda (SP),y ; put sector in accumulator
ldy #5 ; sector offset in IOB
sta (IOB),y ; put sector into IOB
* Sector Buffer for R/W
ldy #4 ; sector buffer address low order byte on stack
lda (SP),y ; put in accumulator
ldy #8 ; offset in IOB
sta (IOB),y ; put in IOB
ldy #5 ; sector buffer address hi order byte on stack
lda (SP),y ; put in accumulator
ldy #9 ; offset in IOB
sta (IOB),y ; put in IOB
* Command
ldy #6 ; command code offset on stack
lda (SP),y ; put command code in accumulator
ldy #$c ; command code offset in IOB
sta (IOB),y ; put accumulator into IOB
* Slot
ldy #8 ; slot offset on stack
lda (SP),y ; put slot in accumulator
asl a ; shift slot left 4 times
asl a ; (multiply * 16)
asl a
asl a
ldy #1 ; slot * 16 offset in IOB
sta (IOB),y ; put slot in IOB
* Drive
ldy #10 ; drive offset on stack
lda (SP),y ; put drive in accumulator
ldy #2 ; drive offset in IOB
sta (IOB),y ; put drive in IOB
* Volume
ldy #12 ; volume offset on stack
lda (SP),y ; put volume in accumulator
ldy #3 ; volume offset in IOB
sta (IOB),y ; put volume in IOB
jsr $3e3 ; get address of RWTS IOB
jsr $3d9 ; call RWTS
* Return Code
ldy #13 ; return code offset in IOB
lda (IOB),y ; put in accumulator
sta R0+1 ; put accumulator in low byte
ldy #0 ; load 0 as high byte
sty R0 ; store 0 - provides integer return of error
clc ; clear carry
rts ; return from subroutine
* Old return code
* Returned 0 (success) or ffff (error, -1)
*
* old code checked carry flag and if no carry jumped
* if carry decremented 0 byte
* duplicated byte to make integer return register
* ldy #0
* bcc .1
* dey
*.1 sty R0
* sty R0+1
* rts
[toc] | [next] | [standalone]
| From | "Bill Buckels" <bbuckels@mts.net> |
|---|---|
| Date | 2013-08-30 12:19 -0500 |
| Message-ID | <kvqk7e$mmq$1@speranza.aioe.org> |
| In reply to | #838 |
"Bill Buckels" <bbuckels@mts.net> wrote: > I will follow this listing with an uncommented original source Note: the zero page registers below are not all used; the SP (stack pointer) and R0 are the only regs used. I will follow this listing with the zero page header from 3.2b (the newer version). VAL EQU 0 SP EQU 2 FRAME EQU 4 PC EQU 6 R0 EQU 8 R1 EQU 12 R2 EQU 16 ACC EQU 20 SEC EQU 22 * * * call sequence: * *rwts(tr, se, buf, cmd, sl, dr, vol); * * IOB EQU $48 * cseg public rwts_ rwts_ jsr $3e3 sta IOB+1 sty IOB ldy #0 lda (SP),y ldy #4 sta (IOB),y ldy #2 lda (SP),y ldy #5 sta (IOB),y ldy #4 lda (SP),y ldy #8 sta (IOB),y ldy #5 lda (SP),y ldy #9 sta (IOB),y ldy #6 lda (SP),y ldy #$c sta (IOB),y ldy #8 lda (SP),y asl a asl a asl a asl a ldy #1 sta (IOB),y ldy #10 lda (SP),y ldy #2 sta (IOB),y ldy #12 lda (SP),y ldy #3 sta (IOB),y jsr $3e3 jsr $3d9 ldy #0 bcc .1 dey .1 sty R0 sty R0+1 rts
[toc] | [prev] | [next] | [standalone]
| From | "Bill Buckels" <bbuckels@mts.net> |
|---|---|
| Date | 2013-08-30 12:28 -0500 |
| Message-ID | <kvqkp2$o9f$1@speranza.aioe.org> |
| In reply to | #839 |
"Bill Buckels" <bbuckels@mts.net> wrote: > I will follow this listing with the zero page header from 3.2b (the newer version). As I said initially, this is a real noodle-scratcher. It works flawlessly in the old version leading me to believe some other setting within the compiler's runtime has changed besides adding a couple more registers to zero page. My thoughts are currently to break this into smaller public functions to decompose the problem, then do hexdumps to disk for analysis, or maybe print in memory. But before I do that, It nags me that working code was in the old compiler's library but never added into the library for the newer version; do you think that Aztec C65's developers had the same problem, so decided to remove rwts from the rewritten 3.2b library for that reason? Anyway, here's the current zero page settings: I will provide one more zero page layout after the one below which shows the differences between the old version's equates and the new version's equates more precisely. * These are set up for the Apple // Dos 3.3 STK EQU $00 ;8 byte stack area VAL EQU STK SP EQU STK+2 AFRAME EQU STK+4 FRAME EQU STK+4 LFRAME EQU STK+6 PC EQU STK+6 TREGS equ $08 ;24 byte tmp register area R0 EQU TREGS+0 R1 EQU TREGS+4 R2 EQU TREGS+8 R3 EQU TREGS+12 R4 EQU TREGS+16 ACC EQU TREGS+20 ;pointers for floating point registers SEC EQU TREGS+22 ;4 bytes (points to 2 - 14 byte areas) REGS EQU $80 ;16 byte user register area TMP EQU $40 ;4 byte zero page temporary area
[toc] | [prev] | [next] | [standalone]
| From | "Bill Buckels" <bbuckels@mts.net> |
|---|---|
| Date | 2013-08-30 13:19 -0500 |
| Message-ID | <kvqnn2$12h$1@speranza.aioe.org> |
| In reply to | #840 |
"Bill Buckels" <bbuckels@mts.net> wrote: >I will provide one more zero page layout ...which shows the differences >between the old version's equates and the new version's equates more >precisely. Thank you for taking time to look at this. I have many other similarly complex issues that I have been working through, and in the end the problem becomes simple and obvious generally with a simple solution. But in the meanwhile I always wish I had more sets of eyes... Like many C compilers that interface with assembly including Microsoft Compilers and the Windows API which uses PASCAL calling convention, the Aztec C65 compiler passes its parameters on a stack but using the C calling convention (in forward order)... pascal is backwards to c. The rwts function takes integer length arguments so it is not hard to calculate the offsets of each parameter passed to the assembly module. The 8 bit architecture of the 6502 makes it difficult to pass values in integers. I realize that I can optimize this module further by using 1 byte parameters from C. This is one of the reasons that Aztec C is less efficient than CC65 which uses 1 byte when Aztec C65 uses two. But it would take me a lifetime to optimize Aztec C65's runtime libraries by myself. So CC65 wins in that area. The stack in Aztec C65 is on zero page. The 6502 series of compilers including the C64 and Atari compilers all use zero page which different offsets but the same regs. While the culprit may be on Zero Page for this problem, it is not obvious to me. Annotated Zero Page listing between versions... the old and the new... Thanks for your help. This is driving me bananas and my knowledge is very limited on 6502 code, DOS 3.3, and the Apple II in general compared to the experts here (I mean that sincerely) so I look forward to your comments: * Comparison to ZPAGE.H From Aztec C 3.2b * Copyright (C) Bill Buckels 2013. All Rights Reserved. * * * The following EQU's are stored directly in the .A65 source. * * Comments for porting DOS 3.3 A65 routines from Aztec C65 3.2b. * * missing - STK EQU $00 ; 8 byte stack area (same offset as VAL) VAL EQU 0 ; same (from blockmv.a65) = STK - 8 byte stack area SP EQU 2 ; same (from blockmv.a65) AFRAME EQU 4 ; same (from OV65.A65) FRAME EQU 4 ; same (from blockmv.a65) LFRAME EQU 6 ; same (from OV65.A65) PC EQU 6 ; same (from blockmv.a65) * missing - TREGS EQU $08 ; 24 byte tmp register area (same offset as R0) R0 EQU 8 ; same (from blockmv.a65) = TREGS - 4 byte tmp register area R1 EQU 12 ; same (from blockmv.a65) R2 EQU 16 ; same (from blockmv.a65) * missing - R3 EQU TREGS+12 (same offset as ACC) * missing - R4 EQU TREGS+16 (same offset as SEC) ACC EQU 20 ; different (from blockmv.a65) = R3 3.2b SEC EQU 22 ; different (from blockmv.a65) = R4 3.2b * different ACC EQU TREGS+20 = ACC+8 (to allow R3 and R4 in 3.2b) * different SEC EQU TREGS+22 = SEC+8 (to allow R3 and R4 in 3.2b) REGS EQU $80 ; same (from OV65.A65) 16 byte user register area * missing - TMP EQU $40 ;4 byte zero page temporary area
[toc] | [prev] | [next] | [standalone]
| From | Antoine Vignau <antoine.vignau@laposte.net> |
|---|---|
| Date | 2013-08-30 12:35 -0700 |
| Message-ID | <2905e0d3-b4fb-4889-81e1-c6c39589d1cc@googlegroups.com> |
| In reply to | #838 |
I would like to help but I do not know Aztec at all, sorry, av
[toc] | [prev] | [next] | [standalone]
| From | "Bill Buckels" <bbuckels@mts.net> |
|---|---|
| Date | 2013-08-30 17:07 -0500 |
| Message-ID | <kvr53q$655$1@speranza.aioe.org> |
| In reply to | #845 |
"Antoine Vignau" <antoine.vignau@laposte.net> wrote: > I would like to help but I do not know Aztec at all, sorry, I am slowly plodding along, and will post my solution Tony. It takes me a long time. For example it took me almost a week back in 1992 to disassemble the mouse firmware on the Apple II so I could relocate it. I can't remember the details, but it seems to me that I wanted it at a fixed location for some reason. That code is still in place in my Aztec C65 stuff today. But 8088 code I could wtite in my sleep and often did:) I am a typical lazy programmer so if someone has time to help I will never refuse:) This is someone's big chance!!! jk of course... Bill
[toc] | [prev] | [next] | [standalone]
| From | "Bill Buckels" <bbuckels@mts.net> |
|---|---|
| Date | 2013-08-30 22:16 -0500 |
| Message-ID | <kvrn7a$ck9$1@speranza.aioe.org> |
| In reply to | #838 |
The following C language function implements DOS 3.3 RWTS (Read Write Track
Sector) for Aztec C65 3.2b. It will be added to the Apple33 distribution for
the next update complete with demo programs.
The rwts() function from the old CII DOS 3.3 compiler was entirely
incompatible with the new 3.2b compiler which also produces ProDOS 8
programs. (The CG65 variant of the 3.2b compiler produces programs for other
6502 platforms like the Commodore 64 and Atari 400/800 and ROMable 6502
code.)
Manx Software never included the rwts() function with the new compiler. This
version is far different from Manx's CII version and follows the more
advanced calling convention of version 3.2b. This is my original work, and
was a little tricky to write and debug. The final version only took a day to
write, but the research took much longer.
You are free to use this code for whatever purpose you wish as long as you
agree that I am not liable in any way whatsoever for its use.
Warning: this program is targetted to DOS 3.3 and C language expert
knowledge level. Use with caution!
Rubywand's DOS Mini-Manual - csa2 version:
http://apple2.org.za/gswv/a2zine/faqs/Csa2DOSMM.html
You can run quite a few DOS 3.3 programs from 3.5" disk, a large RAM disk,
or hard disk. However, there are numerous DOS 3.3 programs which will not
run this way, this one included, and some can even damage files and
directories on the larger media. DOS 3.3 was designed specifically to
support the Disk II drive. Hard disks, RAM disks, and 3.5 disks (like those
used in the Macintosh when it was released in 1984) could not be easily used
with DOS 3.3 (without doing major patching).
http://apple2history.org/history/ah15/
Problems are especially likely when a program modifies and CALLs machine
code routines such as Read/Write Track-Sector (RWTS) and/or makes
assumptions about the physical locations on disk of important DOS 3.3 areas
such as the Volume Table of Contents, CATALOG track, and DOS itself.
Consider yourself warned!
All the Best,
Bill Buckels, August 2013
Code follows:
=========
/* (C) Copyright Bill Buckels 2013.
All rights reserved. */
int rwts(tr, se, buf, cmd, sl, dr, vol)
unsigned tr,se,cmd,sl,dr,vol;
char *buf;
{
struct rwts_iob *r;
unsigned val;
/* read IOB - initialize structure */
val = riob();
/* load variant fields of IOB */
r = (struct rwts_iob *) val;
r->slot = (sl * 16);
r->drive = dr;
r->volume = vol;
r->track = tr;
r->sector = se;
r->buf_addr = (unsigned)&buf[0];
/* Portion of Sector to read
(to read all 256 bytes set to 0) */
r->sect_cnt = 0;
r->cmd_code = cmd;
/* call track sector IO */
val = tsio();
return val;
}
The assembly language functions below are called from the C language
function above and follow the standard C65 32.b and CG65 calling and return
convention:
* TrackSector I/O
* tsio.a65
* Copyright (c) 2013 by Bill Buckels
* the following 2 helper functions are called from
* the Aztec C65 3.2b DOS 3.3 function rwts()
* riob() - get IO buf address
* return IO buf address
* tsio() - track sector IO
* return 0 if success
* return -1 if error
R0 EQU 8
IOB EQU $48
riob_ cseg
public riob_
clc
jsr $3e3 ; get address of RWTS IOB
sta IOB+1 ; IOB address in Y/A)
sty IOB
sta R0+1
sty R0
rts
tsio_ cseg
public tsio_
clc
jsr $3e3 ; get address of RWTS IOB
jsr $3d9 ; call RWTS
ldy #0
bcc .1
dey
.1 sty R0
sty R0+1
rts
The following structures can be is used with the above:
/* Read/Write Track Sector IO Buf Structure */
struct rwts_iob {
unsigned char type;
unsigned char slot;
unsigned char drive;
unsigned char volume;
unsigned char track;
unsigned char sector;
unsigned dev_addr;
unsigned buf_addr;
unsigned char unused;
unsigned char sect_cnt;
unsigned char cmd_code;
unsigned char ret_code;
unsigned char last_v;
unsigned char last_s;
unsigned char last_d;
};
/* Device Characteristics Structure for rwts_iob */
struct rwts_dev {
unsigned char type;
unsigned char phases;
unsigned motor;
};
/* structures for rwts routines */
/* vtoc structure - 256 bytes (1 sector) */
struct vtoc {
char unused;
char ctrack;
char csector;
char version;
char unused2[2];
char volume;
char unused3[32];
char max;
char unused4[8];
char last;
char direction;
char unused5[2];
char tracks;
char sectors;
unsigned bytes;
char bitmap[4][50];
};
/* catalog sector structure - 256 bytes (1 sector) */
struct catsect{
char unused;
char track;
char sector;
char unused2[8];
char f1[35];
char f2[35];
char f3[35];
char f4[35];
char f5[35];
char f6[35];
char f7[35];
};
/* file entry structure - 35 bytes */
struct fentry {
char track;
char sector;
char type;
char name[30];
unsigned int sectors;
};
End of Listing
[toc] | [prev] | [standalone]
Back to top | Article view | comp.sys.apple2.programmer
csiph-web