]> git.sur5r.net Git - cc65/commitdiff
Cleanup and preparation for the new design
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 26 Dec 2003 21:43:18 +0000 (21:43 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 26 Dec 2003 21:43:18 +0000 (21:43 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@2839 b7a2c559-68d2-44c3-8de9-860c34a00d81

12 files changed:
libsrc/Makefile
libsrc/cbm510/.cvsignore
libsrc/cbm510/Makefile
libsrc/cbm510/cbm510-stdjoy.s
libsrc/cbm510/cbm510-stdser.s [new file with mode: 0644]
libsrc/cbm510/cbm510.inc
libsrc/cbm510/crt0.s
libsrc/cbm510/extzp.inc
libsrc/cbm510/extzp.s
libsrc/cbm510/kirq.s
libsrc/cbm510/kscnkey.s
libsrc/cbm510/rs232.s [deleted file]

index 5cd29a41d830649b2b78cbd62bd0b65c4f1a5ceb..71a19a8996dec9c53d338fb6078f0c75bb1d7492 100644 (file)
@@ -158,6 +158,7 @@ cbm510lib:
        mv cbm510/crt0.o cbm510.o
        cp cbm510/*.emd .
        cp cbm510/*.joy .
+       cp cbm510/cbm510-stdser.ser cbm510-std.ser
 
 #-----------------------------------------------------------------------------
 # PET-II series
index 7e84fe058abb715a50b7ee2d877169dedc508b3c..b531b049578ba98fa341553042dd21968f436183 100644 (file)
@@ -1,4 +1,5 @@
 *.emd
 *.joy
+*.ser
 *.tgi
 
index ed58d70e7b3c115e993f9bfb0fc8d181490ffd87..27c0966c01474c0e22f6167e779734d58d18f380 100644 (file)
@@ -20,6 +20,9 @@
 %.joy: %.o ../runtime/zeropage.o extzp.o
        @$(LD) -t module -o $@ $^
 
+%.ser: %.o ../runtime/zeropage.o extzp.o
+       @$(LD) -t module -o $@ $^
+
 %.tgi: %.o ../runtime/zeropage.o extzp.o
        @$(LD) -t module -o $@ $^
 
@@ -54,7 +57,6 @@ OBJS =        _scrsize.o      \
        pokesys.o       \
         randomize.o     \
        revers.o        \
-       rs232.o         \
         sysuname.o      \
        tgi_mode_table.o
 
@@ -65,6 +67,8 @@ EMDS =        cbm510-ram.emd
 
 JOYS = cbm510-stdjoy.joy
 
+SERS = cbm510-stdser.ser
+
 TGIS =
 
 #--------------------------------------------------------------------------
@@ -72,14 +76,14 @@ TGIS =
 
 .PHONY:        all clean zap
 
-all:   $(OBJS) $(EMDS) $(JOYS) $(TGIS)
+all:   $(OBJS) $(EMDS) $(JOYS) $(SERS) $(TGIS)
 
 ../runtime/zeropage.o:
        $(MAKE) -C $(dir $@) $(notdir $@)
 
 clean:
-       @$(RM) $(OBJS) $(EMDS:.emd=.o) $(JOYS:.joy=.o) $(TGIS:.tgi=.o)
+       @$(RM) $(OBJS) $(EMDS:.emd=.o) $(JOYS:.joy=.o) $(SERS:.ser=.o) $(TGIS:.tgi=.o)
 
 zap:   clean
-       @$(RM) $(EMDS) $(JOYS) $(TGIS)
+       @$(RM) $(EMDS) $(JOYS) $(SERS) $(TGIS)
 
index 5f5a26b15b60075f9cf6d53bc75c7e6485009a9c..5dc5e024f853d7c5e7d6fc4b49e03f3068714613 100644 (file)
@@ -95,13 +95,13 @@ READ:   ldx     #$0F            ; Switch to the system bank
 
 ; Get the direction bits
 
-       ldy     #CIA_PRB
+       ldy     #CIA::PRB
        lda     (cia2),y        ; Read joystick inputs
        sta     tmp1
 
 ; Get the fire bits
 
-        ldy     #CIA_PRA
+        ldy     #CIA::PRA
        lda     (cia2),y
 
 ; Make the result value
diff --git a/libsrc/cbm510/cbm510-stdser.s b/libsrc/cbm510/cbm510-stdser.s
new file mode 100644 (file)
index 0000000..59675e0
--- /dev/null
@@ -0,0 +1,454 @@
+;
+; Serial driver for the builtin 6551 ACIA of the Commodore 510.
+;
+; Ullrich von Bassewitz, 2003-12-18
+;
+; The driver is based on the cc65 rs232 module, which in turn is based on
+; Craig Bruce device driver for the Switftlink/Turbo-232.
+;
+; SwiftLink/Turbo-232 v0.90 device driver, by Craig Bruce, 14-Apr-1998.
+;
+; This software is Public Domain.  It is in Buddy assembler format.
+;
+; This device driver uses the SwiftLink RS-232 Serial Cartridge, available from
+; Creative Micro Designs, Inc, and also supports the extensions of the Turbo232
+; Serial Cartridge.  Both devices are based on the 6551 ACIA chip.  It also
+; supports the "hacked" SwiftLink with a 1.8432 MHz crystal.
+;
+; The code assumes that the kernal + I/O are in context.  On the C128, call
+; it from Bank 15.  On the C64, don't flip out the Kernal unless a suitable
+; NMI catcher is put into the RAM under then Kernal.  For the SuperCPU, the
+; interrupt handling assumes that the 65816 is in 6502-emulation mode.
+;
+
+        .include        "zeropage.inc"
+        .include        "extzp.inc"
+        .include        "ser-kernel.inc"
+        .include        "ser-error.inc"
+       .include        "cbm510.inc"
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment        "JUMPTABLE"
+
+; Driver signature
+
+        .byte   $73, $65, $72           ; "ser"
+        .byte   SER_API_VERSION         ; Serial API version number
+
+; Jump table.
+
+        .word   INSTALL
+        .word   UNINSTALL
+        .word   OPEN
+        .word   CLOSE
+        .word   GET
+        .word   PUT
+        .word   STATUS
+        .word   IOCTL
+       .word   IRQ
+
+;----------------------------------------------------------------------------
+;
+; Global variables
+;
+
+.bss
+RecvHead:      .res    1       ; Head of receive buffer
+RecvTail:      .res    1       ; Tail of receive buffer
+RecvFreeCnt:   .res    1       ; Number of bytes in receive buffer
+SendHead:      .res    1       ; Head of send buffer
+SendTail:      .res    1       ; Tail of send buffer
+SendFreeCnt:   .res    1       ; Number of bytes in send buffer
+
+Stopped:       .res    1       ; Flow-stopped flag
+RtsOff:                .res    1       ;
+
+; Send and receive buffers: 256 bytes each
+RecvBuf:       .res    256
+SendBuf:       .res    256
+
+.rodata
+
+; Tables used to translate RS232 params into register values
+
+BaudTable:                      ; bit7 = 1 means setting is invalid
+        .byte   $FF             ; SER_BAUD_45_5
+        .byte   $01             ; SER_BAUD_50
+        .byte   $02             ; SER_BAUD_75
+        .byte   $03             ; SER_BAUD_110
+        .byte   $04             ; SER_BAUD_134_5
+        .byte   $05             ; SER_BAUD_150
+        .byte   $06             ; SER_BAUD_300
+        .byte   $07             ; SER_BAUD_600
+        .byte   $08             ; SER_BAUD_1200
+        .byte   $09             ; SER_BAUD_1800
+        .byte   $0A             ; SER_BAUD_2400
+        .byte   $0B             ; SER_BAUD_3600
+        .byte   $0C             ; SER_BAUD_4800
+        .byte   $0D             ; SER_BAUD_7200
+        .byte   $0E             ; SER_BAUD_9600
+        .byte   $0F             ; SER_BAUD_19200
+        .byte   $FF             ; SER_BAUD_38400
+        .byte   $FF             ; SER_BAUD_57600
+        .byte   $FF             ; SER_BAUD_115200
+        .byte   $FF             ; SER_BAUD_230400
+
+BitTable:
+        .byte   $60             ; SER_BITS_5
+        .byte   $40             ; SER_BITS_6
+        .byte   $20             ; SER_BITS_7
+        .byte   $00             ; SER_BITS_8
+
+StopTable:
+        .byte   $00             ; SER_STOP_1
+        .byte   $80             ; SER_STOP_2
+
+ParityTable:
+        .byte   $00             ; SER_PAR_NONE
+        .byte   $20             ; SER_PAR_ODD
+        .byte   $60             ; SER_PAR_EVEN
+        .byte   $A0             ; SER_PAR_MARK
+        .byte   $E0             ; SER_PAR_SPACE
+
+.code
+
+;----------------------------------------------------------------------------
+; INSTALL routine. Is called after the driver is loaded into memory. If
+; possible, check if the hardware is present.
+; Must return an SER_ERR_xx code in a/x.
+;
+; Since we don't have to manage the IRQ vector on the Plus/4, this is actually
+; the same as:
+;
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Must return an SER_ERR_xx code in a/x.
+
+
+INSTALL:
+UNINSTALL:
+
+; Deactivate DTR and disable 6551 interrupts
+
+       lda     #%00001010
+        jsr     write_cmd
+
+; Done, return an error code
+
+        lda     #<SER_ERR_OK
+        tax                     ; A is zero
+       rts
+
+;----------------------------------------------------------------------------
+; PARAMS routine. A pointer to a ser_params structure is passed in ptr1.
+; Must return an SER_ERR_xx code in a/x.
+
+OPEN:
+
+; Check if the handshake setting is valid
+
+        ldy    #SER_PARAMS::HANDSHAKE  ; Handshake
+        lda     (ptr1),y
+        cmp    #SER_HS_HW              ; This is all we support
+        bne    InvParam
+
+; Initialize buffers
+
+        jsr     InitBuffers
+
+; Set the value for the control register, which contains stop bits, word
+; length and the baud rate.
+
+        ldy     #SER_PARAMS::BAUDRATE
+        lda     (ptr1),y                ; Baudrate index
+        tay
+        lda     BaudTable,y             ; Get 6551 value
+        bmi     InvBaud                        ; Branch if rate not supported
+        sta     tmp1
+
+        ldy    #SER_PARAMS::DATABITS   ; Databits
+        lda     (ptr1),y
+        tay
+        lda     BitTable,y
+        ora     tmp1
+        sta     tmp1
+
+        ldy    #SER_PARAMS::STOPBITS   ; Stopbits
+        lda     (ptr1),y
+        tay
+        lda     StopTable,y
+        ora     tmp1
+        ora    #%00010000              ; Receiver clock source = baudrate
+       ldy     #ACIA::CTRL
+        jsr     write
+
+; Set the value for the command register. We remember the base value in
+; RtsOff, since we will have to manipulate ACIA_CMD often.
+
+        ldy            #SER_PARAMS::PARITY     ; Parity
+        lda     (ptr1),y
+        tay
+        lda     ParityTable,y
+       ora     #%00000001              ; DTR active
+       sta     RtsOff
+               ora     #%00001000              ; Enable receive interrupts
+        jsr     write_cmd
+
+; Done
+
+        lda     #<SER_ERR_OK
+        tax                             ; A is zero
+               rts
+
+; Invalid parameter
+
+InvParam:
+       lda     #<SER_ERR_INIT_FAILED
+       ldx     #>SER_ERR_INIT_FAILED
+       rts
+
+; Baud rate not available
+
+InvBaud:
+        lda     #<SER_ERR_BAUD_UNAVAIL
+        ldx     #>SER_ERR_BAUD_UNAVAIL
+        rts
+
+;----------------------------------------------------------------------------
+; CLOSE: Close the port, disable interrupts and flush the buffer. Called
+; without parameters. Must return an error code in a/x.
+;
+
+CLOSE:
+
+; Stop interrupts, drop DTR
+
+       lda     #%00001010
+        jsr     write_cmd
+
+; Initalize buffers.
+
+        jsr     InitBuffers
+
+; Return OK
+
+        lda     #<SER_ERR_OK
+        tax                             ; A is zero
+               rts
+
+;----------------------------------------------------------------------------
+; GET: Will fetch a character from the receive buffer and store it into the
+; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
+; return.
+;
+
+GET:    ldx    SendFreeCnt             ; Send data if necessary
+               inx                             ; X == $FF?
+       beq     @L1
+       lda     #$00
+       jsr     TryToSend
+
+; Check for buffer empty
+
+@L1:   lda     RecvFreeCnt
+       cmp     #$ff
+       bne     @L2
+       lda     #<SER_ERR_NO_DATA
+       ldx     #>SER_ERR_NO_DATA
+       rts
+
+; Check for flow stopped & enough free: release flow control
+
+@L2:   ldx     Stopped
+       beq     @L3
+       cmp     #63
+       bcc     @L3
+       lda     #$00
+       sta     Stopped
+       lda     RtsOff
+       ora     #%00001000
+        jsr     write_cmd
+
+; Get byte from buffer
+
+@L3:   ldx     RecvHead
+               lda     RecvBuf,x
+       inc     RecvHead
+       inc     RecvFreeCnt
+               ldx     #$00
+       sta     (ptr1,x)
+               txa                             ; Return code = 0
+       rts
+
+;----------------------------------------------------------------------------
+; PUT: Output character in A.
+; Must return an error code in a/x.
+;
+
+PUT:
+
+; Try to send
+
+        ldx    SendFreeCnt
+               inx                             ; X = $ff?
+       beq     @L2
+       pha
+       lda     #$00
+       jsr     TryToSend
+       pla
+
+; Put byte into send buffer & send
+
+@L2:   ldx     SendFreeCnt
+       bne     @L3
+       lda     #<SER_ERR_OVERFLOW      ; X is already zero
+       rts
+
+@L3:   ldx     SendTail
+       sta     SendBuf,x
+       inc     SendTail
+       dec     SendFreeCnt
+       lda     #$ff
+       jsr     TryToSend
+       lda     #<SER_ERR_OK
+       tax
+               rts
+
+;----------------------------------------------------------------------------
+; STATUS: Return the status in the variable pointed to by ptr1.
+; Must return an error code in a/x.
+;
+
+STATUS: lda     #$0F
+        sta     IndReg
+        ldy     #ACIA::STATUS
+        lda     (acia),y
+               ldx     #0
+       sta     (ptr1,x)
+        lda     IndReg
+        sta     ExecReg
+       txa                             ; SER_ERR_OK
+        rts
+
+;----------------------------------------------------------------------------
+; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
+; specific data in ptr1, and the ioctl code in A.
+; Must return an error code in a/x.
+;
+
+IOCTL:  lda     #<SER_ERR_INV_IOCTL     ; We don't support ioclts for now
+        ldx     #>SER_ERR_INV_IOCTL
+        rts
+
+;----------------------------------------------------------------------------
+; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
+; registers are already save, no parameters are passed and no return code
+; is expected.
+;
+
+IRQ:    lda     #$0F
+        sta     IndReg          ; Switch to the system bank
+        ldy     #ACIA::STATUS
+        lda     (acia),y        ; Check ACIA status for receive interrupt
+       and     #$08
+               beq     @L9             ; Jump if no ACIA interrupt
+        ldy     #ACIA::DATA
+        lda            (acia),y        ; Get byte from ACIA
+       ldx     RecvFreeCnt     ; Check if we have free space left
+               beq     @L1             ; Jump if no space in receive buffer
+       ldy     RecvTail        ; Load buffer pointer
+       sta     RecvBuf,y       ; Store received byte in buffer
+       inc     RecvTail        ; Increment buffer pointer
+       dec     RecvFreeCnt     ; Decrement free space counter
+       cpx     #33             ; Check for buffer space low
+               bcs     @L9             ; Assert flow control if buffer space low
+
+; Assert flow control if buffer space too low
+
+@L1:   lda     RtsOff
+        ldy     #ACIA::CMD
+        sta     (acia),y
+       sta     Stopped
+
+; Done, switch back to the execution segment
+
+@L9:    lda     ExecReg
+        sta     IndReg
+        rts
+
+;----------------------------------------------------------------------------
+; Try to send a byte. Internal routine. A = TryHard
+
+.proc   TryToSend
+
+       sta     tmp1            ; Remember tryHard flag
+        lda     #$0F
+        sta     IndReg          ; Switch to the system bank
+@L0:           lda     SendFreeCnt
+       cmp     #$ff
+       beq     @L3             ; Bail out
+
+; Check for flow stopped
+
+@L1:   lda     Stopped
+               bne     @L3             ; Bail out
+
+; Check that swiftlink is ready to send
+
+@L2:           ldy     #ACIA::STATUS
+        lda     (acia),y
+       and     #$10
+       bne     @L4
+       bit     tmp1            ; Keep trying if must try hard
+               bmi     @L0
+
+; Switch back the bank and return
+
+@L3:    lda     ExecReg
+        sta     IndReg
+        rts
+
+; Send byte and try again
+
+@L4:   ldx     SendHead
+       lda     SendBuf,x
+        ldy     #ACIA::DATA
+       sta     (acia),y
+       inc     SendHead
+       inc     SendFreeCnt
+       jmp     @L0
+
+.endproc
+
+
+;----------------------------------------------------------------------------
+; Initialize buffers
+
+InitBuffers:
+        ldx    #0
+        stx     Stopped
+               stx     RecvHead
+       stx     RecvTail
+       stx     SendHead
+       stx     SendTail
+        dex                             ; X = 255
+               stx     RecvFreeCnt
+       stx     SendFreeCnt
+        rts
+
+;----------------------------------------------------------------------------
+; Write to the ACIA changing the indirect segment. Offset is in Y, value in A.
+
+write_cmd:
+        ldy     #ACIA::CMD
+write:  pha
+        lda     #$0F
+        sta     IndReg
+        pla
+        sta     (acia),y
+        lda     ExecReg
+        sta     IndReg
+        rts
+
index 384770d611398b58a5ff36ea8506aa195cb8716d..dd0861cb9934db84741cdf22c76ad1d58c527a48 100644 (file)
@@ -16,60 +16,15 @@ IndReg              = $0001
 ; -----------------------------------
 
 KbdScanBuf             = $20           ; Intermediate for keyboard scan
-; RS232 stuff
-RecvHead       = $21           ; Head of receive buffer
-RecvTail       = $22           ; Tail of receive buffer
-RecvFreeCnt    = $23           ; Number of bytes in receive buffer
-SendHead       = $24           ; Head of send buffer
-SendTail       = $25           ; Tail of send buffer
-SendFreeCnt    = $26           ; Number of bytes free in send buffer
 
 FileNameAdrLo          = $90
 FileNameAdrHi          = $91
 FileNameAdrSeg         = $92
-SaveAdrLow             = $93
-SaveAdrHi              = $94
-SaveAdrSeg             = $95
-EndAdrLow              = $96
-EndAdrHi               = $97
-EndAdrSeg              = $98
-StartAdrLow            = $99
-StartAdrHi             = $9A
-StartAdrSeg            = $9B
-Status                 = $9C
 FileNameLen            = $9D
 LogicalAdr             = $9E
 FirstAdr               = $9F
 SecondAdr              = $A0
-DefInpDev              = $A1
-DefOutDev              = $A2
-TapeBufPtr             = $A3
-TapeBufPtrSeg          = $A5
-rs232BufPtr            = $A6
-rs232BufPtrSeg         = $A8
-StopKeyFlag            = $A9
-CTemp                  = $AA
-snsw1                  = $AB
-SegChgPtr              = $AC
-PChighSave             = $AE
-PClowSave              = $AF
-SRSave                 = $B0
-ACSave                 = $B1
-XRSave                 = $B2
-YRSave                 = $B3
-SPSave                 = $B4
 IndSegSave             = $B5
-IRQSaveHi              = $B7
-IRQSaveLo              = $B8
-Adr1                   = $B9
-Adr2                   = $BB
-MoniCntr               = $BD
-MoniTmp                = $BE
-MoniDevNr              = $BF
-PgmKeyBuf              = $C0
-PgmKeyPtr              = $C2
-sedsal                 = $C4
-sedeal                 = $C6
 SCREEN_PTR     = $C8
 CURS_Y                 = $CA
 CURS_X                 = $CB
@@ -86,25 +41,14 @@ LastLinePos         = $D5
 PgmKeyIndex            = $D6
 RepeatCount            = $D7
 RepeatDelay            = $D8
-sedt1                  = $D9           ; Temp
-sedt2                  = $DA           ; Temp, frequently used
-PrtData                = $DB
-ScreenTop              = $DC
-ScreenBot              = $DD
-ScreenLeft             = $DE
-ScreenRight            = $DF
 ModKey                 = $E0
 NorKey                 = $E1
-BitTable               = $E2
 CURS_FLAG      = $E6           ; 1 = no cursor
 CURS_BLINK     = $E7           ; cursor blink counter
 CRAM_PTR       = $E8
-TempColor      = $EA
 CURS_STATE     = $EB           ; Cursor blink state
 CHARCOLOR      = $EC
 CURS_COLOR     = $ED           ; Color behind cursor
-OutCharTmp     = $EE
-ScreenSeq      = $EF           ; Segment of video RAM
 
 ;-----------------------------------------------------------------------------
 ; Page 3 variables
@@ -116,29 +60,6 @@ ScreenSeq   = $EF           ; Segment of video RAM
 IRQVec              = $0300
 BRKVec              = $0302
 NMIVec              = $0304
-openVec                     = $0306
-closeVec            = $0308
-chkinVec            = $030A
-ckoutVec            = $030C
-clrchVec            = $030E
-basinVec            = $0310
-bsoutVec            = $0312
-stopVec                     = $0314
-getinVec            = $0316
-clallVec            = $0318
-loadVec                     = $031A
-saveVec                     = $031C
-usrcmd              = $031E
-escvec              = $0320
-ctrlvec                     = $0322
-secndVec            = $0324
-tksaVec                     = $0326
-acptrVec            = $0328
-cioutVec            = $032A
-untlkVec            = $032C
-unlsnVec            = $032E
-listnVec            = $0330
-talkVec                     = $0332
 
 ;
 ;
@@ -151,46 +72,19 @@ SysMemBot       = $0352
 SysMemTop           = $0355
 UsrMemBot           = $0358
 UsrMemTop           = $035B
-TimOut              = $035E
-VerifyFlag          = $035F
 DevTabIndex         = $0360
-MsgFlag                     = $0361
-CassBufPtr          = $0362
-t1                  = $0363
-t2                  = $0364
-XSave               = $0365
-SaveX               = $0366
-SaveXt              = $0367
-temp                = $0368
-alarm               = $0369
-TapeVec                     = $036A
-LoadStAdr           = $036F
-CassMotFlag         = $0375
-m6551Ctrl           = $0376
-m6551Cmd            = $0377
-rs232status         = $037A
-dcddsr              = $037B
-rs232head           = $037C
-rs232tail           = $037D
 PgmKeyEnd           = $0380
 PgmKeySeg           = $0382
 RVS                 = $0383
-linetmp                     = $0398
 LastPrtChar         = $0399
 InsertFlag          = $039A
 ScrollFlag          = $039B
-FktTemp                     = $039C
 PgmKeyIdx           = $039D
 LogScrollFlag       = $039E
 BellMode            = $039F    ; Bell on/off 00 = an
 SegSave                     = $03A0
 TabStopTable        = $03A1    ; 80 bits for tabstops
 KeyBuf              = $03AB    ; Keyboard buffer
-funvec              = $03B5    ; Vector for function key handline
-sedt3               = $03B9
-MoniSegSave         = $03f0
-wstvec              = $03F8
-WstFlag                     = $03FA    ; Warm start flag
 
 ; ---------------------------------------------------------------------------
 ; Screen size
@@ -295,47 +189,65 @@ SID_Read3         = $1C
 ; I/O  $db00: CIA 6526 Inter Process Communication
 ; I/O  $dc00: CIA 6526
 
-CIA_PRA                = $00
-CIA_PRB                = $01
-CIA_DDRA               = $02
-CIA_DDRB       = $03
-CIA_ICR                = $0D
-CIA_CRA                = $0E
-CIA_CRB                = $0F
+.struct CIA
+        PRA     .byte
+        PRB     .byte
+        DDRA    .byte
+        DDRB    .byte
+        .union
+            .struct
+                TALO    .byte
+                TAHI    .byte
+            .endstruct
+            TA          .word
+        .endunion
+        .union
+            .struct
+                TBLO    .byte
+                TBHI    .byte
+            .endstruct
+            TB          .word
+        .endunion
+        TOD10   .byte
+        TODSEC  .byte
+        TODMIN  .byte
+        TODHR   .byte
+        SDR     .byte
+        ICR     .byte
+        CRA     .byte
+        CRB     .byte
+.endstruct
 
 
 ; I/O  $dd00: ACIA 6551
 
-;      acia            =       $dd00
-
-       ADataReg        =       $00
-       AStatusReg      =       $01
-       ACmdReg         =       $02
-       ACtrlReg        =       $03
-
+.struct ACIA
+        DATA    .byte
+        STATUS  .byte
+        CMD     .byte
+        CTRL    .BYTE
+.endstruct
 
 
 ; I/O  $de00: Triport #1 6525
-
-;      tpi1            =       $de00
-
-       tpiPortA        =       $00
-       tpiPortB        =       $01
-       tpiPortC        =       $02
-       tpiIntLatch     =       $02
-       tpiDDRA         =       $03
-       tpiDDRB         =       $04
-       tpiDDRC         =       $05
-       tpiIntMask      =       $05
-       tpiCtrlReg      =       $06
-       tpiActIntReg    =       $07
-
-
-
 ; I/O  $df00: Triport #2 6525
 
-;      tpi2            =       $df00
-
+.struct TPI
+        PRA     .byte
+        PRB     .byte
+        .union
+                PRC     .byte
+                INT     .byte
+        .endunion
+        DDRA    .byte
+        DDRB    .byte
+        .union
+                DDRC    .byte
+                IMR     .byte
+        .endunion
+        CR      .byte
+        AIR     .byte
+.endstruct
 
 
 ; Out video memory address
index 2296106a0e8a6efc60426bfd22b5fe653158a489..46f5d0b20ea7ddae331fcee40870dfadb214837e 100644 (file)
@@ -244,7 +244,7 @@ ccopy2:     lda     __VIDRAM_START__,y
 ; CA (STATVID)   = 0
 ; CB (VICDOTSEL) = 0
 
-               ldy     #tpiCtrlReg
+               ldy     #TPI::CR
                lda     (tpi1),y
                sta     vidsave+0
                and     #%00001111
@@ -254,7 +254,7 @@ ccopy2:     lda     __VIDRAM_START__,y
 ; Set bit 14/15 of the VIC address range to the high bits of __VIDRAM_START__
 ; PC6/PC7 (VICBANKSEL 0/1) = 11
 
-               ldy     #tpiPortC
+               ldy     #TPI::PRC
                lda     (tpi2),y
                sta     vidsave+1
                and     #$3F
@@ -388,11 +388,11 @@ _exit:    jsr     donelib         ; Run module destructors
 
 ; Switch back the video to the system bank
 
-       ldy     #tpiCtrlReg
+       ldy     #TPI::CR
        lda     vidsave+0
        sta     (tpi1),y
 
-       ldy     #tpiPortC
+       ldy     #TPI::PRC
        lda     vidsave+1
        sta     (tpi2),y
 
index e80c27bc4036514b673d93729f1e8b7c9775f04f..2352224cadef57385bf5f3da2aa24df71649c00a 100644 (file)
@@ -7,5 +7,5 @@
 ; ------------------------------------------------------------------------
 
                .globalzp       vic, sid, cia1, cia2, acia, tpi1, tpi2, ktab1
-       .globalzp       ktab2, ktab3, ktab4, time, RecvBuf, SendBuf
+       .globalzp       ktab2, ktab3, ktab4, time
 
index d411c8a6c4c46a004310b64b17caca2a418271bd..98687197578050c3424552e9e575828a86b8be60 100644 (file)
@@ -25,6 +25,4 @@ ktab2:                .res    2
 ktab3:         .res    2
 ktab4:         .res    2
 time:          .res    4
-RecvBuf:       .res    2               ; RS232 receive buffer
-SendBuf:       .res    2               ; RS232 transmit buffer
 
index 357fe8e68502be73c52d97b851750c25aa96943b..dc63ee3c0bbd77461804f3b7010f1bb9ab0a4202 100644 (file)
@@ -63,7 +63,7 @@ k_irq:
         cld
        lda     #$0F
        sta     IndReg
-       ldy     #tpiActIntReg
+       ldy     #TPI::AIR
        lda     (tpi1),y                ; Interrupt Register 6525
        beq     noirq
 
@@ -96,7 +96,7 @@ irq1: cmp     #%00010000              ; interrupt from uart?
 ; -------------------------------------------------------------------------
 ; Done
 
-irqend:        ldy     #tpiActIntReg
+irqend:        ldy     #TPI::AIR
                sta     (tpi1),y                ; Clear interrupt
 
 noirq: pla
index 95657508e372adaba0dde3c75f7e8e85f1048de5..af4edadc6c44c167b8bb189cf9c82d9bf8821f10 100644 (file)
@@ -1,4 +1,4 @@
-;             
+;
 ; Ullrich von Bassewitz, 13.09.2001
 ;
 ; Keyboard polling stuff for the 510.
@@ -17,9 +17,9 @@
         sta     NorKey
         lda    #$00
        sta     KbdScanBuf
-       ldy     #tpiPortB
+       ldy     #TPI::PRB
        sta     (tpi2),y
-       ldy     #tpiPortA
+       ldy     #TPI::PRA
        sta     (tpi2),y
         jsr     Poll
         and     #$3F
         jmp     NoKey
 
 L1:    lda     #$FF
-       ldy     #tpiPortA
+       ldy     #TPI::PRA
        sta     (tpi2),y
         asl     a
-       ldy     #tpiPortB
+       ldy     #TPI::PRB
        sta     (tpi2),y
         jsr     Poll
         pha
@@ -48,11 +48,11 @@ L4: lsr     a
         dex
         bpl     L4
         sec
-       ldy     #tpiPortB
+       ldy     TPI::PRB
        lda     (tpi2),y
        rol     a
        sta     (tpi2),y
-               ldy     #tpiPortA
+               ldy     #TPI::PRA
        lda     (tpi2),y
        rol     a
        sta     (tpi2),y
@@ -98,9 +98,9 @@ L8:   tax
 NoKey: ldy     #$FF
 Done:          sty     LastIndex
 End:   lda     #$7F
-       ldy     #tpiPortA
+       ldy     #TPI::PRA
        sta     (tpi2),y
-       ldy     #tpiPortB
+       ldy     #TPI::PRB
        lda     #$FF
        sta     (tpi2),y
         rts
@@ -127,7 +127,7 @@ PutKey:     sta     KeyBuf,x
 ; Poll the keyboard port until it's stable
 
 .proc  Poll
-       ldy     #tpiPortC
+       ldy     TPI::PRC
 L1:    lda     (tpi2),y
        sta     KeySave
        lda     (tpi2),y
diff --git a/libsrc/cbm510/rs232.s b/libsrc/cbm510/rs232.s
deleted file mode 100644 (file)
index b45b040..0000000
+++ /dev/null
@@ -1,631 +0,0 @@
-;
-; SwiftLink/Turbo-232 v0.90 device driver, by Craig Bruce, 14-Apr-1998.
-;
-; This software is Public Domain.  It is in Buddy assembler format.
-;
-; This device driver uses the SwiftLink RS-232 Serial Cartridge, available from
-; Creative Micro Designs, Inc, and also supports the extensions of the Turbo232
-; Serial Cartridge.  Both devices are based on the 6551 ACIA chip.  It also
-; supports the "hacked" SwiftLink with a 1.8432 MHz crystal.
-;
-; The code assumes that the kernal + I/O are in context.  On the C128, call
-; it from Bank 15.  On the C64, don't flip out the Kernal unless a suitable
-; NMI catcher is put into the RAM under then Kernal.  For the SuperCPU, the
-; interrupt handling assumes that the 65816 is in 6502-emulation mode.
-;
-;--------------------------------------------------------------------------
-;
-; Adapted for the use with the cc65 runtime library by
-; Ullrich von Bassewitz (uz@musoftware.de) 02-May-1999.
-;
-; All external functions are C callable, the return value is an error code.
-;
-
-
-       .importzp       ptr1, ptr2, tmp1, tmp2
-       .importzp       acia, RecvBuf, SendBuf
-       .import         popa, popax
-       .import         sys_bank, restore_bank
-       .export         _rs232_init, _rs232_params, _rs232_done, _rs232_get
-       .export         _rs232_put, _rs232_pause, _rs232_unpause, _rs232_status
-       .export         k_rs232
-
-       .include        "cbm510.inc"
-
-
-;----------------------------------------------------------------------------
-;
-; Global variables
-;
-
-.bss
-DropCnt:       .res    4       ; Number of bytes lost from rx buffer full
-Initialized:   .res    1       ; Flag indicating driver is initialized
-Stopped:       .res    1       ; Flow-stopped flag
-RtsOff:                .res    1       ;
-Errors:                .res    1       ; Number of bytes received in error, low byte
-BaudCode:      .res    1       ; Current baud in effect
-
-; Segment, the RS232 buffers are in
-BufferSeg              = 2
-
-; UART register offsets
-RegData                = 0     ; Data register
-RegStatus              = 1     ; Status register
-RegCommand             = 2     ; Command register
-RegControl             = 3     ; Control register
-
-; Error codes. Beware: The codes must match the codes in the C header file
-ErrNotInitialized      = $01
-ErrBaudTooFast         = $02
-ErrBaudNotAvail        = $03
-ErrNoData              = $04
-ErrOverflow            = $05
-
-
-.code
-
-;----------------------------------------------------------------------------
-;
-; unsigned char __fastcall__ rs232_init (char hacked);
-; /* Initialize the serial port, install the interrupt handler. The parameter
-;  * must be true (non zero) for a hacked swiftlink and false (zero) otherwise.
-;  */
-;
-
-_rs232_init:
-               bit     Initialized     ;** shut down if started
-               bpl     @L1
-               pha
-               jsr     _rs232_done
-               pla
-
-; Initialize buffers & control
-
-@L1:   lda     #0
-       sta     RecvHead
-       sta     SendHead
-       sta     RecvTail
-       sta     SendTail
-       sta     Errors
-       sta     Stopped
-       lda     #255
-               sta     RecvFreeCnt
-       sta     SendFreeCnt
-
-; Set default to 2400-8N1, enable interrupts
-
-       jsr     sys_bank                ; Switch indirect to system bank
-
-       ldy     #RegData
-       lda     (acia),y
-       ldy     #RegStatus
-       lda     (acia),y
-       lda     #$18
-       ldy     #RegControl
-       sta     (acia),y
-
-       lda     #$01
-       sta     RtsOff
-       ora     #$08
-       ldy     #RegCommand
-               sta     (acia),y
-       lda     #$06
-       sta     BaudCode
-
-       jsr     restore_bank
-
-       lda     #$ff
-       sta     Initialized
-       lda     #$00
-       tax
-       rts
-
-;----------------------------------------------------------------------------
-;
-; unsigned char __fastcall__ rs232_params (unsigned char params, unsigned char parity);
-; /* Set the port parameters. Use a combination of the #defined values above. */
-;
-; Set communication parameters.
-;
-; baud rates              stops     word    |   parity
-; ---------------------   -----     -----   |   ---------
-; $00=50     $08=9600     $00=1     $00=8   |   $00=none
-; $01=110    $09=19200    $80=2     $20=7   |   $20=odd
-; $02=134.5  $0a=38400              $40=6   |   $60=even
-; $03=300    $0b=57600              $60=5   |   $A0=mark
-; $04=600    $0c=115200                     |   $E0=space
-; $05=1200   $0d=230400
-; $06=2400   $0e=future
-; $07=4800   $0f=future
-;
-
-_rs232_params:
-               jsr     CheckInitialized        ;** check initialized
-               bcc     @L1
-       rts
-
-; Save new parity
-
-@L1:           and     #%11100000
-               ora     #%00000001
-               sta     tmp2
-
-; Set baud/parameters
-
-               jsr     popa
-               sta     tmp1
-               and     #$0f
-               tax
-               lda     Bauds,x
-               cmp     #$ff
-               bne     @L5
-               lda     #ErrBaudNotAvail
-               bne     @L9
-
-@L5:           jsr     sys_bank                ; Indirect segment to system bank
-               tax
-               lda     tmp1
-               and     #$0f
-               sta     BaudCode
-               lda     tmp1
-               and     #%11100000
-               ora     #%00010000
-               sta     tmp1
-               txa
-               and     #$0f
-               ora     tmp1
-               ldy     #RegControl
-               sta     (acia),y
-
-; Set new parity
-
-@L7:           lda     tmp2
-               sta     RtsOff
-               ora     #%00001000
-               ldy     #RegCommand
-               sta     (acia),y
-               jsr     restore_bank            ; Restore indirect bank
-               lda     #0
-@L9:           ldx     #0
-               rts
-
-.rodata
-Bauds:
-   .byte $01,$03,$04,$06,$07,$08,$0a,$0c,$0e,$0f,$ff,$ff,$ff,$ff,$ff,$ff
-     ;in:  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f
-     ;baud50 110 134   3   6  12  24  48  96  19  38  57 115 230 exp exp
-     ;out masks: $0F=Baud, val$FF=err
-.code
-
-;----------------------------------------------------------------------------
-;
-; unsigned char __fastcall__ rs232_done (void);
-; /* Close the port, deinstall the interrupt hander. You MUST call this function
-;  * before terminating the program, otherwise the machine may crash later. If
-;  * in doubt, install an exit handler using atexit(). The function will do
-;  * nothing, if it was already called.
-;  */
-;
-
-
-_rs232_done:
-       bit     Initialized             ;** check initialized
-               bpl     @L9
-
-; Stop interrupts, drop DTR
-
-       lda     RtsOff
-       and     #%11100010
-       ora     #%00000010
-       ldx     IndReg
-       ldy     #$0F
-       sty     IndReg                  ; Set indirect to system bank
-       ldy     #RegCommand
-       sta     (acia),y
-       stx     IndReg                  ; Restore old indirect bank
-
-; Flag uninitialized
-
-@L9:           lda     #$00
-       sta     Initialized
-       tax
-       rts
-
-;----------------------------------------------------------------------------
-;
-; unsigned char __fastcall__ rs232_get (char* B);
-; /* Get a character from the serial port. If no characters are available, the
-;  * function will return RS_ERR_NO_DATA, so this is not a fatal error.
-;  */
-;
-
-_rs232_get:
-       jsr     CheckInitialized        ; Check if initialized
-       bcc     @L1
-       rts
-
-; Check for bytes to send
-
-@L1:   sta     ptr1
-       stx     ptr1+1                  ; Store pointer to received char
-       ldx     SendFreeCnt
-       cpx     #$ff
-       beq     @L2
-       lda     #$00
-       jsr     TryToSend
-
-; Check for buffer empty
-
-@L2:   lda     RecvFreeCnt
-       cmp     #$ff
-       bne     @L3
-       lda     #ErrNoData
-       ldx     #0
-       rts
-
-; Check for flow stopped & enough free: release flow control
-
-@L3:   ldx     Stopped
-       beq     @L4
-       cmp     #63
-       bcc     @L4
-       lda     #$00
-       sta     Stopped
-       lda     RtsOff
-       ora     #%00001000
-       ldx     IndReg
-       ldy     #$0F                    ; Set indirect to system bank
-       sty     IndReg
-       ldy     #RegCommand
-       sta     (acia),y
-       stx     IndReg
-
-; Get byte from buffer
-
-@L4:   ldx     IndReg
-       lda     #BufferSeg              ; Set indirect to buffer bank
-       sta     IndReg
-       ldy     RecvHead
-       lda     (RecvBuf),y
-       stx     IndReg                  ; Restore indirect bank
-       inc     RecvHead
-       inc     RecvFreeCnt
-               ldx     #$00
-       sta     (ptr1,x)
-               txa                             ; Return code = 0
-       rts
-
-;----------------------------------------------------------------------------
-;
-; unsigned char __fastcall__ rs232_put (char B);
-; /* Send a character via the serial port. There is a transmit buffer, but
-;  * transmitting is not done via interrupt. The function returns
-;  * RS_ERR_OVERFLOW if there is no space left in the transmit buffer.
-;  */
-;
-
-_rs232_put:
-       jsr     CheckInitialized        ; Check initialized
-       bcc     @L1
-       rts
-
-; Try to send
-
-@L1:   ldx     SendFreeCnt
-       cpx     #$ff
-       beq     @L2
-       pha
-       lda     #$00
-       jsr     TryToSend
-       pla
-
-; Put byte into send buffer & send
-
-@L2:   ldx     SendFreeCnt
-       bne     @L3
-       lda     #ErrOverflow
-       ldx     #$00
-       rts
-
-; There is enough room (character still in A)
-
-@L3:   ldx     IndReg
-               ldy     #BufferSeg              ; Set indirect to buffer segment
-       sty     IndReg
-       ldy     SendTail
-       sta     (SendBuf),y
-       stx     IndReg                  ; Restore indirect bank
-       inc     SendTail
-       dec     SendFreeCnt
-       lda     #$ff
-       jsr     TryToSend
-       lda     #$00
-       tax
-               rts
-
-;----------------------------------------------------------------------------
-;
-; unsigned char __fastcall__ rs232_pause (void);
-; /* Assert flow control and disable interrupts. */
-;
-
-_rs232_pause:
-; Check initialized
-       jsr     CheckInitialized
-       bcc     @L1
-       rts
-
-; Assert flow control
-
-@L1:   lda     RtsOff
-       sta     Stopped
-       jsr     sys_bank                ; Set indirect to system bank
-       ldy     #RegCommand
-       sta     (acia),y
-
-; Delay for flow stop to be received
-
-       ldx     BaudCode
-       lda     PauseTimes,x
-       jsr     DelayMs
-
-; Stop rx interrupts
-
-       lda     RtsOff
-       ora     #$02
-       ldy     #RegCommand
-       sta     (acia),y
-               jsr     restore_bank            ; Restore indirect segment
-       lda     #0
-       tax
-       rts
-
-
-.rodata
-; Delay times: 32 byte-receive times in milliseconds, or 100 max.
-; Formula = 320,000 / baud
-PauseTimes:
-               .byte 100,100,100,100,100,100,100,067,034,017,009,006,003,002,001,001
-          ;in:  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f
-          ;baud50 110 134   3   6  12  24  48  96  19  38  57 115 230 exp exp
-.code
-
-;----------------------------------------------------------------------------
-;
-; unsigned char __fastcall__ rs232_unpause (void);
-; /* Re-enable interrupts and release flow control */
-;
-
-_rs232_unpause:
-; Check initialized
-       jsr     CheckInitialized
-       bcc     @L1
-       rts
-
-; Re-enable rx interrupts & release flow control
-
-@L1:   lda     #$00
-       sta     Stopped
-       lda     RtsOff
-       ora     #%00001000
-       ldx     IndReg
-       ldy     #$0F
-       sty     IndReg                  ; Set indirect to system bank
-       ldy     #RegCommand
-       sta     (acia),y
-       stx     IndReg                  ; Restore indirect bank
-
-; Poll for stalled char & exit
-
-       jsr     PollReceive
-       lda     #0
-       tax
-       rts
-
-;----------------------------------------------------------------------------
-;
-; unsigned char __fastcall__ rs232_status (unsigned char* status,
-;                                         unsigned char* errors);
-; /* Return the serial port status. */
-;
-
-_rs232_status:
-       sta     ptr2
-       stx     ptr2+1
-       jsr     popax
-       sta     ptr1
-       stx     ptr1+1
-       jsr     CheckInitialized
-               bcs     @L9
-
-; Get status
-
-       ldx     IndReg                  ; Save indirect segment
-       lda     #$0F
-       sta     IndReg                  ; Set system bank as indirect segment
-       ldy     #RegStatus
-       lda     (acia),y                ; Read status register
-       stx     IndReg
-       ldy     #0
-       sta     (ptr1),y
-       jsr     PollReceive             ; bug-recovery hack
-       lda     Errors
-       ldy     #0
-               sta     (ptr2),y
-               tya
-       tax
-@L9:   rts
-
-;----------------------------------------------------------------------------
-;
-; RS232 interrupt handler.
-; The RS232 handler will be called with        the system bank as indirect bank
-; and all registers saved.
-;
-
-k_rs232:
-       ldy     #RegStatus
-               lda     (acia),y                ; check for byte received
-       and     #$08
-       beq     @L9                     ; Nothing to receive
-               lda     (acia),y                ; check for receive errors
-       and     #$07
-               beq     @L1
-       inc     Errors
-@L1:           ldy     #RegData
-       lda     (acia),y                ; get byte and put into receive buffer
-       ldx     RecvFreeCnt
-       beq     @L3
-       ldy     #BufferSeg
-       sty     IndReg
-               ldy     RecvTail
-       sta     (RecvBuf),y             ; Store received character
-       lda     #$0F
-       sta     IndReg                  ; Restore indirect segment
-       inc     RecvTail
-       dec     RecvFreeCnt
-       cpx     #33                     ; check for buffer space low
-               bcs     @L9
-
-; Assert flow control
-
-@L2:   lda     RtsOff                  ; assert flow control if buffer space too low
-       ldy     #RegCommand
-       sta     (acia),y
-       sta     Stopped
-       rts
-
-; Drop this char
-
-@L3:   inc     DropCnt+0               ;not time-critical
-       bne     @L9
-       inc     DropCnt+1
-       bne     @L9
-       inc     DropCnt+2
-       bne     @L9
-       inc     DropCnt+3
-@L9:           rts
-
-
-;----------------------------------------------------------------------------
-;
-; CheckInitialized  -  internal check if initialized
-; Set carry and an error code if not initialized, clear carry and do not
-; change any registers if initialized.
-;
-
-CheckInitialized:
-       bit     Initialized
-       bmi     @L1
-       lda     #ErrNotInitialized
-       ldx     #0
-       sec
-       rts
-
-@L1:   clc
-       rts
-
-;----------------------------------------------------------------------------
-; Try to send a byte. Internal routine. A = TryHard
-
-TryToSend:
-       sta     tmp1            ; Remember tryHard flag
-       ldx     IndReg          ; Save indirect segment
-       lda     #$0F
-       sta     IndReg          ; Set system segment as indirect segment
-@L0:           lda     SendFreeCnt
-       cmp     #$ff
-       beq     @L3             ; Bail out
-
-; Check for flow stopped
-
-@L1:   lda     Stopped
-               bne     @L3             ; Bail out
-
-; Check that the UART is ready to send
-
-@L2:           ldy     #RegStatus
-       lda     (acia),y
-       and     #$10
-       bne     @L4
-       bit     tmp1            ; Keep trying if must try hard
-               bmi     @L0
-@L3:           stx     IndReg          ; Restore indirect segment
-       rts
-
-; Send byte and try again
-
-@L4:           lda     #BufferSeg
-       sta     IndReg
-       ldy     SendHead
-       lda     (SendBuf),y
-       ldy     #$0F
-       sty     IndReg
-       ldy     #RegData
-       sta     (acia),y
-       inc     SendHead
-       inc     SendFreeCnt
-       jmp     @L0
-
-
-;----------------------------------------------------------------------------
-;
-; PollReceive - poll for rx char
-;   This function is useful in odd cases where the 6551 has a character in
-;   it but it fails to raise an NMI.  It might be edge-triggering conditions?
-;   Actually, I'm not entirely sure that this condition can still arrise, but
-;   calling this function does no harm.
-;
-
-PollReceive:
-       ldx     IndReg                  ; Save indirect segment
-       lda     #$0F
-       sta     IndReg                  ; Set system bank as indirect segment
-       ldy     #RegStatus
-       lda     (acia),y
-       and     #$08
-       beq     @L9
-       lda     (acia),y                ; Read a second time? ###
-       and     #$08
-       beq     @L9
-       ldy     #RegData
-       lda     (acia),y
-               ldy     RecvFreeCnt
-       beq     @L9
-       ldy     #BufferSeg
-       sty     IndReg
-               ldy     RecvTail
-       sta     (RecvBuf),y
-       inc     RecvTail
-       dec     RecvFreeCnt
-@L9:   stx     IndReg                  ; Restore indirect segment
-       rts
-
-;----------------------------------------------------------------------------
-;
-;  DelayMs : delay for given number of milliseconds
-;    This implementation isn't very rigerous; it merely delays for the
-;    approximate number of clock cycles for the processor speed.
-;    Algorithm:
-;       repeat for number of milliseconds:
-;          repeat for number of MHz of cpu speed:
-;             delay for 1017 clock cycles
-;
-
-DelayMs:                       ;( .A=milliseconds )
-@L1:           ldy     #1              ; 1MHz
-@L2:           ldx     #203            ;(2)
-@L3:           dex                     ;(2)
-       bne     @L3             ;(3) // 1017 cycles
-       dey
-       bne     @L2
-       sec
-       sbc     #1
-       bne     @L1
-       rts
-
-.end
-
-
-