Zap

Download a compressed, Apple II disk image of the Zap source code.

Zap: a disk and memory editor for Apple UCSD Pascal.

Here's the source code for a disk and memory editor I wrote for Apple's UCSD Pascal bask in 1984. I cleaned up the code, squashed a few bugs and added several conveniences. I also coded the inner loop of the hex conversion is assembler, making it some 50% faster. I was especially pleased with how easy it was to mix assembly with Pascal in the UCSD environment. In contrast, Apple's relocating loader for ProDOS was slow and cumbersome. Later ProDOS compilers, including Kyan and Orca, were a substantial improvement.

If you build the code yourself, you'll have to compile the source (using the system's Compile command) and link the assembly code (using the system's Link command). I use Zap under Apple's version 1.3 (UCSD II.1), but it should work under previous versions.

The disk image contains the file ZAP.TEXT, the source for the current version. The file ZAPA.TEXT is the assembly source, listed here. The file ZAP0.TEXT is the source for an earlier, more portable version. I'd be interested to hear if anyone moves it to another implementation of UCSD Pascal.

The program is provided under the GNU Public License, a copy of which may be found at gnu.org. You should read the license before using zap, noting that there is NO WARRANTY OF ANY KIND. Because here is NO LIABILITY FOR DAMAGES, never use zap on a disk volume for which you do not have a current backup.

Zap: source code.

program tty;

{by John B. Matthews, 5/13/87}

{Kyan Pascal, Apple ][, SSC slot 2}

var ch: char; quit: boolean;


procedure openport;

begin

#a

slot equ $20 ;slot 2

data equ $C088+slot

status equ $C089+slot

command equ $C08A+slot

control equ $C08B+slot

lda #0 ;init buffer pointers

sta bs

sta be

jsr _mli ;install interrupt handler

db $40

dw irqlist

lda #$18 ;1 stop, 8 data, 1200 bps

sta control

lda #9 ;no parity, enable IRQ

sta command

lda data ;throw out garbage

#

end;


{SSC 6551 ACIA rcv interrupt handler}

#a

irq cld

lda status

bmi mine

sec ;not my interrupt

rts

mine tay ;save status

and #8 ;data reg full?

beq claimed

tya ;get status

and #7 ;parity, frame or overrun?

beq read

lda data

lda #'?

bne save

read lda data

save ldy be

sta buf,y

iny

sty be

claimed clc

rts

irqlist db 2,0

dw irq

bs db 0 ;buffer start

be db 0 ;buffer end

buf ds 256 ;circular queue

#


procedure closeport;

begin

#a

lda #2

sta command

lda #1

sta irqlist

jsr _mli

db $41

dw irqlist

lda #2

sta irqlist

#

end;


function getport(var ch:char):boolean;

begin

getport:= false;

#a

sei

ldy bs

cpy be

beq nochar

ldy #6

lda (_sp),y

sta _t

iny

lda (_sp),y

sta _t+1

ldy bs

lda buf,y

iny

sty bs

ldy #0

sta (_t),y

ldy #5

lda #1

sta (_sp),y

nochar cli

#

end;


procedure putport(ch:char);

begin

#a

tdre lda status

and #$10 ;bit 4 set when Tx empty

beq tdre

ldy #5

lda (_sp),y

sta data

#

end;


function keypress(var ch:char):boolean;

begin

keypress:= false;

#a

bit $C000

bpl nokey

ldy #6

lda (_sp),y

sta _t

iny

lda (_sp),y

sta _t+1

lda $C000

and #$7F

ldy #0

sta (_t),y

sta $C010

ldy #5

lda #1

sta (_sp),y

nokey

#

end;


begin {main}

quit:= false;

openport;

repeat

if getport(ch) then write(ch);

if keypress(ch) then begin

putport(ch);

write(ch);

quit:= ch=chr(27)

end;

until quit;

closeport

end. {main}

Zap: assembly listing.

0000| ;HexDump(var source; offset: Integer; var buffer);

0000| ;Convert 16 bytes at source + offset to hex and Ascii;

0000| ;store in buffer; buffer must be at least 64 bytes.

0000|

0000| ;AscDump(var source; offset: Integer; var buffer);

0000| ;Convert 32 bytes at source + offset to Ascii;

0000| ;store in buffer; buffer must be at least 32 bytes.

0000|

0000| .macro pop

0000| pla

0000| sta %1

0000| pla

0000| sta %1+1

0000| .endm

0000|

0000| .macro psh

0000| lda %1+1

0000| pha

0000| lda %1

0000| pha

0000| .endm

0000|

0000| 0000 return .equ 0

0000| 0002 buffer .equ return+2

0000| 0004 offset .equ buffer+2

0000| 0006 source .equ offset+2

0000|

0000| .proc hexdump,3

0000| pop return

0000| 68 # PLA

0001| 85 00 # STA return

0003| 68 # PLA

0004| 85 01 # STA return+1

0006| pop buffer

0006| 68 # PLA

0007| 85 02 # STA buffer

0009| 68 # PLA

000A| 85 03 # STA buffer+1

000C| pop offset

000C| 68 # PLA

000D| 85 04 # STA offset

000F| 68 # PLA

0010| 85 05 # STA offset+1

0012| pop source

0012| 68 # PLA

0013| 85 06 # STA source

0015| 68 # PLA

0016| 85 07 # STA source+1

0018| 18 clc

0019| A5 06 lda source

001B| 65 04 adc offset

001D| 85 06 sta source

001F| A5 07 lda source+1

0021| 65 05 adc offset+1

0023| 85 07 sta source+1

0025| A2 00 ldx #0

0027| 8A hexloop txa

0028| A8 tay

0029| B1 06 lda @source,y

002B| 48 pha

002C| 4A lsr a

002D| 4A lsr a

002E| 4A lsr a

002F| 4A lsr a

0030| 20 **** jsr dohex

0033| 68 pla

0034| 20 **** jsr dohex

0037| A9 20 lda #20

0039| 20 **** jsr store

003C| E8 inx

003D| E0 10 cpx #10

003F| 90E6 bcc hexloop

0041| A0 00 ldy #0

0043| B1 06 ascloop lda @source,y

0045| 29 7F and #7f

0047| C9 20 cmp #20

0049| B0** bcs $1

004B| A9 2E lda #2e

0049* 02

004D| 91 02 $1 sta @buffer,y

004F| C8 iny

0050| C0 10 cpy #10

0052| 90EF bcc ascloop

0054| psh return

0054| A5 01 # LDA return+1

0056| 48 # PHA

0057| A5 00 # LDA return

0059| 48 # PHA

005A| 60 rts

005B|

005B| ;convert lo nibble in A to hex

0035* 5B00

0031* 5B00

005B| 29 0F dohex and #0f

005D| 09 30 ora #30

005F| C9 3A cmp #3a

0061| 90** bcc store

0063| 69 06 adc #06

0065| ;store A in buffer; increment buffer; zeroes Y

0061* 02

003A* 6500

0065| A0 00 store ldy #0

0067| 91 02 sta @buffer,y

0069| E6 02 inc buffer

006B| D0** bne $1

006D| E6 03 inc buffer+1

006B* 02

006F| 60 $1 rts

0070|


0000| .proc ascdump,3

0000| pop return

0000| 68 # PLA

0001| 85 00 # STA return

0003| 68 # PLA

0004| 85 01 # STA return+1

0006| pop buffer

0006| 68 # PLA

0007| 85 02 # STA buffer

0009| 68 # PLA

000A| 85 03 # STA buffer+1

000C| pop offset

000C| 68 # PLA

000D| 85 04 # STA offset

000F| 68 # PLA

0010| 85 05 # STA offset+1

0012| pop source

0012| 68 # PLA

0013| 85 06 # STA source

0015| 68 # PLA

0016| 85 07 # STA source+1

0018| 18 clc

0019| A5 06 lda source

001B| 65 04 adc offset

001D| 85 06 sta source

001F| A5 07 lda source+1

0021| 65 05 adc offset+1

0023| 85 07 sta source+1

0025| A0 00 ldy #0

0027| B1 06 ascloop lda @source,y

0029| 29 7F and #7f

002B| C9 20 cmp #20

002D| B0** bcs $1

002F| A9 2E lda #2e

002D* 02

0031| 91 02 $1 sta @buffer,y

0033| C8 iny

0034| C0 20 cpy #20

0036| 90EF bcc ascloop

0038| psh return

0038| A5 01 # LDA return+1

003A| 48 # PHA

003B| A5 00 # LDA return

003D| 48 # PHA

003E| 60 rts

003F|

003F| .end

Copyright 1984, 2004 John B. Matthews

Distribution permitted under the terms of the GPL: http://www.gnu.org/copyleft/gpl.html.

Last updated 24-May-2008