IEC first partially working version

This commit is contained in:
nino-porcino 2023-10-07 10:20:26 +02:00
parent fea9fa45c2
commit 3e64f6ac69
16 changed files with 1539 additions and 0 deletions

18
demos/iec/apple1.lm Normal file
View File

@ -0,0 +1,18 @@
;=======================================================================================
; APPLE1 SPECIFIC DEFINES
;=======================================================================================
// TODO ascii encoding ?
const WOZMON = $FF1F ; enters monitor
const ECHO = $FFEF ; output ascii character in A (A not destroyed)
const PRBYTE = $FFDC ; print hex byte in A (A destroyed)
const KEY_DATA = $d010 ; read key
const KEY_CTRL = $d011 ; control port
const TERM_DATA = $d012 ; write ascii
const TERM_CTRL = $d013 ; control port
const INBUFFER = $0200 ; woz monitor input buffer
const INBUFSIZE = $80 ; woz monitor input buffer size
const CR = $0D ; carriage return

22
demos/iec/apple1_code.lm Normal file
View File

@ -0,0 +1,22 @@
;=======================================================================================
; APPLE1 SPECIFIC CODE
;=======================================================================================
sub woz_puts()
ldy #0
do
lda (ptr),y
if zero then exit do
jsr ECHO
iny
loop while not zero
end sub
sub getkey()
do
lda KEY_CTRL
loop while not negative
lda KEY_DATA
and #$7f
end sub

68
demos/iec/c64.lm Normal file
View File

@ -0,0 +1,68 @@
processor 6502
; Kernal entries
const GETIN = $ffe4 ; getin rom kernel routine
const CLRSCN = $e544 ; clear screen
const PRNSTR = $ab1e ; print string in A/Y, 0 terminated
const GOHOME = $e566 ; go home
const PRNINT = $bdcd ; print integer in A/X
; zero page
const cursor_ptr = 209
const jiffy_clock = 162
const CRSRCOL = 646
; registers
; color costants
const color_black = 0
const color_white = 1
const color_red = 2
const color_cyan = 3
const color_magenta = 4
const color_green = 5
const color_blue = 6
const color_yellow = 7
; screen costants
const SCREEN_COLS = 40
const SCREEN_ROWS = 25
const VIDEO_MEMORY = 1024
const COLOR_MEMORY = 55296
const COLOR_PAGE_OFFSET = ((color_memory - VIDEO_MEMORY) / 256)
const BASIC_RAM = 2049
const RASTER = $d012
const ROMCHAR = 32768
; useful macros
macro cls
jsr CLRSCN
end macro
mac print
lda #[[{1}_pos]%256]
sta cursor_ptr
lda #[[{1}_pos]/256]
sta cursor_ptr+1
lda #[{1}%256]
ldy #[{1}/256]
jsr my_print
endm
macro waitkey
pha
txa : pha
tya : pha
.lab1
jsr GETIN
cmp #0
beq .lab1
pla : tay
pla : tax
pla
end macro

Binary file not shown.

BIN
demos/iec/docs/disegno.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

BIN
demos/iec/docs/disegno1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

110
demos/iec/iec.lm Normal file
View File

@ -0,0 +1,110 @@
processor 6502
#ifdef C64 then include "c64.lm"
#ifdef C64 then org 2049
#ifdef APPLE1 then include "apple1.lm"
#ifdef APPLE1 then org $280
include "macros.lm"
include "macros_16.lm"
dim ptr as word at 254 ; useful zero page pointer
#ifdef C64
basic start
10 sys {main}
basic end
#endif
main:
PRINTMSG #MSG_OK
call save_file
PRINTMSG #MSG_OK
; clears file content at absolute address
ld16 ptr, #file_content
lda #88 ;'X'
for y=#0 to #15
sta (ptr),y
next
; clears file content at relative address
ld16 ptr, #relative_buffer
lda #88 ;'X'
for y=#0 to #15
sta (ptr),y
next
; do not perform VERIFY when loading
ld VERCK, #0
; prints file content loaded at relative address
PRINTMSG #MSG_RELATIVE_IS
PRINTMSG #relative_buffer
PRINTMSG #MSG_ABSOLUTE_IS
PRINTMSG #file_content
call load_file_relative
PRINTMSG #MSG_OK
call load_file_absolute
PRINTMSG #MSG_OK
; prints file content loaded at relative address
PRINTMSG #MSG_RELATIVE_IS
PRINTMSG #relative_buffer
PRINTMSG #MSG_ABSOLUTE_IS
PRINTMSG #file_content
rts
save_file:
JSR InitPia
ld16 FNADR, #file_name_test
call CalcFileNameLength
ld16 STAL, #file_content
ld16 EAL, #file_content_end
ld FA, #8
ld SA, #1
call SAVE
rts
load_file_relative:
JSR InitPia
ld16 FNADR, #file_name_test
call CalcFileNameLength
ld16 MEMUSS, #relative_buffer
ld FA, #8
ld SA, #0
call LOAD
rts
load_file_absolute:
JSR InitPia
ld16 FNADR, #file_name_test
call CalcFileNameLength
ld FA, #8
ld SA, #1
call LOAD
rts
include "kernal.lm"
#ifdef APPLE1 then include "apple1_code.lm"
file_name_test:
byte "prova",0
file_content:
byte "0123456789ABCDEF"
file_content_end:
byte 13,0 ; filler that allows print as string
relative_buffer:
byte "----------------"
relative_buffer_end:
byte 13,0 ; filler that allows print as string
MSG_OK: byte "OK", 13, 13, 0
MSG_RELATIVE_IS: byte "RELATIVE IS: ",0
MSG_ABSOLUTE_IS: byte "ABSOLUTE IS: ",0

