@@ 4,83 4,83 @@
.db "NES", $1a ; identification of the iNES header
.db 1 ; number of 16KB PRG-ROM pages
.db $01 ; number of 8KB CHR-ROM pages
- .db $70|%0001 ; mapper 7
- .dsb $09, $00 ; clear the remaining bytes
+ .db $00 ; NROM
+ .dsb $09,$00 ; clear the remaining bytes
.fillvalue $FF ; Sets all unused space in rom to value $FF
.org $C000
;; constants
-PPUCTRL .equ $2000
-PPUMASK .equ $2001
-PPUSTATUS .equ $2002
-SPRADDR .equ $2003
-PPUSCROLL .equ $2005
-PPUADDR .equ $2006
-PPUDATA .equ $2007
-APUCH1VOL .equ $4000 ; APU
-APUCH1SWP .equ $4001 ; APU
-APUCH1FRQ .equ $4002 ; APU
-APUCH1LEN .equ $4003 ; APU
-APUCH2VOL .equ $4004 ; APU
-APUCH2SWP .equ $4005 ; APU
-APUCH2FRQ .equ $4006 ; APU
-APUCH2LEN .equ $4007 ; APU
-APUCH3CNT .equ $4008 ; APU
-APUCH3SWP .equ $4009 ; APU
-APUCH3FRQ .equ $400a ; APU
-APUCH3LEN .equ $400b ; APU
-APUCH4VOL .equ $400c ; APU
-APUCH4SWP .equ $400d ; APU
-APUCH4FRQ .equ $400e ; APU
-APUCH4LEN .equ $400f ; APU
-SPRDMA .equ $4014
-APUCTRL .equ $4015
-JOY1 .equ $4016
-JOY2 .equ $4017
-BUTTON_RIGHT .equ #$01
-BUTTON_LEFT .equ #$02
-BUTTON_DOWN .equ #$04
-BUTTON_UP .equ #$08
-BUTTON_START .equ #$10
-BUTTON_SELECT .equ #$20
-BUTTON_B .equ #$40
-BUTTON_A .equ #$80
+ PPUCTRL .equ $2000
+ PPUMASK .equ $2001
+ PPUSTATUS .equ $2002
+ SPRADDR .equ $2003
+ PPUSCROLL .equ $2005
+ PPUADDR .equ $2006
+ PPUDATA .equ $2007
+ APUCH1VOL .equ $4000 ; APU
+ APUCH1SWP .equ $4001 ; APU
+ APUCH1FRQ .equ $4002 ; APU
+ APUCH1LEN .equ $4003 ; APU
+ APUCH2VOL .equ $4004 ; APU
+ APUCH2SWP .equ $4005 ; APU
+ APUCH2FRQ .equ $4006 ; APU
+ APUCH2LEN .equ $4007 ; APU
+ APUCH3CNT .equ $4008 ; APU
+ APUCH3SWP .equ $4009 ; APU
+ APUCH3FRQ .equ $400a ; APU
+ APUCH3LEN .equ $400b ; APU
+ APUCH4VOL .equ $400c ; APU
+ APUCH4SWP .equ $400d ; APU
+ APUCH4FRQ .equ $400e ; APU
+ APUCH4LEN .equ $400f ; APU
+ SPRDMA .equ $4014
+ APUCTRL .equ $4015
+ JOY1 .equ $4016
+ JOY2 .equ $4017
+ BUTTON_RIGHT .equ #$01
+ BUTTON_LEFT .equ #$02
+ BUTTON_DOWN .equ #$04
+ BUTTON_UP .equ #$08
+ BUTTON_START .equ #$10
+ BUTTON_SELECT .equ #$20
+ BUTTON_B .equ #$40
+ BUTTON_A .equ #$80
;; variables
.enum $0000
-position .dsb 1
-cursor .dsb 1
-note .dsb 1
-marker .dsb 1
-btndown .dsb 1
-btnlast .dsb 1
-btnqueue .dsb 1
-rate .dsb 1
-timer .dsb 1
-seed .dsb 1
+ position .dsb 1
+ cursor .dsb 1
+ note .dsb 1
+ marker .dsb 1
+ btndown .dsb 1
+ btnlast .dsb 1
+ btnqueue .dsb 1
+ rate .dsb 1
+ timer .dsb 1
+ seed .dsb 1
.ende
;; reset
-RESET:
- SEI ; disable IRQs
- CLD ; disable decimal mode
+RESET:
+ SEI ; disable IRQs
+ CLD ; disable decimal mode
LDX #$40
- STX $4017 ; disable APU frame IRQ
+ STX $4017 ; disable APU frame IRQ
LDX #$FF
- TXS ; set up stack
- INX ; now X = 0
- STX PPUCTRL ; disable NMI
- STX PPUMASK ; disable rendering
- STX $4010 ; disable DMC IRQs
+ TXS ; set up stack
+ INX ; now X = 0
+ STX PPUCTRL ; disable NMI
+ STX PPUMASK ; disable rendering
+ STX $4010 ; disable DMC IRQs
Vblankwait1: ; First wait for vblank
BIT PPUSTATUS
BPL Vblankwait1
-Clrmem:
+Clrmem:
LDA #$00
STA $0000, x
STA $0100, x
@@ 90,7 90,7 @@ Clrmem:
STA $0600, x
STA $0700, x
LDA #$FE
- STA $0200, x ; move sprites off screen
+ STA $0200, x ; move sprites off screen
INX
BNE Clrmem
@@ 100,90 100,90 @@ Vblankwait2: ; Second wait for vblank
;; setup phase
-SetupPalettes:
+SetupPalettes:
LDA PPUSTATUS
LDA #$3F
STA PPUADDR
LDA #$00
STA PPUADDR
LDX #$00
-@loop:
+@loop:
LDA Palettes, x
STA PPUDATA
INX
CPX #$20
BNE @loop
-SetupAttributes:
+SetupAttributes:
LDA PPUSTATUS
LDA #$23
STA PPUADDR
LDA #$C0
STA PPUADDR
LDX #$00
-@loop:
+@loop:
LDA #$00
STA PPUDATA
INX
CPX #$40
BNE @loop
-SetupSequence:
+SetupSequence:
LDX #$00
-@loop:
- LDA $00 ; set entire sequence to "+"
- STA $10,x ; store on zeropage second row
+@loop:
+ LDA $00 ; set entire sequence to "+"
+ STA $10,x ; store on zeropage second row
INX
CPX #$10
BNE @loop
-SetupVariables:
+SetupVariables:
LDA #$08
- STA rate ; default rate = 08
+ STA rate ; default rate = 08
LDA #$20
- STA note ; default note = C
+ STA note ; default note = C
LDA #$05
STA marker
-SetupAudio:
- LDY #$0f ; init $4000-4013
-@loop:
+SetupAudio:
+ LDY #$0f ; init $4000-4013
+@loop:
LDA ApuStates,y
STA $4000,y
DEY
BPL @loop
- LDA #$0f ; skip over $4014 (OAMDMA)
+ LDA #$0f ; skip over $4014 (OAMDMA)
STA $4015
LDA #$40
STA $4017
-SetupInterface:
-@cursor:
+SetupInterface:
+@cursor:
LDA #$88
- STA $0200 ; set tile.y pos
+ STA $0200 ; set tile.y pos
LDA #$02
- STA $0201 ; set tile.id
+ STA $0201 ; set tile.id
LDA #$00
- STA $0202 ; set tile.attribute
-@marker:
+ STA $0202 ; set tile.attribute
+@marker:
LDA #$88
- STA $0204 ; set tile.y pos
+ STA $0204 ; set tile.y pos
LDA #$03
- STA $0205 ; set tile.id
+ STA $0205 ; set tile.id
LDA #$00
- STA $0206 ; set tile.attribute
+ STA $0206 ; set tile.attribute
-EnableSprites:
- LDA #%10000000 ; enableNMI sprites0 background0
+EnableSprites:
+ LDA #%10000000 ; enableNMI sprites0 background0
STA PPUCTRL
- LDA #%00011110 ; sprites background noclip
+ LDA #%00011110 ; sprites background noclip
STA PPUMASK
;; main phase
-MAIN:
+MAIN:
LDA btnqueue
-@style1:
+@style1:
CMP BUTTON_LEFT
BEQ MoveLeft
CMP BUTTON_RIGHT
@@ 192,7 192,7 @@ MAIN:
BEQ MoveUp
CMP BUTTON_DOWN
BEQ MoveDown
-@style2:
+@style2:
CMP BUTTON_SELECT
BEQ ResetSequence
CMP BUTTON_START
@@ 201,69 201,69 @@ MAIN:
BEQ MoveUp
CMP BUTTON_B
BEQ MoveDown
- JMP MAIN ; infinite loop
+ JMP MAIN ; infinite loop
;; General functions
-MoveLeft:
+MoveLeft:
DEC cursor
LDA cursor
CMP #$ff
- BNE @done ; when equal skip
- LDA #$0f ; wrap around
+ BNE @done ; when equal skip
+ LDA #$0f ; wrap around
STA cursor
-@done:
+@done:
JMP MoveEnd
-MoveRight:
+MoveRight:
INC cursor
LDA cursor
CMP #$10
- BCC @done ; when greaterthan skip
- LDA #$00 ; wrap around
+ BCC @done ; when greaterthan skip
+ LDA #$00 ; wrap around
STA cursor
-@done:
+@done:
JMP MoveEnd
-MoveDown:
+MoveDown:
LDX cursor
DEC $10,x
LDA $10,x
- CMP #$ff ; when equal skip
- BNE @done ; wrap around
+ CMP #$ff ; when equal skip
+ BNE @done ; wrap around
LDA #$07
STA $10,x
-@done:
+@done:
JMP MoveEnd
-MoveUp:
+MoveUp:
LDX cursor
INC $10,x
LDA $10,x
- CMP #$08 ; when greaterthan skip
- BCC @done ; wrap around
+ CMP #$08 ; when greaterthan skip
+ BCC @done ; wrap around
LDA #$00
STA $10,x
-@done:
+@done:
JMP MoveEnd
-MoveMarker:
+MoveMarker:
LDA cursor
STA marker
STA RedrawInterface
JMP MoveEnd
-ResetSequence:
+ResetSequence:
LDX #$00
-@loop:
- LDA #$01 ; set entire sequence to "+"
- STA $10,x ; store on zeropage second row
+@loop:
+ LDA #$01 ; set entire sequence to "+"
+ STA $10,x ; store on zeropage second row
INX
CPX #$10
BNE @loop
JMP MoveEnd
-MoveEnd:
+MoveEnd:
LDA #$00
STA btnqueue
STA RedrawTimeline
@@ 271,30 271,30 @@ MoveEnd:
;; interface
-RedrawTimeline:
+RedrawTimeline:
LDX #$00
-@loop:
- LDA #$22 ; sprite v pos
+@loop:
+ LDA #$22 ; sprite v pos
STA PPUADDR
- TXA ; sprite x pos
+ TXA ; sprite x pos
STA PPUADDR
- LDA #$10, x ; find selection
+ LDA #$10, x ; find selection
CLC
ADC #$10
- CPX cursor ; if cursor
+ CPX cursor ; if cursor
BNE @continue
CLC
- ADC #$08 ; then, highlight
-@continue:
- STA PPUDATA ; sprite id
+ ADC #$08 ; then, highlight
+@continue:
+ STA PPUDATA ; sprite id
INX
CPX #$10
BNE @loop
RTS
-RedrawInterface:
+RedrawInterface:
LDA PPUSTATUS
-@selection:
+@selection:
LDA cursor
CLC
ADC #$20
@@ 303,7 303,7 @@ RedrawInterface:
STY PPUADDR
STX PPUADDR
STA PPUDATA
-@marker:
+@marker:
LDA marker
CLC
ADC #$20
@@ 312,7 312,7 @@ RedrawInterface:
STY PPUADDR
STX PPUADDR
STA PPUDATA
-@position:
+@position:
LDA position
CLC
ADC #$20
@@ 321,7 321,7 @@ RedrawInterface:
STY PPUADDR
STX PPUADDR
STA PPUDATA
-@rate:
+@rate:
LDA rate
CLC
ADC #$20
@@ 330,45 330,45 @@ RedrawInterface:
STY PPUADDR
STX PPUADDR
STA PPUDATA
-@sprites:
+@sprites:
LDA position
ASL
ASL
ASL
CLC
ADC #$40
- STA $0203 ; set tile.x pos
+ STA $0203 ; set tile.x pos
LDA marker
ASL
ASL
ASL
CLC
ADC #$40
- STA $0207 ; set tile.x pos
-@done:
+ STA $0207 ; set tile.x pos
+@done:
RTS
-IncNote:
+IncNote:
INC note
LDA note
CMP #$48
BNE @done
- LDA #$00 ; when reached end
- STA note ; reset note
-@done:
+ LDA #$00 ; when reached end
+ STA note ; reset note
+@done:
RTS
-DecNote:
+DecNote:
DEC note
LDA note
CMP #$ff
BNE @done
LDA #$47
STA note
-@done:
+@done:
RTS
-PlaySnare:
+PlaySnare:
LDA #<$3f8
STA APUCH4LEN
LDA #>$3f8
@@ 379,37 379,37 @@ PlaySnare:
;; operators
-DoInc:
+DoInc:
LDX #$00
-@loop:
+@loop:
JSR IncNote
CPX marker
INX
BCC @loop
JMP DoOperationEnd
-DoDec:
+DoDec:
LDX #$00
-@loop:
+@loop:
JSR DecNote
CPX marker
INX
BCC @loop
JMP DoOperationEnd
-DoTop:
+DoTop:
LDA #$24
STA note
JMP DoOperationEnd
-DoBottom:
+DoBottom:
LDA #$00
STA note
JMP DoOperationEnd
-DoRandomNote:
+DoRandomNote:
LDA seed
-@loop:
+@loop:
SEC
SBC #$48
CMP #$48
@@ 419,35 419,35 @@ DoRandomNote:
JSR PlaySnare
JMP DoOperationEnd
-DoIncMetro:
+DoIncMetro:
INC rate
LDA rate
CMP #$0c
BCC @done
LDA #$01
STA rate
-@done:
+@done:
JMP DoOperationEnd
-DoDecMetro:
+DoDecMetro:
DEC rate
LDA rate
CMP #$00
BNE @done
LDA #$0c
STA rate
-@done:
+@done:
JMP DoOperationEnd
-DoRandomPosition:
+DoRandomPosition:
LDA marker
STA position
JMP DoOperationEnd
-DoOperation:
+DoOperation:
LDX position
LDA $10,x
- CMP #$00 ;
+ CMP #$00
BEQ DoInc
CMP #$01
BEQ DoDec
@@ 467,23 467,23 @@ DoOperation:
DoOperationEnd: ; return from operations
RTS
-DoSound:
+DoSound:
LDX note
-@ch1:
+@ch1:
LDA NotesHi,x
STA APUCH1LEN
LDA NotesLo,x
STA APUCH1FRQ
LDY position
STY APUCH1SWP
-@ch2:
+@ch2:
LDA NotesHi,x
STA APUCH2LEN
LDA NotesLo,x
STA APUCH2FRQ
LDY marker
STY APUCH2SWP
-@ch3:
+@ch3:
LDA NotesHi,x
STA APUCH3LEN
LDA NotesLo,x
@@ 496,19 496,19 @@ DoSound:
NMI: ;
-ReadJoy:
+ReadJoy:
LDA #$01
- STA JOY1 ; start reading
+ STA JOY1 ; start reading
STA btndown
LSR a
STA JOY1
-@loop:
+@loop:
LDA JOY1
LSR a
ROL btndown
BCC @loop
-SaveJoy:
+SaveJoy:
LDA btndown
CMP btnlast
BEQ @done
@@ 516,39 516,39 @@ SaveJoy:
CMP #$00
BEQ @done
STA btnqueue
-@done:
+@done:
LDA #$00
STA SPRADDR
LDA #$02
STA $4014
-RunTimer:
+RunTimer:
INC seed
INC timer
LDA timer
- CMP rate ; check if timer has reached rate
- BNE @done ; skip if timer is less than rate
+ CMP rate ; check if timer has reached rate
+ BNE @done ; skip if timer is less than rate
LDA #$00
- STA timer ; reset timer
+ STA timer ; reset timer
JSR DoOperation
JSR DoSound
INC position
LDA position
- CMP #$10 ; check if position has reached 16
+ CMP #$10 ; check if position has reached 16
BNE @done
LDA #$00
STA position
-@done:
+@done:
-Cleanup:
+Cleanup:
JSR RedrawTimeline
JSR RedrawInterface
LDA PPUSTATUS
- LDA #$c0 ; shift background to center
+ LDA #$c0 ; shift background to center
STA PPUSCROLL
LDA #$00
STA PPUSCROLL
- RTI ; return from interrupt
+ RTI ; return from interrupt
;; tables
@@ 558,13 558,13 @@ Palettes: ;
.db $0F,$3B,$16,$30, $3B,$3B,$0F,$0F, $0F,$3B,$0F,$0F, $0F,$3B,$0F,$0F
.db $0F,$3B,$16,$3B, $0F,$3B,$0F,$0F, $0F,$0F,$0F,$0F, $0F,$0F,$0F,$0F
-ApuStates:
+ApuStates:
.db #%10100111,$08,$00,$00
.db #%00011101,$08,$00,$00
.db #%01011101,$08,$00,$00
.db #%01011011,$08,$00,$00
-NotesHi:
+NotesHi:
.db $07,$07,$07,$06,$06,$05,$05,$05,$05,$04,$04,$04
.db $03,$03,$03,$03,$03,$02,$02,$02,$02,$02,$02,$02
.db $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01
@@ 572,7 572,7 @@ NotesHi:
.db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
.db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
-NotesLo:
+NotesLo:
.db $f1,$7f,$13,$ad,$4d,$f3,$9d,$4c,$00,$b8,$74,$34
.db $f8,$bf,$89,$56,$26,$f9,$ce,$a6,$80,$5c,$3a,$1a
.db $fb,$df,$c4,$ab,$93,$7c,$67,$52,$3f,$2d,$1c,$0c
@@ 1,450 1,433 @@
-/* Lin6
- Version 1.2
+/*
+ Lin6
+ Version 1.3
https://wiki.xxiivv.com/lin6
-*/
-/* Rules:
Variable names must always be lowercase.
+ Variable names are always padded to tab1.
Variable length are always padded to col25.
Variable comments are always padded to col32.
Constant names must always be uppercase.
+ Constant names are always padded to tab1.
Constant length are always padded to col21.
Constant comments are always padded to col32.
Label names must always be capitalized.
- Label names aalways end with :.
+ Label names always end with :.
Label names are always preceeded with a linebreak.
Label comments are never padded.
- Directive names are always padded to col2.
+ Directive names are always padded to tab1.
+ Directive names are always lowercase.
Directive comments are never padded.
Opcode names are always uppercase.
- Opcode names are always padded to col2.
+ Opcode names are always padded to tab1.
Opcode comments are always padded to col32.
- Inline comments are always padded to col2.
+ Inline comments are always padded to tab1.
Spacing comments are always preceeded and followed with a linebreak.
*/
-#include <ctype.h>
#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#define VERSION "1.2"
+#define VERSION "1.3"
#define BUFLEN 512
-typedef enum { false, true } bool;
+char* OPCODES[] = {"ADC", "AND", "ASL", "BCC", "BCS", "BEQ", "BIT", "BMI",
+ "BNE", "BPL", "BRK", "BVC", "BVS", "CLC", "CLD", "CLI",
+ "CLV", "CMP", "CPX", "CPY", "DEC", "DEX", "DEY", "EOR",
+ "INC", "INX", "INY", "JMP", "JSR", "LDA", "LDX", "LDY",
+ "LSR", "NOP", "ORA", "PHA", "PHP", "PLA", "PLP", "ROL",
+ "ROR", "RTI", "RTS", "SBC", "SEC", "SED", "SEI", "STA",
+ "STX", "STY", "TAX", "TAY", "TSX", "TXA", "TXS", "TYA"};
-char *OPCODES[] = {"ADC", "AND", "ASL", "BCC", "BCS", "BEQ", "BIT", "BMI",
- "BNE", "BPL", "BRK", "BVC", "BVS", "CLC", "CLD", "CLI",
- "CLV", "CMP", "CPX", "CPY", "DEC", "DEX", "DEY", "EOR",
- "INC", "INX", "INY", "JMP", "JSR", "LDA", "LDX", "LDY",
- "LSR", "NOP", "ORA", "PHA", "PHP", "PLA", "PLP", "ROL",
- "ROR", "RTI", "RTS", "SBC", "SEC", "SED", "SEI", "STA",
- "STX", "STY", "TAX", "TAY", "TSX", "TXA", "TXS", "TYA"};
+int skipped = 0;
-void substr(char *src, char *dest, int from, int to) {
- memcpy(dest, src + from, to);
- dest[to] = '\0';
+int
+cisp(char c)
+{
+ return c == ' ' || c == '\t' || c == '\n' || c == '\r';
}
-void trimstr(char *src, char *dest) {
- /* leading whitespace */
- int a, b, len = strlen(src) + 1;
- for (a = 0; a < len; a++) {
- if (src[a] != ' ' && src[a] != '\t') {
- break;
- }
- }
- /* traling whitespace */
- for (b = 2; b < len; b++) {
- if (src[len - b] != ' ' && src[len - b] != '\n') {
- break;
- }
- }
- substr(src, dest, a, len - b - a + 1);
+int
+clca(int c)
+{
+ return c >= 'A' && c <= 'Z' ? c + ('a' - 'A') : c;
}
-void fillstr(char *src, int limit, char c) {
- int i, len = strlen(src);
- for (i = len; i < limit; i++) {
- src[i] = c;
- }
- src[limit] = '\0';
+int
+cuca(char c)
+{
+ return c >= 'a' && c <= 'z' ? c - ('a' - 'A') : c;
}
-void swapcstr(char *src, char a, char b) {
- int i, len = strlen(src);
- for (i = 0; i < len; i++) {
- src[i] = src[i] == a ? b : src[i];
- }
+int
+ciuc(char c)
+{
+ return c == cuca(c);
}
-void cpystr(char *src, char *dest) {
- int i, len = strlen(src);
- for (i = 0; i < len; i++) {
- dest[i] = src[i];
- }
- dest[len] = '\0';
+int
+cilc(char c)
+{
+ return c == clca(c);
}
-void ucstr(char *src) {
- int i, len = strlen(src);
- for (i = 0; i < len; i++) {
- src[i] = toupper(src[i]);
- }
+char*
+sstr(char* src, char* dest, int from, int to)
+{
+ int i;
+ char *a = (char*)src + from, *b = (char*)dest;
+ for(i = 0; i < to; i++)
+ b[i] = a[i];
+ dest[to] = '\0';
+ return dest;
}
-void lcstr(char *src) {
- int i, len = strlen(src);
- for (i = 0; i < len; i++) {
- src[i] = tolower(src[i]);
- }
+int
+slen(char* s)
+{
+ int n = 0;
+ while(s[n] != '\0' && s[++n])
+ ;
+ return n;
+}
+
+int
+silc(char* s)
+{
+ int i;
+ for(i = 0; i < slen(s); i++)
+ if(!cilc(s[i]))
+ return 0;
+ return 1;
+}
+
+int
+siuc(char* s)
+{
+ int i;
+ for(i = 0; i < slen(s); i++)
+ if(!ciuc(s[i]))
+ return 0;
+ return 1;
}
-int index_of_comment(char *src) {
- int i, len = strlen(src);
- for (i = 0; i < len; i++) {
- if (src[i] == ';') {
+int
+cpos(char* s, char c)
+{
+ int i;
+ for(i = 0; i < slen(s); i++)
+ if(s[i] == c)
return i;
- }
- }
return -1;
}
-bool opcode_exists(char *opcode) {
- int i;
- for (i = 0; i < 56; i++) {
- if (strcmp(OPCODES[i], opcode) == 0) {
- return true;
- }
- }
- return false;
+char*
+scat(char* dest, const char* src)
+{
+ char* ptr = dest + slen(dest);
+ while(*src != '\0')
+ *ptr++ = *src++;
+ *ptr = '\0';
+ return dest;
}
-bool file_exists(char *filename) {
- FILE *file = fopen(filename, "r");
- if (file != NULL) {
- fclose(file);
- return true;
- }
- return false;
+int
+scmp(char* a, char* b)
+{
+ int i, l = slen(a);
+ if(l != slen(b))
+ return 0;
+ for(i = 0; i < l; ++i)
+ if(a[i] != b[i])
+ return 0;
+ return 1;
}
-void set_line_key(char *src, char *dest) {
- int i, len = strlen(src);
- for (i = 0; i < len; i++) {
- if (src[i] == ' ') {
- break;
- }
- }
- substr(src, dest, 0, i);
- trimstr(dest, dest);
+char*
+suca(char* s)
+{
+ int i;
+ for(i = 0; i < slen(s); i++)
+ s[i] = cuca(s[i]);
+ return s;
}
-void set_line_value(char *src, char *dest) {
- bool step = false;
- int i, comment = index_of_comment(src), len = strlen(src);
- if (comment > -1) {
- len = comment;
- }
- for (i = 0; i < len; i++) {
- if (src[i] != ' ' && step == true) {
- break;
- } else if (src[i] == ' ') {
- step = true;
- }
- }
- substr(src, dest, i, len - i);
- trimstr(dest, dest);
+char*
+slca(char* s)
+{
+ int i;
+ for(i = 0; i < slen(s); i++)
+ s[i] = clca(s[i]);
+ return s;
}
-void set_line_comment(char *src, char *dest) {
- int i, len = strlen(src);
- for (i = 0; i < len; i++) {
- if (src[i] == ';') {
- break;
- }
- }
- substr(src, dest, i, len - i);
- trimstr(dest, dest);
+char*
+strm(char* s)
+{
+ char* end;
+ while(cisp(*s))
+ s++;
+ if(*s == 0)
+ return s;
+ end = s + slen(s) - 1;
+ while(end > s && cisp(*end))
+ end--;
+ end[1] = '\0';
+ return s;
}
-bool has_comment(char *line) {
- int i, len = strlen(line);
- for (i = 0; i < len; i++) {
- if (line[i] == ';') {
- return true;
+int
+spos(char* a, char* b)
+{
+ int i, j, alen = slen(a), blen = slen(b);
+ for(i = 0; i < alen; i++) {
+ for(j = 0; j < blen; j++) {
+ if(a[i + j] == '\0')
+ return -1;
+ if(a[i + j] != b[j])
+ break;
+ if(j == blen - 1)
+ return i;
}
}
- return false;
+ return -1;
}
-bool is_capital(char *str) { return str[0] == toupper(str[0]); }
+char*
+scpy(char* src, char* dest)
+{
+ int i = 0;
+ while((dest[i] = src[i]) != '\0')
+ i++;
+ return dest;
+}
-bool is_lower(char *str) {
- int i, len = strlen(str);
- for (i = 0; i < len; i++) {
- if (str[i] != tolower(str[i])) {
- return false;
- }
- }
- return true;
+void
+setkey(char* src, char* dst)
+{
+ sstr(src, dst, 0, cpos(src, ' ') > 0 ? cpos(src, ' ') : slen(src));
}
-bool is_upper(char *str) {
- int i, len = strlen(str);
- for (i = 0; i < len; i++) {
- if (str[i] != toupper(str[i])) {
- return false;
- }
+void
+setval(char* src, char* dst)
+{
+ int step = 0, i, comment = cpos(src, ';'), len = slen(src);
+ if(comment > -1)
+ len = comment;
+ for(i = 0; i < len; i++) {
+ if(src[i] != ' ' && step == 1)
+ break;
+ else if(src[i] == ' ')
+ step = 1;
}
- return true;
+ sstr(src, dst, i, len - i);
+ scpy(strm(dst), dst);
}
-bool is_label(char *line) {
- int i, len = strlen(line);
- for (i = 0; i < len; i++) {
- if (line[i] == ' ' || line[i] == ';') {
- return false;
- }
- if (line[i] == ':') {
- return true;
- }
+void
+setcmt(char* src, char* dst)
+{
+ if(cpos(src, ';') > 0)
+ sstr(src, dst, cpos(src, ';'), slen(src) - cpos(src, ';'));
+ else
+ scpy("", dst);
+ scpy(strm(dst), dst);
+}
+
+int
+islabel(char* line)
+{
+ int i;
+ for(i = 0; i < slen(line); i++) {
+ if(line[i] == ' ' || line[i] == ';')
+ return 0;
+ if(line[i] == ':')
+ return 1;
}
- return false;
+ return 0;
}
-bool is_opcode(char *line) {
+int
+isopcode(char* line)
+{
+ int i;
char opcode[4];
- substr(line, opcode, 0, 3);
- ucstr(opcode);
- return opcode_exists(opcode);
+ suca(sstr(line, opcode, 0, 3));
+ for(i = 0; i < 56; i++)
+ if(scmp(OPCODES[i], opcode))
+ return 1;
+ return 0;
}
-bool is_directive(char *line) { return line[0] == '.'; }
+int
+iscomment(char* line)
+{
+ return line[0] == ';';
+}
-bool is_spacer_comment(char *line) { return line[0] == ';' && line[1] == ';'; }
+int
+isdirective(char* line)
+{
+ return line[0] == '.';
+}
-bool is_inline_comment(char *line) { return line[0] == ';' && line[1] == ' '; }
+int
+isvariable(char* line)
+{
+ return spos(line, ".dsb") > 0;
+}
-bool is_variable(char *line) {
- int i, len = strlen(line);
- for (i = 0; i < len; i++) {
- if (line[i] == '.' && line[i + 1] == 'd' && line[i + 2] == 's' &&
- line[i + 3] == 'b') {
- return true;
- }
- }
- return false;
+int
+isconstant(char* line)
+{
+ return spos(line, ".equ") > 0;
}
-bool is_constant(char *line) {
- int i, len = strlen(line);
- for (i = 0; i < len; i++) {
- if (line[i] == '.' && line[i + 1] == 'e' && line[i + 2] == 'q' &&
- line[i + 3] == 'u') {
- return true;
- }
- }
- return false;
+void
+dolabel(char* src)
+{
+ char key[BUFLEN], cmt[BUFLEN];
+ setkey(src, key);
+ setcmt(src, cmt);
+ key[0] = cuca(key[0]);
+ if(key[0] == '@' || skipped)
+ printf("%s %s\n", key, cmt);
+ else
+ printf("\n%s %s\n", key, cmt);
+ skipped = 0;
}
-void save(char *filepath, char *output, bool do_inplace) {
- if (do_inplace) {
- FILE *fw = fopen(filepath, "w");
- fprintf(fw, "%s", output);
- fclose(fw);
+void
+doopcode(char* src)
+{
+ char key[BUFLEN], val[BUFLEN], cmt[BUFLEN];
+ setkey(src, key);
+ suca(key);
+ setval(src, val);
+ setcmt(src, cmt);
+ if(slen(cmt) > 1)
+ printf("\t%s %-30s %s\n", key, val, cmt);
+ else
+ printf("\t%s %s\n", key, val);
+ skipped = 0;
+}
+
+void
+docomment(char* src)
+{
+ if(src[0] == src[1]) {
+ printf("\n%s\n\n", src);
+ skipped = 1;
} else {
- printf("%s\n", output);
+ printf("\t%s\n", src);
+ skipped = 0;
}
}
-void lint(char *filepath, char *output, bool do_debug) {
- FILE *fr = fopen(filepath, "r");
- int id = 0, len, count = 0, opcodes = 0, directives = 0, spacers = 0,
- labels = 0, variables = 0, constants = 0, comments = 0;
- bool skipped_last = false;
- char line[BUFLEN];
- char trimed[BUFLEN];
- while (fgets(line, BUFLEN, fr)) {
- id++;
- trimstr(line, trimed);
- swapcstr(trimed, '\t', ' ');
- len = strlen(trimed);
- if (len < 3) {
+void
+dodirective(char* src)
+{
+ char key[BUFLEN], val[BUFLEN], cmt[BUFLEN];
+ setkey(src, key);
+ slca(key);
+ setval(src, val);
+ setcmt(src, cmt);
+ if(slen(cmt) > 1)
+ printf("\t%s %s %s\n", key, val, cmt);
+ else
+ printf("\t%s %s\n", key, val);
+ skipped = 0;
+}
+
+void
+dovariable(char* src)
+{
+ char key[BUFLEN], val[BUFLEN], cmt[BUFLEN];
+ setkey(src, key);
+ slca(key);
+ setval(src, val);
+ setcmt(src, cmt);
+ if(slen(cmt) > 1)
+ printf("\t%-23s %-10s %s\n", key, val, cmt);
+ else
+ printf("\t%-23s %s\n", key, val);
+ skipped = 0;
+}
+
+void
+doconstant(char* src)
+{
+ char key[BUFLEN], val[BUFLEN], cmt[BUFLEN];
+ setkey(src, key);
+ suca(key);
+ setval(src, val);
+ setcmt(src, cmt);
+ printf("\t%-23s %-10s %s\n", key, val, cmt);
+ skipped = 0;
+}
+
+void
+lint(FILE* f)
+{
+ char line[BUFLEN], trimed[BUFLEN];
+ while(fgets(line, BUFLEN, f)) {
+ scpy(strm(line), trimed);
+ if(slen(trimed) < 3)
continue;
- }
- if (is_label(trimed)) {
- char key[BUFLEN];
- char comment[BUFLEN];
- set_line_key(trimed, key);
- set_line_comment(trimed, comment);
- if (!is_capital(key)) {
- printf("Lin6: Label %s not capitalized, at %s:%d.\n", key, filepath,
- id);
- }
- if (key[0] != '@' && !skipped_last) {
- strcat(output, "\n");
- }
- if (has_comment(line)) {
- strcat(output, key);
- strcat(output, " ");
- strcat(output, comment);
- } else {
- strcat(output, key);
- }
- skipped_last = false;
- labels++;
- } else if (is_opcode(trimed)) {
- char key[BUFLEN];
- char value[BUFLEN];
- char comment[BUFLEN];
- set_line_key(trimed, key);
- set_line_value(trimed, value);
- set_line_comment(trimed, comment);
- ucstr(key);
- strcat(output, "\t");
- strcat(output, key);
- strcat(output, " ");
- if (has_comment(line)) {
- fillstr(value, 24, ' ');
- strcat(output, value);
- strcat(output, " ");
- strcat(output, comment);
- } else {
- strcat(output, value);
- }
- skipped_last = false;
- opcodes++;
- } else if (is_directive(trimed)) {
- char key[BUFLEN];
- char value[BUFLEN];
- char comment[BUFLEN];
- set_line_key(trimed, key);
- set_line_value(trimed, value);
- set_line_comment(trimed, comment);
- strcat(output, "\t");
- strcat(output, key);
- strcat(output, " ");
- if (has_comment(line)) {
- strcat(output, value);
- strcat(output, " ");
- strcat(output, comment);
- } else {
- strcat(output, value);
- }
- skipped_last = false;
- directives++;
- } else if (is_inline_comment(trimed)) {
- strcat(output, "\t");
- strcat(output, trimed);
- skipped_last = false;
- comments++;
- } else if (is_spacer_comment(trimed)) {
- strcat(output, "\n");
- strcat(output, trimed);
- strcat(output, "\n");
- skipped_last = true;
- spacers++;
- } else if (is_variable(trimed)) {
- char key[BUFLEN];
- char value[BUFLEN];
- char comment[BUFLEN];
- set_line_key(trimed, key);
- set_line_value(trimed, value);
- set_line_comment(trimed, comment);
- fillstr(key, 24, ' ');
- if (!is_lower(key)) {
- printf("Lin6: Variable %s not lowercase, at %s:%d.\n", key, filepath,
- id);
- }
- strcat(output, key);
- strcat(output, value);
- strcat(output, " ");
- strcat(output, comment);
- skipped_last = false;
- variables++;
- } else if (is_constant(trimed)) {
- char key[BUFLEN];
- char value[BUFLEN];
- char comment[BUFLEN];
- set_line_key(trimed, key);
- set_line_value(trimed, value);
- set_line_comment(trimed, comment);
- fillstr(key, 20, ' ');
- if (!is_upper(key)) {
- printf("Lin6: Constant %s not uppercase, at %s:%d.\n", key, filepath,
- id);
- }
- strcat(output, key);
- strcat(output, value);
- strcat(output, " ");
- strcat(output, comment);
- skipped_last = false;
- constants++;
- } else {
- printf("Lin6: Unknown line-type, at %s:%d.\n", filepath, id);
- strcat(output, line);
- }
- strcat(output, "\n");
- count++;
- }
- if (do_debug) {
- printf("Lin6 debug: %d lines: \n", count);
- printf("\t%d labels\n", labels);
- printf("\t%d opcodes\n", opcodes);
- printf("\t%d directives\n", directives);
- printf("\t%d spacers\n", spacers);
- printf("\t%d variables\n", variables);
- printf("\t%d constants\n", constants);
+ if(islabel(trimed))
+ dolabel(trimed);
+ else if(isopcode(trimed))
+ doopcode(trimed);
+ else if(iscomment(trimed))
+ docomment(trimed);
+ else if(isdirective(trimed))
+ dodirective(trimed);
+ else if(isvariable(trimed))
+ dovariable(trimed);
+ else if(isconstant(trimed))
+ doconstant(trimed);
+ else
+ printf("%s\n", line);
}
- fclose(fr);
+ fclose(f);
}
-void show_version(void) { puts("Lin6 " VERSION); }
+int
+version(void)
+{
+ puts("Lin6 " VERSION);
+ return 0;
+}
-void show_help(void) {
- show_version();
+int
+help(void)
+{
+ version();
puts("");
puts("A tool to format 6502 assembly code.\n");
puts("Usage: Lin6 [-options] [<file> ...]\n");
puts("\t-?\tShow this help");
puts("\t-v\tShow version");
- puts("\t-i\tInplace edit files");
- puts("\t-d\tShow debug\n");
puts("See README for more info.\n");
+ return 0;
}
-int main(int argc, char *argv[]) {
- bool do_debug = false, do_inplace = false;
+int
+main(int argc, char* argv[])
+{
+ FILE* f;
int i;
- if (argc < 2) {
- show_help();
- exit(0);
- }
- for (i = 1; i < argc; i++) {
- if (argv[i][1] == '?') {
- show_help();
- exit(0);
- } else if (argv[i][1] == 'v') {
- show_version();
- exit(0);
- }
- /* read flags */
- if (argv[i][1] == 'd') {
- do_debug = true;
- } else if (argv[i][1] == 'i') {
- do_inplace = true;
- }
- /* do files */
+ if(argc < 2)
+ return help();
+ for(i = 1; i < argc; i++) {
+ if(argv[i][1] == '?')
+ return help();
+ else if(argv[i][1] == 'v')
+ return version();
else {
- char linted[51200];
- if (!file_exists(argv[i])) {
- printf("Lin6: File %s not found\n", argv[i]);
- exit(0);
- }
- lint(argv[i], linted, do_debug);
- save(argv[i], linted, do_inplace);
+ f = fopen(argv[i], "r");
+ if(f != NULL)
+ lint(f);
}
}
return 0;
-}>
\ No newline at end of file
+}