174
demos/iec/kernal.lm Normal file
View File

@ -0,0 +1,174 @@
; Adapted from https://commodore.international/kim-iec/kim1541_public.asm
; zero page locations
STATUS = $90 ;I/O OPERATION STATUS BYTE
C3P0 = $94 ;IEEE BUFFERED CHAR FLAG
BSOUR = $95 ;CHAR BUFFER FOR IEEE
R2D2 = $A3 ;SERIAL BUS USAGE
BSOUR1 = $A4 ;TEMP USED BY SERIAL ROUTINE
COUNT = $A5 ;TEMP USED BY SERIAL ROUTINE
FNLEN = $B7 ;FILENAME LENGTH
FNADR = $BB ;FILENAME ADDRESS
FA = $BA ;FILE PRIMARY ADDRESS
SA = $B9 ;FILE SECONDARY ADDRESS
STAL = $AA ;SAVE END ADDR LOW BYTE FOR SAVE ROUTINE
STAH = $AB ;SAVE END ADDR HIGH BYTE FOR SAVE ROUTINE
SAL = $AC ;START ADDR LOW BYTE FOR SAVE ROUTINE
SAH = $AD ;START ADDR HIGH BYTE FOR SAVE ROUTINE
EAL = $AE ;END ADDRESS LOW BYTE
EAH = $AF ;END ADDRESS HIGH BYTE
MEMUSS = $C3 ;USER SPECIFIED FILE LOAD ADDRESS
VERCK = $0A ;LOAD OR VERIFY FLAG
SPERR = 16 ;VERIFY ERROR IN STATUS
FNAME = $27 ;FILENAME
#ifdef C64
const D2PRA = $DD00 ;CIA2 PERIPHERAL DATA REGISTER A ON C64
const D2DDRA = $DD02 ;CIA2 PERIPHERAL DATA DIR REGISTER A ON C64
const D1T2H = $DC07 ;CIA1 TIMER B HIGH BYTE VALUE
const D1ICR = $DC0D ;CIA1 INTERRUPT CONTROL REGISTER
const D1CRB = $DC0F ;CIA1 CONTROL REGISTER TIMER B
const TIMRB = $19 ;6526 CRB ENABLE ONE-SHOT TB
const BIT_ATN_OUT = %00001000 ; ($08) CIA2 at $DD00 Bit 3: ATN OUT
const BIT_CLK_OUT = %00010000 ; ($10) CIA2 at $DD00 Bit 4: CLOCK OUT
const BIT_DATA_OUT = %00100000 ; ($20) CIA2 at $DD00 Bit 5: DATA OUT
const BIT_CLK_IN = %01000000 ; ($40) CIA2 at $DD00 Bit 6: CLOCK IN
const BIT_DATA_IN = %10000000 ; ($80) CIA2 at $DD00 Bit 7: DATA IN
#endif
#ifdef APPLE1
const D2PRA = $A000 ;VIA PORT B ON APPLE1
const D2DDRA = $A002 ;VIA PORT B DATA DIRECTION REGISTER ON APPLE1
const D1ACR = $A00B ;VIA ACR ON APPLE1
const D2IFR = $A00D ;VIA IFR ON APPLE1
const D2T2H = $A009 ;VIA TIMER 2 HIGH BYTE
const TIMRB = #%01000000 ; FREE RUNNING T1 T2 ONESHOT D1
const BIT_ATN_OUT = %00000100 ; Bit 2: ATN OUT
const BIT_CLK_OUT = %00001000 ; Bit 3: CLOCK OUT
const BIT_DATA_OUT = %00010000 ; Bit 4: DATA OUT
const BIT_CLK_IN = %00100000 ; Bit 5: CLOCK IN
const BIT_DATA_IN = %01000000 ; Bit 6: DATA IN
#endif
/*
byte *const VIA_PORTB = (byte *) 0xA000; // port B register
byte *const VIA_PORTA = (byte *) 0xA001; // port A register
byte *const VIA_DDRB = (byte *) 0xA002; // port A data direction register
byte *const VIA_DDRA = (byte *) 0xA003; // port B data direction register
byte *const VIA_T1CL = (byte *) 0xA004; //
byte *const VIA_T1CH = (byte *) 0xA005; //
byte *const VIA_T1LL = (byte *) 0xA006; //
byte *const VIA_T1LH = (byte *) 0xA007; //
byte *const VIA_T2CL = (byte *) 0xA008; //
byte *const VIA_T2CH = (byte *) 0xA009; //
byte *const VIA_SR = (byte *) 0xA00A; //
byte *const VIA_ACR = (byte *) 0xA00B; //
byte *const VIA_PCR = (byte *) 0xA00C; //
byte *const VIA_IFR = (byte *) 0xA00D; //
byte *const VIA_IER = (byte *) 0xA00E; //
byte *const VIA_PORTANH = (byte *) 0xA00F; //
*/
const PRA_INIT_VALUE = $FF-BIT_ATN_OUT-BIT_CLK_OUT-BIT_DATA_OUT-BIT_CLK_IN-BIT_DATA_IN ; all IEC bits to "0"
const PRA_INIT_DIR = $FF-BIT_CLK_IN-BIT_DATA_IN ; CLK_IN AND DATA_IN "0", others "1"
; make "ASL A" compatible with "ASL"
MACRO ASL "A"
ASL
END MACRO
include "kernal_serial.lm"
include "kernal_load.lm"
include "kernal_save.lm"
MACRO PRINTMSG const
#ifdef APPLE1
LD16 ptr, #{1}
call print_string
#endif
#ifdef C64
LD16 ptr, #{1}
call print_string
#endif
END MACRO
LUKING:
PRINTMSG #MSG_SEARCHING
RTS
LODING:
PRINTMSG #MSG_LOADING
RTS
SAVING:
PRINTMSG #MSG_SAVING
RTS
ERROR8:
PRINTMSG #MSG_MISSING
RTS
ERROR4:
PRINTMSG #MSG_NOT_FOUND
RTS
ERROR5:
PRINTMSG #MSG_DEVICE_NP
RTS
MSG_SEARCHING: BYTE "searching",13,0
MSG_LOADING: BYTE "loading",13,0
MSG_SAVING: BYTE "saving",13,0
MSG_MISSING: BYTE "?missing file name",13,0
MSG_NOT_FOUND: BYTE "?file not found",13,0
MSG_DEVICE_NP: BYTE "?device not present",13,0
SUB print_string()
tya : pha
txa : pha
#ifdef APPLE1
call woz_puts
#endif
#ifdef C64
lda ptr
ldy ptr+1
call PRNSTR
#endif
pla : tax
pla : tay
END SUB
SUB CalcFileNameLength()
LDY #$FF
DO
INY
LDA (FNADR),Y
LOOP WHILE NOT ZERO
STY FNLEN
END SUB
SUB InitPia()
CLD ; NO DECIMAL MODE
SEI ; NO INTERRUPTS
#ifdef C64
LD D2PRA, #PRA_INIT_VALUE ;SETS ALL IEC BITS TO LOW ($07) (#%00000111)
LD D2DDRA, #PRA_INIT_DIR ;SET DATA DIRECTION FOR REGISTER A ($3f) (#%00111111)
#endif
#ifdef APPLE1
LD D2PRA, #PRA_INIT_VALUE ;SETS ALL IEC BITS TO LOW
LD D2DDRA, #PRA_INIT_DIR ;SET DATA DIRECTION FOR REGISTER A
LD D1ACR, #TIMRB ;FREE RUNNING T1 T2 ONESHOT D1 (#%01000000)
lda #0
sta STATUS
sta C3P0
sta BSOUR
sta R2D2
sta BSOUR1
;sta COUNT
#endif
END SUB

148
demos/iec/kernal_load.lm Normal file
View File

@ -0,0 +1,148 @@
LOAD
;********************************
;* C64 KERNAL IEEE LOAD ROUTINE *
;********************************
;LOAD FROM CBM IEEE DEVICE
;
LDY FNLEN ;MUST HAVE FILE NAME
BNE LD25 ;YES...OK
;
JMP ERROR8 ;MISSING FILE NAME
;
LD25 LDX SA ;SAVE SA IN .X
JSR LUKING ;TELL USER LOOKING
LDA #$60 ;SPECIAL LOAD COMMAND
STA SA
JSR OPENI ;OPEN THE FILE
;
LDA FA
JSR TALK ;ESTABLISH THE CHANNEL
LDA SA
JSR TKSA ;TELL IT TO LOAD
;
JSR ACPTR ;GET FIRST BYTE
STA EAL
;
LDA STATUS ;TEST STATUS FOR ERROR
LSR
LSR
BCS LD90 ;FILE NOT FOUND...
JSR ACPTR ;GET SECOND BYTE
STA EAH
;
TXA ;FIND OUT OLD SA
BNE LD30 ;SA<>0 USE DISK ADDRESS
LDA MEMUSS ;ELSE LOAD WHERE USER WANTS
STA EAL
LDA MEMUSS+1
STA EAH
LD30 JSR LODING ;TELL USER LOADING
;
LD40 LDA #$FD ;MASK OFF TIMEOUT
AND STATUS
STA STATUS
;
;JSR STOP ;STOP KEY?
;BNE LD45 ;NO...
;
;JMP BREAK ;STOP KEY PRESSED
;
LD45 JSR ACPTR ;GET BYTE OFF IEEE
TAX
LDA STATUS ;WAS THERE A TIMEOUT?
LSR
LSR
BCS LD40 ;YES...TRY AGAIN
TXA
LDY VERCK ;PERFORMING VERIFY?
BEQ LD50 ;NO...LOAD
LDY #0
CMP (EAL),Y ;VERIFY IT
BEQ LD60 ;O.K....
LDA #SPERR ;NO GOOD...VERIFY ERROR
JSR UDST ;UPDATE STATUS
.BYTE $2C ;SKIP NEXT STORE
;
LD50 STA (EAL),Y
LD60 INC EAL ;INCREMENT STORE ADDR
BNE LD64
INC EAH
LD64 BIT STATUS ;EOI?
BVC LD40 ;NO...CONTINUE LOAD
;
JSR UNTLK ;CLOSE CHANNEL
JSR CLSEI ;CLOSE THE FILE
BCC LD180 ;BRANCH ALWAYS
;
LD90 JMP ERROR4 ;FILE NOT FOUND
;
OPENI LDA SA
BMI OP175 ;NO SA...DONE
LDY FNLEN
BEQ OP175 ;NO FILE NAME...DONE
;
LDA #0 ;CLEAR THE SERIAL STATUS
STA STATUS
;
LDA FA
JSR LISTN ;DEVICE LA TO LISTEN
;
LDA SA
ORA #$F0
JSR SECND
;
LDA STATUS ;ANYBODY HOME?
BPL OP35 ;YES...CONTINUE
;
;THIS ROUTINE IS CALLED BY OTHER
;KERNAL ROUTINES WHICH ARE CALLED
;DIRECTLY BY OS. KILL RETURN
;ADDRESS TO RETURN TO OS.
;
PLA
PLA
JMP ERROR5 ;DEVICE NOT PRESENT
;
OP35 LDA FNLEN
BEQ OP45 ;NO NAME...DONE SEQUENCE
;
;SEND FILE NAME OVER SERIAL
;
LDY #0
OP40 LDA (FNADR),Y
JSR CIOUT
INY
CPY FNLEN
BNE OP40
;
OP45 JMP CUNLSN ;JSR UNLSN: CLC: RTS
;
UDST ORA STATUS
STA STATUS
RTS
;
CLSEI BIT SA
BMI CLSEI2
LDA FA
JSR LISTN
LDA SA
AND #$EF
ORA #$E0
JSR SECND
;
CUNLSN JSR UNLSN ;ENTRY FOR OPENI
;
CLSEI2 CLC
RTS
;
LD180 CLC ;GOOD EXIT
;
; SET UP END LOAD ADDRESS
;
LDX EAL
LDY EAH
;
OP175 CLC ;FLAG GOOD OPEN
OP180 RTS ;EXIT IN PEACE

60
demos/iec/kernal_save.lm Normal file
View File

@ -0,0 +1,60 @@
SAVE
LDA #$61 ; "OPEN" COMMAND CHANNEL 1
STA SA
LDY FNLEN
BNE SV25
;
JMP ERROR8 ;MISSING FILE NAME
;
SV25 JSR OPENI
JSR SAVING
LDA FA
JSR LISTN
LDA SA
JSR SECND
LDY #0
JSR RD300
LDA SAL
JSR CIOUT
LDA SAH
JSR CIOUT
SV30 JSR CMPSTE ;COMPARE START TO END
BCS SV50 ;HAVE REACHED END
LDA (SAL),Y
JSR CIOUT
;JSR STOP
;BNE SV40
;
;BREAK JSR CLSEI
; LDA #0
; SEC
; RTS
;
SV40 JSR INCSAL ;INCREMENT CURRENT ADDR.
BNE SV30
SV50 JSR UNLSN
JSR CLSEI
;
JMP CUNLSN
;
RD300 LDA STAH ; RESTORE STARTING ADDRESS...
STA SAH ;...POINTERS (SAH & SAL)
LDA STAL
STA SAL
RTS
;COMPARE START AND END LOAD/SAVE
;ADDRESSES. SUBROUTINE CALLED BY
;TAPE READ, SAVE, TAPE WRITE
;
CMPSTE SEC
LDA SAL
SBC EAL
LDA SAH
SBC EAH
RTS
;
INCSAL INC SAL
BNE INCR
INC SAH
INCR RTS

336
demos/iec/kernal_serial.lm Normal file
View File

@ -0,0 +1,336 @@
;adapted from https://github.com/mist64/cbmsrc/blob/master/KERNAL_C64_02/serial4.0
;.PAG 'SERIAL ROUTINES'
;COMMAND SERIAL BUS DEVICE TO TALK
;
TALK ORA #$40 ;MAKE A TALK ADR
.BYTE $2C ;SKIP TWO BYTES
;
;COMMAND SERIAL BUS DEVICE TO LISTEN
;
LISTN ORA #$20 ;MAKE A LISTEN ADR
; @@@ JSR RSP232 ;PROTECT SELF FROM RS232 NMI'S --- disabled
LIST1 PHA
;
;
BIT C3P0 ;CHARACTER LEFT IN BUF?
BPL LIST2 ;NO...
;
;SEND BUFFERED CHARACTER
;
SEC ;SET EOI FLAG
ROR R2D2
;
JSR ISOUR ;SEND LAST CHARACTER
;
LSR C3P0 ;BUFFER CLEAR FLAG
LSR R2D2 ;CLEAR EOI FLAG
;
;
LIST2 PLA ;TALK/LISTEN ADDRESS
STA BSOUR
; @@@ SEI
JSR DATAHI
CMP #$3F ;CLKHI ONLY ON UNLISTEN --- is this a bug?
BNE LIST5
JSR CLKHI
;
LIST5 LDA D2PRA ;ASSERT ATTENTION
ORA #BIT_ATN_OUT
STA D2PRA
;
ISOURA NOP ; @@@ SEI
JSR CLKLO ;SET CLOCK LINE LOW
JSR DATAHI
JSR W1MS ;DELAY 1 MS
;
ISOUR NOP ; @@@ SEI ;NO IRQ'S ALLOWED
JSR DATAHI ;MAKE SURE DATA IS RELEASED
JSR DEBPIA ;DATA SHOULD BE LOW
BCS NODEV
JSR CLKHI ;CLOCK LINE HIGH
BIT R2D2 ;EOI FLAG TEST
BPL NOEOI
; DO THE EOI
ISR02 JSR DEBPIA ;WAIT FOR DATA TO GO HIGH
BCC ISR02
;
ISR03 JSR DEBPIA ;WAIT FOR DATA TO GO LOW
BCS ISR03
;
NOEOI JSR DEBPIA ;WAIT FOR DATA HIGH
BCC NOEOI
JSR CLKLO ;SET CLOCK LOW
;
; SET TO SEND DATA
;
LDA #$08 ;COUNT 8 BITS
STA COUNT
;
ISR01
LDA D2PRA ;DEBOUNCE THE BUS
CMP D2PRA
BNE ISR01
ASL A ;SET THE FLAGS
#ifdef APPLE1 then ASL
BCC FRMERR ;DATA MUST BE HI
;
ROR BSOUR ;NEXT BIT INTO CARRY
BCS ISRHI
JSR DATALO
BNE ISRCLK
ISRHI JSR DATAHI
ISRCLK JSR CLKHI ;CLOCK HI
NOP
NOP
NOP
NOP
LDA D2PRA
AND #$FF-BIT_DATA_OUT ;DATA HIGH
ORA #BIT_CLK_OUT ;CLOCK LOW
STA D2PRA
DEC COUNT
BNE ISR01
#ifdef C64
LDA #$04 ;SET TIMER FOR 1MS
STA D1T2H
LDA #TIMRB ;TRIGGER TIMER
STA D1CRB ;--- timer starts here
LDA D1ICR ;CLEAR THE TIMER FLAGS<<<<<<<<<<<<<
ISR04 LDA D1ICR ;--- read timer flag
AND #$02 ;--- $02 is underflow timer B (ICR bit 1)
BNE FRMERR
JSR DEBPIA
BCS ISR04
#endif
#ifdef APPLE1
LDA #$04 ;SET TIMER FOR 1MS
STA D2T2H ;--- timer starts here, flag cleared
ISR04 LDA D2IFR ;--- read timer flag
AND #$20 ;--- $20 is timer 2 (IFR bit 5)
BNE FRMERR
JSR DEBPIA
BCS ISR04
#endif
; @@@ CLI ;LET IRQ'S CONTINUE
RTS
;
NODEV ;DEVICE NOT PRESENT ERROR
LDA #$80
.BYTE $2C
FRMERR ;FRAMING ERROR
LDA #$03
CSBERR JSR UDST ;COMMODORE SERIAL BUSS ERROR ENTRY
; @@@ CLI ;IRQ'S WERE OFF...TURN ON
CLC ;MAKE SURE NO KERNAL ERR
BCC DLABYE ;TURN ATN OFF ,RELEASE ALL LINES
;
;SEND SECONDARY ADDRESS AFTER LISTEN
;
SECND STA BSOUR ;BUFFER CHARACTER
JSR ISOURA ;SEND IT
;RELEASE ATTENTION AFTER LISTEN
;
SCATN LDA D2PRA
AND #$FF-BIT_ATN_OUT
STA D2PRA ;RELEASE ATTENTION
RTS
;TALK SECOND ADDRESS
;
TKSA STA BSOUR ;BUFFER CHARACTER
JSR ISOURA ;SEND SECOND ADDR
TKATN ;SHIFT OVER TO LISTENER
; @@@ SEI ;NO IRQ'S HERE
JSR DATALO ;DATA LINE LOW
JSR SCATN
JSR CLKHI ;CLOCK LINE HIGH JSR/RTS
TKATN1 JSR DEBPIA ;WAIT FOR CLOCK TO GO LOW
BMI TKATN1
; @@@ CLI ;IRQ'S OKAY NOW
RTS
;BUFFERED OUTPUT TO SERIAL BUS
;
CIOUT BIT C3P0 ;BUFFERED CHAR?
BMI CI2 ;YES...SEND LAST
;
SEC ;NO...
ROR C3P0 ;SET BUFFERED CHAR FLAG
BNE CI4 ;BRANCH ALWAYS
;
CI2 PHA ;SAVE CURRENT CHAR
JSR ISOUR ;SEND LAST CHAR
PLA ;RESTORE CURRENT CHAR
CI4 STA BSOUR ;BUFFER CURRENT CHAR
CLC ;CARRY-GOOD EXIT
RTS
;SEND UNTALK COMMAND ON SERIAL BUS
;
UNTLK NOP ; @@@ SEI
JSR CLKLO
LDA D2PRA ;PULL ATN
ORA #BIT_ATN_OUT
STA D2PRA
LDA #$5F ;UNTALK COMMAND
.BYTE $2C ;SKIP TWO BYTES
;SEND UNLISTEN COMMAND ON SERIAL BUS
;
UNLSN LDA #$3F ;UNLISTEN COMMAND
JSR LIST1 ;SEND IT
;
; RELEASE ALL LINES
DLABYE JSR SCATN ;ALWAYS RELEASE ATN
; DELAY THEN RELEASE CLOCK AND DATA
;
DLADLH TXA ;DELAY APPROX 60 US
LDX #10
DLAD00 DEX
BNE DLAD00
TAX
JSR CLKHI
JMP DATAHI
;INPUT A BYTE FROM SERIAL BUS
;
ACPTR
SEI ;NO IRQ ALLOWED
LDA #$00 ;SET EOI/ERROR FLAG
STA COUNT
JSR CLKHI ;MAKE SURE CLOCK LINE IS RELEASED
ACP00A JSR DEBPIA ;WAIT FOR CLOCK HIGH
BPL ACP00A
#ifdef C64
EOIACP
LDA #$01 ;SET TIMER 2 FOR 256US
STA D1T2H
LDA #TIMRB
STA D1CRB
JSR DATAHI ;DATA LINE HIGH (MAKES TIMMING MORE LIKE VIC-20
LDA D1ICR ;CLEAR THE TIMER FLAGS<<<<<<<<<<<<
ACP00 LDA D1ICR
AND #$02 ;CHECK THE TIMER
BNE ACP00B ;RAN OUT.....
JSR DEBPIA ;CHECK THE CLOCK LINE
BMI ACP00 ;NO NOT YET
BPL ACP01 ;YES.....
#endif
#ifdef APPLE1
EOIACP LDA #$01 ;SET TIMER 2 FOR 256US
STA D2T2H
JSR DATAHI ;DATA LINE HIGH (MAKES TIMMING MORE LIKE VIC-20
ACP00 LDA D2IFR
AND #$20 ;CHECK THE TIMER
BNE ACP00B ;RAN OUT.....
JSR DEBPIA ;CHECK THE CLOCK LINE
BMI ACP00 ;NO NOT YET
BPL ACP01 ;YES.....
#endif
;
ACP00B LDA COUNT ;CHECK FOR ERROR (TWICE THRU TIMEOUTS)
BEQ ACP00C
LDA #2
JMP CSBERR ; ST = 2 READ TIMEOUT
;
; TIMER RAN OUT DO AN EOI THING
;
ACP00C JSR DATALO ;DATA LINE LOW
JSR CLKHI ; DELAY AND THEN SET DATAHI (FIX FOR 40US C64)
LDA #$40
JSR UDST ;OR AN EOI BIT INTO STATUS
INC COUNT ;GO AROUND AGAIN FOR ERROR CHECK ON EOI
BNE EOIACP
;
; DO THE BYTE TRANSFER
;
ACP01 LDA #8 ;SET UP COUNTER
STA COUNT
;
ACP03 LDA D2PRA ;WAIT FOR CLOCK HIGH
CMP D2PRA ;DEBOUNCE
BNE ACP03
ASL A ;SHIFT DATA INTO CARRY
#ifdef APPLE1 then ASL
BPL ACP03 ;CLOCK STILL LOW...
ROR BSOUR1 ;ROTATE DATA IN
;
ACP03A LDA D2PRA ;WAIT FOR CLOCK LOW
CMP D2PRA ;DEBOUNCE
BNE ACP03A
ASL A
#ifdef APPLE1 then ASL
BMI ACP03A
DEC COUNT
BNE ACP03 ;MORE BITS.....
;...EXIT...
JSR DATALO ;DATA LOW
BIT STATUS ;CHECK FOR EOI
BVC ACP04 ;NONE...
;
JSR DLADLH ;DELAY THEN SET DATA HIGH
;
ACP04 LDA BSOUR1
; @@@ CLI ;IRQ IS OK
CLC ;GOOD EXIT
RTS
;
CLKHI ;SET CLOCK LINE HIGH (INVERTED)
LDA D2PRA
AND #$FF-BIT_CLK_OUT
STA D2PRA
RTS
;
CLKLO ;SET CLOCK LINE LOW (INVERTED)
LDA D2PRA
ORA #BIT_CLK_OUT
STA D2PRA
RTS
;
DATAHI ;SET DATA LINE HIGH (INVERTED)
LDA D2PRA
AND #$FF-BIT_DATA_OUT
STA D2PRA
RTS
;
DATALO ;SET DATA LINE LOW (INVERTED)
LDA D2PRA
ORA #BIT_DATA_OUT
STA D2PRA
RTS
;
DEBPIA LDA D2PRA ;DEBOUNCE THE PIA
CMP D2PRA
BNE DEBPIA
#ifdef APPLE1 then ASL
ASL A ;SHIFT THE DATA BIT INTO THE CARRY...
RTS ;...AND THE CLOCK INTO NEG FLAG
;
W1MS ;DELAY 1MS USING LOOP
TXA ;SAVE .X
LDX #200-16 ;1000US-(1000/500*8=#40US HOLDS)
W1MS1 DEX ;5US LOOP
BNE W1MS1
TAX ;RESTORE .X
RTS
;.END
;*******************************
;WRITTEN 8/11/80 BOB FAIRBAIRN
;TEST SERIAL0.6 8/12/80 RJF
;CHANGE I/O STRUCTURE 8/21/80 RJF
;MORE I/O CHANGES 8/24/80 RJF
;FINAL RELEASE INTO KERNAL 8/26/80 RJF
;SOME CLEAN UP 9/8/80 RSR
;ADD IRQ PROTECT ON ISOUR AND TKATN 9/22/80 RSR
;FIX UNTALK 10/7/80 RSR
;MODIFY FOR VIC-40 I/O SYSTEM 12/08/81 RSR
;ADD SEI TO (UNTLK,ISOURA,LIST2) 12/14/81 RSR
;MODIFY FOR 6526 FLAGS FIX ERRS 12/31/81 RSR
;MODIFY FOR COMMODORE 64 I/O 3/11/82 RSR
;CHANGE ACPTR EOI FOR BETTER RESPONSE 3/28/82 RSR
;CHANGE WAIT 1 MS ROUTINE FOR LESS CODE 4/8/82 RSR
;******************************
;.END

18
demos/iec/m.bat Normal file
View File

@ -0,0 +1,18 @@
@echo off
set DASM=C:\Users\Nino1\Desktop\USB\compilers\dasm\dasm.exe
set ASMPROC=call asmproc
rem set ASMPROC=node ..\..\asmproc\dist\asmproc
%ASMPROC% -i iec.lm -o iec.asm -t dasm -d APPLE1
if %errorlevel% == -1 goto fine
%DASM% iec.asm -f1 -liec.lst -oiec.prg
if %errorlevel% == -1 goto fine
call node ..\..\tools\prg2bin.js -i iec.prg -o iec#060280
echo "ALL OK!"
:fine

170
demos/iec/macros.lm Normal file
View File

@ -0,0 +1,170 @@
;
; Aliases
;
MACRO poke mem, const
lda #{2}
sta {1}
END MACRO
MACRO call mem
jsr {1}
END MACRO
macro ret
rts
end macro
macro push "a"
pha
end macro
macro pop "a"
pla
end macro
macro or mem
ora {1}
end macro
macro or const
ora #{1}
end macro
;
; Easy loads
;
macro ld "a", mem
lda {2}
end macro
macro ld "a", const
lda #{2}
end macro
macro ld "a", indirect
ldy #0
lda {2},y
end macro
macro ld "x", mem
ldx {2}
end macro
macro ld "x", const
ldx #{2}
end macro
macro ld "y", mem
ldy {2}
end macro
macro ld "y", const
ldy #{2}
end macro
macro ld mem, "a"
sta {1}
end macro
macro ld mem, "x"
stx {1}
end macro
macro ld mem, "y"
sty {1}
end macro
macro ld "a", "x"
txa
end macro
macro ld "a", "y"
tya
end macro
macro ld "x", "a"
tax
end macro
macro ld "y", "a"
tay
end macro
MACRO ld "ya", const
lda #(({2}) MOD 256)
ldy #(({2})/256)
END MACRO
MACRO ld "ya", mem
lda {1}
ldy {1}+1
END MACRO
macro ld mem, mem
lda {2}
sta {1}
end macro
macro ld mem, const
lda #{2}
sta {1}
end macro
macro ld indirect, "a"
ldy #0
sta {1},y
end macro
;
; Easy add and sub
;
MACRO add mem
clc
adc {1}
END MACRO
MACRO add const
clc
adc #{1}
END MACRO
MACRO add mem, const
clc
lda {1}
adc #{2}
sta {1}
END MACRO
MACRO add mem, mem
clc
lda {1}
adc {2}
sta {1}
END MACRO
MACRO sub mem
sec
sbc {1}
END MACRO
MACRO sub const
sec
sbc #{1}
END MACRO
MACRO sub mem, const
sec
lda {1}
sbc #{2}
sta {1}
END MACRO
MACRO sub mem, mem
sec
lda {1}
sbc {2}
sta {1}
END MACRO

271
demos/iec/macros_16.lm Normal file
View File

@ -0,0 +1,271 @@
; ======================================================
; Macros for 16 bit operations
; The suffix "16" is added to common opcodes, eg "add16"
; Only the A register is used (except ld16 (indirect))
; ======================================================
; Summary
; add16, adc16
; sub16, sbc16
; inc16, dec16
; ld16
; cmp16
; shr16, shl16
; push16, pop16
macro add16 mem, const
lda {1}
clc
adc #(({2}) MOD 256)
sta {1}
lda {1}+1
#if {2} < 256
if carry then inc {1}+1
#else
adc #(({2})/256)
sta {1}+1
#endif
end macro
macro add16 mem, mem
lda {1}
clc
adc {2}
sta {1}
lda {1}+1
adc {2}+1
sta {1}+1
end macro
macro add16 mem, const, "1"
lda {1}
sec
adc #(({2}) MOD 256)
sta {1}
lda {1}+1
adc #({2}/256)
sta {1}+1
end macro
macro add16 mem, mem, "1"
lda {1}
sec
adc {2}
sta {1}
lda {1}+1
adc {2}+1
sta {1}+1
end macro
macro adc16 mem, const
lda {1}
adc #(({2}) MOD 256)
sta {1}
lda {1}+1
#if {2} < 256
bcc .local_out
inc {1}+1
#else
adc #(({2})/256)
sta {1}+1
#endif
.local_out:
end macro
macro adc16 mem, mem
lda {1}
adc {2}
sta {1}
lda {1}+1
adc {2}+1
sta {1}+1
end macro
macro sub16 mem, const
lda {1}
sec
sbc #(({2}) MOD 256)
sta {1}
lda {1}+1
sbc #(({2})/256)
sta {1}+1
end macro
macro sub16 mem, mem
lda {1}
sec
sbc {2}
sta {1}
lda {1}+1
sbc {2}+1
sta {1}+1
end macro
macro sub16 mem, const, "1"
lda {1}
clc
sbc #(({2}) MOD 256)
sta {1}
lda {1}+1
sbc #(({2})/256)
sta {1}+1
end macro
macro sub16 mem, mem, "1"
lda {1}
clc
sbc {2}
sta {1}
lda {1}+1
sbc {2}+1
sta {1}+1
end macro
macro sbc16 mem, const
lda {1}
sbc #(({2}) MOD 256)
sta {1}
lda {1}+1
sbc #(({2})/256)
sta {1}+1
end macro
macro sbc16 mem, mem
lda {1}
sbc {2}
sta {1}
lda {1}+1
sbc {2}+1
sta {1}+1
end macro
macro inc16 mem
inc {1}
if zero then inc {1}+1
end macro
macro dec16 mem
dec {1}
if negative then dec {1}+1
end macro
macro ld16 "ay", const
lda #(({2}) MOD 256)
ldy #(({2})/256)
end macro
macro ld16 "ay", mem
lda {2}
ldy {2}+1
end macro
macro ld16 "ax", const
lda #(({2}) MOD 256)
ldx #(({2})/256)
end macro
macro ld16 "ax", mem
lda {2}
ldx {2}+1
end macro
macro ld16 mem, "ay"
sta {1}
sty {1}+1
end macro
macro ld16 mem, "ax"
sta {1}
stx {1}+1
end macro
macro ld16 mem, const
lda #(({2}) MOD 256)
sta {1}
#if (({2}) MOD 256) != (({2})/256)
lda #(({2})/256)
#endif
sta {1}+1
end macro
macro ld16 mem, mem
lda {2}
sta {1}
lda {2}+1
sta {1}+1
end macro
macro ld16 indirect, mem
ldy #0
lda {2}
sta ({1}),y
lda {2}+1
iny
sta ({1}),y
end macro
macro ld16 indirect, const
ldy #0
lda #({2} MOD 256)
sta ({1}),y
lda #({2}/256)
iny
sta ({1}),y
end macro
macro cmp16 mem, const
lda {1}+1
cmp #(({2})/256)
if zero then
lda {1}
cmp #(({2}) MOD 256)
end if
end macro
macro cmp16 mem, mem
lda {1}+1
cmp {2}+1
if zero then
lda {1}
cmp {2}
end if
end macro
macro shl16 mem
asl {1}
rol {1}+1
end macro
macro shr16 mem
lsr {1}
ror {1}+1
end macro
macro push16 mem
lda {1}
pha
lda {1}+1
pha
end macro
macro push16 const
lda #(({1}) MOD 256)
pha
lda #(({1})/256)
pha
end macro
macro pop16 mem
pla
sta {1}+1
pla
sta {1}
end macro
macro mul16 mem, const
ECHO "to be implemented"
end macro
macro mul16 mem, mem
ECHO "to be implemented"
end macro

105
demos/iec/read_file.lm Normal file
View File

@ -0,0 +1,105 @@
//
// this is an example of reading a file with the high-level kernal routines
//
/*
basic start
5 POKE 36879,8:PRINT "{clr}{wht}";
6 REM the ReadFile() function does something like this:
10 LA=7680
20 OPEN 1,8,2,"iec"
30 IF ST<>0 THEN GOTO 60
40 GET#1,A$:IF A$="" THEN A$=CHR$(0)
50 POKE LA,ASC(A$):LA=LA+1:GOTO 30
60 CLOSE 1
basic end
*/
basic start
5 POKE 36879,8:PRINT "{clr}{wht}";
10 print "{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}disk drive test"
20 sys {main}
basic end
main:
call ReadFile
rts
const SETNAM = $FFBD ; Kernal Set Filename
const SETLFS = $FFBA ; Kernal Set Logical First and Secondary
const ICHKIN = $FFC6 ; Kernal Set Input
const READST = $FFB7 ; Kernal read status byte
const ICHRIN = $FFCF ; Kernal read a byte from file
const ICLOSE = $FFC3 ; Kernal close
const ICLRCH = $FFCC ; Kernal clear channel
#ifdef C64
const load_address = 1024
#endif
#ifdef VIC20
const load_address = 7680
#endif
sub ReadFile()
ld16 $ae, #load_address ; destination buffer
LDA #fname_end-fname
LDX #<fname
LDY #>fname
JSR SETNAM
LDA #$02 ; file number 2
LDX #$08 ; default to device 8
LDY #$02 ; secondary address 2
JSR $FFBA ; call SETLFS
JSR $FFC0 ; call OPEN
; check if the file could not be opened
if carry then
jsr open_error ; handle open error
jmp close ; even if OPEN failed, the file has to be closed
end if
LDX #$02 ; filenumber 2
JSR ICHKIN ; file 2 now used as input
LDY #$00 ; keep y indexing at 0
do
JSR READST ; read status byte
if not zero then exit do ; either EOF or read error
JSR ICHRIN ; get a byte from file
STA ($AE),Y ; write byte to memory
inc16 $ae ; increment pointer
loop while not zero
AND #$40 ; end of file?
if zero then jsr read_error
close:
LDA #$02 ; filenumber 2
JSR ICLOSE
JSR ICLRCH
RTS
open_error:
; Akkumulator contains BASIC error code
; most likely errors:
; A = $05 (DEVICE NOT PRESENT)
;... error handling for open errors ...
lda #00
sta load_address
rts
read_error:
; for further information, the drive error channel has to be read
;... error handling for read errors ...
lda #01
sta load_address
rts
end sub
fname:
byte "iec"
fname_end:

39
demos/iec/x.lm Normal file
View File

@ -0,0 +1,39 @@
basic start
100 print "{wht}saving file"
110 sys {save_file}
120 GOSUB 2000:rem stampa ST
130 gosub 1000:rem read file with basic
140 gosub 200:rem read file with lm
150 end
200 rem =============================
205 print "loading file at $2000"
210 sys {load_file}
220 print "load ok"
230 l={file_content_end}-{file_content_start}
240 for t=0 to l-1
250 poke 1024+t,peek(8192+t)
260 next
270 return
1000 rem ========================
1005 REM reads the file "prova"
1006 print "reading back file"
1007 C=0
1010 OPEN 1,8,2,"prova"
1020 IF ST<>0 THEN GOTO 1050
1030 GET#1,A$:IF A$="" THEN A$=CHR$(0)
1040 PRINT A$;:C=C+1:GOTO 1020
1050 PRINT:GOSUB 2000
1055 PRINT "bytes=";C
1060 CLOSE 1
1070 RETURN
2000 PRINT "st=";ST;
2001 IF (ST AND 2)<>0 THEN PRINT "timeout ";
2010 IF (ST AND 16)<>0 THEN PRINT "verify error";
2020 IF (ST AND 64)<>0 THEN PRINT "eof ";
2030 IF (ST AND 128)<>0 THEN PRINT "device not present ";
2035 PRINT
2040 RETURN
basic end